Sat Aug 6 00:39:47 2011

Asterisk developer's documentation


chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

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

Go to the source code of this file.

Data Structures

struct  ast_peer_list
 The peer list: Peers and Friends. More...
struct  ast_register_list
 The register list: Other SIP proxys we register with and place calls to. More...
struct  ast_user_list
 The user list: Users and friends. More...
struct  c_referstatusstring
struct  cfsip_methods
struct  cfsip_options
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More...
struct  cfsubscription_types
struct  domain
 Domain data structure. More...
struct  domain_list
struct  offered_media
struct  provisional_keepalive_data
 provisional keep alive scheduler item data More...
struct  sip_auth
 sip_auth: Credentials for authentication to other SIP services More...
struct  sip_dual
 structure used in transfers More...
struct  sip_extenstate_update
struct  sip_extenstate_updates
 list of extension state updates for the dialog list. More...
struct  sip_history
 sip_history: Structure for saving transactions within a SIP dialog More...
struct  sip_history_head
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_pvt::request_queue
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  sip_via
 Structure to store Via information. 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, INFO"
 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   "Anonymous"
#define CAN_CREATE_DIALOG   1
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2
#define CAN_NOT_CREATE_DIALOG   0
#define CHECK_AUTH_BUF_INITLEN   256
#define DEC_CALL_LIMIT   0
#define DEC_CALL_RINGING   2
#define DEFAULT_ALLOW_EXT_DOM   TRUE
#define DEFAULT_ALLOWGUEST   TRUE
#define DEFAULT_AUTOCREATEPEER   FALSE
#define DEFAULT_CALLERID   "asterisk"
#define DEFAULT_COMPACTHEADERS   FALSE
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DEFAULT_EXPIRY   120
#define DEFAULT_EXPIRY   900
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_CALL_BITRATE   (384)
#define DEFAULT_MAX_EXPIRY   3600
#define DEFAULT_MAX_FORWARDS   "70"
#define DEFAULT_MAXMS   2000
#define DEFAULT_MIN_EXPIRY   60
#define DEFAULT_MOHINTERPRET   "default"
#define DEFAULT_MOHSUGGEST   ""
#define DEFAULT_MWITIME   10
#define DEFAULT_NOTIFYMIME   "application/simple-message-summary"
#define DEFAULT_NOTIFYRINGING   TRUE
#define DEFAULT_PEDANTIC   FALSE
#define DEFAULT_QUALIFY   FALSE
#define DEFAULT_REALM   "asterisk"
#define DEFAULT_REGISTRATION_TIMEOUT   20
#define DEFAULT_RETRANS   1000
#define DEFAULT_SRVLOOKUP   TRUE
#define DEFAULT_T1MIN   100
#define DEFAULT_TOS_AUDIO   0
#define DEFAULT_TOS_SIP   0
#define DEFAULT_TOS_VIDEO   0
#define DEFAULT_TRANS_TIMEOUT   -1
#define DEFAULT_USERAGENT   "Asterisk PBX"
#define DEFAULT_VMEXTEN   "asterisk"
#define EXPIRY_GUARD_LIMIT   30
#define EXPIRY_GUARD_MIN   500
#define EXPIRY_GUARD_PCT   0.20
#define EXPIRY_GUARD_SECS   15
#define FALSE   0
#define FLAG_FATAL   (1 << 1)
#define FLAG_RESPONSE   (1 << 0)
#define FORMAT   "%-15.15s %-15.15s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n"
#define FORMAT   "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n"
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
#define FORMAT   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT2   "%-15.15s %-15.15s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n"
#define FORMAT2   "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n"
#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3H   "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n"
#define FORMAT3L   "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n"
#define FROMDOMAIN_INVALID   "anonymous.invalid"
#define INC_CALL_LIMIT   1
#define INC_CALL_RINGING   3
#define INITIAL_CSEQ   101
#define IPTOS_MINCOST   0x02
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MAX_AUTHTRIES   3
#define MAX_HISTORY_ENTRIES   50
#define MAX_RETRANS   6
#define NO_RTP   0
#define NOT_SUPPORTED   0
#define PROVIS_KEEPALIVE_TIMEOUT   60000
#define RTP   1
#define SDP_MAX_RTPMAP_CODECS   32
#define SDP_SAMPLE_RATE(x)   8000
#define SIP_ALREADYGONE   (1 << 0)
#define SIP_CALL_LIMIT   (1 << 28)
#define SIP_CAN_REINVITE   (1 << 20)
#define SIP_CAN_REINVITE_NAT   (2 << 20)
#define SIP_DEFER_BYE_ON_TRANSFER   (1 << 15)
#define SIP_DTMF   (3 << 16)
#define SIP_DTMF_AUTO   (3 << 16)
#define SIP_DTMF_INBAND   (1 << 16)
#define SIP_DTMF_INFO   (2 << 16)
#define SIP_DTMF_RFC2833   (0 << 16)
#define SIP_FLAGS_TO_COPY
#define SIP_FREE_BIT   (1 << 14)
#define SIP_G726_NONSTANDARD   (1 << 31)
#define SIP_GOTREFER   (1 << 7)
#define SIP_INC_COUNT   (1 << 30)
#define SIP_INSECURE_INVITE   (1 << 24)
#define SIP_INSECURE_PORT   (1 << 23)
#define SIP_MAX_HEADERS   64
#define SIP_MAX_LINES   64
#define SIP_MAX_PACKET   4096
#define SIP_NAT   (3 << 18)
#define SIP_NAT_ALWAYS   (3 << 18)
#define SIP_NAT_NEVER   (0 << 18)
#define SIP_NAT_RFC3581   (1 << 18)
#define SIP_NAT_ROUTE   (2 << 18)
#define SIP_NEEDDESTROY   (1 << 1)
#define SIP_NEEDREINVITE   (1 << 5)
#define SIP_NO_HISTORY   (1 << 27)
#define SIP_NOVIDEO   (1 << 2)
#define SIP_OPT_100REL   (1 << 1)
#define SIP_OPT_EARLY_SESSION   (1 << 3)
#define SIP_OPT_EVENTLIST   (1 << 11)
#define SIP_OPT_GRUU   (1 << 12)
#define SIP_OPT_HISTINFO   (1 << 15)
#define SIP_OPT_JOIN   (1 << 4)
#define SIP_OPT_NOREFERSUB   (1 << 14)
#define SIP_OPT_PATH   (1 << 5)
#define SIP_OPT_PRECONDITION   (1 << 7)
#define SIP_OPT_PREF   (1 << 6)
#define SIP_OPT_PRIVACY   (1 << 8)
#define SIP_OPT_REPLACES   (1 << 0)
#define SIP_OPT_RESPRIORITY   (1 << 16)
#define SIP_OPT_SDP_ANAT   (1 << 9)
#define SIP_OPT_SEC_AGREE   (1 << 10)
#define SIP_OPT_TARGET_DIALOG   (1 << 13)
#define SIP_OPT_TIMER   (1 << 2)
#define SIP_OUTGOING   (1 << 13)
#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)
#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)
#define SIP_PAGE2_BUGGY_MWI   (1 << 26)
#define SIP_PAGE2_CALL_ONHOLD   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (2 << 23)
#define SIP_PAGE2_DEBUG   (3 << 11)
#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)
#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)
#define SIP_PAGE2_DIALOG_ESTABLISHED   (1 << 29)
#define SIP_PAGE2_DYNAMIC   (1 << 13)
#define SIP_PAGE2_FLAGS_TO_COPY
#define SIP_PAGE2_FORWARD_LOOP_DETECTED   (1 << 31)
#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_RPORT_PRESENT   (1 << 30)
#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)
#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)
#define SIP_PAGE2_RTUPDATE   (1 << 1)
#define SIP_PAGE2_SELFDESTRUCT   (1 << 14)
#define SIP_PAGE2_STATECHANGEQUEUE   (1 << 9)
#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)
#define SIP_PAGE2_T38SUPPORT   (7 << 20)
#define SIP_PAGE2_T38SUPPORT_RTP   (2 << 20)
#define SIP_PAGE2_T38SUPPORT_TCP   (4 << 20)
#define SIP_PAGE2_T38SUPPORT_UDPTL   (1 << 20)
#define SIP_PAGE2_UDPTL_DESTINATION   (1 << 28)
#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)
#define SIP_PENDINGBYE   (1 << 6)
#define SIP_PKT_DEBUG   (1 << 0)
#define SIP_PKT_IGNORE   (1 << 2)
#define SIP_PKT_IGNORE_REQ   (1 << 4)
#define SIP_PKT_WITH_TOTAG   (1 << 1)
#define SIP_PROG_INBAND   (3 << 25)
#define SIP_PROG_INBAND_NEVER   (0 << 25)
#define SIP_PROG_INBAND_NO   (1 << 25)
#define SIP_PROG_INBAND_YES   (2 << 25)
#define SIP_PROGRESS_SENT   (1 << 4)
#define SIP_PROMISCREDIR   (1 << 8)
#define SIP_REALTIME   (1 << 11)
#define SIP_REINVITE   (7 << 20)
#define SIP_REINVITE_UPDATE   (4 << 20)
#define SIP_RINGING   (1 << 3)
#define SIP_SENDRPID   (1 << 29)
#define SIP_TRANS_TIMEOUT   32000
#define SIP_TRUSTRPID   (1 << 9)
#define SIP_USECLIENTCODE   (1 << 12)
#define SIP_USEREQPHONE   (1 << 10)
#define SIPBUFSIZE   512
#define sipdebug   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG)
#define sipdebug_config   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG)
#define sipdebug_console   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE)
#define STANDARD_SIP_PORT   5060
 Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
#define SUPPORTED   1
#define SUPPORTED_EXTENSIONS   "replaces"
 SIP Extensions we support.
#define T38FAX_FILL_BIT_REMOVAL   (1 << 0)
#define T38FAX_RATE_12000   (1 << 12)
#define T38FAX_RATE_14400   (1 << 13)
#define T38FAX_RATE_2400   (1 << 8)
#define T38FAX_RATE_4800   (1 << 9)
#define T38FAX_RATE_7200   (1 << 10)
#define T38FAX_RATE_9600   (1 << 11)
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF   (1 << 3)
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)
#define T38FAX_TRANSCODING_JBIG   (1 << 2)
#define T38FAX_TRANSCODING_MMR   (1 << 1)
#define T38FAX_UDP_EC_FEC   (1 << 4)
#define T38FAX_UDP_EC_NONE   (0 << 4)
#define T38FAX_UDP_EC_REDUNDANCY   (2 << 4)
#define T38FAX_VERSION   (3 << 6)
#define T38FAX_VERSION_0   (0 << 6)
#define T38FAX_VERSION_1   (1 << 6)
#define TRUE   1
#define UNLINK(element, head, prev)
#define VIDEO_CODEC_MASK   0x1fc0000
#define XMIT_ERROR   -2

Enumerations

enum  check_auth_result {
  AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2,
  AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6,
  AUTH_ACL_FAILED = -7
}
 Authentication result from check_auth* functions. More...
enum  domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG }
 Modes for SIP domain handling in the PBX. More...
enum  invitestates {
  INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3,
  INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7
}
 States for the INVITE transaction, not the dialog. More...
enum  media_type { SDP_AUDIO, SDP_VIDEO, SDP_IMAGE }
enum  parse_register_result { PARSE_REGISTER_DENIED, 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_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 __reg_module (void)
static int __set_address_from_contact (const char *fullcontact, struct sockaddr_in *sin)
static int __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acknowledges receipt of a packet and stops retransmission called with p locked.
static int __sip_autodestruct (const void *data)
 Kill a SIP dialog (called by scheduler).
static int __sip_destroy (struct sip_pvt *p, int lockowner)
 Execute destruction of SIP dialog structure, release memory.
static int __sip_do_register (struct sip_registry *r)
 Register with SIP proxy.
static void __sip_pretend_ack (struct sip_pvt *p)
 Pretend to ack all packets called with p locked.
static int __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod)
 Transmit packet with retransmits.
static int __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acks receipt of packet, keep it around (used for provisional responses).
static int __sip_show_channels (int fd, int argc, char *argv[], int subscriptions)
 SIP show channels CLI (main function).
static int __sip_xmit (struct sip_pvt *p, char *data, int len)
 Transmit SIP message.
static int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Base transmit response function.
static void __unreg_module (void)
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_content (struct sip_request *req, const char *line)
 Add content (not header) to SIP message.
static int add_digit (struct sip_request *req, char digit, unsigned int duration)
 Add DTMF INFO tone to sip message.
static int add_extensionstate_update (char *context, char *exten, int state, void *data)
static int add_header (struct sip_request *req, const char *var, const char *value)
 Add 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, int add_audio, int add_t38)
 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_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 int addr_is_multicast (struct in_addr *addr)
 Check if an ip is an multicast IP. addr the address to check.
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 append_history_va (struct sip_pvt *p, const char *fmt, va_list ap)
 Append to SIP dialog history with arg list.
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?
static int attempt_transfer (struct sip_dual *transferer, struct sip_dual *target)
 Attempt transfer of SIP call This fix for attended transfers on a local PBX.
static int auto_congest (const void *nothing)
 Scheduled congestion on a call.
static void build_callid_pvt (struct sip_pvt *pvt)
 Build SIP Call-ID value for a non-REGISTER transaction.
static void build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain)
 Build SIP Call-ID value for a REGISTER transaction.
static void build_contact (struct sip_pvt *p)
 Build contact header - the contact header we send out.
static struct sip_peerbuild_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
 Build peer from configuration (file or realtime static/dynamic).
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 Build reply digest.
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 Build route list from Record-Route header.
static void build_rpid (struct sip_pvt *p)
 Build the Remote Party-ID & From using callingpres options.
static struct sip_userbuild_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
 Initiate a SIP user structure from configuration (configuration or realtime).
static void build_via (struct sip_pvt *p)
 Build a Via header for a request.
static void change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
 Change hold state for a call.
static enum check_auth_result check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore)
 Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
static void check_auth_buf_init (void)
static void check_extenstate_updates (struct sip_pvt *pvt)
static void check_pendings (struct sip_pvt *p)
 Check pending actions on SIP call.
static int check_sip_domain (const char *domain, char *context, size_t len)
 check_sip_domain: Check if domain part of uri is local to our server
static int check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin)
 Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
static enum check_auth_result check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer)
 Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
static void check_via (struct sip_pvt *p, const struct sip_request *req)
 check Via: header for hostname, port and rport request/answer
static void cleanup_stale_contexts (char *new, char *old)
 Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
static void clear_extenstate_updates (struct sip_pvt *pvt)
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 void clearmarked_extenstate_updates (void)
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, struct sockaddr_in *sin)
 create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
static int create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer)
 Create address structure from peer reference. return -1 on error, 0 on success.
static void destroy_association (struct sip_peer *peer)
 Remove registration data from realtime database or AST/DB when registration expires.
static int determine_firstline_parts (struct sip_request *req)
 Parse first line of incoming SIP request.
static void * do_monitor (void *data)
 The SIP monitoring thread.
static int do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init)
 Add authentication on outbound SIP packet.
static int do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader)
 Authenticate for outbound registration.
static void do_setnat (struct sip_pvt *p, int natflags)
 Set nat mode on the various data sockets.
static int does_peer_need_mwi (struct sip_peer *peer)
 Check whether peer needs a new MWI notification check.
static const char * domain_mode_to_text (const enum domain_mode mode)
 Print domain mode to cli.
static const char * dtmfmode2str (int mode)
 Convert DTMF mode to printable string.
static int expire_register (const void *data)
 Expire registration of SIP peer.
static void extract_uri (struct sip_pvt *p, struct sip_request *req)
 Check Contact: URI of SIP message.
static int finalize_content (struct sip_request *req)
 Add 'Content-Length' header to SIP message.
static const char * find_alias (const char *name, const char *_default)
 Find compressed SIP alias.
static struct sip_pvtfind_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
 Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
static const char * find_closing_quote (const char *start, const char *lim)
 Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.
static struct sip_peerfind_peer (const char *peer, struct sockaddr_in *sin, int realtime, int devstate_only)
 Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
static struct sip_authfind_realm_authentication (struct sip_auth *authlist, const char *realm)
 Find authentication for a specific realm.
static int find_sdp (struct sip_request *req)
 Determine whether a SIP message contains an SDP in its body.
static int find_sip_method (const char *msg)
 find_sip_method: Find SIP method from header
static struct cfsubscription_typesfind_subscription_type (enum subscriptiontype subtype)
 Find subscription type in array.
static struct sip_userfind_user (const char *name, int realtime)
 Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
static void free_old_route (struct sip_route *route)
 Remove route from route list.
static void free_via (struct sip_via *v)
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_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct sockaddr_in *sin)
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_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 char get_sdp_line (int *start, int stop, struct sip_request *req, const char **value)
 Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.
static struct sip_pvtget_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag)
 Lock interface lock and find matching pvt lock.
static const char * gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
 Get tag from packet.
static int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 Handle flag-type options common to configuration of devices - users and peers.
static int handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *nounlock)
 Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer.
static int handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
 Handle incoming SIP requests (methods).
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req)
 Handle incoming BYE request.
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req)
 Handle incoming CANCEL request.
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 Receive SIP INFO Message.
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock)
 Handle incoming INVITE request.
static int handle_request_message (struct sip_pvt *p, struct sip_request *req)
 Handle incoming MESSAGE request.
static int handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
 Handle incoming notifications.
static int handle_request_options (struct sip_pvt *p, struct sip_request *req)
 Handle incoming OPTIONS request.
static int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock)
static int handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e)
 Handle incoming REGISTER request.
static int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
 Handle incoming SUBSCRIBE request.
static void handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int 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 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 void markall_extenstate_updates (void)
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 int notify_extenstate_update (char *context, char *exten, int state, void *data)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem.
static void parse_copy (struct sip_request *dst, const struct sip_request *src)
 Copy SIP request, parse it.
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req)
 Parse 302 Moved temporalily response.
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 Save contact header for 200 OK on INVITE.
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
 Parse contact header and save registration (peer registration).
static int parse_request (struct sip_request *req)
 Parse a SIP message.
static unsigned int parse_sip_options (struct sip_pvt *pvt, const char *supported)
 Parse supported header in incoming packet.
static struct sip_viaparse_via (const char *header)
 Parse a Via header.
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 void process_request_queue (struct sip_pvt *p, int *recount, int *nounlock)
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 int process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp *newaudiortp, int *last_rtpmap_codec)
static int process_sdp_a_image (const char *a, struct sip_pvt *p)
static int process_sdp_a_sendonly (const char *a, int *sendonly)
static int process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp *newvideortp, int *last_rtpmap_codec)
static int process_sdp_c (const char *c, struct ast_hostent *hp)
static int process_via (struct sip_pvt *p, const struct sip_request *req)
 Process the Via header according to RFC 3261 section 18.2.2.
static int queue_request (struct sip_pvt *p, const struct sip_request *req)
static struct sip_peerrealtime_peer (const char *newpeername, struct sockaddr_in *sin, int devstate_only)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey, int lastms)
 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 void remove_provisional_keepalive_sched (struct sip_pvt *pvt)
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 resp_needs_contact (const char *msg, enum sipmethod method)
 Test if this response needs a contact header.
static int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Prepare SIP response packet.
static int restart_monitor (void)
 Start the channel monitor thread.
static int retrans_pkt (const void *data)
 Retransmit SIP message if no answer (Called from scheduler).
static int scheduler_process_request_queue (const void *data)
static int send_provisional_keepalive (const void *data)
static int send_provisional_keepalive_full (struct provisional_keepalive_data *data, int with_sdp)
 This is called by the scheduler to resend the last provisional message in a dialog.
static int send_provisional_keepalive_with_sdp (const void *data)
static int send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Send SIP Request to the other part of the dialogue.
static int send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Transmit response on SIP request.
static int set_address_from_contact (struct sip_pvt *pvt)
 Change the other partys IP address based on given contact.
static void set_destination (struct sip_pvt *p, char *uri)
 Set destination from SIP URI.
static void set_insecure_flags (struct ast_flags *flags, const char *value, int lineno)
 Parse the "insecure" setting from sip.conf or from realtime.
static void set_nonce_randdata (struct sip_pvt *p, int forceupdate)
 builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
static void set_peer_defaults (struct sip_peer *peer)
 Set peer defaults before configuring specific configurations.
static int sip_addheader (struct ast_channel *chan, void *data)
 Add a SIP header to an outbound INVITE.
static int sip_addrcmp (char *name, struct sockaddr_in *sin)
 Support routine for find_peer.
static struct sip_pvtsip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method)
 Allocate SIP_PVT structure and set defaults.
static void sip_alreadygone (struct sip_pvt *dialog)
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
static int sip_call (struct ast_channel *ast, char *dest, int timeout)
 Initiate SIP call from PBX used from the dial() application.
static int sip_cancel_destroy (struct sip_pvt *p)
 Cancel destruction of SIP dialog.
static int sip_debug_test_addr (const struct sockaddr_in *addr)
 See if we pass debug IP filter.
static int sip_debug_test_pvt (struct sip_pvt *p)
 Test PVT for debugging output.
static void sip_destroy (struct sip_pvt *p)
 Destroy SIP call structure.
static void sip_destroy_peer (struct sip_peer *peer)
 Destroy peer object from memory.
static void sip_destroy_user (struct sip_user *user)
 Remove user object from in-memory storage.
static int sip_devicestate (void *data)
 Part of PBX channel interface.
static int sip_do_debug (int fd, int argc, char *argv[])
 Turn on SIP debugging (CLI command).
static int sip_do_debug_deprecated (int fd, int argc, char *argv[])
static int sip_do_debug_ip (int fd, int argc, char *argv[])
 Enable SIP Debugging in CLI.
static int sip_do_debug_peer (int fd, int argc, char *argv[])
 sip_do_debug_peer: Turn on SIP debugging with peer mask
static int sip_do_history (int fd, int argc, char *argv[])
 Enable SIP History logging (CLI).
static int sip_do_reload (enum channelreloadreason reason)
 Reload module.
static int sip_dtmfmode (struct ast_channel *chan, void *data)
 Set the DTMFmode for an outbound SIP call (application).
static void sip_dump_history (struct sip_pvt *dialog)
 Dump SIP history to debug log file at end of lifespan for SIP dialog.
static int sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
static int sip_get_codec (struct ast_channel *chan)
 Return SIP UA's codec (part of the RTP interface).
static enum ast_rtp_get_result sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite audio (part of RTP interface).
static struct ast_udptlsip_get_udptl_peer (struct ast_channel *chan)
static enum ast_rtp_get_result sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite video (part of RTP interface).
static int sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite)
 Handle T38 reinvite.
static int sip_hangup (struct ast_channel *ast)
 sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
static int sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
static const char * sip_nat_mode (const struct sip_pvt *p)
 Display SIP nat mode.
static struct ast_channelsip_new (struct sip_pvt *i, int state, const char *title)
 Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
static int sip_no_debug (int fd, int argc, char *argv[])
 Disable SIP Debugging in CLI.
static int sip_no_debug_deprecated (int fd, int argc, char *argv[])
static int sip_no_history (int fd, int argc, char *argv[])
 Disable SIP History logging (CLI).
static int sip_notify (int fd, int argc, char *argv[])
 Cli command to send SIP notify to peer.
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno)
 Park a call using the subsystem in res_features.c This is executed in a separate thread.
static void * sip_park_thread (void *stuff)
 Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
static void sip_peer_hold (struct sip_pvt *p, int hold)
 Change onhold state of a peer using a pvt structure.
static void sip_poke_all_peers (void)
 Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
static int sip_poke_noanswer (const void *data)
 React to lack of answer to Qualify poke.
static int sip_poke_peer (struct sip_peer *peer)
 Check availability of peer, also keep NAT open.
static int sip_poke_peer_s (const void *data)
 Poke peer (send qualify to check if peer is alive and well).
static int sip_prune_realtime (int fd, int argc, char *argv[])
 Remove temporary realtime objects from memory (CLI).
static struct ast_framesip_read (struct ast_channel *ast)
 Read SIP RTP from channel.
static struct sockaddr_in * sip_real_dst (const struct sip_pvt *p)
 The real destination address for a write.
static int sip_refer_allocate (struct sip_pvt *p)
 Allocate SIP refer structure.
static int sip_reg_timeout (const void *data)
 Registration timeout, register again.
static int sip_register (char *value, int lineno)
 Parse register=> line in sip.conf and add to registry.
static void sip_registry_destroy (struct sip_registry *reg)
 Destroy registry object Objects created with the register= statement in static configuration.
static int sip_reinvite_retry (const void *data)
 Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
static int sip_reload (int fd, int argc, char *argv[])
 Force reload of module from cli.
static struct ast_channelsip_request_call (const char *type, int format, void *data, int *cause)
 PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
static int sip_reregister (const void *data)
 Update registration with SIP Proxy.
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network.
static void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog.
static void sip_send_all_registers (void)
 Send all known registrations.
static int sip_send_mwi_to_peer (struct sip_peer *peer, int force)
 Send message waiting indication to alert peer that they've got voicemail.
static int sip_senddigit_begin (struct ast_channel *ast, char digit)
static int sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
static int sip_sendtext (struct ast_channel *ast, const char *text)
 Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 Set the RTP peer for this call.
static int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
static int sip_show_channel (int fd, int argc, char *argv[])
 Show details of one active dialog.
static int sip_show_channels (int fd, int argc, char *argv[])
 Show active SIP channels.
static int sip_show_domains (int fd, int argc, char *argv[])
 CLI command to list local domains.
static int sip_show_history (int fd, int argc, char *argv[])
 Show history details of one dialog.
static int sip_show_inuse (int fd, int argc, char *argv[])
 CLI Command to show calls within limits set by call_limit.
static int sip_show_objects (int fd, int argc, char *argv[])
 List all allocated SIP Objects (realtime or static).
static int sip_show_peer (int fd, int argc, char *argv[])
 Show one peer in detail.
static int sip_show_peers (int fd, int argc, char *argv[])
 CLI Show Peers command.
static int sip_show_registry (int fd, int argc, char *argv[])
 Show SIP Registry (registrations with other SIP proxies.
static int sip_show_settings (int fd, int argc, char *argv[])
 List global settings for the SIP channel.
static int sip_show_subscriptions (int fd, int argc, char *argv[])
 Show active SIP subscriptions.
static int sip_show_user (int fd, int argc, char *argv[])
 Show one user in detail.
static int sip_show_users (int fd, int argc, char *argv[])
 CLI Command 'SIP Show Users'.
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect.
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call.
static int sip_uri_cmp (const char *input1, const char *input2)
static int sip_uri_headers_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp
static int sip_uri_params_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp to compare URI parameters
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 void temp_pvt_init (void)
 A per-thread temporary pvt structure.
static char * transfermode2str (enum transfermodes mode)
 Convert transfer mode to text string.
static void transmit_fake_auth_response (struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype 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_provisional_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp)
static int transmit_refer (struct sip_pvt *p, const char *dest)
 Transmit SIP REFER message (initiated by the transfer() dialplan application.
static int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA.
static int transmit_reinvite_with_sdp (struct sip_pvt *p)
 Transmit reinvite with SDP.
static int transmit_reinvite_with_t38_sdp (struct sip_pvt *p)
 Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path.
static int transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit SIP request, auth added.
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits.
static int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
static int transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
 Transmit response, no retransmits, using a temporary pvt structure.
static int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Append Accept header, content length before transmitting response.
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request.
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append date and content length before transmitting response.
static int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Used for 200 OK and 183 early media.
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_sip_request (struct sip_pvt *p, struct sip_request *req)
 Transmit SIP request unreliably (only used in sip_notify subsystem).
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem.
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
static int unload_module (void)
 PBX unload module API.
static void unmark_extenstate_update (struct sip_pvt *pvt)
static void * unref_provisional_keepalive (struct provisional_keepalive_data *data)
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).
static void update_provisional_keepalive (struct sip_pvt *pvt, int with_sdp)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, }
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 const struct ast_module_infoast_module_info = &__mod_info
static struct sip_authauthl = NULL
static int autocreatepeer
static struct sockaddr_in bindaddr = { 0, }
static unsigned int chan_idx
static struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = check_auth_buf_init , }
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 struct ast_haglobal_contact_ha = NULL
 Global list of addresses dynamic peers are not allowed to use.
static int global_directrtpsetup
static int global_dynamic_exclude_static = 0
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 int global_prematuremediafilter
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_shrinkcallerid
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 ast_mutex_t iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
 Protect the SIP dialog list (of sip_pvt's).
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 ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static ast_mutex_t netlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
static char no_debug_usage []
static char no_history_usage []
static const char notify_config [] = "sip_notify.conf"
static struct ast_confignotify_types = NULL
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 seen_lastms = 0
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 ast_mutex_t sip_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
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_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = temp_pvt_init , }
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

SIP over TLS

Better support of forking

VIA branch tag transaction checking

Transaction support

Overview of the handling of SIP sessions
The SIP channel handles several types of SIP sessions, or dialogs, not all of them being "telephone calls".
In the SIP channel, there's a list of active SIP dialogs, which includes all of these when they are active. "sip show channels" in the CLI will show most of these, excluding subscriptions which are shown by "sip show subscriptions"

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

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

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

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

Definition in file chan_sip.c.


Define Documentation

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

SIP Methods we support.

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

Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), local_attended_transfer(), notify_extenstate_update(), 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   "Anonymous"

Definition at line 202 of file chan_sip.c.

Referenced by initreqprep().

#define CAN_CREATE_DIALOG   1

Definition at line 374 of file chan_sip.c.

#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2

Definition at line 375 of file chan_sip.c.

#define CAN_NOT_CREATE_DIALOG   0

Definition at line 373 of file chan_sip.c.

#define CHECK_AUTH_BUF_INITLEN   256

Definition at line 9399 of file chan_sip.c.

Referenced by check_auth(), and transmit_fake_auth_response().

#define DEC_CALL_LIMIT   0

Definition at line 622 of file chan_sip.c.

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

#define DEC_CALL_RINGING   2

Definition at line 624 of file chan_sip.c.

Referenced by handle_response_invite(), and update_call_counter().

#define DEFAULT_ALLOW_EXT_DOM   TRUE

Definition at line 515 of file chan_sip.c.

#define DEFAULT_ALLOWGUEST   TRUE

Definition at line 509 of file chan_sip.c.

#define DEFAULT_AUTOCREATEPEER   FALSE

Definition at line 519 of file chan_sip.c.

#define DEFAULT_CALLERID   "asterisk"

Definition at line 506 of file chan_sip.c.

#define DEFAULT_COMPACTHEADERS   FALSE

Definition at line 511 of file chan_sip.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 502 of file chan_sip.c.

#define DEFAULT_DEFAULT_EXPIRY   120

Definition at line 173 of file chan_sip.c.

#define DEFAULT_EXPIRY   900

Expire slowly

Definition at line 190 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

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

#define DEFAULT_MAX_CALL_BITRATE   (384)

Max bitrate for video

Definition at line 522 of file chan_sip.c.

#define DEFAULT_MAX_EXPIRY   3600

Definition at line 175 of file chan_sip.c.

#define DEFAULT_MAX_FORWARDS   "70"

Definition at line 177 of file chan_sip.c.

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

#define DEFAULT_MAXMS   2000

Qualification: Must be faster than 2 seconds by default

Definition at line 205 of file chan_sip.c.

#define DEFAULT_MIN_EXPIRY   60

Definition at line 174 of file chan_sip.c.

#define DEFAULT_MOHINTERPRET   "default"

Definition at line 503 of file chan_sip.c.

#define DEFAULT_MOHSUGGEST   ""

Definition at line 504 of file chan_sip.c.

#define DEFAULT_MWITIME   10

Definition at line 508 of file chan_sip.c.

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

Definition at line 507 of file chan_sip.c.

#define DEFAULT_NOTIFYRINGING   TRUE

Definition at line 517 of file chan_sip.c.

#define DEFAULT_PEDANTIC   FALSE

Definition at line 518 of file chan_sip.c.

#define DEFAULT_QUALIFY   FALSE

Definition at line 520 of file chan_sip.c.

#define DEFAULT_REALM   "asterisk"

Definition at line 516 of file chan_sip.c.

#define DEFAULT_REGISTRATION_TIMEOUT   20

Definition at line 176 of file chan_sip.c.

#define DEFAULT_RETRANS   1000

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

Definition at line 209 of file chan_sip.c.

#define DEFAULT_SRVLOOKUP   TRUE

Recommended setting is ON

Definition at line 510 of file chan_sip.c.

#define DEFAULT_T1MIN   100

100 MS for minimal roundtrip time

Definition at line 521 of file chan_sip.c.

#define DEFAULT_TOS_AUDIO   0

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

Definition at line 513 of file chan_sip.c.

#define DEFAULT_TOS_SIP   0

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

Definition at line 512 of file chan_sip.c.

#define DEFAULT_TOS_VIDEO   0

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

Definition at line 514 of file chan_sip.c.

#define DEFAULT_TRANS_TIMEOUT   -1

Definition at line 214 of file chan_sip.c.

Referenced by __sip_autodestruct(), auto_congest(), 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(), notify_extenstate_update(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and transmit_fake_auth_response().

#define DEFAULT_USERAGENT   "Asterisk PBX"

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

Definition at line 524 of file chan_sip.c.

#define DEFAULT_VMEXTEN   "asterisk"

Definition at line 505 of file chan_sip.c.

#define EXPIRY_GUARD_LIMIT   30

Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS

Definition at line 182 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 184 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 188 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 181 of file chan_sip.c.

Referenced by handle_response_register().

#define FALSE   0

Definition at line 155 of file chan_sip.c.

#define FLAG_FATAL   (1 << 1)

Definition at line 1092 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)

Definition at line 1091 of file chan_sip.c.

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

#define FORMAT   "%-15.15s %-15.15s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n"

#define FORMAT   "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n"

#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"

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

#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"

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

#define FORMAT2   "%-15.15s %-15.15s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n"

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

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

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

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

Referenced by __sip_show_channels().

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

#define FROMDOMAIN_INVALID   "anonymous.invalid"

Definition at line 203 of file chan_sip.c.

Referenced by initreqprep().

#define INC_CALL_LIMIT   1

Definition at line 623 of file chan_sip.c.

Referenced by handle_request_invite(), and update_call_counter().

#define INC_CALL_RINGING   3

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

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

#define IPTOS_MINCOST   0x02

Definition at line 168 of file chan_sip.c.

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

Definition at line 199 of file chan_sip.c.

#define MAX_AUTHTRIES   3

Try authentication three times, then fail

Definition at line 216 of file chan_sip.c.

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

#define MAX_HISTORY_ENTRIES   50

Max entires in the history list for a sip_pvt

Definition at line 1089 of file chan_sip.c.

Referenced by append_history_va().

#define MAX_RETRANS   6

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

Definition at line 210 of file chan_sip.c.

#define NO_RTP   0

Definition at line 240 of file chan_sip.c.

#define NOT_SUPPORTED   0

Definition at line 416 of file chan_sip.c.

#define PROVIS_KEEPALIVE_TIMEOUT   60000

How long to wait before retransmitting a provisional response (rfc 3261 13.3.1.1)

Definition at line 215 of file chan_sip.c.

Referenced by send_provisional_keepalive_full(), and update_provisional_keepalive().

#define RTP   1

Definition at line 239 of file chan_sip.c.

#define SDP_MAX_RTPMAP_CODECS   32

Maximum number of codecs allowed in received SDP

Definition at line 222 of file chan_sip.c.

Referenced by process_sdp_a_audio(), and process_sdp_a_video().

#define SDP_SAMPLE_RATE (  )     8000

Note:
G.722 actually is supposed to specified as 8 kHz, even though it is really 16 kHz. Update this macro for other formats as they are added in the future.

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

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

#define SIP_CALL_LIMIT   (1 << 28)

Call limit enforced for this call

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

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

#define SIP_CAN_REINVITE_NAT   (2 << 20)

allow media reinvite when new peer is behind NAT

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

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

#define SIP_DTMF   (3 << 16)

DTMF Support: four settings, uses two bits

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

Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), sip_alloc(), and sip_new().

#define SIP_DTMF_INBAND   (1 << 16)

DTMF Support: Inband audio, only for ULAW/ALAW - "inband"

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

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

#define SIP_FLAGS_TO_COPY

Value:

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

#define SIP_G726_NONSTANDARD   (1 << 31)

Use non-standard packing for G726-32 data

Definition at line 786 of file chan_sip.c.

Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp_a_audio().

#define SIP_GOTREFER   (1 << 7)

Got a refer?

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

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

#define SIP_INSECURE_INVITE   (1 << 24)

don't require authentication for incoming INVITEs

Definition at line 776 of file chan_sip.c.

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

#define SIP_INSECURE_PORT   (1 << 23)

don't require matching port for incoming requests

Definition at line 775 of file chan_sip.c.

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

#define SIP_MAX_HEADERS   64

Max amount of SIP headers to read

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

Referenced by parse_request().

#define SIP_MAX_PACKET   4096

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

Definition at line 220 of file chan_sip.c.

#define SIP_NAT   (3 << 18)

four settings, uses two bits

Definition at line 764 of file chan_sip.c.

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

#define SIP_NAT_ALWAYS   (3 << 18)

NAT Both ROUTE and RFC3581

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

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)

NAT RFC3581

Definition at line 766 of file chan_sip.c.

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

#define SIP_NAT_ROUTE   (2 << 18)

NAT Only ROUTE

Definition at line 767 of file chan_sip.c.

Referenced by _sip_show_peers(), build_peer(), check_user_full(), create_addr(), 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 743 of file chan_sip.c.

Referenced by __sip_autodestruct(), __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 747 of file chan_sip.c.

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

#define SIP_NO_HISTORY   (1 << 27)

Suppress recording request/response history

Definition at line 782 of file chan_sip.c.

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

#define SIP_NOVIDEO   (1 << 2)

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

Definition at line 744 of file chan_sip.c.

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

#define SIP_OPT_100REL   (1 << 1)

Definition at line 419 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)

Definition at line 421 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)

Definition at line 429 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)

Definition at line 430 of file chan_sip.c.

#define SIP_OPT_HISTINFO   (1 << 15)

Definition at line 433 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)

Definition at line 422 of file chan_sip.c.

#define SIP_OPT_NOREFERSUB   (1 << 14)

Definition at line 432 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)

Definition at line 423 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)

Definition at line 425 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)

Definition at line 424 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)

Definition at line 426 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)

Definition at line 418 of file chan_sip.c.

Referenced by handle_request_invite().

#define SIP_OPT_RESPRIORITY   (1 << 16)

Definition at line 434 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)

Definition at line 427 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)

Definition at line 428 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)

Definition at line 431 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)

Definition at line 420 of file chan_sip.c.

#define SIP_OUTGOING   (1 << 13)

Direction of the last transaction in this dialog

Definition at line 755 of file chan_sip.c.

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

#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)

Allow overlap dialing ?

Definition at line 810 of file chan_sip.c.

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

#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)

Allow subscriptions from this peer?

Definition at line 809 of file chan_sip.c.

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

#define SIP_PAGE2_BUGGY_MWI   (1 << 26)

26: Buggy CISCO MWI fix

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

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

#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)

23: Active hold

Definition at line 818 of file chan_sip.c.

Referenced by change_hold_state().

#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)

23: Inactive hold

Definition at line 820 of file chan_sip.c.

Referenced by add_sdp(), and change_hold_state().

#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (2 << 23)

23: One directional hold

Definition at line 819 of file chan_sip.c.

Referenced by add_sdp(), and change_hold_state().

#define SIP_PAGE2_DEBUG   (3 << 11)

Definition at line 803 of file chan_sip.c.

#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)

Definition at line 804 of file chan_sip.c.

#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)

Definition at line 805 of file chan_sip.c.

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

#define SIP_PAGE2_DIALOG_ESTABLISHED   (1 << 29)

29: Has a dialog been established?

Definition at line 825 of file chan_sip.c.

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

#define SIP_PAGE2_DYNAMIC   (1 << 13)

Dynamic Peers register with Asterisk

Definition at line 806 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 829 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_FORWARD_LOOP_DETECTED   (1 << 31)

31: Do call forward when receiving 482 Loop Detected

Definition at line 827 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), handle_response(), and sip_show_settings().

#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 10)

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

Referenced by get_sip_pvt_byid_locked(), handle_response_invite(), sip_request_call(), and update_call_counter().

#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)

25: ????

Definition at line 821 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_RPORT_PRESENT   (1 << 30)

30: Was rport received in the Via header?

Definition at line 826 of file chan_sip.c.

Referenced by check_user_full(), and check_via().

#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)

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

Referenced by expire_register(), and sip_show_settings().

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)

Definition at line 795 of file chan_sip.c.

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

#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)

Definition at line 799 of file chan_sip.c.

Referenced by realtime_update_peer(), and sip_show_settings().

#define SIP_PAGE2_RTUPDATE   (1 << 1)

Definition at line 796 of file chan_sip.c.

Referenced by destroy_association(), handle_response_peerpoke(), sip_poke_noanswer(), sip_show_settings(), and update_peer().

#define SIP_PAGE2_SELFDESTRUCT   (1 << 14)

Automatic peers need to destruct themselves

Definition at line 807 of file chan_sip.c.

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

#define SIP_PAGE2_STATECHANGEQUEUE   (1 << 9)

D: Unsent state pending change exists

Definition at line 801 of file chan_sip.c.

Referenced by handle_response(), and notify_extenstate_update().

#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)

Only issue MWI notification if subscribed to

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

Referenced by create_addr_from_peer(), sip_alloc(), and sip_write().

#define SIP_PAGE2_T38SUPPORT_RTP   (2 << 20)

21: T38 Fax Passthrough Support (not implemented)

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

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

#define SIP_PAGE2_UDPTL_DESTINATION   (1 << 28)

28: Use source IP of RTP as destination if NAT is enabled

Definition at line 824 of file chan_sip.c.

Referenced by handle_common_options(), and process_sdp().

#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)

Definition at line 808 of file chan_sip.c.

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

#define SIP_PENDINGBYE   (1 << 6)

Need to send bye after we ack?

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

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

#define SIP_PKT_IGNORE_REQ   (1 << 4)

Req ignore - ???

Definition at line 838 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 836 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 778 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 779 of file chan_sip.c.

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 25)

Definition at line 780 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 25)

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

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)

Promiscuous redirection

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

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

#define SIP_REINVITE   (7 << 20)

three bits used

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

Referenced by sip_indicate().

#define SIP_SENDRPID   (1 << 29)

Remote Party-ID Support

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

Referenced by sip_call(), and sip_sipredirect().

#define SIP_TRUSTRPID   (1 << 9)

Trust RPID headers?

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

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

#define SIPBUFSIZE   512

Definition at line 162 of file chan_sip.c.

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

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

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

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

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

Referenced by __set_address_from_contact(), build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), process_via(), set_destination(), set_peer_defaults(), sip_show_registry(), transmit_notify_with_mwi(), 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 415 of file chan_sip.c.

#define SUPPORTED_EXTENSIONS   "replaces"

SIP Extensions we support.

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

Referenced by add_sdp(), and process_sdp_a_image().

#define T38FAX_RATE_12000   (1 << 12)

12000 bps t38FaxRate

Definition at line 860 of file chan_sip.c.

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

Referenced by process_sdp_a_image(), and t38_get_rate().

#define T38FAX_RATE_2400   (1 << 8)

2400 bps t38FaxRate

Definition at line 856 of file chan_sip.c.

Referenced by process_sdp_a_image(), and t38_get_rate().

#define T38FAX_RATE_4800   (1 << 9)

4800 bps t38FaxRate

Definition at line 857 of file chan_sip.c.

Referenced by process_sdp_a_image(), and t38_get_rate().

#define T38FAX_RATE_7200   (1 << 10)

7200 bps t38FaxRate

Definition at line 858 of file chan_sip.c.

Referenced by process_sdp_a_image(), and t38_get_rate().

#define T38FAX_RATE_9600   (1 << 11)

9600 bps t38FaxRate

Definition at line 859 of file chan_sip.c.

Referenced by process_sdp_a_image(), and t38_get_rate().

#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF   (1 << 3)

Unset for transferredTCF (UDPTL), set for localTCF (TPKT)

Definition at line 846 of file chan_sip.c.

Referenced by add_sdp(), and process_sdp_a_image().

#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)

Definition at line 845 of file chan_sip.c.

Referenced by create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().

#define T38FAX_TRANSCODING_JBIG   (1 << 2)

Default: 0 (unset)

Definition at line 843 of file chan_sip.c.

Referenced by add_sdp(), and process_sdp_a_image().

#define T38FAX_TRANSCODING_MMR   (1 << 1)

Default: 0 (unset)

Definition at line 842 of file chan_sip.c.

Referenced by add_sdp(), and process_sdp_a_image().

#define T38FAX_UDP_EC_FEC   (1 << 4)

Set for t38UDPFEC

Definition at line 849 of file chan_sip.c.

Referenced by create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().

#define T38FAX_UDP_EC_NONE   (0 << 4)

two bits, if unset NO t38UDPEC field in T38 SDP

Definition at line 848 of file chan_sip.c.

Referenced by add_sdp(), create_addr_from_peer(), process_sdp(), process_sdp_a_image(), and sip_alloc().

#define T38FAX_UDP_EC_REDUNDANCY   (2 << 4)

Set for t38UDPRedundancy

Definition at line 850 of file chan_sip.c.

Referenced by add_sdp(), create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().

#define T38FAX_VERSION   (3 << 6)

two bits, 2 values so far, up to 4 values max

Definition at line 852 of file chan_sip.c.

Referenced by add_sdp().

#define T38FAX_VERSION_0   (0 << 6)

Version 0

Definition at line 853 of file chan_sip.c.

Referenced by add_sdp(), and process_sdp_a_image().

#define T38FAX_VERSION_1   (1 << 6)

Version 1

Definition at line 854 of file chan_sip.c.

Referenced by add_sdp(), and process_sdp_a_image().

#define TRUE   1

Definition at line 159 of file chan_sip.c.

#define UNLINK ( element,
head,
prev   ) 

--- some list management macros.

Definition at line 1720 of file chan_sip.c.

Referenced by __sip_ack(), __sip_destroy(), and handle_request_cancel().

#define VIDEO_CODEC_MASK   0x1fc0000

Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO

Definition at line 166 of file chan_sip.c.

#define XMIT_ERROR   -2

Definition at line 164 of file chan_sip.c.

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


Enumeration Type Documentation

enum check_auth_result

Authentication result from check_auth* functions.

Enumerator:
AUTH_SUCCESSFUL 
AUTH_CHALLENGE_SENT 
AUTH_SECRET_FAILED 
AUTH_USERNAME_MISMATCH 
AUTH_NOT_FOUND 
AUTH_FAKE_AUTH 
AUTH_UNKNOWN_DOMAIN 
AUTH_PEER_NOT_DYNAMIC 
AUTH_ACL_FAILED 

Definition at line 349 of file chan_sip.c.

00349                        {
00350    AUTH_SUCCESSFUL = 0,
00351    AUTH_CHALLENGE_SENT = 1,
00352    AUTH_SECRET_FAILED = -1,
00353    AUTH_USERNAME_MISMATCH = -2,
00354    AUTH_NOT_FOUND = -3,
00355    AUTH_FAKE_AUTH = -4,
00356    AUTH_UNKNOWN_DOMAIN = -5,
00357    AUTH_PEER_NOT_DYNAMIC = -6,
00358    AUTH_ACL_FAILED = -7,
00359 };

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

00705                  {
00706    SIP_DOMAIN_AUTO,     /*!< This domain is auto-configured */
00707    SIP_DOMAIN_CONFIG,      /*!< This domain is from configuration */
00708 };

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/sent 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 259 of file chan_sip.c.

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

enum media_type

Enumerator:
SDP_AUDIO 
SDP_VIDEO 
SDP_IMAGE 

Definition at line 5643 of file chan_sip.c.

05643                 {
05644    SDP_AUDIO,
05645    SDP_VIDEO,
05646    SDP_IMAGE,
05647 };

enum parse_register_result

Enumerator:
PARSE_REGISTER_DENIED 
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

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

00896                  {
00897         REFER_IDLE,                    /*!< No REFER is in progress */
00898         REFER_SENT,                    /*!< Sent REFER to transferee */
00899         REFER_RECEIVED,                /*!< Received REFER from transferer */
00900         REFER_CONFIRMED,               /*!< Refer confirmed with a 100 TRYING */
00901         REFER_ACCEPTED,                /*!< Accepted by transferee */
00902         REFER_RINGING,                 /*!< Target Ringing */
00903         REFER_200OK,                   /*!< Answered by transfer target */
00904         REFER_FAILED,                  /*!< REFER declined - go on */
00905         REFER_NOAUTH                   /*!< We had no auth for REFER */
00906 };

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

00343                    {
00344    PROXY_AUTH,
00345    WWW_AUTH,
00346 };

enum sip_result

Enumerator:
AST_SUCCESS 
AST_FAILURE 

Definition at line 251 of file chan_sip.c.

00251                 {
00252    AST_SUCCESS = 0,
00253    AST_FAILURE = -1,
00254 };

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

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

enum sipregistrystate

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

Enumerator:
REG_STATE_UNREGISTERED  We are not registered
REG_STATE_REGSENT  Registration request sent
REG_STATE_AUTHSENT  We have tried to authenticate
REG_STATE_REGISTERED  Registered 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 362 of file chan_sip.c.

00362                       {
00363    REG_STATE_UNREGISTERED = 0,   /*!< We are not registered */
00364    REG_STATE_REGSENT,   /*!< Registration request sent */
00365    REG_STATE_AUTHSENT,  /*!< We have tried to authenticate */
00366    REG_STATE_REGISTERED,   /*!< Registered and done */
00367    REG_STATE_REJECTED,  /*!< Registration rejected */
00368    REG_STATE_TIMEOUT,   /*!< Registration timed out */
00369    REG_STATE_NOAUTH, /*!< We have no accepted credentials */
00370    REG_STATE_FAILED, /*!< Registration failed after several tries */
00371 };

enum subscriptiontype

Enumerator:
NONE 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 
MWI_NOTIFICATION 

Definition at line 293 of file chan_sip.c.

00293                       { 
00294    NONE = 0,
00295    XPIDF_XML,
00296    DIALOG_INFO_XML,
00297    CPIM_PIDF_XML,
00298    PIDF_XML,
00299    MWI_NOTIFICATION
00300 };

enum t38state

T38 States for a call.

Enumerator:
T38_DISABLED  Not enabled
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 877 of file chan_sip.c.

00877               {
00878         T38_DISABLED = 0,                /*!< Not enabled */
00879         T38_LOCAL_REINVITE,              /*!< Offered from local - REINVITE */
00880         T38_PEER_DIRECT,                 /*!< Offered from peer */
00881         T38_PEER_REINVITE,               /*!< Offered from peer - REINVITE */
00882         T38_ENABLED                      /*!< Negotiated (enabled) */
00883 };

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

00245                    {
00246    TRANSFER_OPENFORALL,            /*!< Allow all SIP transfers */
00247    TRANSFER_CLOSED,                /*!< Allow no SIP transfers */
00248 };

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

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


Function Documentation

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

Definition at line 4675 of file chan_sip.c.

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

04676 {
04677    int pass;
04678 
04679    /*
04680     * Technically you can place arbitrary whitespace both before and after the ':' in
04681     * a header, although RFC3261 clearly says you shouldn't before, and place just
04682     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
04683     * a good idea to say you can do it, and if you can do it, why in the hell would.
04684     * you say you shouldn't.
04685     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
04686     * and we always allow spaces after that for compatibility.
04687     */
04688    for (pass = 0; name && pass < 2;pass++) {
04689       int x, len = strlen(name);
04690       for (x=*start; x<req->headers; x++) {
04691          if (!strncasecmp(req->header[x], name, len)) {
04692             char *r = req->header[x] + len;  /* skip name */
04693             if (pedanticsipchecking)
04694                r = ast_skip_blanks(r);
04695 
04696             if (*r == ':') {
04697                *start = x+1;
04698                return ast_skip_blanks(r+1);
04699             }
04700          }
04701       }
04702       if (pass == 0) /* Try aliases */
04703          name = find_alias(name, NULL);
04704    }
04705 
04706    /* Don't return NULL, so get_header is always a valid pointer */
04707    return "";
04708 }

static void __reg_module ( void   )  [static]

Definition at line 20459 of file chan_sip.c.

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

Definition at line 8997 of file chan_sip.c.

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

Referenced by build_peer(), and set_address_from_contact().

08998 {
08999    struct hostent *hp;
09000    struct ast_hostent ahp;
09001    int port;
09002    char *c, *host, *pt;
09003    char contact_buf[256];
09004    char *contact;
09005 
09006    /* Work on a copy */
09007    ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
09008    contact = contact_buf;
09009 
09010    /* Make sure it's a SIP URL */
09011    if (strncasecmp(contact, "sip:", 4)) {
09012       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
09013    } else
09014       contact += 4;
09015 
09016    /* Ditch arguments */
09017    /* XXX this code is replicated also shortly below */
09018 
09019    /* Grab host */
09020    host = strchr(contact, '@');
09021    if (!host) {   /* No username part */
09022       host = contact;
09023       c = NULL;
09024    } else {
09025       *host++ = '\0';
09026    }
09027    pt = strchr(host, ':');
09028    if (pt) {
09029       *pt++ = '\0';
09030       port = atoi(pt);
09031    } else
09032       port = STANDARD_SIP_PORT;
09033 
09034    contact = strsep(&contact, ";"); /* trim ; and beyond in username part */
09035    host = strsep(&host, ";");    /* trim ; and beyond in host/domain part */
09036 
09037    /* XXX This could block for a long time XXX */
09038    /* We should only do this if it's a name, not an IP */
09039    hp = ast_gethostbyname(host, &ahp);
09040    if (!hp)  {
09041       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
09042       return -1;
09043    }
09044    sin->sin_family = AF_INET;
09045    memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
09046    sin->sin_port = htons(port);
09047 
09048    return 0;
09049 }

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

Acknowledges receipt of a packet and stops retransmission called with p locked.

Definition at line 2291 of file chan_sip.c.

References ast_log(), AST_SCHED_DEL_SPINLOCK, ast_test_flag, sip_pvt::callid, 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(), handle_request_invite(), and handle_response().

02292 {
02293    struct sip_pkt *cur, *prev = NULL;
02294 
02295    /* Just in case... */
02296    char *msg;
02297    int res = FALSE;
02298 
02299    msg = sip_methods[sipmethod].text;
02300 
02301    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
02302       if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
02303          ((ast_test_flag(cur, FLAG_RESPONSE)) || 
02304           (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
02305          if (!resp && (seqno == p->pendinginvite)) {
02306             if (option_debug)
02307                ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
02308             p->pendinginvite = 0;
02309          }
02310          /* this is our baby */
02311          res = TRUE;
02312          UNLINK(cur, p->packets, prev);
02313          if (cur->retransid > -1) {
02314             if (sipdebug && option_debug > 3)
02315                ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
02316          }
02317          /* This odd section is designed to thwart a 
02318           * race condition in the packet scheduler. There are
02319           * two conditions under which deleting the packet from the
02320           * scheduler can fail.
02321           *
02322           * 1. The packet has been removed from the scheduler because retransmission
02323           * is being attempted. The problem is that if the packet is currently attempting
02324           * retransmission and we are at this point in the code, then that MUST mean
02325           * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the
02326           * lock temporarily to allow retransmission.
02327           *
02328           * 2. The packet has reached its maximum number of retransmissions and has
02329           * been permanently removed from the packet scheduler. If this is the case, then
02330           * the packet's retransid will be set to -1. The atomicity of the setting and checking
02331           * of the retransid to -1 is ensured since in both cases p's lock is held.
02332           */
02333          AST_SCHED_DEL_SPINLOCK(sched, cur->retransid, &p->lock);
02334          free(cur);
02335          break;
02336       }
02337    }
02338    if (option_debug)
02339       ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res == FALSE ? "Not Found" : "Found");
02340    return res;
02341 }

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

Kill a SIP dialog (called by scheduler).

Definition at line 2193 of file chan_sip.c.

References append_history, ast_channel_trylock, ast_channel_unlock, AST_EXTENSION_DEACTIVATED, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, DEADLOCK_AVOIDANCE, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::lastmsg, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::method, method_match(), NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_destroy(), sip_methods, SIP_NEEDDESTROY, sip_scheddestroy(), sip_pvt::subscribed, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.

Referenced by sip_scheddestroy().

02194 {
02195    struct sip_pvt *p = (struct sip_pvt *)data;
02196 
02197    /* If this is a subscription, tell the phone that we got a timeout */
02198    if (p->subscribed) {
02199       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
02200       p->subscribed = NONE;
02201       append_history(p, "Subscribestatus", "timeout");
02202       if (option_debug > 2)
02203          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
02204       return 10000;  /* Reschedule this destruction so that we know that it's gone */
02205    }
02206 
02207    /* If there are packets still waiting for delivery, delay the destruction */
02208    /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block
02209    * of code make a sort of "safety relief valve", that allows sip channels
02210    * that were created via INVITE, then thru some sequence were CANCELED,
02211    * to die, rather than infinitely be rescheduled */
02212    if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) {
02213       char method_str[31];
02214       if (option_debug > 2)
02215          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
02216       append_history(p, "ReliableXmit", "timeout");
02217       if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) {
02218          if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) {
02219             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
02220          }
02221       }
02222       return 10000;
02223    }
02224 
02225    /* Reset schedule ID */
02226    p->autokillid = -1;
02227 
02228    if (option_debug)
02229       ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
02230    append_history(p, "AutoDestroy", "%s", p->callid);
02231 
02232    /*
02233     * Lock both the pvt and the channel safely so that we can queue up a frame.
02234     */
02235    ast_mutex_lock(&p->lock);
02236    while (p->owner && ast_channel_trylock(p->owner)) {
02237       DEADLOCK_AVOIDANCE(&p->lock);
02238    }
02239 
02240    if (p->owner) {
02241       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
02242       ast_queue_hangup(p->owner);
02243       ast_channel_unlock(p->owner);
02244       ast_mutex_unlock(&p->lock);
02245    } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
02246       if (option_debug > 2)
02247          ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid);
02248       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
02249       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
02250       ast_mutex_unlock(&p->lock);
02251    } else {
02252       ast_mutex_unlock(&p->lock);
02253       sip_destroy(p);
02254    }
02255 
02256    return 0;
02257 }

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

Execute destruction of SIP dialog structure, release memory.

Definition at line 3392 of file chan_sip.c.

References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), ast_free, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::callid, clear_extenstate_updates(), DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, sip_history::list, LOG_DEBUG, sip_pvt::method, sip_peer::mwipvt, ast_channel::name, sip_pvt::next, sip_history::next, option_debug, sip_pvt::owner, sip_pvt::relatedpeer, remove_provisional_keepalive_sched(), sip_pkt::retransid, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), ast_channel::tech_pvt, UNLINK, unref_provisional_keepalive(), update_call_counter(), and sip_pvt::vrtp.

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

03393 {
03394    struct sip_pvt *cur, *prev = NULL;
03395    struct sip_pkt *cp;
03396    struct sip_request *req;
03397 
03398    /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
03399    if (p->rtp && ast_rtp_get_bridged(p->rtp)) {
03400       ast_verbose("Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03401       return -1;
03402    }
03403 
03404    if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) {
03405       ast_verbose("Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03406       return -1;
03407    }
03408 
03409    if (sip_debug_test_pvt(p) || option_debug > 2)
03410       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
03411 
03412    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03413       update_call_counter(p, DEC_CALL_LIMIT);
03414       if (option_debug > 1)
03415          ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
03416    }
03417 
03418    /* Unlink us from the owner if we have one */
03419    if (p->owner) {
03420       if (lockowner)
03421          ast_channel_lock(p->owner);
03422       if (option_debug)
03423          ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
03424       p->owner->tech_pvt = NULL;
03425       /* Make sure that the channel knows its backend is going away */
03426       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03427       if (lockowner)
03428          ast_channel_unlock(p->owner);
03429       /* Give the channel a chance to react before deallocation */
03430       usleep(1);
03431    }
03432 
03433    /* Remove link from peer to subscription of MWI */
03434    if (p->relatedpeer) {
03435       if (p->relatedpeer->mwipvt == p) {
03436          p->relatedpeer->mwipvt = NULL;
03437       }
03438       ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer);
03439    }
03440 
03441    if (dumphistory)
03442       sip_dump_history(p);
03443 
03444    if (p->options)
03445       free(p->options);
03446 
03447    if (p->stateid > -1)
03448       ast_extension_state_del(p->stateid, NULL);
03449 
03450    /* remove any pending extension notify that could be left in
03451     * the extension update queue relating to this dialog. */
03452    clear_extenstate_updates(p);
03453 
03454    AST_SCHED_DEL(sched, p->initid);
03455    AST_SCHED_DEL(sched, p->waitid);
03456    AST_SCHED_DEL(sched, p->autokillid);
03457    AST_SCHED_DEL(sched, p->request_queue_sched_id);
03458 
03459    remove_provisional_keepalive_sched(p);
03460    if (p->provisional_keepalive_data) {
03461       ast_mutex_lock(&p->lock);
03462       p->provisional_keepalive_data = unref_provisional_keepalive(p->provisional_keepalive_data);
03463       ast_mutex_unlock(&p->lock);
03464    }
03465 
03466    if (p->rtp) {
03467       ast_rtp_destroy(p->rtp);
03468    }
03469    if (p->vrtp) {
03470       ast_rtp_destroy(p->vrtp);
03471    }
03472    if (p->udptl)
03473       ast_udptl_destroy(p->udptl);
03474    if (p->refer)
03475       free(p->refer);
03476    if (p->route) {
03477       free_old_route(p->route);
03478       p->route = NULL;
03479    }
03480    if (p->registry) {
03481       if (p->registry->call == p)
03482          p->registry->call = NULL;
03483       ASTOBJ_UNREF(p->registry, sip_registry_destroy);
03484    }
03485 
03486    /* Clear history */
03487    if (p->history) {
03488       struct sip_history *hist;
03489       while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
03490          free(hist);
03491          p->history_entries--;
03492       }
03493       free(p->history);
03494       p->history = NULL;
03495    }
03496 
03497    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
03498       ast_free(req);
03499    }
03500 
03501    for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) {
03502       if (cur == p) {
03503          UNLINK(cur, iflist, prev);
03504          break;
03505       }
03506    }
03507    if (!cur) {
03508       ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid);
03509       return 0;
03510    } 
03511 
03512    /* remove all current packets in this dialog */
03513    while((cp = p->packets)) {
03514       p->packets = p->packets->next;
03515       AST_SCHED_DEL(sched, cp->retransid);
03516       free(cp);
03517    }
03518    if (p->chanvars) {
03519       ast_variables_destroy(p->chanvars);
03520       p->chanvars = NULL;
03521    }
03522    ast_mutex_destroy(&p->lock);
03523 
03524    ast_string_field_free_memory(p);
03525 
03526    free(p);
03527    return 0;
03528 }

static int __sip_do_register ( struct sip_registry r  )  [static]

Register with SIP proxy.

Definition at line 8414 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

08415 {
08416    int res;
08417 
08418    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
08419    return res;
08420 }

static void __sip_pretend_ack ( struct sip_pvt p  )  [static]

Pretend to ack all packets called with p locked.

Definition at line 2345 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_request::method, sip_pvt::packets, sip_pkt::seqno, and sip_methods.

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

02346 {
02347    struct sip_pkt *cur = NULL;
02348 
02349    while (p->packets) {
02350       int method;
02351       if (cur == p->packets) {
02352          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
02353          return;
02354       }
02355       cur = p->packets;
02356       method = (cur->method) ? cur->method : find_sip_method(cur->data);
02357       __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method);
02358    }
02359 }

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

References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, ast_test_flag, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, SIP_INVITE, sipdebug, sip_pvt::timer_t1, and XMIT_ERROR.

Referenced by send_request(), and send_response().

02141 {
02142    struct sip_pkt *pkt;
02143    int siptimer_a = DEFAULT_RETRANS;
02144    int xmitres = 0;
02145    int respid;
02146 
02147    if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1)))
02148       return AST_FAILURE;
02149    memcpy(pkt->data, data, len);
02150    pkt->method = sipmethod;
02151    pkt->packetlen = len;
02152    pkt->next = p->packets;
02153    pkt->owner = p;
02154    pkt->seqno = seqno;
02155    pkt->data[len] = '\0';
02156    if (resp) {
02157       ast_set_flag(pkt, FLAG_RESPONSE);
02158       /* Parse out the response code */
02159       if (sscanf(pkt->data, "SIP/2.0 %30d", &respid) == 1) {
02160          pkt->response_code = respid;
02161       }
02162    }
02163    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
02164    pkt->retransid = -1;
02165    if (fatal)
02166       ast_set_flag(pkt, FLAG_FATAL);
02167    if (pkt->timer_t1)
02168       siptimer_a = pkt->timer_t1 * 2;
02169 
02170    if (option_debug > 3 && sipdebug)
02171       ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
02172    pkt->retransid = -1;
02173    pkt->next = p->packets;
02174    p->packets = pkt;
02175    if (sipmethod == SIP_INVITE) {
02176       /* Note this is a pending invite */
02177       p->pendinginvite = seqno;
02178    }
02179 
02180    xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);   /* Send packet */
02181 
02182    if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
02183       append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
02184       return AST_FAILURE;
02185    } else {
02186       /* Schedule retransmission */
02187       pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
02188       return AST_SUCCESS;
02189    }
02190 }

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

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

Referenced by handle_response(), and sip_hangup().

02363 {
02364    struct sip_pkt *cur;
02365    int res = FALSE;
02366 
02367    for (cur = p->packets; cur; cur = cur->next) {
02368       if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
02369          (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
02370          /* this is our baby */
02371          if (cur->retransid > -1) {
02372             if (option_debug > 3 && sipdebug)
02373                ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
02374          }
02375          AST_SCHED_DEL(sched, cur->retransid);
02376          res = TRUE;
02377          break;
02378       }
02379    }
02380    if (option_debug)
02381       ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found");
02382    return res;
02383 }

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

SIP show channels CLI (main function).

Definition at line 12200 of file chan_sip.c.

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

Referenced by sip_show_channels(), and sip_show_subscriptions().

12201 {
12202 #define FORMAT3L "%-15.15s  %-15.15s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s %6d\n"
12203 #define FORMAT3H "%-15.15s  %-15.15s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s %-6s\n"
12204 #define FORMAT2  "%-15.15s  %-15.15s  %-11.11s  %-11.11s  %-15.15s  %-7.7s  %-15.15s\n"
12205 #define FORMAT   "%-15.15s  %-15.15s  %-11.11s  %5.5d/%5.5d  %-15.15s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
12206    struct sip_pvt *cur;
12207    int numchans = 0;
12208    int usedchans = 0;
12209    char *referstatus = NULL;
12210 
12211    if (argc != 3)
12212       return RESULT_SHOWUSAGE;
12213    ast_mutex_lock(&iflock);
12214    cur = iflist;
12215    if (!subscriptions)
12216       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
12217    else 
12218       ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry");
12219    for (; cur; cur = cur->next) {
12220       referstatus = "";
12221       if (cur->refer) { /* SIP transfer in progress */
12222          referstatus = referstatus2str(cur->refer->status);
12223       }
12224       if (cur->subscribed == NONE && !subscriptions) {
12225          char formatbuf[SIPBUFSIZE/2];
12226          ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 
12227             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
12228             cur->callid, 
12229             cur->ocseq, cur->icseq,
12230             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
12231             ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
12232             ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
12233             cur->lastmsg ,
12234             referstatus
12235          );
12236          numchans++;
12237       }
12238       if (cur->subscribed != NONE && subscriptions) {
12239          ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr),
12240             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
12241                cur->callid,
12242             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
12243             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
12244             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
12245             subscription_type2str(cur->subscribed),
12246             cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>",
12247             cur->expiry
12248 );
12249          numchans++;
12250       }
12251       if (cur->owner) { /* Count SIP dialog owned by a real channel */
12252          usedchans++;
12253       }
12254    }
12255    ast_mutex_unlock(&iflock);
12256    if (!subscriptions)
12257       ast_cli(fd, "%d active SIP dialog%s\n", numchans, (numchans != 1) ? "s" : "");
12258    else
12259       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
12260    ast_cli(fd, "%d used SIP channel%s\n", usedchans, (usedchans != 1) ? "s" : "");
12261    return RESULT_SUCCESS;
12262 #undef FORMAT
12263 #undef FORMAT2
12264 #undef FORMAT3
12265 }

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

Transmit SIP message.

Definition at line 1887 of file chan_sip.c.

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

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

01888 {
01889    int res;
01890    const struct sockaddr_in *dst = sip_real_dst(p);
01891    res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
01892 
01893    if (res == -1) {
01894       switch (errno) {
01895       case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
01896       case EHOSTUNREACH:   /* Host can't be reached */
01897       case ENETDOWN:       /* Inteface down */
01898       case ENETUNREACH: /* Network failure */
01899       case ECONNREFUSED:      /* ICMP port unreachable */ 
01900          res = XMIT_ERROR; /* Don't bother with trying to transmit again */
01901       }
01902 
01903    }
01904 
01905    if (res != len)
01906       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));
01907    return res;
01908 }

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

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

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

06961 {
06962    struct sip_request resp;
06963    int seqno = 0;
06964 
06965    if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) {
06966       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
06967       return -1;
06968    }
06969    respprep(&resp, p, msg, req);
06970    /* If we are cancelling an incoming invite for some reason, add information
06971       about the reason why we are doing this in clear text */
06972    if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
06973       char buf[10];
06974 
06975       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
06976       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
06977       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
06978    }
06979    return send_response(p, &resp, reliable, seqno);
06980 }

static void __unreg_module ( void   )  [static]

Definition at line 20459 of file chan_sip.c.

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 11756 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, sip_peer::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_FORWARD_LOOP_DETECTED, 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().

11757 {
11758    char status[30] = "";
11759    char cbuf[256];
11760    struct sip_peer *peer;
11761    char codec_buf[512];
11762    struct ast_codec_pref *pref;
11763    struct ast_variable *v;
11764    struct sip_auth *auth;
11765    int x = 0, codec = 0, load_realtime;
11766    int realtimepeers;
11767 
11768    realtimepeers = ast_check_realtime("sippeers");
11769 
11770    if (argc < 4)
11771       return RESULT_SHOWUSAGE;
11772 
11773    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
11774    peer = find_peer(argv[3], NULL, load_realtime, 0);
11775    if (s) {    /* Manager */
11776       if (peer) {
11777          const char *id = astman_get_header(m,"ActionID");
11778 
11779          astman_append(s, "Response: Success\r\n");
11780          if (!ast_strlen_zero(id))
11781             astman_append(s, "ActionID: %s\r\n",id);
11782       } else {
11783          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]);
11784          astman_send_error(s, m, cbuf);
11785          return 0;
11786       }
11787    }
11788    if (peer && type==0 ) { /* Normal listing */
11789       ast_cli(fd,"\n\n");
11790       ast_cli(fd, "  * Name       : %s\n", peer->name);
11791       if (realtimepeers) { /* Realtime is enabled */
11792          ast_cli(fd, "  Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No");
11793       }
11794       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
11795       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
11796       for (auth = peer->auth; auth; auth = auth->next) {
11797          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
11798          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
11799       }
11800       ast_cli(fd, "  Context      : %s\n", peer->context);
11801       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
11802       ast_cli(fd, "  Language     : %s\n", peer->language);
11803       if (!ast_strlen_zero(peer->accountcode))
11804          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
11805       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
11806       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
11807       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
11808       if (!ast_strlen_zero(peer->fromuser))
11809          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
11810       if (!ast_strlen_zero(peer->fromdomain))
11811          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
11812       ast_cli(fd, "  Callgroup    : ");
11813       print_group(fd, peer->callgroup, 0);
11814       ast_cli(fd, "  Pickupgroup  : ");
11815       print_group(fd, peer->pickupgroup, 0);
11816       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
11817       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
11818       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
11819       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
11820       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
11821       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
11822       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
11823       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
11824       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)));
11825       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
11826       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
11827       ast_cli(fd, "  T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No");
11828 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
11829       ast_cli(fd, "  T38 pt RTP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No");
11830       ast_cli(fd, "  T38 pt TCP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No");
11831 #endif
11832       ast_cli(fd, "  CanReinvite  : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No");
11833       ast_cli(fd, "  PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No");
11834       ast_cli(fd, "  User=Phone   : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No");
11835       ast_cli(fd, "  Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No");
11836       ast_cli(fd, "  Trust RPID   : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No");
11837       ast_cli(fd, "  Send RPID    : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No");
11838       ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
11839       ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
11840       ast_cli(fd, "  Forward Loop : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED) ? "Yes" : "No");
11841 
11842       /* - is enumerated */
11843       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
11844       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
11845       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
11846       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));
11847       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
11848       if (!ast_strlen_zero(global_regcontext))
11849          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
11850       ast_cli(fd, "  Def. Username: %s\n", peer->username);
11851       ast_cli(fd, "  SIP Options  : ");
11852       if (peer->sipoptions) {
11853          int lastoption = -1;
11854          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
11855             if (sip_options[x].id != lastoption) {
11856                if (peer->sipoptions & sip_options[x].id)
11857                   ast_cli(fd, "%s ", sip_options[x].text);
11858                lastoption = x;
11859             }
11860          }
11861       } else
11862          ast_cli(fd, "(none)");
11863 
11864       ast_cli(fd, "\n");
11865       ast_cli(fd, "  Codecs       : ");
11866       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
11867       ast_cli(fd, "%s\n", codec_buf);
11868       ast_cli(fd, "  Codec Order  : (");
11869       print_codec_to_cli(fd, &peer->prefs);
11870       ast_cli(fd, ")\n");
11871 
11872       ast_cli(fd, "  Auto-Framing:  %s \n", peer->autoframing ? "Yes" : "No");
11873       ast_cli(fd, "  Status       : ");
11874       peer_status(peer, status, sizeof(status));
11875       ast_cli(fd, "%s\n",status);
11876       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
11877       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
11878       if (peer->chanvars) {
11879          ast_cli(fd, "  Variables    :\n");
11880          for (v = peer->chanvars ; v ; v = v->next)
11881             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
11882       }
11883       ast_cli(fd,"\n");
11884       ASTOBJ_UNREF(peer,sip_destroy_peer);
11885    } else  if (peer && type == 1) { /* manager listing */
11886       char buf[256];
11887       astman_append(s, "Channeltype: SIP\r\n");
11888       astman_append(s, "ObjectName: %s\r\n", peer->name);
11889       astman_append(s, "ChanObjectType: peer\r\n");
11890       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
11891       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
11892       astman_append(s, "Context: %s\r\n", peer->context);
11893       astman_append(s, "Language: %s\r\n", peer->language);
11894       if (!ast_strlen_zero(peer->accountcode))
11895          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
11896       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
11897       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
11898       if (!ast_strlen_zero(peer->fromuser))
11899          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
11900       if (!ast_strlen_zero(peer->fromdomain))
11901          astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
11902       astman_append(s, "Callgroup: ");
11903       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup));
11904       astman_append(s, "Pickupgroup: ");
11905       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup));
11906       astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
11907       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
11908       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
11909       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
11910       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
11911       astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
11912       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
11913       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
11914       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)));
11915       astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
11916       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
11917       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
11918       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
11919       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
11920       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
11921 
11922       /* - is enumerated */
11923       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
11924       astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg);
11925       astman_append(s, "ToHost: %s\r\n", peer->tohost);
11926       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));
11927       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));
11928       astman_append(s, "Default-Username: %s\r\n", peer->username);
11929       if (!ast_strlen_zero(global_regcontext))
11930          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
11931       astman_append(s, "Codecs: ");
11932       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
11933       astman_append(s, "%s\r\n", codec_buf);
11934       astman_append(s, "CodecOrder: ");
11935       pref = &peer->prefs;
11936       for(x = 0; x < 32 ; x++) {
11937          codec = ast_codec_pref_index(pref,x);
11938          if (!codec)
11939             break;
11940          astman_append(s, "%s", ast_getformatname(codec));
11941          if (x < 31 && ast_codec_pref_index(pref,x+1))
11942             astman_append(s, ",");
11943       }
11944 
11945       astman_append(s, "\r\n");
11946       astman_append(s, "Status: ");
11947       peer_status(peer, status, sizeof(status));
11948       astman_append(s, "%s\r\n", status);
11949       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
11950       astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact);
11951       if (peer->chanvars) {
11952          for (v = peer->chanvars ; v ; v = v->next) {
11953             astman_append(s, "ChanVariable:\n");
11954             astman_append(s, " %s,%s\r\n", v->name, v->value);
11955          }
11956       }
11957 
11958       ASTOBJ_UNREF(peer,sip_destroy_peer);
11959 
11960    } else {
11961       ast_cli(fd,"Peer %s not found.\n", argv[3]);
11962       ast_cli(fd,"\n");
11963    }
11964 
11965    return RESULT_SUCCESS;
11966 }

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

References ast_check_realtime(), ast_cli(), ast_copy_string(), 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().

11300 {
11301    regex_t regexbuf;
11302    int havepattern = FALSE;
11303 
11304 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
11305 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
11306 
11307    char name[256];
11308    int total_peers = 0;
11309    int peers_mon_online = 0;
11310    int peers_mon_offline = 0;
11311    int peers_unmon_offline = 0;
11312    int peers_unmon_online = 0;
11313    const char *id;
11314    char idtext[256] = "";
11315    int realtimepeers;
11316 
11317    realtimepeers = ast_check_realtime("sippeers");
11318 
11319    if (s) { /* Manager - get ActionID */
11320       id = astman_get_header(m,"ActionID");
11321       if (!ast_strlen_zero(id))
11322          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
11323    }
11324 
11325    switch (argc) {
11326    case 5:
11327       if (!strcasecmp(argv[3], "like")) {
11328          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
11329             return RESULT_SHOWUSAGE;
11330          havepattern = TRUE;
11331       } else
11332          return RESULT_SHOWUSAGE;
11333    case 3:
11334       break;
11335    default:
11336       return RESULT_SHOWUSAGE;
11337    }
11338 
11339    if (!s) /* Normal list */
11340       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
11341    
11342    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
11343       char status[20] = "";
11344       char srch[2000];
11345       char pstatus;
11346       
11347       ASTOBJ_RDLOCK(iterator);
11348 
11349       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
11350          ASTOBJ_UNLOCK(iterator);
11351          continue;
11352       }
11353 
11354       if (!ast_strlen_zero(iterator->username) && !s)
11355          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
11356       else
11357          ast_copy_string(name, iterator->name, sizeof(name));
11358       
11359       pstatus = peer_status(iterator, status, sizeof(status));
11360       if (pstatus == 1)
11361          peers_mon_online++;
11362       else if (pstatus == 0)
11363          peers_mon_offline++;
11364       else {
11365          if (iterator->addr.sin_port == 0)
11366             peers_unmon_offline++;
11367          else
11368             peers_unmon_online++;
11369       }
11370 
11371       snprintf(srch, sizeof(srch), FORMAT, name,
11372          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
11373          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
11374          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
11375          iterator->ha ? " A " : "   ",    /* permit/deny */
11376          ntohs(iterator->addr.sin_port), status,
11377          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
11378 
11379       if (!s)  {/* Normal CLI list */
11380          ast_cli(fd, FORMAT, name, 
11381          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
11382          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
11383          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
11384          iterator->ha ? " A " : "   ",       /* permit/deny */
11385          
11386          ntohs(iterator->addr.sin_port), status,
11387          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
11388       } else { /* Manager format */
11389          /* The names here need to be the same as other channels */
11390          astman_append(s, 
11391          "Event: PeerEntry\r\n%s"
11392          "Channeltype: SIP\r\n"
11393          "ObjectName: %s\r\n"
11394          "ChanObjectType: peer\r\n" /* "peer" or "user" */
11395          "IPaddress: %s\r\n"
11396          "IPport: %d\r\n"
11397          "Dynamic: %s\r\n"
11398          "Natsupport: %s\r\n"
11399          "VideoSupport: %s\r\n"
11400          "ACL: %s\r\n"
11401          "Status: %s\r\n"
11402          "RealtimeDevice: %s\r\n\r\n", 
11403          idtext,
11404          iterator->name, 
11405          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-",
11406          ntohs(iterator->addr.sin_port), 
11407          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no",   /* Dynamic or not? */
11408          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
11409          ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
11410          iterator->ha ? "yes" : "no",       /* permit/deny */
11411          status,
11412          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no");
11413       }
11414 
11415       ASTOBJ_UNLOCK(iterator);
11416 
11417       total_peers++;
11418    } while(0) );
11419    
11420    if (!s)
11421       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
11422               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
11423 
11424    if (havepattern)
11425       regfree(&regexbuf);
11426 
11427    if (total)
11428       *total = total_peers;
11429    
11430 
11431    return RESULT_SUCCESS;
11432 #undef FORMAT
11433 #undef FORMAT2
11434 }

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

Definition at line 16575 of file chan_sip.c.

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

16576 {
16577    struct ast_rtp_quality qos;
16578    struct sip_pvt *p = chan->tech_pvt;
16579    char *all = "", *parse = ast_strdupa(preparse);
16580    AST_DECLARE_APP_ARGS(args,
16581       AST_APP_ARG(param);
16582       AST_APP_ARG(type);
16583       AST_APP_ARG(field);
16584    );
16585    AST_STANDARD_APP_ARGS(args, parse);
16586 
16587    /* Sanity check */
16588    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
16589       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
16590       return 0;
16591    }
16592 
16593    if (strcasecmp(args.param, "rtpqos"))
16594       return 0;
16595 
16596    /* Default arguments of audio,all */
16597    if (ast_strlen_zero(args.type))
16598       args.type = "audio";
16599    if (ast_strlen_zero(args.field))
16600       args.field = "all";
16601 
16602    memset(buf, 0, buflen);
16603    memset(&qos, 0, sizeof(qos));
16604 
16605    if (p == NULL) {
16606       return -1;
16607    }
16608 
16609    if (strcasecmp(args.type, "AUDIO") == 0) {
16610       all = ast_rtp_get_quality(p->rtp, &qos);
16611    } else if (strcasecmp(args.type, "VIDEO") == 0) {
16612       all = ast_rtp_get_quality(p->vrtp, &qos);
16613    }
16614 
16615    if (strcasecmp(args.field, "local_ssrc") == 0)
16616       snprintf(buf, buflen, "%u", qos.local_ssrc);
16617    else if (strcasecmp(args.field, "local_lostpackets") == 0)
16618       snprintf(buf, buflen, "%u", qos.local_lostpackets);
16619    else if (strcasecmp(args.field, "local_jitter") == 0)
16620       snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
16621    else if (strcasecmp(args.field, "local_count") == 0)
16622       snprintf(buf, buflen, "%u", qos.local_count);
16623    else if (strcasecmp(args.field, "remote_ssrc") == 0)
16624       snprintf(buf, buflen, "%u", qos.remote_ssrc);
16625    else if (strcasecmp(args.field, "remote_lostpackets") == 0)
16626       snprintf(buf, buflen, "%u", qos.remote_lostpackets);
16627    else if (strcasecmp(args.field, "remote_jitter") == 0)
16628       snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
16629    else if (strcasecmp(args.field, "remote_count") == 0)
16630       snprintf(buf, buflen, "%u", qos.remote_count);
16631    else if (strcasecmp(args.field, "rtt") == 0)
16632       snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
16633    else if (strcasecmp(args.field, "all") == 0)
16634       ast_copy_string(buf, all, buflen);
16635    else {
16636       ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
16637       return -1;
16638    }
16639    return 0;
16640 }

static void add_blank ( struct sip_request req  )  [static]

add a blank line if no body

Definition at line 2396 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02397 {
02398    if (!req->lines) {
02399       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
02400       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
02401       req->len += strlen(req->data + req->len);
02402    }
02403 }

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

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

Referenced by add_sdp().

07173 {
07174    int rtp_code;
07175    struct ast_format_list fmt;
07176 
07177 
07178    if (debug)
07179       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
07180    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
07181       return;
07182 
07183    if (p->rtp) {
07184       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
07185       fmt = ast_codec_pref_getsize(pref, codec);
07186    } 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 */
07187       return;
07188    ast_build_string(m_buf, m_size, " %d", rtp_code);
07189    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
07190           ast_rtp_lookup_mime_subtype(1, codec,
07191                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
07192           sample_rate);
07193    if (codec == AST_FORMAT_G729A) {
07194       /* Indicate that we don't support VAD (G.729 annex B) */
07195       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
07196    } else if (codec == AST_FORMAT_G723_1) {
07197       /* Indicate that we don't support VAD (G.723.1 annex A) */
07198       ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code);
07199    } else if (codec == AST_FORMAT_ILBC) {
07200       /* Add information about us using only 20/30 ms packetization */
07201       ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
07202    }
07203 
07204    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
07205       *min_packet_size = fmt.cur_ms;
07206 
07207    /* Our first codec packetization processed cannot be less than zero */
07208    if ((*min_packet_size) == 0  && fmt.cur_ms)
07209       *min_packet_size = fmt.cur_ms;
07210 }

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

Add content (not header) to SIP message.

Definition at line 6491 of file chan_sip.c.

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

Referenced by add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify().

06492 {
06493    if (req->lines) {
06494       ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n");
06495       return -1;
06496    }
06497 
06498    if (req->len + strlen(req->content) + strlen(line) >= sizeof(req->data) - 4) {
06499       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
06500       return -1;
06501    }
06502 
06503    snprintf(req->content + strlen(req->content), sizeof(req->content) - strlen(req->content), "%s", line);
06504    return 0;
06505 }

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

Add DTMF INFO tone to sip message.

Definition at line 7140 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_info_with_digit().

07141 {
07142    char tmp[256];
07143 
07144    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
07145    add_header(req, "Content-Type", "application/dtmf-relay");
07146    add_content(req, tmp);
07147    return 0;
07148 }

static int add_extensionstate_update ( char *  context,
char *  exten,
int  state,
void *  data 
) [static]

Definition at line 9601 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, AST_PTHREADT_STOP, sip_extenstate_update::list, and update().

Referenced by handle_request_subscribe().

09602 {
09603    struct sip_extenstate_update *update;
09604    size_t exten_len = strlen(exten);
09605    size_t context_len = strlen(context);
09606 
09607    if (!(update = ast_calloc(1, sizeof(*update) + exten_len + context_len + 2))) {
09608       return -1;
09609    }
09610 
09611    strcpy(update->exten, exten);
09612 
09613    update->context = (char *) (update->exten + exten_len + 1);
09614    strcpy(update->context, context);
09615 
09616    update->state = state;
09617    update->pvt = data;
09618 
09619    AST_LIST_LOCK(&sip_extenstate_updates);
09620    AST_LIST_INSERT_TAIL(&sip_extenstate_updates, update, list);
09621    AST_LIST_UNLOCK(&sip_extenstate_updates);
09622 
09623    /* Tell the do_monitor thread it has to do stuff! That thread is so lazy :( */
09624    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
09625       pthread_kill(monitor_thread, SIGURG);
09626    }
09627 
09628    return 0;
09629 }

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

Add header to SIP message.

Definition at line 6437 of file chan_sip.c.

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

06438 {
06439    int maxlen = sizeof(req->data) - 4 - req->len - strlen(req->content); /* 4 bytes are for two \r\n ? */
06440 
06441    if (req->headers == SIP_MAX_HEADERS) {
06442       ast_log(LOG_WARNING, "Out of SIP header space\n");
06443       return -1;
06444    }
06445 
06446    if (req->lines) {
06447       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
06448       return -1;
06449    }
06450 
06451    if (maxlen <= 0) {
06452       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
06453       return -1;
06454    }
06455 
06456    req->header[req->headers] = req->data + req->len;
06457 
06458    if (compactheaders)
06459       var = find_alias(var, var);
06460 
06461    snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
06462    req->len += strlen(req->header[req->headers]);
06463    req->headers++;
06464 
06465    return 0;   
06466 }

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

07252 {
07253    int rtp_code;
07254 
07255    if (debug)
07256       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
07257    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
07258       return;
07259 
07260    ast_build_string(m_buf, m_size, " %d", rtp_code);
07261    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
07262           ast_rtp_lookup_mime_subtype(0, format, 0),
07263           sample_rate);
07264    if (format == AST_RTP_DTMF)
07265       /* Indicate we support DTMF and FLASH... */
07266       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
07267 }

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

Add realm authentication in list.

Definition at line 18407 of file chan_sip.c.

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

Referenced by build_peer().

18408 {
18409    char authcopy[256];
18410    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
18411    struct sip_auth *a, *b, *auth;
18412 
18413    if (ast_strlen_zero(configuration))
18414       return authlist;
18415 
18416    if (option_debug)
18417       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
18418 
18419    ast_copy_string(authcopy, configuration, sizeof(authcopy));
18420 
18421    username = authcopy;
18422    /* split user[:secret] and realm */
18423    realm = strrchr(username, '@');
18424    if (realm)
18425       *realm++ = '\0';
18426    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
18427       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
18428       return authlist;
18429    }
18430 
18431    /* parse username at ':' for secret, or '#" for md5secret */
18432    if ((secret = strchr(username, ':'))) {
18433       *secret++ = '\0';
18434    } else if ((md5secret = strchr(username, '#'))) {
18435       *md5secret++ = '\0';
18436    }
18437 
18438    if (!(auth = ast_calloc(1, sizeof(*auth))))
18439       return authlist;
18440 
18441    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
18442    ast_copy_string(auth->username, username, sizeof(auth->username));
18443    if (secret)
18444       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
18445    if (md5secret)
18446       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
18447 
18448    /* find the end of the list */
18449    for (b = NULL, a = authlist; a ; b = a, a = a->next)
18450       ;
18451    if (b)
18452       b->next = auth;   /* Add structure add end of list */
18453    else
18454       authlist = auth;
18455 
18456    if (option_verbose > 2)
18457       ast_verbose("Added authentication for realm %s\n", realm);
18458 
18459    return authlist;
18460 
18461 }

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

Add route header into request per learned route.

Definition at line 6606 of file chan_sip.c.

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

Referenced by initreqprep(), and reqprep().

06607 {
06608    char r[SIPBUFSIZE*2], *p;
06609    int n, rem = sizeof(r);
06610 
06611    if (!route)
06612       return;
06613 
06614    p = r;
06615    for (;route ; route = route->next) {
06616       n = strlen(route->hop);
06617       if (rem < n+3) /* we need room for ",<route>" */
06618          break;
06619       if (p != r) {  /* add a separator after fist route */
06620          *p++ = ',';
06621          --rem;
06622       }
06623       *p++ = '<';
06624       ast_copy_string(p, route->hop, rem); /* cannot fail */
06625       p += n;
06626       *p++ = '>';
06627       rem -= (n+2);
06628    }
06629    *p = '\0';
06630    add_header(req, "Route", r);
06631 }

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

Add Session Description Protocol message.

Definition at line 7277 of file chan_sip.c.

References add_codec_to_sdp(), add_content(), add_header(), 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_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose(), t38properties::capability, capability, debug, FALSE, sip_pvt::flags, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_DEBUG, LOG_NOTICE, sip_pvt::maxcallbitrate, sip_pvt::offered_media, option_debug, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SDP_AUDIO, SDP_IMAGE, SDP_SAMPLE_RATE, SDP_VIDEO, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, SIPBUFSIZE, sip_pvt::t38, 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, t38properties::t38support, TRUE, sip_pvt::udptl, sip_pvt::udptlredirip, sip_pvt::vredirip, and sip_pvt::vrtp.

07278 {
07279    int alreadysent = 0;
07280    int doing_directmedia = FALSE;
07281 
07282    struct sockaddr_in sin;
07283    struct sockaddr_in vsin;
07284    struct sockaddr_in dest;
07285    struct sockaddr_in vdest = { 0, };
07286 
07287    /* SDP fields */
07288    char *version =   "v=0\r\n";     /* Protocol version */
07289    char *subject =   "s=session\r\n";  /* Subject of the session */
07290    char owner[256];           /* Session owner/creator */
07291    char connection[256];            /* Connection data */
07292    char *stime = "t=0 0\r\n";          /* Time the session is active */
07293    char bandwidth[256] = "";        /* Max bitrate */
07294    char *hold;
07295    char m_audio[256];            /* Media declaration line for audio */
07296    char m_video[256];            /* Media declaration line for video */
07297    char m_modem[256];                              /* Media declaration line for t38 */
07298    char a_audio[1024];           /* Attributes for audio */
07299    char a_video[1024];           /* Attributes for video */
07300    char a_modem[1024];                             /* Attributes for t38 */
07301    char *m_audio_next = m_audio;
07302    char *m_video_next = m_video;
07303    char *m_modem_next = m_modem;
07304    size_t m_audio_left = sizeof(m_audio);
07305    size_t m_video_left = sizeof(m_video);
07306    size_t m_modem_left = sizeof(m_modem);
07307    char *a_audio_next = a_audio;
07308    char *a_video_next = a_video;
07309    char *a_modem_next = a_modem;
07310    size_t a_audio_left = sizeof(a_audio);
07311    size_t a_video_left = sizeof(a_video);
07312    size_t a_modem_left = sizeof(a_modem);
07313    char dummy_answer[256];
07314 
07315    int x;
07316    int capability = 0;
07317    int needvideo = FALSE;
07318    int debug = sip_debug_test_pvt(p);
07319    int min_audio_packet_size = 0;
07320    int min_video_packet_size = 0;
07321 
07322    m_video[0] = '\0';   /* Reset the video media string if it's not needed */
07323    m_modem[0] = '\0';
07324    
07325    if (!p->rtp) {
07326       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
07327       return AST_FAILURE;
07328    }
07329 
07330    /* Set RTP Session ID and version */
07331    if (!p->sessionid) {
07332       p->sessionid = getpid();
07333       p->sessionversion = p->sessionid;
07334    } else
07335       p->sessionversion++;
07336 
07337    /* Get our addresses */
07338    ast_rtp_get_us(p->rtp, &sin);
07339    if (p->vrtp)
07340       ast_rtp_get_us(p->vrtp, &vsin);
07341 
07342    /* Is this a re-invite to move the media out, then use the original offer from caller  */
07343    if (p->redirip.sin_addr.s_addr) {
07344       dest.sin_port = p->redirip.sin_port;
07345       dest.sin_addr = p->redirip.sin_addr;
07346       doing_directmedia = p->redircodecs ? TRUE : FALSE;
07347    } else {
07348       dest.sin_addr = p->ourip;
07349       dest.sin_port = sin.sin_port;
07350    }
07351 
07352         snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
07353    snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
07354 
07355    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
07356       hold = "a=recvonly\r\n";
07357    else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE)
07358       hold = "a=inactive\r\n";
07359    else
07360       hold = "a=sendrecv\r\n";
07361 
07362    if (add_audio) {
07363       char codecbuf[SIPBUFSIZE];
07364       capability = p->jointcapability;
07365 
07366       if (option_debug > 1) {
07367          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");
07368          ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
07369       }
07370 
07371       if (doing_directmedia) {
07372          capability &= p->redircodecs;
07373          if (option_debug > 1) {
07374             ast_log(LOG_NOTICE, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability));
07375          }
07376       }
07377 
07378 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
07379       if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) {
07380          ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
07381          ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
07382       }
07383 #endif
07384 
07385       /* Check if we need video in this call */
07386       if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
07387          if (p->vrtp) {
07388             needvideo = TRUE;
07389             if (option_debug > 1)
07390                ast_log(LOG_DEBUG, "This call needs video offers!\n");
07391          } else if (option_debug > 1)
07392             ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n");
07393       }
07394 
07395 
07396       /* Ok, we need video. Let's add what we need for video and set codecs.
07397          Video is handled differently than audio since we can not transcode. */
07398       if (needvideo) {
07399          /* Determine video destination */
07400          if (p->vredirip.sin_addr.s_addr) {
07401             vdest.sin_addr = p->vredirip.sin_addr;
07402             vdest.sin_port = p->vredirip.sin_port;
07403          } else {
07404             vdest.sin_addr = p->ourip;
07405             vdest.sin_port = vsin.sin_port;
07406          }
07407          ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vsin.sin_port));
07408 
07409          /* Build max bitrate string */
07410          if (p->maxcallbitrate)
07411             snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
07412          if (debug) 
07413             ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));   
07414       }
07415 
07416       if (debug) 
07417          ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 
07418 
07419       ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
07420 
07421       /* Now, start adding audio codecs. These are added in this order:
07422          - First what was requested by the calling channel
07423          - Then preferences in order from sip.conf device config for this peer/user
07424          - Then other codecs in capabilities, including video
07425       */
07426 
07427       /* Prefer the audio codec we were requested to use, first, no matter what 
07428          Note that p->prefcodec can include video codecs, so mask them out
07429       */
07430       if (capability & p->prefcodec) {
07431          int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
07432 
07433          add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
07434                 &m_audio_next, &m_audio_left,
07435                 &a_audio_next, &a_audio_left,
07436                 debug, &min_audio_packet_size);
07437          alreadysent |= codec;
07438       }
07439 
07440       /* Start by sending our preferred audio codecs */
07441       for (x = 0; x < 32; x++) {
07442          int codec;
07443 
07444          if (!(codec = ast_codec_pref_index(&p->prefs, x)))
07445             break; 
07446 
07447          if (!(capability & codec))
07448             continue;
07449 
07450          if (alreadysent & codec)
07451             continue;
07452 
07453          add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
07454                 &m_audio_next, &m_audio_left,
07455                 &a_audio_next, &a_audio_left,
07456                 debug, &min_audio_packet_size);
07457          alreadysent |= codec;
07458       }
07459 
07460       /* Now send any other common audio and video codecs, and non-codec formats: */
07461       for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
07462          if (!(capability & x))  /* Codec not requested */
07463             continue;
07464 
07465          if (alreadysent & x) /* Already added to SDP */
07466             continue;
07467 
07468          if (x <= AST_FORMAT_MAX_AUDIO)
07469             add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
07470                    &m_audio_next, &m_audio_left,
07471                    &a_audio_next, &a_audio_left,
07472                    debug, &min_audio_packet_size);
07473          else 
07474             add_codec_to_sdp(p, x, 90000,
07475                    &m_video_next, &m_video_left,
07476                    &a_video_next, &a_video_left,
07477                    debug, &min_video_packet_size);
07478       }
07479 
07480       /* Now add DTMF RFC2833 telephony-event as a codec */
07481       for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
07482          if (!(p->jointnoncodeccapability & x))
07483             continue;
07484 
07485          add_noncodec_to_sdp(p, x, 8000,
07486                    &m_audio_next, &m_audio_left,
07487                    &a_audio_next, &a_audio_left,
07488                    debug);
07489       }
07490 
07491       if (option_debug > 2)
07492          ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n");
07493 
07494       if (!p->owner || !ast_internal_timing_enabled(p->owner))
07495          ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
07496 
07497       if (min_audio_packet_size)
07498          ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size);
07499 
07500       if (min_video_packet_size)
07501          ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size);
07502 
07503       if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
07504          ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
07505 
07506       ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
07507       if (needvideo)
07508          ast_build_string(&m_video_next, &m_video_left, "\r\n");
07509    }
07510 
07511    if (add_t38 && p->udptl) {
07512       struct sockaddr_in udptlsin;
07513       struct sockaddr_in udptldest = { 0, };
07514 
07515       ast_udptl_get_us(p->udptl, &udptlsin);
07516 
07517       if (p->udptlredirip.sin_addr.s_addr) {
07518          udptldest.sin_port = p->udptlredirip.sin_port;
07519          udptldest.sin_addr = p->udptlredirip.sin_addr;
07520       } else {
07521          udptldest.sin_addr = p->ourip;
07522          udptldest.sin_port = udptlsin.sin_port;
07523       }
07524 
07525       if (debug) {
07526          ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
07527          ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
07528             p->t38.capability,
07529             p->t38.peercapability,
07530             p->t38.jointcapability);
07531       }
07532 
07533       ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
07534 
07535       if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
07536          ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
07537       if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
07538          ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
07539       if ((x = t38_get_rate(p->t38.jointcapability)))
07540          ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
07541       if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL)
07542          ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n");
07543       if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR)
07544          ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n");
07545       if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG)
07546          ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n");
07547       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
07548       x = ast_udptl_get_local_max_datagram(p->udptl);
07549       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
07550       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
07551       if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
07552          ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
07553    }
07554 
07555    add_header(resp, "Content-Type", "application/sdp");
07556    add_content(resp, version);
07557    add_content(resp, owner);
07558    add_content(resp, subject);
07559    add_content(resp, connection);
07560    if (needvideo)    /* only if video response is appropriate */
07561       add_content(resp, bandwidth);
07562    add_content(resp, stime);
07563    if (add_audio) {
07564       add_content(resp, m_audio);
07565       add_content(resp, a_audio);
07566       add_content(resp, hold);
07567    } else if (p->offered_media[SDP_AUDIO].offered) {
07568       snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].text);
07569       add_content(resp, dummy_answer);
07570    }
07571    if (needvideo) { /* only if video response is appropriate */
07572       add_content(resp, m_video);
07573       add_content(resp, a_video);
07574       add_content(resp, hold);   /* Repeat hold for the video stream */
07575    } else if (p->offered_media[SDP_VIDEO].offered) {
07576       snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].text);
07577       add_content(resp, dummy_answer);
07578    }
07579    if (add_t38) {
07580       add_content(resp, m_modem);
07581       add_content(resp, a_modem);
07582    } else if (p->offered_media[SDP_IMAGE].offered) {
07583       add_content(resp, "m=image 0 udptl t38\r\n");
07584    }
07585 
07586    /* Update lastrtprx when we send our SDP */
07587    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
07588 
07589    if (option_debug > 2) {
07590       char buf[SIPBUFSIZE];
07591       ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability));
07592    }
07593 
07594    return AST_SUCCESS;
07595 }

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

References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::list, LOG_DEBUG, and sipdebug.

18344 {
18345    struct domain *d;
18346 
18347    if (ast_strlen_zero(domain)) {
18348       ast_log(LOG_WARNING, "Zero length domain.\n");
18349       return 1;
18350    }
18351 
18352    if (!(d = ast_calloc(1, sizeof(*d))))
18353       return 0;
18354 
18355    ast_copy_string(d->domain, domain, sizeof(d->domain));
18356 
18357    if (!ast_strlen_zero(context))
18358       ast_copy_string(d->context, context, sizeof(d->context));
18359 
18360    d->mode = mode;
18361 
18362    AST_LIST_LOCK(&domain_list);
18363    AST_LIST_INSERT_TAIL(&domain_list, d, list);
18364    AST_LIST_UNLOCK(&domain_list);
18365 
18366    if (sipdebug)  
18367       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
18368 
18369    return 1;
18370 }

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

Add text body to SIP message.

Definition at line 7130 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_message_with_text().

07131 {
07132    /* XXX Convert \n's to \r\n's XXX */
07133    add_header(req, "Content-Type", "text/plain");
07134    add_content(req, text);
07135    return 0;
07136 }

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

References add_content(), and add_header().

Referenced by transmit_info_with_vidupdate().

07153 {
07154    const char *xml_is_a_huge_waste_of_space =
07155       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
07156       " <media_control>\r\n"
07157       "  <vc_primitive>\r\n"
07158       "   <to_encoder>\r\n"
07159       "    <picture_fast_update>\r\n"
07160       "    </picture_fast_update>\r\n"
07161       "   </to_encoder>\r\n"
07162       "  </vc_primitive>\r\n"
07163       " </media_control>\r\n";
07164    add_header(req, "Content-Type", "application/media_control+xml");
07165    add_content(req, xml_is_a_huge_waste_of_space);
07166    return 0;
07167 }

static int addr_is_multicast ( struct in_addr *  addr  )  [static]

Check if an ip is an multicast IP. addr the address to check.

This function checks if an address is in the 224.0.0.0/4 network block.

Returns:
non-zero if this is a multicast address

Definition at line 5132 of file chan_sip.c.

Referenced by process_via().

05133 {
05134    return ((ntohl(addr->s_addr) & 0xf0000000) == 0xe0000000);
05135 }

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

07068 {
07069    char tmpdat[256];
07070    struct tm tm;
07071    time_t t = time(NULL);
07072 
07073    gmtime_r(&t, &tm);
07074    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
07075    add_header(req, "Date", tmpdat);
07076 }

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

Append to SIP dialog history with arg list.

Definition at line 1995 of file chan_sip.c.

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

01996 {
01997    va_list ap;
01998 
01999    if (!p)
02000       return;
02001 
02002    if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 
02003       && !recordhistory && !dumphistory) {
02004       return;
02005    }
02006 
02007    va_start(ap, fmt);
02008    append_history_va(p, fmt, ap);
02009    va_end(ap);
02010 
02011    return;
02012 }

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

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, free, sip_history::list, and MAX_HISTORY_ENTRIES.

Referenced by append_history_full().

01969 {
01970    char buf[80], *c = buf; /* max history length */
01971    struct sip_history *hist;
01972    int l;
01973 
01974    vsnprintf(buf, sizeof(buf), fmt, ap);
01975    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
01976    l = strlen(buf) + 1;
01977    if (!(hist = ast_calloc(1, sizeof(*hist) + l)))
01978       return;
01979    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
01980       free(hist);
01981       return;
01982    }
01983    memcpy(hist->event, buf, l);
01984    if (p->history_entries == MAX_HISTORY_ENTRIES) {
01985       struct sip_history *oldest;
01986       oldest = AST_LIST_REMOVE_HEAD(p->history, list);
01987       p->history_entries--;
01988       free(oldest);
01989    }
01990    AST_LIST_INSERT_TAIL(p->history, hist, list);
01991    p->history_entries++;
01992 }

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

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

Referenced by attempt_transfer(), and handle_invite_replaces().

14747 {
14748    if (chan && chan->_state == AST_STATE_UP) {
14749       if (ast_test_flag(chan, AST_FLAG_MOH))
14750          ast_moh_stop(chan);
14751       else if (chan->generatordata)
14752          ast_deactivate_generator(chan);
14753    }
14754 }

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

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

01929 {
01930    struct sockaddr_in theirs, ours;
01931 
01932    /* Get our local information */
01933    ast_ouraddrfor(them, us);
01934    theirs.sin_addr = *them;
01935    ours.sin_addr = *us;
01936 
01937    if (localaddr && externip.sin_addr.s_addr &&
01938        (ast_apply_ha(localaddr, &theirs)) &&
01939        (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) {
01940       if (externexpire && time(NULL) >= externexpire) {
01941          struct ast_hostent ahp;
01942          struct hostent *hp;
01943 
01944          externexpire = time(NULL) + externrefresh;
01945          if ((hp = ast_gethostbyname(externhost, &ahp))) {
01946             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
01947          } else
01948             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
01949       }
01950       *us = externip.sin_addr;
01951       if (option_debug) {
01952          ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 
01953             ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
01954       }
01955    } else if (bindaddr.sin_addr.s_addr)
01956       *us = bindaddr.sin_addr;
01957    return AST_SUCCESS;
01958 }

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

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

14759 {
14760    int res = 0;
14761    struct ast_channel *peera = NULL,   
14762       *peerb = NULL,
14763       *peerc = NULL,
14764       *peerd = NULL;
14765 
14766 
14767    /* We will try to connect the transferee with the target and hangup
14768       all channels to the transferer */   
14769    if (option_debug > 3) {
14770       ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
14771       if (transferer->chan1)
14772          ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
14773       else
14774          ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
14775       if (target->chan1)
14776          ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
14777       else
14778          ast_log(LOG_DEBUG, "-- No target first channel ---\n");
14779       if (transferer->chan2)
14780          ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
14781       else
14782          ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
14783       if (target->chan2)
14784          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)");
14785       else
14786          ast_log(LOG_DEBUG, "-- No target second channel ---\n");
14787       ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
14788    }
14789    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
14790       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
14791       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
14792       peerc = transferer->chan2; /* Asterisk to Transferee */
14793       peerd = target->chan2;     /* Asterisk to Target */
14794       if (option_debug > 2)
14795          ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
14796    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
14797       peera = target->chan1;     /* Transferer to PBX -> target channel */
14798       peerb = transferer->chan1; /* Transferer to IVR*/
14799       peerc = target->chan2;     /* Asterisk to Target */
14800       peerd = transferer->chan2; /* Nothing */
14801       if (option_debug > 2)
14802          ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
14803    }
14804 
14805    if (peera && peerb && peerc && (peerb != peerc)) {
14806       ast_quiet_chan(peera);     /* Stop generators */
14807       ast_quiet_chan(peerb);  
14808       ast_quiet_chan(peerc);
14809       if (peerd)
14810          ast_quiet_chan(peerd);
14811 
14812       if (option_debug > 3)
14813          ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
14814       if (ast_channel_masquerade(peerb, peerc)) {
14815          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
14816          res = -1;
14817       } else
14818          ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
14819       return res;
14820    } else {
14821       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
14822       if (transferer->chan1)
14823          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
14824       if (target->chan1)
14825          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
14826       return -2;
14827    }
14828    return 0;
14829 }

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

Scheduled congestion on a call.

Definition at line 3255 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(), DEFAULT_TRANS_TIMEOUT, sip_pvt::initid, sip_pvt::lock, LOG_NOTICE, ast_channel::name, sip_pvt::owner, and sip_scheddestroy().

03256 {
03257    struct sip_pvt *p = (struct sip_pvt *)nothing;
03258 
03259    ast_mutex_lock(&p->lock);
03260    p->initid = -1;
03261    if (p->owner) {
03262       /* XXX fails on possible deadlock */
03263       if (!ast_channel_trylock(p->owner)) {
03264          ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
03265          append_history(p, "Cong", "Auto-congesting (timer)");
03266          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
03267          ast_channel_unlock(p->owner);
03268       }
03269 
03270       /* Give the channel a chance to act before we proceed with destruction */
03271       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03272    }
03273    ast_mutex_unlock(&p->lock);
03274    return 0;
03275 }

static void build_callid_pvt ( struct sip_pvt pvt  )  [static]

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

Definition at line 4843 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, sip_pvt::callid, sip_pvt::fromdomain, 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().

04844 {
04845    char buf[33];
04846 
04847    const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
04848    
04849    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04850 
04851 }

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

References ast_inet_ntoa(), ast_string_field_build, sip_pvt::callid, generate_random_string(), and S_OR.

Referenced by transmit_register().

04855 {
04856    char buf[33];
04857 
04858    const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
04859 
04860    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04861 }

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

Definition at line 7772 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), sip_pvt::exten, ourport, SIPBUFSIZE, and STANDARD_SIP_PORT.

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

07773 {
07774    char tmp[SIPBUFSIZE];
07775    char *user;
07776 
07777    user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 1);
07778 
07779    /* Construct Contact: header */
07780    if (ourport != STANDARD_SIP_PORT)
07781       ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", user, ast_strlen_zero(user) ? "" : "@", ast_inet_ntoa(p->ourip), ourport);
07782    else
07783       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user, ast_strlen_zero(user) ? "" : "@", ast_inet_ntoa(p->ourip));
07784 }

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

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

Definition at line 18675 of file chan_sip.c.

References __set_address_from_contact(), sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_copy_string(), ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_inet_ntoa(), 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_REF, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::contactha, sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_contact_ha, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastms, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_ERROR, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, sip_peer::name, ast_variable::next, sip_peer::objflags, option_debug, peerl, sip_peer::pickupgroup, sip_peer::portinuri, 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_NAT_ROUTE, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_poke_peer(), SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::useragent, sip_peer::username, ast_variable::value, and sip_peer::vmexten.

18676 {
18677    struct sip_peer *peer = NULL;
18678    struct ast_ha *oldha = NULL;
18679    int obproxyfound=0;
18680    int found=0;
18681    int firstpass=1;
18682    int format=0;     /* Ama flags */
18683    time_t regseconds = 0;
18684    char *varname = NULL, *varval = NULL;
18685    struct ast_variable *tmpvar = NULL;
18686    struct ast_flags peerflags[2] = {{(0)}};
18687    struct ast_flags mask[2] = {{(0)}};
18688    int alt_fullcontact = alt ? 1 : 0;
18689    char fullcontact[sizeof(peer->fullcontact)] = "";
18690 
18691    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
18692       /* Note we do NOT use find_peer here, to avoid realtime recursion */
18693       /* We also use a case-sensitive comparison (unlike find_peer) so
18694          that case changes made to the peer name will be properly handled
18695          during reload
18696       */
18697       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
18698 
18699    if (peer) {
18700       /* Already in the list, remove it and it will be added back (or FREE'd)  */
18701       found = 1;
18702       if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
18703          firstpass = 0;
18704    } else {
18705       if (!(peer = ast_calloc(1, sizeof(*peer))))
18706          return NULL;
18707 
18708       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
18709          rpeerobjs++;
18710       else
18711          speerobjs++;
18712       ASTOBJ_INIT(peer);
18713    }
18714    /* Note that our peer HAS had its reference count incrased */
18715    if (firstpass) {
18716       peer->lastmsgssent = -1;
18717       oldha = peer->ha;
18718       peer->ha = NULL;
18719       set_peer_defaults(peer);   /* Set peer defaults */
18720    }
18721    if (!found && name)
18722          ast_copy_string(peer->name, name, sizeof(peer->name));
18723 
18724    /* If we have channel variables, remove them (reload) */
18725    if (peer->chanvars) {
18726       ast_variables_destroy(peer->chanvars);
18727       peer->chanvars = NULL;
18728       /* XXX should unregister ? */
18729    }
18730 
18731    if (found)
18732       peer->portinuri = 0;
18733 
18734    /* If we have realm authentication information, remove them (reload) */
18735    clear_realm_authentication(peer->auth);
18736    peer->auth = NULL;
18737 
18738    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
18739       if (!devstate_only) {
18740          if (handle_common_options(&peerflags[0], &mask[0], v)) {
18741             continue;
18742          }
18743          if (realtime && !strcasecmp(v->name, "regseconds")) {
18744             ast_get_time_t(v->value, &regseconds, 0, NULL);
18745          } else if (realtime && !strcasecmp(v->name, "name")) {
18746             ast_copy_string(peer->name, v->value, sizeof(peer->name));
18747          } else if (realtime && !strcasecmp(v->name, "useragent")) {
18748             ast_copy_string(peer->useragent, v->value, sizeof(peer->useragent));
18749          } else if (realtime && !strcasecmp(v->name, "fullcontact")) {
18750             if (alt_fullcontact && !alt) {
18751                /* Reset, because the alternate also has a fullcontact and we
18752                 * do NOT want the field value to be doubled. It might be
18753                 * tempting to skip this, but the first table might not have
18754                 * fullcontact and since we're here, we know that the alternate
18755                 * absolutely does. */
18756                alt_fullcontact = 0;
18757                fullcontact[0] = '\0';
18758             }
18759             /* Reconstruct field, because realtime separates our value at the ';' */
18760             if (!ast_strlen_zero(fullcontact)) {
18761                strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1);
18762                strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1);
18763             } else {
18764                ast_copy_string(fullcontact, v->value, sizeof(fullcontact));
18765                ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT);
18766             }
18767          } else if (!strcasecmp(v->name, "secret")) {
18768             ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
18769          } else if (!strcasecmp(v->name, "md5secret")) {
18770             ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
18771          } else if (!strcasecmp(v->name, "auth")) {
18772             peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
18773          } else if (!strcasecmp(v->name, "callerid")) {
18774             ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
18775          } else if (!strcasecmp(v->name, "fullname")) {
18776             ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
18777          } else if (!strcasecmp(v->name, "trunkname")) {
18778             /* This is actually for a trunk, so we don't want to override callerid */
18779             ast_copy_string(peer->cid_name, "", sizeof(peer->cid_name));
18780          } else if (!strcasecmp(v->name, "cid_number")) {
18781             ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
18782          } else if (!strcasecmp(v->name, "context")) {
18783             ast_copy_string(peer->context, v->value, sizeof(peer->context));
18784          } else if (!strcasecmp(v->name, "subscribecontext")) {
18785             ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
18786          } else if (!strcasecmp(v->name, "fromdomain")) {
18787             ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
18788          } else if (!strcasecmp(v->name, "usereqphone")) {
18789             ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
18790          } else if (!strcasecmp(v->name, "fromuser")) {
18791             ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
18792          } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
18793             if (!strcasecmp(v->value, "dynamic")) {
18794                if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
18795                   ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
18796                } else {
18797                   /* They'll register with us */
18798                   if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
18799                      /* Initialize stuff if this is a new peer, or if it used to be
18800                       * non-dynamic before the reload. */
18801                      memset(&peer->addr.sin_addr, 0, 4);
18802                      if (peer->addr.sin_port) {
18803                         /* If we've already got a port, make it the default rather than absolute */
18804                         peer->defaddr.sin_port = peer->addr.sin_port;
18805                         peer->addr.sin_port = 0;
18806                      }
18807                   }
18808                   ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
18809                }
18810             } else {
18811                /* Non-dynamic.  Make sure we become that way if we're not */
18812                if (!AST_SCHED_DEL(sched, peer->expire)) {
18813                   struct sip_peer *peer_ptr = peer;
18814                   ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
18815                }
18816                ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
18817                if (!strcasecmp(v->name, "outboundproxy")) {
18818                   if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
18819                      ast_log(LOG_ERROR, "srvlookup failed for outboundproxy: %s, on peer %s, removing peer\n", v->value, peer->name);
18820                      ASTOBJ_UNREF(peer, sip_destroy_peer);
18821                      return NULL;
18822                   }
18823                }
18824                if (!strcasecmp(v->name, "outboundproxy"))
18825                   obproxyfound=1;
18826                else {
18827                   ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
18828                   if (!peer->addr.sin_port)
18829                      peer->addr.sin_port = htons(STANDARD_SIP_PORT);
18830                }
18831                if (global_dynamic_exclude_static) {
18832                   global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha);
18833                }
18834             }
18835          } else if (!strcasecmp(v->name, "defaultip")) {
18836             if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) {
18837                ASTOBJ_UNREF(peer, sip_destroy_peer);
18838                return NULL;
18839             }
18840          } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
18841             if (!ast_strlen_zero(v->value)) {
18842                peer->ha = ast_append_ha(v->name, v->value, peer->ha);
18843             }
18844          } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
18845             if (!ast_strlen_zero(v->value)) {
18846                peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha);
18847             }
18848          } else if (!strcasecmp(v->name, "port")) {
18849             peer->portinuri = 1;
18850             if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC))
18851                peer->defaddr.sin_port = htons(atoi(v->value));
18852             else
18853                peer->addr.sin_port = htons(atoi(v->value));
18854          } else if (!strcasecmp(v->name, "callingpres")) {
18855             peer->callingpres = ast_parse_caller_presentation(v->value);
18856             if (peer->callingpres == -1)
18857                peer->callingpres = atoi(v->value);
18858          } else if (!strcasecmp(v->name, "username")) {
18859             ast_copy_string(peer->username, v->value, sizeof(peer->username));
18860          } else if (!strcasecmp(v->name, "language")) {
18861             ast_copy_string(peer->language, v->value, sizeof(peer->language));
18862          } else if (!strcasecmp(v->name, "regexten")) {
18863             ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
18864          } else if (!strcasecmp(v->name, "amaflags")) {
18865             format = ast_cdr_amaflags2int(v->value);
18866             if (format < 0) {
18867                ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
18868             } else {
18869                peer->amaflags = format;
18870             }
18871          } else if (!strcasecmp(v->name, "accountcode")) {
18872             ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
18873          } else if (!strcasecmp(v->name, "mohinterpret")
18874             || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
18875             ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
18876          } else if (!strcasecmp(v->name, "mohsuggest")) {
18877             ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
18878          } else if (!strcasecmp(v->name, "mailbox")) {
18879             ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
18880          } else if (!strcasecmp(v->name, "hasvoicemail")) {
18881             /* People expect that if 'hasvoicemail' is set, that the mailbox will
18882              * be also set, even if not explicitly specified. */
18883             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
18884                ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox));
18885             }
18886          } else if (!strcasecmp(v->name, "subscribemwi")) {
18887             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
18888          } else if (!strcasecmp(v->name, "vmexten")) {
18889             ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
18890          } else if (!strcasecmp(v->name, "callgroup")) {
18891             peer->callgroup = ast_get_group(v->value);
18892          } else if (!strcasecmp(v->name, "allowtransfer")) {
18893             peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
18894          } else if (!strcasecmp(v->name, "pickupgroup")) {
18895             peer->pickupgroup = ast_get_group(v->value);
18896          } else if (!strcasecmp(v->name, "allow")) {
18897             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
18898          } else if (!strcasecmp(v->name, "disallow")) {
18899             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
18900          } else if (!strcasecmp(v->name, "autoframing")) {
18901             peer->autoframing = ast_true(v->value);
18902          } else if (!strcasecmp(v->name, "rtptimeout")) {
18903             if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
18904                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
18905                peer->rtptimeout = global_rtptimeout;
18906             }
18907          } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
18908             if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
18909                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
18910                peer->rtpholdtimeout = global_rtpholdtimeout;
18911             }
18912          } else if (!strcasecmp(v->name, "rtpkeepalive")) {
18913             if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
18914                ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
18915                peer->rtpkeepalive = global_rtpkeepalive;
18916             }
18917          } else if (!strcasecmp(v->name, "setvar")) {
18918             /* Set peer channel variable */
18919             varname = ast_strdupa(v->value);
18920             if ((varval = strchr(varname, '='))) {
18921                *varval++ = '\0';
18922                if ((tmpvar = ast_variable_new(varname, varval))) {
18923                   tmpvar->next = peer->chanvars;
18924                   peer->chanvars = tmpvar;
18925                }
18926             }
18927          }
18928       }
18929 
18930       /* These apply to devstate lookups */
18931       if (realtime && !strcasecmp(v->name, "lastms")) {
18932          sscanf(v->value, "%30d", &peer->lastms);
18933       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
18934          inet_aton(v->value, &(peer->addr.sin_addr));
18935       } else if (!strcasecmp(v->name, "qualify")) {
18936          if (!strcasecmp(v->value, "no")) {
18937             peer->maxms = 0;
18938          } else if (!strcasecmp(v->value, "yes")) {
18939             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
18940          } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
18941             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);
18942             peer->maxms = 0;
18943          }
18944          if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {
18945             /* This would otherwise cause a network storm, where the
18946              * qualify response refreshes the peer from the database,
18947              * which in turn causes another qualify to be sent, ad
18948              * infinitum. */
18949             ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime.  Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name);
18950             peer->maxms = 0;
18951          }
18952       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
18953          peer->call_limit = atoi(v->value);
18954          if (peer->call_limit < 0) {
18955             peer->call_limit = 0;
18956          }
18957       }
18958    }
18959 
18960    if (!ast_strlen_zero(fullcontact)) {
18961       ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact));
18962       /* We have a hostname in the fullcontact, but if we don't have an
18963        * address listed on the entry (or if it's 'dynamic'), then we need to
18964        * parse the entry to obtain the IP address, so a dynamic host can be
18965        * contacted immediately after reload (as opposed to waiting for it to
18966        * register once again). But if we have an address for this peer and NAT was
18967        * specified, use that address instead. */
18968       if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) || !peer->addr.sin_addr.s_addr) {
18969          __set_address_from_contact(fullcontact, &peer->addr);
18970       }
18971    }
18972 
18973    if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !obproxyfound && !ast_strlen_zero(peer->tohost)) {
18974       if (ast_get_ip_or_srv(&peer->addr, peer->tohost, srvlookup && !peer->portinuri ? "_sip._udp" : NULL)) {
18975          ast_log(LOG_ERROR, "host lookup failed for %s, on peer %s, removing peer\n", peer->tohost, peer->name);
18976          ASTOBJ_UNREF(peer, sip_destroy_peer);
18977          return NULL;
18978       }
18979    }
18980 
18981    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
18982       time_t nowtime = time(NULL);
18983 
18984       if ((nowtime - regseconds) > 0) {
18985          destroy_association(peer);
18986          memset(&peer->addr, 0, sizeof(peer->addr));
18987          peer->lastms = -1;
18988          if (option_debug)
18989             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
18990       }
18991    }
18992 
18993    /* Startup regular pokes */
18994    if (realtime && peer->lastms > 0) {
18995       ASTOBJ_REF(peer);
18996       sip_poke_peer(peer);
18997    }
18998 
18999    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
19000    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
19001    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
19002       global_allowsubscribe = TRUE; /* No global ban any more */
19003    if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME))
19004       reg_source_db(peer);
19005    ASTOBJ_UNMARK(peer);
19006    ast_free_ha(oldha);
19007    return peer;
19008 }

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

References append_history, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_registry::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, option_debug, sip_pvt::peerauth, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_pvt::uri, sip_auth::username, sip_pvt::username, and username.

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

12972 {
12973    char a1[256];
12974    char a2[256];
12975    char a1_hash[256];
12976    char a2_hash[256];
12977    char resp[256];
12978    char resp_hash[256];
12979    char uri[256];
12980    char opaque[256] = "";
12981    char cnonce[80];
12982    const char *username;
12983    const char *secret;
12984    const char *md5secret;
12985    struct sip_auth *auth = NULL; /* Realm authentication */
12986 
12987    if (!ast_strlen_zero(p->domain))
12988       ast_copy_string(uri, p->domain, sizeof(uri));
12989    else if (!ast_strlen_zero(p->uri))
12990       ast_copy_string(uri, p->uri, sizeof(uri));
12991    else
12992       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
12993 
12994    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
12995 
12996    /* Check if we have separate auth credentials */
12997    if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */
12998       auth = find_realm_authentication(authl, p->realm); /* If not, global list */
12999 
13000    if (auth) {
13001       if (sipdebug && option_debug > 1)
13002          ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
13003       username = auth->username;
13004       secret = auth->secret;
13005       md5secret = auth->md5secret;
13006       if (sipdebug)
13007          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
13008    } else {
13009       /* No authentication, use peer or register= config */
13010       username = p->authname;
13011       secret =  p->peersecret;
13012       md5secret = p->peermd5secret;
13013    }
13014    if (ast_strlen_zero(username))   /* We have no authentication */
13015       return -1;
13016 
13017    /* Calculate SIP digest response */
13018    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
13019    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
13020    if (!ast_strlen_zero(md5secret))
13021       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
13022    else
13023       ast_md5_hash(a1_hash,a1);
13024    ast_md5_hash(a2_hash,a2);
13025 
13026    p->noncecount++;
13027    if (!ast_strlen_zero(p->qop))
13028       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
13029    else
13030       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
13031    ast_md5_hash(resp_hash, resp);
13032 
13033    /* only include the opaque string if it's set */
13034    if (!ast_strlen_zero(p->opaque)) {
13035      snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
13036    }
13037 
13038    /* XXX We hard code our qop to "auth" for now.  XXX */
13039    if (!ast_strlen_zero(p->qop))
13040       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount);
13041    else
13042       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque);
13043 
13044    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
13045 
13046    return 0;
13047 }

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

References __get_header(), ast_copy_string(), 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(), handle_request_subscribe(), and handle_response_invite().

09280 {
09281    struct sip_route *thishop, *head, *tail;
09282    int start = 0;
09283    int len;
09284    const char *rr, *contact, *c;
09285 
09286    /* Once a persistant route is set, don't fool with it */
09287    if (p->route && p->route_persistant) {
09288       if (option_debug)
09289          ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
09290       return;
09291    }
09292 
09293    if (p->route) {
09294       free_old_route(p->route);
09295       p->route = NULL;
09296    }
09297 
09298    /* We only want to create the route set the first time this is called */
09299    p->route_persistant = 1;
09300    
09301    /* Build a tailq, then assign it to p->route when done.
09302     * If backwards, we add entries from the head so they end up
09303     * in reverse order. However, we do need to maintain a correct
09304     * tail pointer because the contact is always at the end.
09305     */
09306    head = NULL;
09307    tail = head;
09308    /* 1st we pass through all the hops in any Record-Route headers */
09309    for (;;) {
09310       /* Each Record-Route header */
09311       rr = __get_header(req, "Record-Route", &start);
09312       if (*rr == '\0')
09313          break;
09314       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
09315          ++rr;
09316          len = strcspn(rr, ">") + 1;
09317          /* Make a struct route */
09318          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
09319             /* ast_calloc is not needed because all fields are initialized in this block */
09320             ast_copy_string(thishop->hop, rr, len);
09321             if (option_debug > 1)
09322                ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
09323             /* Link in */
09324             if (backwards) {
09325                /* Link in at head so they end up in reverse order */
09326                thishop->next = head;
09327                head = thishop;
09328                /* If this was the first then it'll be the tail */
09329                if (!tail)
09330                   tail = thishop;
09331             } else {
09332                thishop->next = NULL;
09333                /* Link in at the end */
09334                if (tail)
09335                   tail->next = thishop;
09336                else
09337                   head = thishop;
09338                tail = thishop;
09339             }
09340          }
09341       }
09342    }
09343 
09344    /* Only append the contact if we are dealing with a strict router */
09345    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
09346       /* 2nd append the Contact: if there is one */
09347       /* Can be multiple Contact headers, comma separated values - we just take the first */
09348       contact = get_header(req, "Contact");
09349       if (!ast_strlen_zero(contact)) {
09350          if (option_debug > 1)
09351             ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
09352          /* Look for <: delimited address */
09353          c = strchr(contact, '<');
09354          if (c) {
09355             /* Take to > */
09356             ++c;
09357             len = strcspn(c, ">") + 1;
09358          } else {
09359             /* No <> - just take the lot */
09360             c = contact;
09361             len = strlen(contact) + 1;
09362          }
09363          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
09364             /* ast_calloc is not needed because all fields are initialized in this block */
09365             ast_copy_string(thishop->hop, c, len);
09366             thishop->next = NULL;
09367             /* Goes at the end */
09368             if (tail)
09369                tail->next = thishop;
09370             else
09371                head = thishop;
09372          }
09373       }
09374    }
09375 
09376    /* Store as new route */
09377    p->route = head;
09378 
09379    /* For debugging dump what we ended up with */
09380    if (sip_debug_test_pvt(p))
09381       list_route(p->route);
09382 }

static void build_rpid ( struct sip_pvt p  )  [static]

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

Definition at line 7787 of file chan_sip.c.

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

Referenced by initreqprep().

07788 {
07789    int send_pres_tags = TRUE;
07790    const char *privacy=NULL;
07791    const char *screen=NULL;
07792    char buf[256];
07793    const char *clid = default_callerid;
07794    const char *clin = NULL;
07795    const char *fromdomain;
07796 
07797    if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
07798       return;
07799 
07800    if (p->owner && !ast_strlen_zero(p->owner->cid.cid_num))
07801       clid = p->owner->cid.cid_num;
07802    if (p->owner && p->owner->cid.cid_name)
07803       clin = p->owner->cid.cid_name;
07804    if (ast_strlen_zero(clin))
07805       clin = clid;
07806 
07807    switch (p->callingpres) {
07808    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
07809       privacy = "off";
07810       screen = "no";
07811       break;
07812    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
07813       privacy = "off";
07814       screen = "yes";
07815       break;
07816    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
07817       privacy = "off";
07818       screen = "no";
07819       break;
07820    case AST_PRES_ALLOWED_NETWORK_NUMBER:
07821       privacy = "off";
07822       screen = "yes";
07823       break;
07824    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
07825       privacy = "full";
07826       screen = "no";
07827       break;
07828    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
07829       privacy = "full";
07830       screen = "yes";
07831       break;
07832    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
07833       privacy = "full";
07834       screen = "no";
07835       break;
07836    case AST_PRES_PROHIB_NETWORK_NUMBER:
07837       privacy = "full";
07838       screen = "yes";
07839       break;
07840    case AST_PRES_NUMBER_NOT_AVAILABLE:
07841       send_pres_tags = FALSE;
07842       break;
07843    default:
07844       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
07845       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
07846          privacy = "full";
07847       else
07848          privacy = "off";
07849       screen = "no";
07850       break;
07851    }
07852    
07853    fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
07854 
07855    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
07856    if (send_pres_tags)
07857       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
07858    ast_string_field_set(p, rpid, buf);
07859 
07860    ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
07861                 S_OR(p->fromuser, clid),
07862                 fromdomain, p->tag);
07863 }

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

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

Definition at line 18492 of file chan_sip.c.

References ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, default_prefs, ast_flags::flags, format, global_flags, handle_common_options(), ast_variable::lineno, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.

18493 {
18494    struct sip_user *user;
18495    int format;
18496    struct ast_ha *oldha = NULL;
18497    char *varname = NULL, *varval = NULL;
18498    struct ast_variable *tmpvar = NULL;
18499    struct ast_flags userflags[2] = {{(0)}};
18500    struct ast_flags mask[2] = {{(0)}};
18501 
18502 
18503    if (!(user = ast_calloc(1, sizeof(*user))))
18504       return NULL;
18505       
18506    suserobjs++;
18507    ASTOBJ_INIT(user);
18508    ast_copy_string(user->name, name, sizeof(user->name));
18509    oldha = user->ha;
18510    user->ha = NULL;
18511    ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
18512    ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
18513    user->capability = global_capability;
18514    user->allowtransfer = global_allowtransfer;
18515    user->maxcallbitrate = default_maxcallbitrate;
18516    user->autoframing = global_autoframing;
18517    user->prefs = default_prefs;
18518    /* set default context */
18519    strcpy(user->context, default_context);
18520    strcpy(user->language, default_language);
18521    strcpy(user->mohinterpret, default_mohinterpret);
18522    strcpy(user->mohsuggest, default_mohsuggest);
18523    /* First we walk through the v parameters list and then the alt parameters list */
18524    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
18525       if (handle_common_options(&userflags[0], &mask[0], v))
18526          continue;
18527 
18528       if (!strcasecmp(v->name, "context")) {
18529          ast_copy_string(user->context, v->value, sizeof(user->context));
18530       } else if (!strcasecmp(v->name, "subscribecontext")) {
18531          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
18532       } else if (!strcasecmp(v->name, "setvar")) {
18533          varname = ast_strdupa(v->value);
18534          if ((varval = strchr(varname,'='))) {
18535             *varval++ = '\0';
18536             if ((tmpvar = ast_variable_new(varname, varval))) {
18537                tmpvar->next = user->chanvars;
18538                user->chanvars = tmpvar;
18539             }
18540          }
18541       } else if (!strcasecmp(v->name, "permit") ||
18542                !strcasecmp(v->name, "deny")) {
18543          user->ha = ast_append_ha(v->name, v->value, user->ha);
18544       } else if (!strcasecmp(v->name, "allowtransfer")) {
18545          user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
18546       } else if (!strcasecmp(v->name, "secret")) {
18547          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
18548       } else if (!strcasecmp(v->name, "md5secret")) {
18549          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
18550       } else if (!strcasecmp(v->name, "callerid")) {
18551          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
18552       } else if (!strcasecmp(v->name, "fullname")) {
18553          ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
18554       } else if (!strcasecmp(v->name, "trunkname")) {
18555          /* This is actually for a trunk, so we don't want to override callerid */
18556          ast_copy_string(user->cid_name, "", sizeof(user->cid_name));
18557       } else if (!strcasecmp(v->name, "cid_number")) {
18558          ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
18559       } else if (!strcasecmp(v->name, "callgroup")) {
18560          user->callgroup = ast_get_group(v->value);
18561       } else if (!strcasecmp(v->name, "pickupgroup")) {
18562          user->pickupgroup = ast_get_group(v->value);
18563       } else if (!strcasecmp(v->name, "language")) {
18564          ast_copy_string(user->language, v->value, sizeof(user->language));
18565       } else if (!strcasecmp(v->name, "mohinterpret") 
18566          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
18567          ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
18568       } else if (!strcasecmp(v->name, "mohsuggest")) {
18569          ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
18570       } else if (!strcasecmp(v->name, "accountcode")) {
18571          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
18572       } else if (!strcasecmp(v->name, "call-limit")) {
18573          user->call_limit = atoi(v->value);
18574          if (user->call_limit < 0)
18575             user->call_limit = 0;
18576       } else if (!strcasecmp(v->name, "amaflags")) {
18577          format = ast_cdr_amaflags2int(v->value);
18578          if (format < 0) {
18579             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
18580          } else {
18581             user->amaflags = format;
18582          }
18583       } else if (!strcasecmp(v->name, "allow")) {
18584          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
18585       } else if (!strcasecmp(v->name, "disallow")) {
18586          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
18587       } else if (!strcasecmp(v->name, "autoframing")) {
18588          user->autoframing = ast_true(v->value);
18589       } else if (!strcasecmp(v->name, "callingpres")) {
18590          user->callingpres = ast_parse_caller_presentation(v->value);
18591          if (user->callingpres == -1)
18592             user->callingpres = atoi(v->value);
18593       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
18594          user->maxcallbitrate = atoi(v->value);
18595          if (user->maxcallbitrate < 0)
18596             user->maxcallbitrate = default_maxcallbitrate;
18597       }
18598       /* We can't just report unknown options here because this may be a
18599        * type=friend entry.  All user options are valid for a peer, but not
18600        * the other way around.  */
18601    }
18602    ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
18603    ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
18604    if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
18605       global_allowsubscribe = TRUE; /* No global ban any more */
18606    ast_free_ha(oldha);
18607    return user;
18608 }

static void build_via ( struct sip_pvt p  )  [static]

Build a Via header for a request.

Definition at line 1912 of file chan_sip.c.

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

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

01913 {
01914    /* Work around buggy UNIDEN UIP200 firmware */
01915    const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
01916 
01917    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01918    snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
01919        ast_inet_ntoa(p->ourip), ourport, (int) p->branch, rport);
01920 }

static void change_hold_state ( struct sip_pvt dialog,
struct sip_request req,
int  holdstate,
int  sendonly 
) [static]

Change hold state for a call.

Definition at line 5617 of file chan_sip.c.

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

Referenced by handle_request_invite(), and process_sdp().

05618 {
05619    if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
05620       sip_peer_hold(dialog, holdstate);
05621    if (global_callevents)
05622       manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold",
05623                "Channel: %s\r\n"
05624                "Uniqueid: %s\r\n",
05625                dialog->owner->name, 
05626                dialog->owner->uniqueid);
05627    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data);
05628    if (!holdstate) {    /* Put off remote hold */
05629       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
05630       return;
05631    }
05632    /* No address for RTP, we're on hold */
05633 
05634    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
05635       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
05636    else if (sendonly == 2) /* Inactive stream */
05637       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
05638    else
05639       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
05640    return;
05641 }

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

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

Returns:
0 on success, non-zero on error

XXX

Todo:
need a better return code here

XXX

Todo:
need a better return code here

Definition at line 9406 of file chan_sip.c.

References append_history, ast_copy_string(), ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, AUTH_CHALLENGE_SENT, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), keys, LOG_NOTICE, sip_pvt::randdata, s, S_OR, set_nonce_randdata(), sip_methods, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stalenonce, ast_dynamic_str::str, text, transmit_response_with_auth(), and TRUE.

Referenced by check_user_full(), and register_verify().

09409 {
09410    const char *response = "407 Proxy Authentication Required";
09411    const char *reqheader = "Proxy-Authorization";
09412    const char *respheader = "Proxy-Authenticate";
09413    const char *authtoken;
09414    char a1_hash[256];
09415    char resp_hash[256]="";
09416    char *c;
09417    int  wrongnonce = FALSE;
09418    int  good_response;
09419    const char *usednonce = p->randdata;
09420    struct ast_dynamic_str *buf;
09421    int res;
09422 
09423    /* table of recognised keywords, and their value in the digest */
09424    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
09425    struct x {
09426       const char *key;
09427       const char *s;
09428    } *i, keys[] = {
09429       [K_RESP] = { "response=", "" },
09430       [K_URI] = { "uri=", "" },
09431       [K_USER] = { "username=", "" },
09432       [K_NONCE] = { "nonce=", "" },
09433       [K_LAST] = { NULL, NULL}
09434    };
09435 
09436    /* Always OK if no secret */
09437    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
09438       return AUTH_SUCCESSFUL;
09439    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
09440       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
09441          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
09442          different circumstances! What a surprise. */
09443       response = "401 Unauthorized";
09444       reqheader = "Authorization";
09445       respheader = "WWW-Authenticate";
09446    }
09447    authtoken =  get_header(req, reqheader);  
09448    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
09449       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
09450          information */
09451       if (!reliable) {
09452          /* Resend message if this was NOT a reliable delivery.   Otherwise the
09453             retransmission should get it */
09454          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
09455          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
09456          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09457       }
09458       return AUTH_CHALLENGE_SENT;
09459    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
09460       /* We have no auth, so issue challenge and request authentication */
09461       set_nonce_randdata(p, 1); /* Create nonce for challenge */
09462       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
09463       /* Schedule auto destroy in 32 seconds */
09464       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09465       return AUTH_CHALLENGE_SENT;
09466    } 
09467 
09468    /* --- We have auth, so check it */
09469 
09470    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
09471          an example in the spec of just what it is you're doing a hash on. */
09472 
09473    if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN)))
09474       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
09475 
09476    /* Make a copy of the response and parse it */
09477    res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken);
09478 
09479    if (res == AST_DYNSTR_BUILD_FAILED)
09480       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
09481 
09482    c = buf->str;
09483 
09484    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
09485       for (i = keys; i->key != NULL; i++) {
09486          const char *separator = ",";  /* default */
09487 
09488          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
09489             continue;
09490          /* Found. Skip keyword, take text in quotes or up to the separator. */
09491          c += strlen(i->key);
09492          if (*c == '"') { /* in quotes. Skip first and look for last */
09493             c++;
09494             separator = "\"";
09495          }
09496          i->s = c;
09497          strsep(&c, separator);
09498          break;
09499       }
09500       if (i->key == NULL) /* not found, jump after space or comma */
09501          strsep(&c, " ,");
09502    }
09503 
09504    /* Verify that digest username matches  the username we auth as */
09505    if (strcmp(username, keys[K_USER].s)) {
09506       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
09507          username, keys[K_USER].s);
09508       /* Oops, we're trying something here */
09509       return AUTH_USERNAME_MISMATCH;
09510    }
09511 
09512    /* Verify nonce from request matches our nonce, and the nonce has not already been responded to.
09513     * If this check fails, send 401 with new nonce */
09514    if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */
09515       wrongnonce = TRUE;
09516       usednonce = keys[K_NONCE].s;
09517    } else {
09518       p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */
09519    }
09520 
09521    if (!ast_strlen_zero(md5secret))
09522       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
09523    else {
09524       char a1[256];
09525       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
09526       ast_md5_hash(a1_hash, a1);
09527    }
09528 
09529    /* compute the expected response to compare with what we received */
09530    {
09531       char a2[256];
09532       char a2_hash[256];
09533       char resp[256];
09534 
09535       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
09536             S_OR(keys[K_URI].s, uri));
09537       ast_md5_hash(a2_hash, a2);
09538       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
09539       ast_md5_hash(resp_hash, resp);
09540    }
09541 
09542    good_response = keys[K_RESP].s &&
09543          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
09544    if (wrongnonce) {
09545       if (good_response) {
09546          if (sipdebug)
09547             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From"));
09548          /* We got working auth token, based on stale nonce . */
09549          set_nonce_randdata(p, 0);
09550          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
09551       } else {
09552          /* Everything was wrong, so give the device one more try with a new challenge */
09553          if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
09554             if (sipdebug)
09555                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
09556             set_nonce_randdata(p, 1);
09557          } else {
09558             if (sipdebug)
09559                ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
09560          }
09561          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
09562       }
09563 
09564       /* Schedule auto destroy in 32 seconds */
09565       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09566       return AUTH_CHALLENGE_SENT;
09567    } 
09568    if (good_response) {
09569       append_history(p, "AuthOK", "Auth challenge successful for %s", username);
09570       return AUTH_SUCCESSFUL;
09571    }
09572 
09573    /* Ok, we have a bad username/secret pair */
09574    /* Tell the UAS not to re-send this authentication data, because
09575       it will continue to fail
09576    */
09577 
09578    return AUTH_SECRET_FAILED;
09579 }

static void check_auth_buf_init ( void   )  [static]

Definition at line 9398 of file chan_sip.c.

09409 {

static void check_extenstate_updates ( struct sip_pvt pvt  )  [static]

Definition at line 9635 of file chan_sip.c.

References ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, sip_extenstate_update::list, notify_extenstate_update(), sip_extenstate_update::pvt, and update().

Referenced by do_monitor().

09636 {
09637    struct sip_extenstate_update *update = NULL;
09638 
09639    if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
09640       /* avoid holding the lock if possible */
09641       return;
09642    }
09643 
09644    do {
09645       if (update) {
09646          /* The notify can not happen while the list lock is held. */
09647          notify_extenstate_update(update->context, update->exten, update->state, pvt);
09648          ast_free(update);
09649       }
09650 
09651       AST_LIST_LOCK(&sip_extenstate_updates);
09652       AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) {
09653          if (update->pvt == pvt) {
09654             AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list);
09655             break;
09656          }
09657       }
09658       AST_LIST_TRAVERSE_SAFE_END
09659       AST_LIST_UNLOCK(&sip_extenstate_updates);
09660    } while (update);
09661 }

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

Note:
both sip_pvt and sip_pvt's owner channel (if present) must be locked for this function.

Definition at line 13452 of file chan_sip.c.

References ast_clear_flag, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_CANCELLED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lastinvite, LOG_DEBUG, option_debug, sip_pvt::owner, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.

Referenced by handle_request(), handle_response_invite(), and sip_reinvite_retry().

13453 {
13454    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
13455       /* if we can't BYE, then this is really a pending CANCEL */
13456       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) {
13457          p->invitestate = INV_CANCELLED;
13458          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
13459          /* Actually don't destroy us yet, wait for the 487 on our original 
13460             INVITE, but do set an autodestruct just in case we never get it. */
13461       } else {
13462          /* We have a pending outbound invite, don't send someting
13463             new in-transaction */
13464          if (p->pendinginvite)
13465             return;
13466 
13467          if (p->owner) {
13468             ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
13469          }
13470          /* Perhaps there is an SD change INVITE outstanding */
13471          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
13472       }
13473       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
13474       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13475    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
13476       /* if we can't REINVITE, hold it for later */
13477       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
13478          if (option_debug)
13479             ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
13480       } else {
13481          if (option_debug)
13482             ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
13483          /* Didn't get to reinvite yet, so do it now */
13484          transmit_reinvite_with_sdp(p);
13485          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE);
13486       }
13487    }
13488 }

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

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

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

18374 {
18375    struct domain *d;
18376    int result = 0;
18377 
18378    AST_LIST_LOCK(&domain_list);
18379    AST_LIST_TRAVERSE(&domain_list, d, list) {
18380       if (strcasecmp(d->domain, domain))
18381          continue;
18382 
18383       if (len && !ast_strlen_zero(d->context))
18384          ast_copy_string(context, d->context, len);
18385       
18386       result = 1;
18387       break;
18388    }
18389    AST_LIST_UNLOCK(&domain_list);
18390 
18391    return result;
18392 }

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

References check_user_full().

Referenced by handle_request_invite().

11046 {
11047    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
11048 }

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 10712 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_copy_string(), 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_variables_destroy(), 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, sip_peer::name, sip_user::name, 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_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RPORT_PRESENT, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.

Referenced by check_user(), and handle_request_subscribe().

10715 {
10716    struct sip_user *user = NULL;
10717    struct sip_peer *peer;
10718    char from[256], *c;
10719    char *of;
10720    char rpid_num[50];
10721    const char *rpid;
10722    enum check_auth_result res = AUTH_SUCCESSFUL;
10723    char *t;
10724    char calleridname[50];
10725    int debug=sip_debug_test_addr(sin);
10726    struct ast_variable *tmpvar = NULL, *v = NULL;
10727    char *uri2 = ast_strdupa(uri);
10728 
10729    /* Terminate URI */
10730    t = uri2;
10731    while (*t && *t > 32 && *t != ';')
10732       t++;
10733    *t = '\0';
10734    ast_copy_string(from, get_header(req, "From"), sizeof(from));  /* XXX bug in original code, overwrote string */
10735    if (pedanticsipchecking)
10736       ast_uri_decode(from);
10737    /* XXX here tries to map the username for invite things */
10738    memset(calleridname, 0, sizeof(calleridname));
10739    get_calleridname(from, calleridname, sizeof(calleridname));
10740    if (calleridname[0])
10741       ast_string_field_set(p, cid_name, calleridname);
10742 
10743    rpid = get_header(req, "Remote-Party-ID");
10744    memset(rpid_num, 0, sizeof(rpid_num));
10745    if (!ast_strlen_zero(rpid)) 
10746       p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
10747 
10748    of = get_in_brackets(from);
10749    if (ast_strlen_zero(p->exten)) {
10750       t = uri2;
10751       if (!strncasecmp(t, "sip:", 4))
10752          t+= 4;
10753       ast_string_field_set(p, exten, t);
10754       t = strchr(p->exten, '@');
10755       if (t)
10756          *t = '\0';
10757       if (ast_strlen_zero(p->our_contact))
10758          build_contact(p);
10759    }
10760    /* save the URI part of the From header */
10761    ast_string_field_set(p, from, of);
10762    if (strncasecmp(of, "sip:", 4)) {
10763       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
10764    } else
10765       of += 4;
10766    /* Get just the username part */
10767    if ((c = strchr(of, '@'))) {
10768       char *tmp;
10769       *c = '\0';
10770       if ((c = strchr(of, ':')))
10771          *c = '\0';
10772       tmp = ast_strdupa(of);
10773       /* We need to be able to handle auth-headers looking like
10774          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
10775       */
10776       tmp = strsep(&tmp, ";");
10777       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
10778          ast_shrink_phone_number(tmp);
10779       ast_string_field_set(p, cid_num, tmp);
10780    }
10781 
10782    if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */
10783       user = find_user(of, 1);
10784 
10785    /* Find user based on user name in the from header */
10786    if (user && ast_apply_ha(user->ha, sin)) {
10787       ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
10788       ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
10789       if (sipmethod == SIP_INVITE) {
10790          /* destroy old channel vars and copy new channel vars */
10791          ast_variables_destroy(p->chanvars);
10792          p->chanvars = NULL;
10793          for (v = user->chanvars ; v ; v = v->next) {
10794             if ((tmpvar = ast_variable_new(v->name, v->value))) {
10795                tmpvar->next = p->chanvars; 
10796                p->chanvars = tmpvar;
10797             }
10798          }
10799       }
10800       p->prefs = user->prefs;
10801       /* Set Frame packetization */
10802       if (p->rtp) {
10803          ast_rtp_codec_setpref(p->rtp, &p->prefs);
10804          p->autoframing = user->autoframing;
10805       }
10806       /* replace callerid if rpid found, and not restricted */
10807       if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
10808          char *tmp;
10809          if (*calleridname)
10810             ast_string_field_set(p, cid_name, calleridname);
10811          tmp = ast_strdupa(rpid_num);
10812          if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
10813             ast_shrink_phone_number(tmp);
10814          ast_string_field_set(p, cid_num, tmp);
10815       }
10816       
10817       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) );
10818 
10819       if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
10820          if (sip_cancel_destroy(p))
10821             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
10822          ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
10823          ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
10824          /* Copy SIP extensions profile from INVITE */
10825          if (p->sipoptions)
10826             user->sipoptions = p->sipoptions;
10827 
10828          /* If we have a call limit, set flag */
10829          if (user->call_limit)
10830             ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
10831          if (!ast_strlen_zero(user->context))
10832             ast_string_field_set(p, context, user->context);
10833          if (!ast_strlen_zero(user->cid_num)) {
10834             char *tmp = ast_strdupa(user->cid_num);
10835             if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
10836                ast_shrink_phone_number(tmp);
10837             ast_string_field_set(p, cid_num, tmp);
10838          }
10839          if (!ast_strlen_zero(user->cid_name))
10840             ast_string_field_set(p, cid_name, user->cid_name);
10841          ast_string_field_set(p, username, user->name);
10842          ast_string_field_set(p, peername, user->name);
10843          ast_string_field_set(p, peersecret, user->secret);
10844          ast_string_field_set(p, peermd5secret, user->md5secret);
10845          ast_string_field_set(p, subscribecontext, user->subscribecontext);
10846          ast_string_field_set(p, accountcode, user->accountcode);
10847          ast_string_field_set(p, language, user->language);
10848          ast_string_field_set(p, mohsuggest, user->mohsuggest);
10849          ast_string_field_set(p, mohinterpret, user->mohinterpret);
10850          p->allowtransfer = user->allowtransfer;
10851          p->amaflags = user->amaflags;
10852          p->callgroup = user->callgroup;
10853          p->pickupgroup = user->pickupgroup;
10854          if (user->callingpres)  /* User callingpres setting will override RPID header */
10855             p->callingpres = user->callingpres;
10856          
10857          /* Set default codec settings for this call */
10858          p->capability = user->capability;      /* User codec choice */
10859          p->jointcapability = user->capability;    /* Our codecs */
10860          if (p->peercapability)           /* AND with peer's codecs */
10861             p->jointcapability &= p->peercapability;
10862          if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
10863              (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
10864             p->noncodeccapability |= AST_RTP_DTMF;
10865          else
10866             p->noncodeccapability &= ~AST_RTP_DTMF;
10867          p->jointnoncodeccapability = p->noncodeccapability;
10868          if (p->t38.peercapability)
10869             p->t38.jointcapability &= p->t38.peercapability;
10870          p->maxcallbitrate = user->maxcallbitrate;
10871          /* If we do not support video, remove video from call structure */
10872          if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
10873             ast_rtp_destroy(p->vrtp);
10874             p->vrtp = NULL;
10875          }
10876       }
10877       if (user && debug)
10878          ast_verbose("Found user '%s'\n", user->name);
10879    } else {
10880       if (user) {
10881          if (!authpeer && debug)
10882             ast_verbose("Found user '%s', but fails host access\n", user->name);
10883          ASTOBJ_UNREF(user,sip_destroy_user);
10884       }
10885       user = NULL;
10886    }
10887 
10888    if (!user) {
10889       /* If we didn't find a user match, check for peers */
10890       if (sipmethod == SIP_SUBSCRIBE)
10891          /* For subscribes, match on peer name only */
10892          peer = find_peer(of, NULL, 1, 0);
10893       else
10894          /* Look for peer based on the IP address we received data from */
10895          /* If peer is registered from this IP address or have this as a default
10896             IP address, this call is from the peer 
10897          */
10898          peer = find_peer(NULL, &p->recv, 1, 0);
10899 
10900       if (peer) {
10901          /* Set Frame packetization */
10902          if (p->rtp) {
10903             ast_rtp_codec_setpref(p->rtp, &peer->prefs);
10904             p->autoframing = peer->autoframing;
10905          }
10906          if (debug)
10907             ast_verbose("Found peer '%s'\n", peer->name);
10908 
10909          /* Take the peer */
10910          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
10911          ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
10912 
10913          /* Copy SIP extensions profile to peer */
10914          if (p->sipoptions)
10915             peer->sipoptions = p->sipoptions;
10916 
10917          /* replace callerid if rpid found, and not restricted */
10918          if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
10919             char *tmp = ast_strdupa(rpid_num);
10920             if (*calleridname)
10921                ast_string_field_set(p, cid_name, calleridname);
10922             if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
10923                ast_shrink_phone_number(tmp);
10924             ast_string_field_set(p, cid_num, tmp);
10925          }
10926          do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE));
10927 
10928          ast_string_field_set(p, peersecret, peer->secret);
10929          ast_string_field_set(p, peermd5secret, peer->md5secret);
10930          ast_string_field_set(p, subscribecontext, peer->subscribecontext);
10931          ast_string_field_set(p, mohinterpret, peer->mohinterpret);
10932          ast_string_field_set(p, mohsuggest, peer->mohsuggest);
10933          if (peer->callingpres)  /* Peer calling pres setting will override RPID */
10934             p->callingpres = peer->callingpres;
10935          if (peer->maxms && peer->lastms)
10936             p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
10937          if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
10938             /* Pretend there is no required authentication */
10939             ast_string_field_free(p, peersecret);
10940             ast_string_field_free(p, peermd5secret);
10941          }
10942          if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) {
10943             ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
10944             ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
10945             /* If we have a call limit, set flag */
10946             if (peer->call_limit)
10947                ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
10948             ast_string_field_set(p, peername, peer->name);
10949             ast_string_field_set(p, authname, peer->name);
10950 
10951             if (sipmethod == SIP_INVITE) {
10952                /* destroy old channel vars and copy new channel vars */
10953                ast_variables_destroy(p->chanvars);
10954                p->chanvars = NULL;
10955                for (v = peer->chanvars ; v ; v = v->next) {
10956                   if ((tmpvar = ast_variable_new(v->name, v->value))) {
10957                      tmpvar->next = p->chanvars; 
10958                      p->chanvars = tmpvar;
10959                   }
10960                }
10961             }
10962             if (authpeer) {
10963                (*authpeer) = ASTOBJ_REF(peer);  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
10964             }
10965 
10966             if (!ast_strlen_zero(peer->username)) {
10967                ast_string_field_set(p, username, peer->username);
10968                /* Use the default username for authentication on outbound calls */
10969                /* XXX this takes the name from the caller... can we override ? */
10970                ast_string_field_set(p, authname, peer->username);
10971             }
10972             if (!ast_strlen_zero(peer->cid_num)) {
10973                char *tmp = ast_strdupa(peer->cid_num);
10974                if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
10975                   ast_shrink_phone_number(tmp);
10976                ast_string_field_set(p, cid_num, tmp);
10977             }
10978             if (!ast_strlen_zero(peer->cid_name)) 
10979                ast_string_field_set(p, cid_name, peer->cid_name);
10980             ast_string_field_set(p, fullcontact, peer->fullcontact);
10981             if (!ast_strlen_zero(peer->context))
10982                ast_string_field_set(p, context, peer->context);
10983             ast_string_field_set(p, peersecret, peer->secret);
10984             ast_string_field_set(p, peermd5secret, peer->md5secret);
10985             ast_string_field_set(p, language, peer->language);
10986             ast_string_field_set(p, accountcode, peer->accountcode);
10987             p->amaflags = peer->amaflags;
10988             p->callgroup = peer->callgroup;
10989             p->pickupgroup = peer->pickupgroup;
10990             p->capability = peer->capability;
10991             p->prefs = peer->prefs;
10992             p->jointcapability = peer->capability;
10993             if (p->peercapability)
10994                p->jointcapability &= p->peercapability;
10995             p->maxcallbitrate = peer->maxcallbitrate;
10996             if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) {
10997                ast_rtp_destroy(p->vrtp);
10998                p->vrtp = NULL;
10999             }
11000             if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
11001                 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
11002                p->noncodeccapability |= AST_RTP_DTMF;
11003             else
11004                p->noncodeccapability &= ~AST_RTP_DTMF;
11005             p->jointnoncodeccapability = p->noncodeccapability;
11006             if (p->t38.peercapability)
11007                p->t38.jointcapability &= p->t38.peercapability;
11008          }
11009          ASTOBJ_UNREF(peer, sip_destroy_peer);
11010       } else { 
11011          if (debug)
11012             ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
11013 
11014          /* do we allow guests? */
11015          if (!global_allowguest) {
11016             if (global_alwaysauthreject)
11017                res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
11018             else
11019                res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
11020          } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
11021             char *tmp = ast_strdupa(rpid_num);
11022             if (*calleridname)
11023                ast_string_field_set(p, cid_name, calleridname);
11024             if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
11025                ast_shrink_phone_number(tmp);
11026             ast_string_field_set(p, cid_num, tmp);
11027          }
11028       }
11029 
11030    }
11031 
11032    if (user)
11033       ASTOBJ_UNREF(user, sip_destroy_user);
11034 
11035    if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) {
11036       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
11037    }
11038 
11039    return res;
11040 }

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

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

Definition at line 10569 of file chan_sip.c.

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

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

10570 {
10571    char via[512];
10572    char *c, *pt, *maddr;
10573    struct hostent *hp;
10574    struct ast_hostent ahp;
10575 
10576    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
10577 
10578    /* Work on the leftmost value of the topmost Via header */
10579    c = strchr(via, ',');
10580    if (c)
10581       *c = '\0';
10582 
10583    /* Check for rport */
10584    c = strstr(via, ";rport");
10585    if (c && (c[6] != '=')) /* rport query, not answer */
10586       ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT);
10587 
10588    /* Check for maddr */
10589    maddr = strstr(via, "maddr=");
10590    if (maddr) {
10591       maddr += 6;
10592       c = maddr + strspn(maddr, "0123456789.");
10593       *c = '\0';
10594    }
10595 
10596    c = strchr(via, ';');
10597    if (c)
10598       *c = '\0';
10599 
10600    c = strchr(via, ' ');
10601    if (c) {
10602       *c = '\0';
10603       c = ast_skip_blanks(c+1);
10604       if (strcasecmp(via, "SIP/2.0/UDP")) {
10605          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
10606          return;
10607       }
10608       pt = strchr(c, ':');
10609       if (pt)
10610          *pt++ = '\0';  /* remember port pointer */
10611       /* Use maddr if found */
10612       if (maddr)
10613          c = maddr;
10614       hp = ast_gethostbyname(c, &ahp);
10615       if (!hp) {
10616          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
10617          return;
10618       }
10619       memset(&p->sa, 0, sizeof(p->sa));
10620       p->sa.sin_family = AF_INET;
10621       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
10622       p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
10623 
10624       if (sip_debug_test_pvt(p)) {
10625          const struct sockaddr_in *dst = sip_real_dst(p);
10626          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
10627       }
10628    }
10629 }

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

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

11490 {
11491    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
11492 
11493    while ((oldcontext = strsep(&old, "&"))) {
11494       stalecontext = '\0';
11495       ast_copy_string(newlist, new, sizeof(newlist));
11496       stringp = newlist;
11497       while ((newcontext = strsep(&stringp, "&"))) {
11498          if (strcmp(newcontext, oldcontext) == 0) {
11499             /* This is not the context you're looking for */
11500             stalecontext = '\0';
11501             break;
11502          } else if (strcmp(newcontext, oldcontext)) {
11503             stalecontext = oldcontext;
11504          }
11505          
11506       }
11507       if (stalecontext)
11508          ast_context_destroy(ast_context_find(stalecontext), "SIP");
11509    }
11510 }

static void clear_extenstate_updates ( struct sip_pvt pvt  )  [static]

Definition at line 9737 of file chan_sip.c.

References ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, sip_extenstate_update::list, sip_extenstate_update::pvt, and update().

Referenced by __sip_destroy().

09738 {
09739    struct sip_extenstate_update *update = NULL;
09740 
09741    if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
09742       /* avoid holding the lock if possible */
09743       return;
09744    }
09745 
09746    AST_LIST_LOCK(&sip_extenstate_updates);
09747    AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) {
09748       if (update->pvt == pvt) {
09749          AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list);
09750          ast_free(update);
09751       }
09752    }
09753    AST_LIST_TRAVERSE_SAFE_END
09754    AST_LIST_UNLOCK(&sip_extenstate_updates);
09755 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 18464 of file chan_sip.c.

References free, and sip_auth::next.

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

18465 {
18466    struct sip_auth *a = authlist;
18467    struct sip_auth *b;
18468 
18469    while (a) {
18470       b = a;
18471       a = a->next;
18472       free(b);
18473    }
18474 
18475    return 1;
18476 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

Definition at line 18395 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and domain::list.

Referenced by reload_config(), and unload_module().

18396 {
18397    struct domain *d;
18398 
18399    AST_LIST_LOCK(&domain_list);
18400    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
18401       free(d);
18402    AST_LIST_UNLOCK(&domain_list);
18403 }

static void clearmarked_extenstate_updates ( void   )  [static]

Definition at line 9667 of file chan_sip.c.

References ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, sip_extenstate_update::list, and update().

Referenced by do_monitor().

09668 {
09669    struct sip_extenstate_update *update = NULL;
09670 
09671    if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
09672       /* avoid holding the lock if possible */
09673       return;
09674    }
09675 
09676    AST_LIST_LOCK(&sip_extenstate_updates);
09677    AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) {
09678       if (update->marked) {
09679          AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list);
09680          ast_free(update);
09681       }
09682    }
09683    AST_LIST_TRAVERSE_SAFE_END
09684    AST_LIST_UNLOCK(&sip_extenstate_updates);
09685 
09686 }

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

References complete_sip_peer().

12318 {
12319    if (pos == 3)
12320       return complete_sip_peer(word, state, 0);
12321 
12322    return NULL;
12323 }

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

Do completion on peer name.

Definition at line 12291 of file chan_sip.c.

References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and peerl.

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

12292 {
12293    char *result = NULL;
12294    int wordlen = strlen(word);
12295    int which = 0;
12296 
12297    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
12298       /* locking of the object is not required because only the name and flags are being compared */
12299       if (!strncasecmp(word, iterator->name, wordlen) &&
12300             (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
12301             ++which > state)
12302          result = ast_strdup(iterator->name);
12303    } while(0) );
12304    return result;
12305 }

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

12386 {
12387    if (pos == 4)
12388       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
12389    return NULL;
12390 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

12394 {
12395    if (pos == 4)
12396       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
12397 
12398    return NULL;
12399 }

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

References complete_sip_peer().

12309 {
12310    if (pos == 3)
12311       return complete_sip_peer(word, state, 0);
12312 
12313    return NULL;
12314 }

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

References complete_sip_user().

12347 {
12348    if (pos == 3)
12349       return complete_sip_user(word, state, 0);
12350 
12351    return NULL;
12352 }

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

Do completion on user name.

Definition at line 12326 of file chan_sip.c.

References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and userl.

Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().

12327 {
12328    char *result = NULL;
12329    int wordlen = strlen(word);
12330    int which = 0;
12331 
12332    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
12333       /* locking of the object is not required because only the name and flags are being compared */
12334       if (!strncasecmp(word, iterator->name, wordlen)) {
12335          if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
12336             continue;
12337          if (++which > state) {
12338             result = ast_strdup(iterator->name);
12339          }
12340       }
12341    } while(0) );
12342    return result;
12343 }

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

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

12269 {
12270    int which=0;
12271    struct sip_pvt *cur;
12272    char *c = NULL;
12273    int wordlen = strlen(word);
12274 
12275    if (pos != 3) {
12276       return NULL;
12277    }
12278 
12279    ast_mutex_lock(&iflock);
12280    for (cur = iflist; cur; cur = cur->next) {
12281       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
12282          c = ast_strdup(cur->callid);
12283          break;
12284       }
12285    }
12286    ast_mutex_unlock(&iflock);
12287    return c;
12288 }

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

Support routine for 'sip notify' CLI.

Definition at line 12355 of file chan_sip.c.

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

12356 {
12357    char *c = NULL;
12358 
12359    if (pos == 2) {
12360       int which = 0;
12361       char *cat = NULL;
12362       int wordlen = strlen(word);
12363 
12364       /* do completion for notify type */
12365 
12366       if (!notify_types)
12367          return NULL;
12368       
12369       while ( (cat = ast_category_browse(notify_types, cat)) ) {
12370          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
12371             c = ast_strdup(cat);
12372             break;
12373          }
12374       }
12375       return c;
12376    }
12377 
12378    if (pos > 2)
12379       return complete_sip_peer(word, state, 0);
12380 
12381    return NULL;
12382 }

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

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

Referenced by respprep().

06520 {
06521    int start = 0;
06522    int copied = 0;
06523    for (;;) {
06524       const char *tmp = __get_header(orig, field, &start);
06525 
06526       if (ast_strlen_zero(tmp))
06527          break;
06528       /* Add what we're responding to */
06529       add_header(req, field, tmp);
06530       copied++;
06531    }
06532    return copied ? 0 : -1;
06533 }

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

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

Referenced by reqprep(), and respprep().

06509 {
06510    const char *tmp = get_header(orig, field);
06511 
06512    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
06513       return add_header(req, field, tmp);
06514    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
06515    return -1;
06516 }

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 7618 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(), queue_request(), sip_park(), and sip_park_thread().

07619 {
07620    long offset;
07621    int x;
07622    offset = ((void *)dst) - ((void *)src);
07623    /* First copy stuff */
07624    memcpy(dst, src, sizeof(*dst));
07625    /* Now fix pointer arithmetic */
07626    for (x=0; x < src->headers; x++)
07627       dst->header[x] += offset;
07628    for (x=0; x < src->lines; x++)
07629       dst->line[x] += offset;
07630    dst->rlPart1 += offset;
07631    dst->rlPart2 += offset;
07632 }

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

References __get_header(), add_header(), ast_copy_string(), 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().

06542 {
06543    int copied = 0;
06544    int start = 0;
06545 
06546    for (;;) {
06547       char new[512];
06548       const char *oh = __get_header(orig, field, &start);
06549 
06550       if (ast_strlen_zero(oh))
06551          break;
06552 
06553       if (!copied) { /* Only check for empty rport in topmost via header */
06554          char leftmost[512], *others, *rport;
06555 
06556          /* Only work on leftmost value */
06557          ast_copy_string(leftmost, oh, sizeof(leftmost));
06558          others = strchr(leftmost, ',');
06559          if (others)
06560              *others++ = '\0';
06561 
06562          /* Find ;rport;  (empty request) */
06563          rport = strstr(leftmost, ";rport");
06564          if (rport && *(rport+6) == '=') 
06565             rport = NULL;     /* We already have a parameter to rport */
06566 
06567          /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting)  */
06568          if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
06569             /* We need to add received port - rport */
06570             char *end;
06571 
06572             rport = strstr(leftmost, ";rport");
06573 
06574             if (rport) {
06575                end = strchr(rport + 1, ';');
06576                if (end)
06577                   memmove(rport, end, strlen(end) + 1);
06578                else
06579                   *rport = '\0';
06580             }
06581 
06582             /* Add rport to first VIA header if requested */
06583             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
06584                leftmost, ast_inet_ntoa(p->recv.sin_addr),
06585                ntohs(p->recv.sin_port),
06586                others ? "," : "", others ? others : "");
06587          } else {
06588             /* We should *always* add a received to the topmost via */
06589             snprintf(new, sizeof(new), "%s;received=%s%s%s",
06590                leftmost, ast_inet_ntoa(p->recv.sin_addr),
06591                others ? "," : "", others ? others : "");
06592          }
06593          oh = new;   /* the header to copy */
06594       }  /* else add the following via headers untouched */
06595       add_header(req, field, oh);
06596       copied++;
06597    }
06598    if (!copied) {
06599       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
06600       return -1;
06601    }
06602    return 0;
06603 }

static int create_addr ( struct sip_pvt dialog,
const char *  opeer,
struct sockaddr_in *  sin 
) [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 3179 of file chan_sip.c.

References ahp, ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, create_addr_from_peer(), do_setnat(), find_peer(), sip_pvt::flags, hp, sip_pvt::portinuri, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), SIP_NAT, SIP_NAT_ROUTE, STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.

03180 {
03181    struct hostent *hp;
03182    struct ast_hostent ahp;
03183    struct sip_peer *p;
03184    char *port;
03185    int portno = 0;
03186    char host[MAXHOSTNAMELEN], *hostn;
03187    char peer[256];
03188 
03189    ast_copy_string(peer, opeer, sizeof(peer));
03190    port = strchr(peer, ':');
03191    if (port) {
03192       *port++ = '\0';
03193       dialog->portinuri = 1;
03194    }
03195    dialog->sa.sin_family = AF_INET;
03196    dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
03197    p = find_peer(peer, NULL, 1, 0);
03198 
03199    if (p) {
03200       int res = create_addr_from_peer(dialog, p);
03201       if (port) {
03202          portno = atoi(port);
03203          dialog->sa.sin_port = dialog->recv.sin_port = htons(portno);
03204       }
03205       ASTOBJ_UNREF(p, sip_destroy_peer);
03206       return res;
03207    }
03208 
03209    do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
03210 
03211    ast_string_field_set(dialog, tohost, peer);
03212 
03213    if (sin) {
03214       memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr));
03215       if (!sin->sin_port) {
03216          if (ast_strlen_zero(port) || sscanf(port, "%30u", &portno) != 1) {
03217             portno = STANDARD_SIP_PORT;
03218          }
03219       } else {
03220          portno = ntohs(sin->sin_port);
03221       }
03222    } else {
03223       hostn = peer;
03224       /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then
03225        * an A record lookup should be used instead of SRV.
03226        */
03227       if (!port && srvlookup) {
03228          char service[MAXHOSTNAMELEN];
03229          int tportno;
03230          int ret;
03231 
03232          snprintf(service, sizeof(service), "_sip._udp.%s", peer);
03233          ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
03234          if (ret > 0) {
03235             hostn = host;
03236             portno = tportno;
03237          }
03238       }
03239       if (!portno)
03240          portno = port ? atoi(port) : STANDARD_SIP_PORT;
03241     
03242       hp = ast_gethostbyname(hostn, &ahp);
03243       if (!hp) {
03244          ast_log(LOG_WARNING, "No such host: %s\n", peer);
03245          return -1;
03246       }
03247       memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
03248    }
03249    dialog->sa.sin_port = htons(portno);
03250    dialog->recv = dialog->sa;
03251    return 0;
03252 }

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

References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::auth, sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, 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, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_peer::name, sip_pvt::noncodeccapability, option_debug, sip_pvt::peerauth, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::portinuri, sip_pvt::portinuri, 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_pvt::tohost, 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().

03069 {
03070    if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
03071        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
03072       dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr;
03073       dialog->recv = dialog->sa;
03074    } else 
03075       return -1;
03076 
03077    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
03078    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
03079    dialog->capability = peer->capability;
03080    if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) {
03081       ast_rtp_destroy(dialog->vrtp);
03082       dialog->vrtp = NULL;
03083    }
03084    dialog->prefs = peer->prefs;
03085    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
03086       dialog->t38.capability = global_t38_capability;
03087       if (dialog->udptl) {
03088          if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC )
03089             dialog->t38.capability |= T38FAX_UDP_EC_FEC;
03090          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
03091             dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
03092          else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE )
03093             dialog->t38.capability |= T38FAX_UDP_EC_NONE;
03094          dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
03095          if (option_debug > 1)
03096             ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability);
03097       }
03098       dialog->t38.jointcapability = dialog->t38.capability;
03099    } else if (dialog->udptl) {
03100       ast_udptl_destroy(dialog->udptl);
03101       dialog->udptl = NULL;
03102    }
03103    do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE );
03104 
03105    if (dialog->rtp) {
03106       ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
03107       ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
03108       ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout);
03109       ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout);
03110       ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive);
03111       /* Set Frame packetization */
03112       ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
03113       dialog->autoframing = peer->autoframing;
03114    }
03115    if (dialog->vrtp) {
03116       ast_rtp_setdtmf(dialog->vrtp, 0);
03117       ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
03118       ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout);
03119       ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout);
03120       ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive);
03121    }
03122 
03123    ast_string_field_set(dialog, peername, peer->name);
03124    ast_string_field_set(dialog, authname, peer->username);
03125    ast_string_field_set(dialog, username, peer->username);
03126    ast_string_field_set(dialog, peersecret, peer->secret);
03127    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
03128    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
03129    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
03130    ast_string_field_set(dialog, tohost, peer->tohost);
03131    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
03132    if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) {
03133       char *tmpcall;
03134       char *c;
03135       tmpcall = ast_strdupa(dialog->callid);
03136       c = strchr(tmpcall, '@');
03137       if (c) {
03138          *c = '\0';
03139          ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain);
03140       }
03141    }
03142    if (ast_strlen_zero(dialog->tohost))
03143       ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
03144    if (!ast_strlen_zero(peer->fromdomain))
03145       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
03146    if (!ast_strlen_zero(peer->fromuser))
03147       ast_string_field_set(dialog, fromuser, peer->fromuser);
03148    if (!ast_strlen_zero(peer->language))
03149       ast_string_field_set(dialog, language, peer->language);
03150    dialog->maxtime = peer->maxms;
03151    dialog->callgroup = peer->callgroup;
03152    dialog->pickupgroup = peer->pickupgroup;
03153    dialog->peerauth = peer->auth;
03154    dialog->allowtransfer = peer->allowtransfer;
03155    /* Set timer T1 to RTT for this peer (if known by qualify=) */
03156    /* Minimum is settable or default to 100 ms */
03157    if (peer->maxms && peer->lastms)
03158       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
03159    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
03160        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
03161       dialog->noncodeccapability |= AST_RTP_DTMF;
03162    else
03163       dialog->noncodeccapability &= ~AST_RTP_DTMF;
03164    dialog->jointnoncodeccapability = dialog->noncodeccapability;
03165    ast_string_field_set(dialog, context, peer->context);
03166    dialog->rtptimeout = peer->rtptimeout;
03167    if (peer->call_limit)
03168       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
03169    dialog->maxcallbitrate = peer->maxcallbitrate;
03170    if (!dialog->portinuri)
03171       dialog->portinuri = peer->portinuri;
03172    
03173    return 0;
03174 }

static void destroy_association ( struct sip_peer peer  )  [static]

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

Definition at line 8833 of file chan_sip.c.

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

Referenced by build_peer(), and expire_register().

08834 {
08835    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
08836       if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT) && ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) {
08837          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", NULL);
08838          ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL);
08839       } else 
08840          ast_db_del("SIP/Registry", peer->name);
08841    }
08842 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 7667 of file chan_sip.c.

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

Referenced by parse_request().

07668 {
07669    char *e = ast_skip_blanks(req->header[0]);   /* there shouldn't be any */
07670 
07671    if (!*e)
07672       return -1;
07673    req->rlPart1 = e; /* method or protocol */
07674    e = ast_skip_nonblanks(e);
07675    if (*e)
07676       *e++ = '\0';
07677    /* Get URI or status code */
07678    e = ast_skip_blanks(e);
07679    if ( !*e )
07680       return -1;
07681    ast_trim_blanks(e);
07682 
07683    if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
07684       if (strlen(e) < 3)   /* status code is 3 digits */
07685          return -1;
07686       req->rlPart2 = e;
07687    } else { /* We have a request */
07688       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
07689          ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
07690          e++;
07691          if (!*e)
07692             return -1; 
07693       }
07694       req->rlPart2 = e; /* URI */
07695       e = ast_skip_nonblanks(e);
07696       if (*e)
07697          *e++ = '\0';
07698       e = ast_skip_blanks(e);
07699       if (strcasecmp(e, "SIP/2.0") ) {
07700          ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
07701          return -1;
07702       }
07703    }
07704    return 1;
07705 }

static void * do_monitor ( void *  data  )  [static]

The SIP monitoring thread.

Note:
This thread monitors all the SIP sessions and peers that needs notification of mwi (and thus do not have a separate thread) indefinitely

Note:
If we can't get a lock on an interface, skip it and come back later. Note that there is the possibility of a deadlock with sip_hangup otherwise, because sip_hangup is called with the channel locked first, and the iface lock is attempted second.

Definition at line 17637 of file chan_sip.c.

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

17638 {
17639    int res;
17640    struct sip_pvt *sip;
17641    struct sip_peer *peer = NULL;
17642    time_t t;
17643    int fastrestart = FALSE;
17644    int lastpeernum = -1;
17645    int curpeernum;
17646    int reloading;
17647 
17648    /* Add an I/O event to our SIP UDP socket */
17649    if (sipsock > -1) 
17650       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
17651    
17652    /* From here on out, we die whenever asked */
17653    for(;;) {
17654       /* Check for a reload request */
17655       ast_mutex_lock(&sip_reload_lock);
17656       reloading = sip_reloading;
17657       sip_reloading = FALSE;
17658       ast_mutex_unlock(&sip_reload_lock);
17659       if (reloading) {
17660          if (option_verbose > 0)
17661             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
17662          sip_do_reload(sip_reloadreason);
17663 
17664          /* Change the I/O fd of our UDP socket */
17665          if (sipsock > -1) {
17666             if (sipsock_read_id)
17667                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
17668             else
17669                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
17670          } else if (sipsock_read_id) {
17671             ast_io_remove(io, sipsock_read_id);
17672             sipsock_read_id = NULL;
17673          }
17674       }
17675 
17676       /* we only want to mark the extenstate updates for destruction
17677        * if the dialog list is being traversed */
17678       if (!fastrestart) {
17679          markall_extenstate_updates();
17680       }
17681 
17682 restartsearch:
17683       /* Check for interfaces needing to be killed and for pending extension state notifications. */
17684       ast_mutex_lock(&iflock);
17685       t = time(NULL);
17686       /* don't scan the interface list if it hasn't been a reasonable period
17687          of time since the last time we did it (when MWI is being sent, we can
17688          get back to this point every millisecond or less)
17689       */
17690       for (sip = iflist; !fastrestart && sip; sip = sip->next) {
17691          /*! \note If we can't get a lock on an interface, skip it and come
17692           * back later. Note that there is the possibility of a deadlock with
17693           * sip_hangup otherwise, because sip_hangup is called with the channel
17694           * locked first, and the iface lock is attempted second.
17695           */
17696          if (ast_mutex_trylock(&sip->lock)) {
17697             /* make sure to unmark any extension state updates for this pvt so
17698              * they can be sent out when we come back to it. */
17699             unmark_extenstate_update(sip);
17700             continue;
17701          }
17702 
17703          /* since we are iterating through all the sip_pvts here, this is a good place
17704           * to send out extension state updates. */
17705          check_extenstate_updates(sip);
17706 
17707          /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
17708          if (sip->rtp && sip->owner &&
17709              (sip->owner->_state == AST_STATE_UP) &&
17710              !sip->redirip.sin_addr.s_addr &&
17711              sip->t38.state != T38_ENABLED) {
17712             if (sip->lastrtptx &&
17713                 ast_rtp_get_rtpkeepalive(sip->rtp) &&
17714                 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
17715                /* Need to send an empty RTP packet */
17716                sip->lastrtptx = time(NULL);
17717                ast_rtp_sendcng(sip->rtp, 0);
17718             }
17719             if (sip->lastrtprx &&
17720                (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
17721                 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
17722                /* Might be a timeout now -- see if we're on hold */
17723                struct sockaddr_in sin = { 0, };
17724                ast_rtp_get_peer(sip->rtp, &sin);
17725                if (!ast_test_flag(&sip->flags[1], SIP_PAGE2_CALL_ONHOLD) || 
17726                    (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
17727                     (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
17728                   /* Needs a hangup */
17729                   if (ast_rtp_get_rtptimeout(sip->rtp)) {
17730                      while (sip->owner && ast_channel_trylock(sip->owner)) {
17731                         DEADLOCK_AVOIDANCE(&sip->lock);
17732                      }
17733                      if (sip->owner) {
17734                         ast_log(LOG_NOTICE,
17735                            "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
17736                            sip->owner->name,
17737                            (long) (t - sip->lastrtprx));
17738                         /* Issue a softhangup */
17739                         ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
17740                         ast_channel_unlock(sip->owner);
17741                         /* forget the timeouts for this call, since a hangup
17742                            has already been requested and we don't want to
17743                            repeatedly request hangups
17744                         */
17745                         ast_rtp_set_rtptimeout(sip->rtp, 0);
17746                         ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
17747                         if (sip->vrtp) {
17748                            ast_rtp_set_rtptimeout(sip->vrtp, 0);
17749                            ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
17750                         }
17751                      }
17752                   }
17753                }
17754             }
17755          }
17756          /* If we have sessions that needs to be destroyed, do it now */
17757          if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
17758              !sip->owner) {
17759             ast_mutex_unlock(&sip->lock);
17760             __sip_destroy(sip, 1);
17761             ast_mutex_unlock(&iflock);
17762             usleep(1);
17763             goto restartsearch;
17764          }
17765          ast_mutex_unlock(&sip->lock);
17766       }
17767       ast_mutex_unlock(&iflock);
17768 
17769       /* we only want to clear the extension state updates if the dialog list was traversed */
17770       if (!fastrestart) {
17771          clearmarked_extenstate_updates();
17772       }
17773 
17774       /* XXX TODO The scheduler usage in this module does not have sufficient 
17775        * synchronization being done between running the scheduler and places 
17776        * scheduling tasks.  As it is written, any scheduled item may not run 
17777        * any sooner than about  1 second, regardless of whether a sooner time 
17778        * was asked for. */
17779 
17780       pthread_testcancel();
17781       /* Wait for sched or io */
17782       res = ast_sched_wait(sched);
17783       if ((res < 0) || (res > 1000))
17784          res = 1000;
17785       /* If we might need to send more mailboxes, don't wait long at all.*/
17786       if (fastrestart)
17787          res = 1;
17788       res = ast_io_wait(io, res);
17789       if (option_debug && res > 20)
17790          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
17791       ast_mutex_lock(&monlock);
17792       res = ast_sched_runq(sched);
17793       if (option_debug && res >= 20)
17794          ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
17795 
17796       /* Send MWI notifications to peers - static and cached realtime peers */
17797       t = time(NULL);
17798       fastrestart = FALSE;
17799       curpeernum = 0;
17800       peer = NULL;
17801       /* Find next peer that needs mwi */
17802       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
17803          if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
17804             fastrestart = TRUE;
17805             lastpeernum = curpeernum;
17806             peer = ASTOBJ_REF(iterator);
17807          };
17808          curpeernum++;
17809       } while (0)
17810       );
17811       /* Send MWI to the peer */
17812       if (peer) {
17813          ASTOBJ_WRLOCK(peer);
17814          sip_send_mwi_to_peer(peer, FALSE);
17815          ASTOBJ_UNLOCK(peer);
17816          ASTOBJ_UNREF(peer,sip_destroy_peer);
17817       } else {
17818          /* Reset where we come from */
17819          lastpeernum = -1;
17820       }
17821       ast_mutex_unlock(&monlock);
17822    }
17823    /* Never reached */
17824    return NULL;
17825    
17826 }

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

12873 {
12874    char digest[1024];
12875 
12876    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
12877       return -2;
12878 
12879    p->authtries++;
12880    if (option_debug > 1)
12881       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
12882    memset(digest, 0, sizeof(digest));
12883    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
12884       /* No way to authenticate */
12885       return -1;
12886    }
12887    /* Now we have a reply digest */
12888    p->options->auth = digest;
12889    p->options->authheader = respheader;
12890    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
12891 }

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

12852 {
12853    char digest[1024];
12854    p->authtries++;
12855    memset(digest,0,sizeof(digest));
12856    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
12857       /* There's nothing to use for authentication */
12858       /* No digest challenge in request */
12859       if (sip_debug_test_pvt(p) && p->registry)
12860          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
12861          /* No old challenge */
12862       return -1;
12863    }
12864    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
12865       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
12866    if (sip_debug_test_pvt(p) && p->registry)
12867       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
12868    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
12869 }

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

Set nat mode on the various data sockets.

Definition at line 3044 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(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().

03045 {
03046    const char *mode = natflags ? "On" : "Off";
03047 
03048    if (p->rtp) {
03049       if (option_debug)
03050          ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode);
03051       ast_rtp_setnat(p->rtp, natflags);
03052    }
03053    if (p->vrtp) {
03054       if (option_debug)
03055          ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode);
03056       ast_rtp_setnat(p->vrtp, natflags);
03057    }
03058    if (p->udptl) {
03059       if (option_debug)
03060          ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode);
03061       ast_udptl_setnat(p->udptl, natflags);
03062    }
03063 }

static int does_peer_need_mwi ( struct sip_peer peer  )  [static]

Check whether peer needs a new MWI notification check.

Definition at line 17616 of file chan_sip.c.

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

Referenced by do_monitor().

17617 {
17618    time_t t = time(NULL);
17619 
17620    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
17621        !peer->mwipvt) { /* We don't have a subscription */
17622       peer->lastmsgcheck = t; /* Reset timer */
17623       return FALSE;
17624    }
17625 
17626    if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
17627       return TRUE;
17628 
17629    return FALSE;
17630 }

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

Print domain mode to cli.

Definition at line 11685 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

11686 {
11687    switch (mode) {
11688    case SIP_DOMAIN_AUTO:
11689       return "[Automatic]";
11690    case SIP_DOMAIN_CONFIG:
11691       return "[Configured]";
11692    }
11693 
11694    return "";
11695 }

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

Convert DTMF mode to printable string.

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

11459 {
11460    switch (mode) {
11461    case SIP_DTMF_RFC2833:
11462       return "rfc2833";
11463    case SIP_DTMF_INFO:
11464       return "info";
11465    case SIP_DTMF_INBAND:
11466       return "inband";
11467    case SIP_DTMF_AUTO:
11468       return "auto";
11469    }
11470    return "<error>";
11471 }

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

Expire registration of SIP peer.

Definition at line 8845 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(), sip_peer::name, peerl, sip_peer::portinuri, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.

Referenced by parse_register_contact(), and reg_source_db().

08846 {
08847    struct sip_peer *peer = (struct sip_peer *)data;
08848    
08849    if (!peer)     /* Hmmm. We have no peer. Weird. */
08850       return 0;
08851 
08852    memset(&peer->addr, 0, sizeof(peer->addr));
08853 
08854    destroy_association(peer); /* remove registration data from storage */
08855    
08856    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08857    register_peer_exten(peer, FALSE);   /* Remove regexten */
08858    peer->expire = -1;
08859    peer->portinuri = 0;
08860    ast_device_state_changed("SIP/%s", peer->name);
08861 
08862    /* Do we need to release this peer from memory? 
08863       Only for realtime peers and autocreated peers
08864    */
08865    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
08866        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
08867       struct sip_peer *peer_ptr = peer_ptr;
08868       peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);
08869       if (peer_ptr) {
08870          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08871       }
08872    }
08873 
08874    ASTOBJ_UNREF(peer, sip_destroy_peer);
08875 
08876    return 0;
08877 }

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

Check Contact: URI of SIP message.

Definition at line 7759 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and SIPBUFSIZE.

Referenced by handle_request(), and handle_request_invite().

07760 {
07761    char stripped[SIPBUFSIZE];
07762    char *c;
07763 
07764    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
07765    c = get_in_brackets(stripped);
07766    c = strsep(&c, ";"); /* trim ; and beyond */
07767    if (!ast_strlen_zero(c))
07768       ast_string_field_set(p, uri, c);
07769 }

static int finalize_content ( struct sip_request req  )  [static]

Add 'Content-Length' header to SIP message.

Definition at line 6469 of file chan_sip.c.

References add_header(), ast_log(), ast_strlen_zero(), sip_request::content, sip_request::data, sip_request::len, and sip_request::lines.

Referenced by send_request(), and send_response().

06470 {
06471    char clen[10];
06472 
06473    if (req->lines) {
06474       ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n");
06475       return -1;
06476    }
06477 
06478    snprintf(clen, sizeof(clen), "%zd", strlen(req->content));
06479    add_header(req, "Content-Length", clen);
06480 
06481    if (!ast_strlen_zero(req->content)) {
06482       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n%s", req->content);
06483       req->len += strlen(req->data + req->len);
06484    }
06485 
06486    req->lines = !ast_strlen_zero(req->content);
06487    return 0;
06488 }

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

References aliases.

04639 {
04640    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
04641    static const struct cfalias {
04642       char * const fullname;
04643       char * const shortname;
04644    } aliases[] = {
04645       { "Content-Type",  "c" },
04646       { "Content-Encoding",    "e" },
04647       { "From",       "f" },
04648       { "Call-ID",       "i" },
04649       { "Contact",       "m" },
04650       { "Content-Length",   "l" },
04651       { "Subject",       "s" },
04652       { "To",         "t" },
04653       { "Supported",     "k" },
04654       { "Refer-To",      "r" },
04655       { "Referred-By",   "b" },
04656       { "Allow-Events",  "u" },
04657       { "Event",      "o" },
04658       { "Via",     "v" },
04659       { "Accept-Contact",      "a" },
04660       { "Reject-Contact",      "j" },
04661       { "Request-Disposition", "d" },
04662       { "Session-Expires",     "x" },
04663       { "Identity",            "y" },
04664       { "Identity-Info",       "n" },
04665    };
04666    int x;
04667 
04668    for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
04669       if (!strcasecmp(aliases[x].fullname, name))
04670          return aliases[x].shortname;
04671 
04672    return _default;
04673 }

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

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

Referenced by sipsock_read().

05190 {
05191    struct sip_pvt *p = NULL;
05192    char *tag = "";   /* note, tag is never NULL */
05193    char totag[128];
05194    char fromtag[128];
05195    const char *callid = get_header(req, "Call-ID");
05196    const char *from = get_header(req, "From");
05197    const char *to = get_header(req, "To");
05198    const char *cseq = get_header(req, "Cseq");
05199 
05200    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
05201    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
05202    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
05203          ast_strlen_zero(from) || ast_strlen_zero(cseq))
05204       return NULL;   /* Invalid packet */
05205 
05206    if (pedanticsipchecking) {
05207       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
05208          we need more to identify a branch - so we have to check branch, from
05209          and to tags to identify a call leg.
05210          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
05211          in sip.conf
05212          */
05213       if (gettag(req, "To", totag, sizeof(totag)))
05214          ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
05215       gettag(req, "From", fromtag, sizeof(fromtag));
05216 
05217       tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
05218 
05219       if (option_debug > 4 )
05220          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);
05221    }
05222 
05223    ast_mutex_lock(&iflock);
05224    for (p = iflist; p; p = p->next) {
05225       /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
05226       int found = FALSE;
05227       if (ast_strlen_zero(p->callid))
05228          continue;
05229       if (req->method == SIP_REGISTER)
05230          found = (!strcmp(p->callid, callid));
05231       else {
05232          found = !strcmp(p->callid, callid);
05233          if (pedanticsipchecking && found) {
05234             found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag);
05235          }
05236       }
05237 
05238       if (option_debug > 4)
05239          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);
05240 
05241       /* If we get a new request within an existing to-tag - check the to tag as well */
05242       if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {  /* SIP Request */
05243          if (p->tag[0] == '\0' && totag[0]) {
05244             /* We have no to tag, but they have. Wrong dialog */
05245             found = FALSE;
05246          } else if (totag[0]) {        /* Both have tags, compare them */
05247             if (strcmp(totag, p->tag)) {
05248                found = FALSE;    /* This is not our packet */
05249             }
05250          }
05251          if (!found && option_debug > 4)
05252             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);
05253       }
05254       if (found) {
05255          /* Found the call */
05256          ast_mutex_lock(&p->lock);
05257          ast_mutex_unlock(&iflock);
05258          return p;
05259       }
05260    }
05261    ast_mutex_unlock(&iflock);
05262 
05263    /* See if the method is capable of creating a dialog */
05264    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
05265       if (intended_method == SIP_REFER) {
05266          /* We do support REFER, but not outside of a dialog yet */
05267          transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
05268       } else if (intended_method == SIP_NOTIFY) {
05269          /* We do not support out-of-dialog NOTIFY either,
05270             like voicemail notification, so cancel that early */
05271          transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 No subscription");
05272       } else {
05273          /* Ok, time to create a new SIP dialog object, a pvt */
05274          if ((p = sip_alloc(callid, sin, 1, intended_method)))  {
05275             /* Ok, we've created a dialog, let's go and process it */
05276             ast_mutex_lock(&p->lock);
05277          } else {
05278             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
05279                getting a dialog from sip_alloc. 
05280    
05281                Without a dialog we can't retransmit and handle ACKs and all that, but at least
05282                send an error message.
05283    
05284                Sorry, we apologize for the inconvienience
05285             */
05286             transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
05287             if (option_debug > 3)
05288                ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
05289          }
05290       }
05291       return p;
05292    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
05293       /* A method we do not support, let's take it on the volley */
05294       transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
05295    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
05296       /* This is a request outside of a dialog that we don't know about 
05297          ...never reply to an ACK!
05298       */
05299       transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
05300    }
05301    /* We do not respond to responses for dialogs that we don't know about, we just drop
05302       the session quickly */
05303 
05304    return p;
05305 }

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

References s.

Referenced by get_in_brackets().

02595 {
02596         char last_char = '\0';
02597         const char *s;
02598         for (s = start; *s && s != lim; last_char = *s++) {
02599                 if (*s == '"' && last_char != '\\')
02600                         break;
02601         }
02602         return s;
02603 }

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

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

Definition at line 2956 of file chan_sip.c.

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

02957 {
02958    struct sip_peer *p = NULL;
02959 
02960    if (peer)
02961       p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
02962    else
02963       p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
02964 
02965    if (!p && (realtime || devstate_only))
02966       p = realtime_peer(peer, sin, devstate_only);
02967 
02968    return p;
02969 }

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

Find authentication for a specific realm.

Definition at line 18479 of file chan_sip.c.

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

Referenced by build_reply_digest().

18480 {
18481    struct sip_auth *a;
18482 
18483    for (a = authlist; a; a = a->next) {
18484       if (!strcasecmp(a->realm, realm))
18485          break;
18486    }
18487 
18488    return a;
18489 }

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_count to indicate where the SDP lives in the message body.

Definition at line 5525 of file chan_sip.c.

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

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

05526 {
05527    const char *content_type;
05528    const char *content_length;
05529    const char *search;
05530    char *boundary;
05531    unsigned int x;
05532    int boundaryisquoted = FALSE;
05533    int found_application_sdp = FALSE;
05534    int found_end_of_headers = FALSE;
05535 
05536    content_length = get_header(req, "Content-Length");
05537 
05538    if (!ast_strlen_zero(content_length)) {
05539       if (sscanf(content_length, "%30u", &x) != 1) {
05540          ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
05541          return 0;
05542       }
05543 
05544       /* Content-Length of zero means there can't possibly be an
05545          SDP here, even if the Content-Type says there is */
05546       if (x == 0)
05547          return 0;
05548    }
05549 
05550    content_type = get_header(req, "Content-Type");
05551 
05552    /* if the body contains only SDP, this is easy */
05553    if (!strncasecmp(content_type, "application/sdp", 15)) {
05554       req->sdp_start = 0;
05555       req->sdp_count = req->lines;
05556       return req->lines ? 1 : 0;
05557    }
05558 
05559    /* if it's not multipart/mixed, there cannot be an SDP */
05560    if (strncasecmp(content_type, "multipart/mixed", 15))
05561       return 0;
05562 
05563    /* if there is no boundary marker, it's invalid */
05564    if ((search = strcasestr(content_type, ";boundary=")))
05565       search += 10;
05566    else if ((search = strcasestr(content_type, "; boundary=")))
05567       search += 11;
05568    else
05569       return 0;
05570 
05571    if (ast_strlen_zero(search))
05572       return 0;
05573 
05574    /* If the boundary is quoted with ", remove quote */
05575    if (*search == '\"')  {
05576       search++;
05577       boundaryisquoted = TRUE;
05578    }
05579 
05580    /* make a duplicate of the string, with two extra characters
05581       at the beginning */
05582    boundary = ast_strdupa(search - 2);
05583    boundary[0] = boundary[1] = '-';
05584    /* Remove final quote */
05585    if (boundaryisquoted)
05586       boundary[strlen(boundary) - 1] = '\0';
05587 
05588    /* search for the boundary marker, the empty line delimiting headers from
05589       sdp part and the end boundry if it exists */
05590 
05591    for (x = 0; x < (req->lines ); x++) {
05592       if(!strncasecmp(req->line[x], boundary, strlen(boundary))){
05593          if(found_application_sdp && found_end_of_headers){
05594             req->sdp_count = (x - 1) - req->sdp_start;
05595             return 1;
05596          }
05597          found_application_sdp = FALSE;
05598       }
05599       if(!strcasecmp(req->line[x], "Content-Type: application/sdp"))
05600          found_application_sdp = TRUE;
05601       
05602       if(strlen(req->line[x]) == 0 ){
05603          if(found_application_sdp && !found_end_of_headers){
05604             req->sdp_start = x;
05605             found_end_of_headers = TRUE;
05606          }
05607       }
05608    }
05609    if(found_application_sdp && found_end_of_headers) {
05610       req->sdp_count = x - req->sdp_start;
05611       return TRUE;
05612    }
05613    return FALSE;
05614 }

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

find_sip_method: Find SIP method from header

Definition at line 1795 of file chan_sip.c.

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

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

01796 {
01797    int i, res = 0;
01798    
01799    if (ast_strlen_zero(msg))
01800       return 0;
01801    for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
01802       if (method_match(i, msg))
01803          res = sip_methods[i].id;
01804    }
01805    return res;
01806 }

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

Find subscription type in array.

Definition at line 12175 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

12176 {
12177    int i;
12178 
12179    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
12180       if (subscription_types[i].type == subtype) {
12181          return &subscription_types[i];
12182       }
12183    }
12184    return &subscription_types[0];
12185 }

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

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

03036 {
03037    struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name);
03038    if (!u && realtime)
03039       u = realtime_user(name);
03040    return u;
03041 }

static void free_old_route ( struct sip_route route  )  [static]

Remove route from route list.

Definition at line 9256 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

09257 {
09258    struct sip_route *next;
09259 
09260    while (route) {
09261       next = route->next;
09262       free(route);
09263       route = next;
09264    }
09265 }

static void free_via ( struct sip_via v  )  [static]

Definition at line 5008 of file chan_sip.c.

References ast_free, and sip_via::via.

Referenced by parse_via(), and process_via().

05009 {
05010    if (!v) {
05011       return;
05012    }
05013 
05014    ast_free(v->via);
05015    ast_free(v);
05016 }

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

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

13209 {
13210    if (ast_strlen_zero(data)) {
13211       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
13212       return -1;
13213    }
13214    if (check_sip_domain(data, NULL, 0))
13215       ast_copy_string(buf, data, len);
13216    else
13217       buf[0] = '\0';
13218    return 0;
13219 }

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

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

13145 {
13146    struct sip_pvt *p;
13147    const char *content = NULL;
13148    AST_DECLARE_APP_ARGS(args,
13149       AST_APP_ARG(header);
13150       AST_APP_ARG(number);
13151    );
13152    int i, number, start = 0;
13153 
13154    if (ast_strlen_zero(data)) {
13155       ast_log(LOG_WARNING, "This function requires a header name.\n");
13156       return -1;
13157    }
13158 
13159    ast_channel_lock(chan);
13160    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
13161       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
13162       ast_channel_unlock(chan);
13163       return -1;
13164    }
13165 
13166    AST_STANDARD_APP_ARGS(args, data);
13167    if (!args.number) {
13168       number = 1;
13169    } else {
13170       sscanf(args.number, "%30d", &number);
13171       if (number < 1)
13172          number = 1;
13173    }
13174 
13175    p = chan->tech_pvt;
13176 
13177    /* If there is no private structure, this channel is no longer alive */
13178    if (!p) {
13179       ast_channel_unlock(chan);
13180       return -1;
13181    }
13182 
13183    for (i = 0; i < number; i++)
13184       content = __get_header(&p->initreq, args.header, &start);
13185 
13186    if (ast_strlen_zero(content)) {
13187       ast_channel_unlock(chan);
13188       return -1;
13189    }
13190 
13191    ast_copy_string(buf, content, len);
13192    ast_channel_unlock(chan);
13193 
13194    return 0;
13195 }

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

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

13328 {
13329    struct sip_pvt *p;
13330 
13331    *buf = 0;
13332    
13333    if (!data) {
13334       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
13335       return -1;
13336    }
13337 
13338    ast_channel_lock(chan);
13339    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
13340       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
13341       ast_channel_unlock(chan);
13342       return -1;
13343    }
13344 
13345    p = chan->tech_pvt;
13346 
13347    /* If there is no private structure, this channel is no longer alive */
13348    if (!p) {
13349       ast_channel_unlock(chan);
13350       return -1;
13351    }
13352 
13353    if (!strcasecmp(data, "peerip")) {
13354       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
13355    } else  if (!strcasecmp(data, "recvip")) {
13356       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
13357    } else  if (!strcasecmp(data, "from")) {
13358       ast_copy_string(buf, p->from, len);
13359    } else  if (!strcasecmp(data, "uri")) {
13360       ast_copy_string(buf, p->uri, len);
13361    } else  if (!strcasecmp(data, "useragent")) {
13362       ast_copy_string(buf, p->useragent, len);
13363    } else  if (!strcasecmp(data, "peername")) {
13364       ast_copy_string(buf, p->peername, len);
13365    } else if (!strcasecmp(data, "t38passthrough")) {
13366       if (p->t38.state == T38_DISABLED) {
13367          ast_copy_string(buf, "0", len);
13368       } else { /* T38 is offered or enabled in this call */
13369          ast_copy_string(buf, "1", len);
13370       }
13371    } else {
13372       ast_channel_unlock(chan);
13373       return -1;
13374    }
13375    ast_channel_unlock(chan);
13376 
13377    return 0;
13378 }

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

References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_copy_string(), 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, and sip_peer::useragent.

13234 {
13235    struct sip_peer *peer;
13236    char *colname;
13237 
13238    if ((colname = strchr(data, ':')))  /*! \todo Will be deprecated after 1.4 */
13239       *colname++ = '\0';
13240    else if ((colname = strchr(data, '|')))
13241       *colname++ = '\0';
13242    else
13243       colname = "ip";
13244 
13245    if (!(peer = find_peer(data, NULL, 1, 0)))
13246       return -1;
13247 
13248    if (!strcasecmp(colname, "ip")) {
13249       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
13250    } else  if (!strcasecmp(colname, "status")) {
13251       peer_status(peer, buf, len);
13252    } else  if (!strcasecmp(colname, "language")) {
13253       ast_copy_string(buf, peer->language, len);
13254    } else  if (!strcasecmp(colname, "regexten")) {
13255       ast_copy_string(buf, peer->regexten, len);
13256    } else  if (!strcasecmp(colname, "limit")) {
13257       snprintf(buf, len, "%d", peer->call_limit);
13258    } else  if (!strcasecmp(colname, "curcalls")) {
13259       snprintf(buf, len, "%d", peer->inUse);
13260    } else  if (!strcasecmp(colname, "accountcode")) {
13261       ast_copy_string(buf, peer->accountcode, len);
13262    } else  if (!strcasecmp(colname, "useragent")) {
13263       ast_copy_string(buf, peer->useragent, len);
13264    } else  if (!strcasecmp(colname, "mailbox")) {
13265       ast_copy_string(buf, peer->mailbox, len);
13266    } else  if (!strcasecmp(colname, "context")) {
13267       ast_copy_string(buf, peer->context, len);
13268    } else  if (!strcasecmp(colname, "expire")) {
13269       snprintf(buf, len, "%d", peer->expire);
13270    } else  if (!strcasecmp(colname, "dynamic")) {
13271       ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
13272    } else  if (!strcasecmp(colname, "callerid_name")) {
13273       ast_copy_string(buf, peer->cid_name, len);
13274    } else  if (!strcasecmp(colname, "callerid_num")) {
13275       ast_copy_string(buf, peer->cid_num, len);
13276    } else  if (!strcasecmp(colname, "codecs")) {
13277       ast_getformatname_multiple(buf, len -1, peer->capability);
13278    } else  if (!strncasecmp(colname, "codec[", 6)) {
13279       char *codecnum;
13280       int index = 0, codec = 0;
13281       
13282       codecnum = colname + 6; /* move past the '[' */
13283       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
13284       index = atoi(codecnum);
13285       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
13286          ast_copy_string(buf, ast_getformatname(codec), len);
13287       } else {
13288          buf[0] = '\0';
13289       }
13290    } else {
13291       buf[0] = '\0';
13292    }
13293 
13294    ASTOBJ_UNREF(peer, sip_destroy_peer);
13295 
13296    return 0;
13297 }

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

Generate 32 byte random string for callid's etc.

Definition at line 4830 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

04831 {
04832    long val[4];
04833    int x;
04834 
04835    for (x=0; x<4; x++)
04836       val[x] = ast_random();
04837    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
04838 
04839    return buf;
04840 }

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

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

Referenced by handle_request_bye().

10510 {
10511    char tmp[256] = "", *c, *a;
10512    struct sip_request *req = oreq ? oreq : &p->initreq;
10513    struct sip_refer *referdata = NULL;
10514    const char *transfer_context = NULL;
10515    
10516    if (!p->refer && !sip_refer_allocate(p))
10517       return -1;
10518 
10519    referdata = p->refer;
10520 
10521    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
10522    c = get_in_brackets(tmp);
10523 
10524    if (pedanticsipchecking)
10525       ast_uri_decode(c);
10526    
10527    if (strncasecmp(c, "sip:", 4)) {
10528       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
10529       return -1;
10530    }
10531    c += 4;
10532    if ((a = strchr(c, ';')))  /* Remove arguments */
10533       *a = '\0';
10534    
10535    if ((a = strchr(c, '@'))) {   /* Separate Domain */
10536       *a++ = '\0';
10537       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
10538    }
10539    
10540    if (sip_debug_test_pvt(p))
10541       ast_verbose("Looking for %s in %s\n", c, p->context);
10542 
10543    if (p->owner)  /* Mimic behaviour in res_features.c */
10544       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
10545 
10546    /* By default, use the context in the channel sending the REFER */
10547    if (ast_strlen_zero(transfer_context)) {
10548       transfer_context = S_OR(p->owner->macrocontext,
10549                S_OR(p->context, default_context));
10550    }
10551    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
10552       /* This is a blind transfer */
10553       if (option_debug)
10554          ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
10555       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
10556       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
10557       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
10558       referdata->refer_call = NULL;
10559       /* Set new context */
10560       ast_string_field_set(p, context, transfer_context);
10561       return 0;
10562    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
10563       return 1;
10564    }
10565 
10566    return -1;
10567 }

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

Get a specific line from the message body.

Definition at line 4622 of file chan_sip.c.

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

Referenced by handle_request_info().

04623 {
04624    int x;
04625    int len = strlen(name);
04626    char *r;
04627 
04628    for (x = 0; x < req->lines; x++) {
04629       r = get_body_by_line(req->line[x], name, len);
04630       if (r[0] != '\0')
04631          return r;
04632    }
04633 
04634    return "";
04635 }

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

References ast_skip_blanks().

Referenced by get_body(), and get_sdp_iterate().

04568 {
04569    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
04570       return ast_skip_blanks(line + nameLen + 1);
04571 
04572    return "";
04573 }

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

Get caller id name from SIP headers.

Definition at line 10632 of file chan_sip.c.

References ast_copy_string(), and ast_skip_blanks().

Referenced by check_user_full().

10633 {
10634    const char *end = strchr(input,'<');   /* first_bracket */
10635    const char *tmp = strchr(input,'"');   /* first quote */
10636    int bytes = 0;
10637    int maxbytes = outputsize - 1;
10638 
10639    if (!end || end == input)  /* we require a part in brackets */
10640       return NULL;
10641 
10642    end--; /* move just before "<" */
10643 
10644    if (tmp && tmp <= end) {
10645       /* The quote (tmp) precedes the bracket (end+1).
10646        * Find the matching quote and return the content.
10647        */
10648       end = strchr(tmp+1, '"');
10649       if (!end)
10650          return NULL;
10651       bytes = (int) (end - tmp);
10652       /* protect the output buffer */
10653       if (bytes > maxbytes)
10654          bytes = maxbytes;
10655       ast_copy_string(output, tmp + 1, bytes);
10656    } else {
10657       /* No quoted string, or it is inside brackets. */
10658       /* clear the empty characters in the begining*/
10659       input = ast_skip_blanks(input);
10660       /* clear the empty characters in the end */
10661       while(*end && *end < 33 && end > input)
10662          end--;
10663       if (end >= input) {
10664          bytes = (int) (end - input) + 2;
10665          /* protect the output buffer */
10666          if (bytes > maxbytes)
10667             bytes = maxbytes;
10668          ast_copy_string(output, input, bytes);
10669       } else
10670          return NULL;
10671    }
10672    return output;
10673 }

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

References ast_canmatch_extension(), ast_copy_string(), ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), check_sip_domain(), sip_pvt::cid_num, sip_pvt::context, context, sip_pvt::domain, exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, sip_request::method, option_debug, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, and sip_pvt::subscribecontext.

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

10132 {
10133    char tmp[256] = "", *uri, *a;
10134    char tmpf[256] = "", *from;
10135    struct sip_request *req;
10136    char *colon;
10137    char *decoded_uri;
10138    
10139    req = oreq;
10140    if (!req)
10141       req = &p->initreq;
10142 
10143    /* Find the request URI */
10144    if (req->rlPart2)
10145       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
10146    
10147    if (pedanticsipchecking)
10148       ast_uri_decode(tmp);
10149 
10150    uri = get_in_brackets(tmp);
10151 
10152    if (strncasecmp(uri, "sip:", 4)) {
10153       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
10154       return -1;
10155    }
10156    uri += 4;
10157 
10158    /* Now find the From: caller ID and name */
10159    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
10160    if (!ast_strlen_zero(tmpf)) {
10161       if (pedanticsipchecking)
10162          ast_uri_decode(tmpf);
10163       from = get_in_brackets(tmpf);
10164    } else {
10165       from = NULL;
10166    }
10167    
10168    if (!ast_strlen_zero(from)) {
10169       if (strncasecmp(from, "sip:", 4)) {
10170          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
10171          return -1;
10172       }
10173       from += 4;
10174       if ((a = strchr(from, '@')))
10175          *a++ = '\0';
10176       else
10177          a = from;   /* just a domain */
10178       from = strsep(&from, ";"); /* Remove userinfo options */
10179       a = strsep(&a, ";");    /* Remove URI options */
10180       ast_string_field_set(p, fromdomain, a);
10181    }
10182 
10183    /* Skip any options and find the domain */
10184 
10185    /* Get the target domain */
10186    if ((a = strchr(uri, '@'))) {
10187       *a++ = '\0';
10188    } else { /* No username part */
10189       a = uri;
10190       uri = "s";  /* Set extension to "s" */
10191    }
10192    colon = strchr(a, ':'); /* Remove :port */
10193    if (colon)
10194       *colon = '\0';
10195 
10196    uri = strsep(&uri, ";");   /* Remove userinfo options */
10197    a = strsep(&a, ";");    /* Remove URI options */
10198 
10199    ast_string_field_set(p, domain, a);
10200 
10201    if (!AST_LIST_EMPTY(&domain_list)) {
10202       char domain_context[AST_MAX_EXTENSION];
10203 
10204       domain_context[0] = '\0';
10205       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
10206          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
10207             if (option_debug)
10208                ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
10209             return -2;
10210          }
10211       }
10212       /* If we have a context defined, overwrite the original context */
10213       if (!ast_strlen_zero(domain_context))
10214          ast_string_field_set(p, context, domain_context);
10215    }
10216 
10217    /* If the request coming in is a subscription and subscribecontext has been specified use it */
10218    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext))
10219       ast_string_field_set(p, context, p->subscribecontext);
10220 
10221    if (sip_debug_test_pvt(p))
10222       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
10223 
10224    /* Since extensions.conf can have unescaped characters, try matching a
10225     * decoded uri in addition to the non-decoded uri. */
10226    decoded_uri = ast_strdupa(uri);
10227    ast_uri_decode(decoded_uri);
10228 
10229    /* If this is a subscription we actually just need to see if a hint exists for the extension */
10230    if (req->method == SIP_SUBSCRIBE) {
10231       char hint[AST_MAX_EXTENSION];
10232       int which = 0;
10233       if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) ||
10234           (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) {
10235          if (!oreq) {
10236             ast_string_field_set(p, exten, which ? decoded_uri : uri);
10237          }
10238          return 0;
10239       } else {
10240          return -1;
10241       }
10242    } else {
10243       int which = 0;
10244       /* Check the dialplan for the username part of the request URI,
10245          the domain will be stored in the SIPDOMAIN variable
10246          Return 0 if we have a matching extension */
10247       if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) ||
10248           (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) && (which = 1)) ||
10249           !strcmp(decoded_uri, ast_pickup_ext())) {
10250          if (!oreq) {
10251             ast_string_field_set(p, exten, which ? decoded_uri : uri);
10252          }
10253          return 0;
10254       }
10255    }
10256 
10257    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
10258    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
10259        ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) ||
10260        !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) {
10261       return 1;
10262    }
10263    
10264    return -1;
10265 }

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

Get header from SIP request.

Definition at line 4711 of file chan_sip.c.

References __get_header().

04712 {
04713    int start = 0;
04714    return __get_header(req, name, &start);
04715 }

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

02617 {
02618    const char *parse = tmp;
02619    char *first_bracket;
02620 
02621    /*
02622     * Skip any quoted text until we find the part in brackets.
02623          * On any error give up and return the full string.
02624          */
02625         while ( (first_bracket = strchr(parse, '<')) ) {
02626                 char *first_quote = strchr(parse, '"');
02627 
02628       if (!first_quote || first_quote > first_bracket)
02629          break; /* no need to look at quoted part */
02630       /* the bracket is within quotes, so ignore it */
02631       parse = find_closing_quote(first_quote + 1, NULL);
02632       if (!*parse) { /* not found, return full string ? */
02633          /* XXX or be robust and return in-bracket part ? */
02634          ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
02635          break;
02636       }
02637       parse++;
02638    }
02639    if (first_bracket) {
02640       char *second_bracket = strchr(first_bracket + 1, '>');
02641       if (second_bracket) {
02642          *second_bracket = '\0';
02643          tmp = first_bracket + 1;
02644       } else {
02645          ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
02646       }
02647    }
02648    return tmp;
02649 }

static int get_ip_and_port_from_sdp ( struct sip_request req,
const enum media_type  media,
struct sockaddr_in *  sin 
) [static]

Definition at line 5649 of file chan_sip.c.

References ast_gethostbyname(), ast_log(), ast_strlen_zero(), get_sdp_iterate(), hp, len(), SDP_AUDIO, sip_request::sdp_start, and SDP_VIDEO.

Referenced by handle_request_invite().

05650 {
05651    const char *m;
05652    const char *c;
05653    int miterator = req->sdp_start;
05654    int citerator = req->sdp_start;
05655    int x = 0;
05656    int numberofports;
05657    int len;
05658    char host[258] = ""; /*Initialize to empty so we will know if we have any input */
05659    struct ast_hostent audiohp;
05660    struct hostent *hp;
05661 
05662    c = get_sdp_iterate(&citerator, req, "c");
05663    if (sscanf(c, "IN IP4 %256s", host) != 1) {
05664       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
05665       /* Continue since there may be a valid host in a c= line specific to the audio stream */
05666    }
05667    /* We only want the m and c lines for audio */
05668    for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) {
05669       if ((media == SDP_AUDIO && ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
05670           (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0))) ||
05671          (media == SDP_VIDEO && ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
05672           (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len > 0)))) {
05673          /* See if there's a c= line for this media stream.
05674           * XXX There is no guarantee that we'll be grabbing the c= line for this
05675           * particular media stream here. However, this is the same logic used in process_sdp.
05676           */
05677          c = get_sdp_iterate(&citerator, req, "c");
05678          if (!ast_strlen_zero(c)) {
05679             sscanf(c, "IN IP4 %256s", host);
05680          }
05681          break;
05682       }
05683    }
05684 
05685    if (ast_strlen_zero(host) || x == 0) {
05686       ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video");
05687       return -1;
05688    }
05689 
05690    hp = ast_gethostbyname(host, &audiohp);
05691    if (!hp) {
05692       ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video");
05693       return -1;
05694    }
05695 
05696    memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
05697    sin->sin_port = htons(x);
05698    return 0;
05699 }

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

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

Referenced by handle_request_notify(), and receive_message().

11052 {
11053    int x;
11054    int y;
11055 
11056    buf[0] = '\0';
11057    y = len - strlen(buf) - 5;
11058    if (y < 0)
11059       y = 0;
11060    for (x=0;x<req->lines;x++) {
11061       strncat(buf, req->line[x], y); /* safe */
11062       y -= strlen(req->line[x]) + 1;
11063       if (y < 0)
11064          y = 0;
11065       if (y != 0)
11066          strcat(buf, "\n"); /* safe */
11067    }
11068    return 0;
11069 }

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

Get referring dnis.

Definition at line 10102 of file chan_sip.c.

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

Referenced by handle_request_invite().

10103 {
10104    char tmp[256], *c, *a;
10105    struct sip_request *req;
10106    
10107    req = oreq;
10108    if (!req)
10109       req = &p->initreq;
10110    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
10111    if (ast_strlen_zero(tmp))
10112       return 0;
10113    c = get_in_brackets(tmp);
10114    if (strncasecmp(c, "sip:", 4)) {
10115       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
10116       return -1;
10117    }
10118    c += 4;
10119    a = c;
10120    strsep(&a, "@;"); /* trim anything after @ or ; */
10121    if (sip_debug_test_pvt(p))
10122       ast_verbose("RDNIS is %s\n", c);
10123    ast_string_field_set(p, rdnis, c);
10124 
10125    return 0;
10126 }

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

References ast_copy_string(), ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, sip_pvt::callid, sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_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(), sip_pvt::tag, and sip_pvt::theirtag.

Referenced by handle_request_refer().

10339 {
10340 
10341    const char *p_referred_by = NULL;
10342    char *h_refer_to = NULL; 
10343    char *h_referred_by = NULL;
10344    char *refer_to;
10345    const char *p_refer_to;
10346    char *referred_by_uri = NULL;
10347    char *ptr;
10348    struct sip_request *req = NULL;
10349    const char *transfer_context = NULL;
10350    struct sip_refer *referdata;
10351 
10352 
10353    req = outgoing_req;
10354    referdata = transferer->refer;
10355 
10356    if (!req)
10357       req = &transferer->initreq;
10358 
10359    p_refer_to = get_header(req, "Refer-To");
10360    if (ast_strlen_zero(p_refer_to)) {
10361       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
10362       return -2;  /* Syntax error */
10363    }
10364    h_refer_to = ast_strdupa(p_refer_to);
10365    refer_to = get_in_brackets(h_refer_to);
10366    if (pedanticsipchecking)
10367       ast_uri_decode(refer_to);
10368 
10369    if (strncasecmp(refer_to, "sip:", 4)) {
10370       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
10371       return -3;
10372    }
10373    refer_to += 4;       /* Skip sip: */
10374 
10375    /* Get referred by header if it exists */
10376    p_referred_by = get_header(req, "Referred-By");
10377    if (!ast_strlen_zero(p_referred_by)) {
10378       char *lessthan;
10379       h_referred_by = ast_strdupa(p_referred_by);
10380       if (pedanticsipchecking)
10381          ast_uri_decode(h_referred_by);
10382 
10383       /* Store referrer's caller ID name */
10384       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
10385       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
10386          *(lessthan - 1) = '\0'; /* Space */
10387       }
10388 
10389       referred_by_uri = get_in_brackets(h_referred_by);
10390       if(strncasecmp(referred_by_uri, "sip:", 4)) {
10391          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
10392          referred_by_uri = (char *) NULL;
10393       } else {
10394          referred_by_uri += 4;      /* Skip sip: */
10395       }
10396    }
10397 
10398    /* Check for arguments in the refer_to header */
10399    if ((ptr = strcasestr(refer_to, "replaces="))) {
10400       char *to = NULL, *from = NULL;
10401       
10402       /* This is an attended transfer */
10403       referdata->attendedtransfer = 1;
10404       ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
10405       ast_uri_decode(referdata->replaces_callid);
10406       if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
10407          *ptr++ = '\0';
10408       }
10409       
10410       if (ptr) {
10411          /* Find the different tags before we destroy the string */
10412          to = strcasestr(ptr, "to-tag=");
10413          from = strcasestr(ptr, "from-tag=");
10414       }
10415       
10416       /* Grab the to header */
10417       if (to) {
10418          ptr = to + 7;
10419          if ((to = strchr(ptr, '&')))
10420             *to = '\0';
10421          if ((to = strchr(ptr, ';')))
10422             *to = '\0';
10423          ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
10424       }
10425       
10426       if (from) {
10427          ptr = from + 9;
10428          if ((to = strchr(ptr, '&')))
10429             *to = '\0';
10430          if ((to = strchr(ptr, ';')))
10431             *to = '\0';
10432          ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
10433       }
10434 
10435       if (!strcmp(referdata->replaces_callid, transferer->callid) &&
10436          (!pedanticsipchecking ||
10437          (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) &&
10438          !strcmp(referdata->replaces_callid_totag, transferer->tag)))) {
10439             ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid);
10440             return -4;
10441       }
10442 
10443       if (option_debug > 1) {
10444          if (!pedanticsipchecking)
10445             ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
10446          else
10447             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>" );
10448       }
10449    }
10450    
10451    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
10452       char *urioption = NULL, *domain;
10453       *ptr++ = '\0';
10454 
10455       if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */
10456          *urioption++ = '\0';
10457       
10458       domain = ptr;
10459       if ((ptr = strchr(domain, ':'))) /* Remove :port */
10460          *ptr = '\0';
10461       
10462       /* Save the domain for the dial plan */
10463       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
10464       if (urioption)
10465          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
10466    }
10467 
10468    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
10469       *ptr = '\0';
10470    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
10471    
10472    if (referred_by_uri) {
10473       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
10474          *ptr = '\0';
10475       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
10476    } else {
10477       referdata->referred_by[0] = '\0';
10478    }
10479 
10480    /* Determine transfer context */
10481    if (transferer->owner)  /* Mimic behaviour in res_features.c */
10482       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
10483 
10484    /* By default, use the context in the channel sending the REFER */
10485    if (ast_strlen_zero(transfer_context)) {
10486       transfer_context = S_OR(transferer->owner->macrocontext,
10487                S_OR(transferer->context, default_context));
10488    }
10489 
10490    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
10491    
10492    /* Either an existing extension or the parking extension */
10493    if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
10494       if (sip_debug_test_pvt(transferer)) {
10495          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
10496       }
10497       /* We are ready to transfer to the extension */
10498       return 0;
10499    } 
10500    if (sip_debug_test_pvt(transferer))
10501       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
10502 
10503    /* Failure, we can't find this extension */
10504    return -1;
10505 }

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

References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

10680 {
10681    char *start;
10682    char *end;
10683 
10684    start = strchr(input,':');
10685    if (!start) {
10686       output[0] = '\0';
10687       return 0;
10688    }
10689    start++;
10690 
10691    /* we found "number" */
10692    ast_copy_string(output,start,maxlen);
10693    output[maxlen-1] = '\0';
10694 
10695    end = strchr(output,'@');
10696    if (end)
10697       *end = '\0';
10698    else
10699       output[0] = '\0';
10700    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
10701       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
10702 
10703    return 0;
10704 }

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

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

04580 {
04581    int len = strlen(name);
04582 
04583    while (*start < (req->sdp_start + req->sdp_count)) {
04584       const char *r = get_body_by_line(req->line[(*start)++], name, len);
04585       if (r[0] != '\0')
04586          return r;
04587    }
04588 
04589    /* if the line was not found, ensure that *start points past the SDP */
04590    (*start)++;
04591 
04592    return "";
04593 }

static char get_sdp_line ( int *  start,
int  stop,
struct sip_request req,
const char **  value 
) [static]

Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.

Definition at line 4600 of file chan_sip.c.

References ast_skip_blanks(), sip_request::line, sip_request::sdp_count, sip_request::sdp_start, and type.

Referenced by process_sdp().

04601 {
04602    char type = '\0';
04603    const char *line = NULL;
04604 
04605    if (stop > (req->sdp_start + req->sdp_count)) {
04606       stop = req->sdp_start + req->sdp_count;
04607    }
04608 
04609    while (*start < stop) {
04610       line = req->line[(*start)++];
04611       if (line[1] == '=') {
04612          type = line[0];
04613          *value = ast_skip_blanks(line + 2);
04614          break;
04615       }
04616    }
04617 
04618    return type;
04619 }

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

References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, DEADLOCK_AVOIDANCE, sip_pvt::flags, iflist, iflock, sip_pvt::lock, LOG_DEBUG, match(), sip_pvt::next, option_debug, sip_pvt::owner, SIP_PAGE2_OUTGOING_CALL, sip_pvt::tag, and sip_pvt::theirtag.

Referenced by handle_request_invite(), and local_attended_transfer().

10270 {
10271    struct sip_pvt *sip_pvt_ptr;
10272 
10273    ast_mutex_lock(&iflock);
10274 
10275    if (option_debug > 3 && totag) {
10276       ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
10277    }
10278 
10279    /* Search interfaces and find the match */
10280    for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
10281       if (!strcmp(sip_pvt_ptr->callid, callid)) {
10282          int match = 1;
10283 
10284          if (option_debug > 3)
10285             ast_log(LOG_DEBUG, "Found call with callid %s (ourtag=%s, theirtag=%s)\n", callid, sip_pvt_ptr->tag, sip_pvt_ptr->theirtag);
10286 
10287          /* Go ahead and lock it (and its owner) before returning */
10288          ast_mutex_lock(&sip_pvt_ptr->lock);
10289 
10290          /* Check if tags match. If not, this is not the call we want
10291           * (With a forking SIP proxy, several call legs share the
10292           * call id, but have different tags)
10293           */
10294          if (pedanticsipchecking) {
10295             /* RFC 3891
10296              * > 3.  User Agent Server Behavior: Receiving a Replaces Header
10297              * > The Replaces header contains information used to match an existing
10298              * > SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE
10299              * > with a Replaces header, the User Agent (UA) attempts to match this
10300              * > information with a confirmed or early dialog.  The User Agent Server
10301              * > (UAS) matches the to-tag and from-tag parameters as if they were tags
10302              * > present in an incoming request.  In other words, the to-tag parameter
10303              * > is compared to the local tag, and the from-tag parameter is compared
10304              * > to the remote tag.
10305              *
10306              * Thus, the totag is always compared to the local tag, regardless if
10307              * this our call is an incoming or outgoing call.
10308              */
10309             if (ast_strlen_zero(fromtag) || strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, sip_pvt_ptr->tag)))
10310                match = 0;
10311          }
10312 
10313          if (!match) {
10314             ast_mutex_unlock(&sip_pvt_ptr->lock);
10315             continue;
10316          }
10317 
10318          if (option_debug > 3 && totag)             
10319             ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
10320                ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING",
10321                sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
10322 
10323          /* deadlock avoidance... */
10324          while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
10325             DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock);
10326          }
10327          break;
10328       }
10329    }
10330    ast_mutex_unlock(&iflock);
10331    if (option_debug > 3 && !sip_pvt_ptr)
10332       ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
10333    return sip_pvt_ptr;
10334 }

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

References ast_copy_string(), and get_header().

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

14837 {
14838    const char *thetag;
14839 
14840    if (!tagbuf)
14841       return NULL;
14842    tagbuf[0] = '\0';    /* reset the buffer */
14843    thetag = get_header(req, header);
14844    thetag = strcasestr(thetag, ";tag=");
14845    if (thetag) {
14846       thetag += 5;
14847       ast_copy_string(tagbuf, thetag, tagbufsize);
14848       return strsep(&tagbuf, ";");
14849    }
14850    return NULL;
14851 }

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

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

Referenced by build_peer(), and build_user().

18228 {
18229    int res = 1;
18230 
18231    if (!strcasecmp(v->name, "trustrpid")) {
18232       ast_set_flag(&mask[0], SIP_TRUSTRPID);
18233       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
18234    } else if (!strcasecmp(v->name, "sendrpid")) {
18235       ast_set_flag(&mask[0], SIP_SENDRPID);
18236       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
18237    } else if (!strcasecmp(v->name, "g726nonstandard")) {
18238       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
18239       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
18240    } else if (!strcasecmp(v->name, "useclientcode")) {
18241       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
18242       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
18243    } else if (!strcasecmp(v->name, "dtmfmode")) {
18244       ast_set_flag(&mask[0], SIP_DTMF);
18245       ast_clear_flag(&flags[0], SIP_DTMF);
18246       if (!strcasecmp(v->value, "inband"))
18247          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
18248       else if (!strcasecmp(v->value, "rfc2833"))
18249          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
18250       else if (!strcasecmp(v->value, "info"))
18251          ast_set_flag(&flags[0], SIP_DTMF_INFO);
18252       else if (!strcasecmp(v->value, "auto"))
18253          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
18254       else {
18255          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
18256          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
18257       }
18258    } else if (!strcasecmp(v->name, "nat")) {
18259       ast_set_flag(&mask[0], SIP_NAT);
18260       ast_clear_flag(&flags[0], SIP_NAT);
18261       if (!strcasecmp(v->value, "never"))
18262          ast_set_flag(&flags[0], SIP_NAT_NEVER);
18263       else if (!strcasecmp(v->value, "route"))
18264          ast_set_flag(&flags[0], SIP_NAT_ROUTE);
18265       else if (ast_true(v->value))
18266          ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
18267       else
18268          ast_set_flag(&flags[0], SIP_NAT_RFC3581);
18269    } else if (!strcasecmp(v->name, "canreinvite")) {
18270       ast_set_flag(&mask[0], SIP_REINVITE);
18271       ast_clear_flag(&flags[0], SIP_REINVITE);
18272       if(ast_true(v->value)) {
18273          ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
18274       } else if (!ast_false(v->value)) {
18275          char buf[64];
18276          char *word, *next = buf;
18277 
18278          ast_copy_string(buf, v->value, sizeof(buf));
18279          while ((word = strsep(&next, ","))) {
18280             if(!strcasecmp(word, "update")) {
18281                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
18282             } else if(!strcasecmp(word, "nonat")) {
18283                ast_set_flag(&flags[0], SIP_CAN_REINVITE);
18284                ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
18285             } else {
18286                ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
18287             }
18288          }
18289       }
18290    } else if (!strcasecmp(v->name, "insecure")) {
18291       ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
18292       ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
18293       set_insecure_flags(flags, v->value, v->lineno);
18294    } else if (!strcasecmp(v->name, "progressinband")) {
18295       ast_set_flag(&mask[0], SIP_PROG_INBAND);
18296       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
18297       if (ast_true(v->value))
18298          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
18299       else if (strcasecmp(v->value, "never"))
18300          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
18301    } else if (!strcasecmp(v->name, "promiscredir")) {
18302       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
18303       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
18304    } else if (!strcasecmp(v->name, "videosupport")) {
18305       ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
18306       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
18307    } else if (!strcasecmp(v->name, "allowoverlap")) {
18308       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
18309       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
18310    } else if (!strcasecmp(v->name, "allowsubscribe")) {
18311       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
18312       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
18313    } else if (!strcasecmp(v->name, "t38pt_udptl")) {
18314       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
18315       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
18316 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
18317    } else if (!strcasecmp(v->name, "t38pt_rtp")) {
18318       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
18319       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
18320    } else if (!strcasecmp(v->name, "t38pt_tcp")) {
18321       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
18322       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
18323 #endif
18324    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
18325       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
18326       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
18327    } else if (!strcasecmp(v->name, "buggymwi")) {
18328       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
18329       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
18330    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
18331       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
18332       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
18333    } else if (!strcasecmp(v->name, "forwardloopdetected")) {
18334       ast_set_flag(&mask[1], SIP_PAGE2_FORWARD_LOOP_DETECTED);
18335       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_FORWARD_LOOP_DETECTED);
18336    } else
18337       res = 0;
18338 
18339    return res;
18340 }

static int handle_invite_replaces ( struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore,
int  seqno,
struct sockaddr_in *  sin,
int *  nounlock 
) [static]

Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer.

Note:
this function is called by handle_request_invite(). Four locks held at the beginning of this function, p, p->owner, p->refer->refer_call->owner... only p's lock should remain at the end of this function. p's lock is held by sipsock_read()

Definition at line 15026 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_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_quiet_chan(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, ast_channel::name, 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().

15027 {
15028    int earlyreplace = 0;
15029    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
15030    struct ast_channel *c = p->owner;   /* Our incoming call */
15031    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
15032    struct ast_channel *targetcall;     /* The bridge to the take-over target */
15033 
15034    /* Check if we're in ring state */
15035    if (replacecall->_state == AST_STATE_RING)
15036       earlyreplace = 1;
15037 
15038    /* Check if we have a bridge */
15039    if (!(targetcall = ast_bridged_channel(replacecall))) {
15040       /* We have no bridge */
15041       if (!earlyreplace) {
15042          if (option_debug > 1)
15043             ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
15044          oneleggedreplace = 1;
15045       }
15046    } 
15047    if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING)
15048          ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n");
15049 
15050    if (option_debug > 3) {
15051       if (targetcall) 
15052          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); 
15053       else
15054          ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 
15055    }
15056 
15057    if (ignore) {
15058       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
15059       /* We should answer something here. If we are here, the
15060          call we are replacing exists, so an accepted 
15061          can't harm */
15062       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
15063       /* Do something more clever here */
15064       if (c) {
15065          *nounlock = 1;
15066          ast_channel_unlock(c);
15067       }
15068       ast_channel_unlock(replacecall);
15069       ast_mutex_unlock(&p->refer->refer_call->lock);
15070       return 1;
15071    } 
15072    if (!c) {
15073       /* What to do if no channel ??? */
15074       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
15075       transmit_response_reliable(p, "503 Service Unavailable", req);
15076       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
15077       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15078       ast_channel_unlock(replacecall);
15079       ast_mutex_unlock(&p->refer->refer_call->lock);
15080       return 1;
15081    }
15082    append_history(p, "Xfer", "INVITE/Replace received");
15083    /* We have three channels to play with
15084       channel c: New incoming call
15085       targetcall: Call from PBX to target
15086       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
15087       replacecall: The owner of the previous
15088       We need to masq C into refer_call to connect to 
15089       targetcall;
15090       If we are talking to internal audio stream, target call is null.
15091    */
15092 
15093    /* Fake call progress */
15094    transmit_response(p, "100 Trying", req);
15095    ast_setstate(c, AST_STATE_RING);
15096 
15097    /* Masquerade the new call into the referred call to connect to target call 
15098       Targetcall is not touched by the masq */
15099 
15100    /* Answer the incoming call and set channel to UP state */
15101    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
15102       
15103    ast_setstate(c, AST_STATE_UP);
15104    
15105    /* Stop music on hold and other generators */
15106    ast_quiet_chan(replacecall);
15107    ast_quiet_chan(targetcall);
15108    if (option_debug > 3)
15109       ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
15110 
15111    /* Make sure that the masq does not free our PVT for the old call */
15112    if (! earlyreplace && ! oneleggedreplace )
15113       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
15114       
15115    /* Prepare the masquerade - if this does not happen, we will be gone */
15116    if(ast_channel_masquerade(replacecall, c))
15117       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
15118    else if (option_debug > 3)
15119       ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
15120 
15121    /* C should now be in place of replacecall */
15122    if (ast_do_masquerade(replacecall)) {
15123       ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n");
15124    }
15125 
15126    if (earlyreplace || oneleggedreplace ) {
15127       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
15128    }
15129 
15130    ast_setstate(c, AST_STATE_DOWN);
15131    if (option_debug > 3) {
15132       struct ast_channel *test;
15133       ast_log(LOG_DEBUG, "After transfer:----------------------------\n");
15134       ast_log(LOG_DEBUG, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
15135       if (replacecall)
15136          ast_log(LOG_DEBUG, " -- replacecall:        %s State %s\n", replacecall->name, ast_state2str(replacecall->_state));
15137       if (p->owner) {
15138          ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state));
15139          test = ast_bridged_channel(p->owner);
15140          if (test)
15141             ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state));
15142          else
15143             ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n");
15144       } else 
15145          ast_log(LOG_DEBUG, " -- No channel yet \n");
15146       ast_log(LOG_DEBUG, "End After transfer:----------------------------\n");
15147    }
15148 
15149    /* unlock sip pvt and owner so hangup can do its thing */
15150    ast_channel_unlock(replacecall);
15151    ast_channel_unlock(c);
15152    ast_mutex_unlock(&p->refer->refer_call->lock);
15153    ast_mutex_unlock(&p->lock);
15154    *nounlock = 1;
15155 
15156    /* The call should be down with no ast_channel, so hang it up */
15157    c->tech_pvt = NULL;
15158    ast_hangup(c);
15159 
15160    ast_mutex_lock(&p->lock); /* lock PVT structure again after hangup */
15161 
15162    return 0;
15163 }

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.

called with p and p->owner locked

Definition at line 17118 of file chan_sip.c.

References __get_header(), __sip_ack(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_request::method, sip_pvt::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_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_peer::useragent.

17119 {
17120    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
17121       relatively static */
17122    const char *cmd;
17123    const char *cseq;
17124    const char *useragent;
17125    const char *via;
17126    const char *callid;
17127    int via_pos = 0;
17128    int seqno;
17129    int len;
17130    int ignore = FALSE;
17131    int respid;
17132    int res = 0;
17133    int debug = sip_debug_test_pvt(p);
17134    char *e;
17135    int error = 0;
17136    int oldmethod = p->method;
17137    int acked = 0;
17138 
17139    /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via.
17140     * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request,
17141     * so we can check to make sure these fields exist for all requests and responses */
17142    cseq = get_header(req, "Cseq");
17143    cmd = req->header[0];
17144    /* Save the via_pos so we can check later that responses only have 1 Via header */
17145    via = __get_header(req, "Via", &via_pos);
17146    /* This must exist already because we've called find_call by now */
17147    callid = get_header(req, "Call-ID");
17148 
17149    /* Must have Cseq */
17150    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) {
17151       ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid);
17152       error = 1;
17153    }
17154    if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) {
17155       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
17156       error = 1;
17157    }
17158    if (error) {
17159       if (!p->initreq.headers)   /* New call */
17160          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
17161       return -1;
17162    }
17163    /* Get the command XXX */
17164 
17165    cmd = req->rlPart1;
17166    e = ast_skip_blanks(req->rlPart2);
17167 
17168    /* Save useragent of the client */
17169    useragent = get_header(req, "User-Agent");
17170    if (!ast_strlen_zero(useragent))
17171       ast_string_field_set(p, useragent, useragent);
17172 
17173    /* Find out SIP method for incoming request */
17174    if (req->method == SIP_RESPONSE) {  /* Response to our request */
17175       /* Response to our request -- Do some sanity checks */   
17176       if (ast_strlen_zero(e)) {
17177          return 0;
17178       }
17179       if (sscanf(e, "%30d %n", &respid, &len) != 1) {
17180          ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
17181          return 0;
17182       }
17183       if (respid <= 0) {
17184          ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
17185          return 0;
17186       }
17187       /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse
17188        * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple
17189        * headers joined with a comma. Fixing that would pretty much involve writing a new parser */
17190       if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) {
17191          ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid);
17192          return 0;
17193       }
17194       if (!p->initreq.headers) {
17195          if (option_debug)
17196             ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we don't know about. Cseq %d Cmd %s\n", seqno, cmd);
17197          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
17198          return 0;
17199       }
17200       if (p->ocseq && (p->ocseq < seqno)) {
17201          if (option_debug)
17202             ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
17203          return -1;
17204       } else {
17205          if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
17206             extract_uri(p, req);
17207          }
17208          handle_response(p, respid, e + len, req, seqno);
17209       }
17210       return 0;
17211    }
17212 
17213    /* New SIP request coming in 
17214       (could be new request in existing SIP dialog as well...) 
17215     */         
17216    
17217    p->method = req->method;   /* Find out which SIP method they are using */
17218    if (option_debug > 3)
17219       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
17220 
17221    if (p->icseq && (p->icseq > seqno) ) {
17222       if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
17223          if (option_debug > 2)
17224             ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n");
17225       }  else {
17226          if (option_debug)
17227             ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
17228          if (req->method != SIP_ACK)
17229             transmit_response(p, "500 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
17230          return -1;
17231       }
17232    } else if (p->icseq &&
17233          p->icseq == seqno &&
17234          req->method != SIP_ACK &&
17235          (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) {
17236       /* ignore means "don't do anything with it" but still have to 
17237          respond appropriately.  We do this if we receive a repeat of
17238          the last sequence number  */
17239       ignore = 2;
17240       ast_set_flag(req, SIP_PKT_IGNORE);
17241       ast_set_flag(req, SIP_PKT_IGNORE_REQ);
17242       if (option_debug > 2)
17243          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
17244    }
17245       
17246    if (seqno >= p->icseq)
17247       /* Next should follow monotonically (but not necessarily 
17248          incrementally -- thanks again to the genius authors of SIP --
17249          increasing */
17250       p->icseq = seqno;
17251 
17252    /* Find their tag if we haven't got it */
17253    if (ast_strlen_zero(p->theirtag)) {
17254       char tag[128];
17255 
17256       gettag(req, "From", tag, sizeof(tag));
17257       ast_string_field_set(p, theirtag, tag);
17258    }
17259    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
17260 
17261    if (pedanticsipchecking) {
17262       /* If this is a request packet without a from tag, it's not
17263          correct according to RFC 3261  */
17264       /* Check if this a new request in a new dialog with a totag already attached to it,
17265          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
17266       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
17267          /* If this is a first request and it got a to-tag, it is not for us */
17268          if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) {
17269             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
17270             /* Will cease to exist after ACK */
17271          } else if (req->method != SIP_ACK) {
17272             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
17273             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17274          }
17275          return res;
17276       }
17277    }
17278 
17279    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
17280       transmit_response(p, "400 Bad request", req);
17281       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17282       return -1;
17283    }
17284 
17285    /* Handle various incoming SIP methods in requests */
17286    switch (p->method) {
17287    case SIP_OPTIONS:
17288       res = handle_request_options(p, req);
17289       break;
17290    case SIP_INVITE:
17291       res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock);
17292       break;
17293    case SIP_REFER:
17294       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
17295       break;
17296    case SIP_CANCEL:
17297       res = handle_request_cancel(p, req);
17298       break;
17299    case SIP_BYE:
17300       res = handle_request_bye(p, req);
17301       break;
17302    case SIP_MESSAGE:
17303       res = handle_request_message(p, req);
17304       break;
17305    case SIP_SUBSCRIBE:
17306       res = handle_request_subscribe(p, req, sin, seqno, e);
17307       break;
17308    case SIP_REGISTER:
17309       res = handle_request_register(p, req, sin, e);
17310       break;
17311    case SIP_INFO:
17312       if (ast_test_flag(req, SIP_PKT_DEBUG))
17313          ast_verbose("Receiving INFO!\n");
17314       if (!ignore) 
17315          handle_request_info(p, req);
17316       else  /* if ignoring, transmit response */
17317          transmit_response(p, "200 OK", req);
17318       break;
17319    case SIP_NOTIFY:
17320       res = handle_request_notify(p, req, sin, seqno, e);
17321       break;
17322    case SIP_ACK:
17323       /* Make sure we don't ignore this */
17324       if (seqno == p->pendinginvite) {
17325          p->invitestate = INV_TERMINATED;
17326          p->pendinginvite = 0;
17327          acked = __sip_ack(p, seqno, FLAG_RESPONSE, 0);
17328          if (find_sdp(req)) {
17329             if (process_sdp(p, req))
17330                return -1;
17331          }
17332          check_pendings(p);
17333       } else if (p->glareinvite == seqno) {
17334          /* handle ack for the 491 pending send for glareinvite */
17335          p->glareinvite = 0;
17336          acked = __sip_ack(p, seqno, 1, 0);
17337       }
17338       if (!acked) {
17339          /* Got an ACK that did not match anything. Ignore
17340           * silently and restore previous method */
17341          p->method = oldmethod;
17342       }
17343       /* Got an ACK that we did not match. Ignore silently */
17344       if (!p->lastinvite && ast_strlen_zero(p->randdata))
17345          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
17346       break;
17347    default:
17348       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
17349       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
17350          cmd, ast_inet_ntoa(p->sa.sin_addr));
17351       /* If this is some new method, and we don't have a call, destroy it now */
17352       if (!p->initreq.headers)
17353          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
17354       break;
17355    }
17356    return res;
17357 }

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

Handle incoming BYE request.

Definition at line 16643 of file chan_sip.c.

References __sip_pretend_ack(), append_history, ast_async_goto(), ast_bridged_channel(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), ast_channel::context, context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, LOG_DEBUG, LOG_NOTICE, option_debug, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), and transmit_response_reliable().

Referenced by handle_request().

16644 {
16645    struct ast_channel *c=NULL;
16646    int res;
16647    struct ast_channel *bridged_to;
16648    
16649    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
16650    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE)) 
16651       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
16652 
16653    __sip_pretend_ack(p);
16654 
16655    p->invitestate = INV_TERMINATED;
16656 
16657    copy_request(&p->initreq, req);
16658    check_via(p, req);
16659    sip_alreadygone(p);
16660 
16661    /* Get RTCP quality before end of call */
16662    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
16663       char *audioqos, *videoqos;
16664       if (p->rtp) {
16665          audioqos = ast_rtp_get_quality(p->rtp, NULL);
16666          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
16667             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
16668          if (p->owner)
16669             pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
16670       }
16671       if (p->vrtp) {
16672          videoqos = ast_rtp_get_quality(p->vrtp, NULL);
16673          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
16674             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
16675          if (p->owner)
16676             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
16677       }
16678    }
16679 
16680    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
16681 
16682    if (!ast_strlen_zero(get_header(req, "Also"))) {
16683       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
16684          ast_inet_ntoa(p->recv.sin_addr));
16685       if (ast_strlen_zero(p->context))
16686          ast_string_field_set(p, context, default_context);
16687       res = get_also_info(p, req);
16688       if (!res) {
16689          c = p->owner;
16690          if (c) {
16691             bridged_to = ast_bridged_channel(c);
16692             if (bridged_to) {
16693                /* Don't actually hangup here... */
16694                ast_queue_control(c, AST_CONTROL_UNHOLD);
16695                ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
16696             } else
16697                ast_queue_hangup(p->owner);
16698          }
16699       } else {
16700          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
16701          if (p->owner)
16702             ast_queue_hangup(p->owner);
16703       }
16704    } else if (p->owner) {
16705       ast_queue_hangup(p->owner);
16706       if (option_debug > 2)
16707          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
16708    } else {
16709       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16710       if (option_debug > 2)
16711          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
16712    }
16713    ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
16714    transmit_response(p, "200 OK", req);
16715 
16716    return 1;
16717 }

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

Handle incoming CANCEL request.

Definition at line 16513 of file chan_sip.c.

References __sip_pretend_ack(), ast_free, ast_log(), ast_queue_hangup(), AST_SCHED_DEL, AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, sip_pkt::next, option_debug, sip_dual::req, sip_pkt::response_code, sip_pkt::retransid, sched, sip_pkt::seqno, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().

Referenced by handle_request().

16514 {
16515       
16516    check_via(p, req);
16517    sip_alreadygone(p);
16518 
16519    /* At this point, we could have cancelled the invite at the same time
16520       as the other side sends a CANCEL. Our final reply with error code
16521       might not have been received by the other side before the CANCEL
16522       was sent, so let's just give up retransmissions and waiting for
16523       ACK on our error code. The call is hanging up any way. */
16524    if (p->invitestate == INV_TERMINATED)
16525       __sip_pretend_ack(p);
16526    else
16527       p->invitestate = INV_CANCELLED;
16528    
16529    if (p->owner && p->owner->_state == AST_STATE_UP) {
16530       /* This call is up, cancel is ignored, we need a bye */
16531       transmit_response(p, "200 OK", req);
16532       if (option_debug)
16533          ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
16534       return 0;
16535    }
16536 
16537    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 
16538       update_call_counter(p, DEC_CALL_LIMIT);
16539 
16540    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
16541    if (p->owner)
16542       ast_queue_hangup(p->owner);
16543    else
16544       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16545    if (p->initreq.len > 0) {
16546       struct sip_pkt *pkt, *prev_pkt;
16547       /* If the CANCEL we are receiving is a retransmission, and we already have scheduled
16548        * a reliable 487, then we don't want to schedule another one on top of the previous
16549        * one.
16550        *
16551        * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 
16552        * response in this situation. What if we've sent all of our reliable responses 
16553        * already and now all of a sudden, we get this second CANCEL?
16554        *
16555        * The only way to do this correctly is to cancel our previously-scheduled reliably-
16556        * transmitted response and send a new one in its place.
16557        */
16558       for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) {
16559          if (pkt->seqno == p->lastinvite && pkt->response_code == 487) {
16560             AST_SCHED_DEL(sched, pkt->retransid);
16561             UNLINK(pkt, p->packets, prev_pkt);
16562             ast_free(pkt);
16563             break;
16564          }
16565       }
16566       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
16567       transmit_response(p, "200 OK", req);
16568       return 1;
16569    } else {
16570       transmit_response(p, "481 Call Leg Does Not Exist", req);
16571       return 0;
16572    }
16573 }

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

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

Referenced by handle_request().

12541 {
12542    char buf[1024];
12543    unsigned int event;
12544    const char *c = get_header(req, "Content-Type");
12545 
12546    /* Need to check the media/type */
12547    if (!strcasecmp(c, "application/dtmf-relay") ||
12548          !strcasecmp(c, "application/DTMF") ||
12549        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
12550       unsigned int duration = 0;
12551 
12552       /* Try getting the "signal=" part */
12553       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
12554          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
12555          transmit_response(p, "200 OK", req); /* Should return error */
12556          return;
12557       } else {
12558          ast_copy_string(buf, c, sizeof(buf));
12559       }
12560 
12561       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
12562          duration = atoi(c);
12563       if (!duration)
12564          duration = 100; /* 100 ms */
12565 
12566       if (!p->owner) {  /* not a PBX call */
12567          transmit_response(p, "481 Call leg/transaction does not exist", req);
12568          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12569          return;
12570       }
12571 
12572       if (ast_strlen_zero(buf)) {
12573          transmit_response(p, "200 OK", req);
12574          return;
12575       }
12576 
12577       if (buf[0] == '*')
12578          event = 10;
12579       else if (buf[0] == '#')
12580          event = 11;
12581       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
12582          event = 12 + buf[0] - 'A';
12583       else
12584          event = atoi(buf);
12585       if (event == 16) {
12586          /* send a FLASH event */
12587          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
12588          ast_queue_frame(p->owner, &f);
12589          if (sipdebug)
12590             ast_verbose("* DTMF-relay event received: FLASH\n");
12591       } else {
12592          /* send a DTMF event */
12593          struct ast_frame f = { AST_FRAME_DTMF, };
12594          if (event < 10) {
12595             f.subclass = '0' + event;
12596          } else if (event < 11) {
12597             f.subclass = '*';
12598          } else if (event < 12) {
12599             f.subclass = '#';
12600          } else if (event < 16) {
12601             f.subclass = 'A' + (event - 12);
12602          }
12603          f.len = duration;
12604          ast_queue_frame(p->owner, &f);
12605          if (sipdebug)
12606             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
12607       }
12608       transmit_response(p, "200 OK", req);
12609       return;
12610    } else if (!strcasecmp(c, "application/media_control+xml")) {
12611       /* Eh, we'll just assume it's a fast picture update for now */
12612       if (p->owner)
12613          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
12614       transmit_response(p, "200 OK", req);
12615       return;
12616    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
12617       /* Client code (from SNOM phone) */
12618       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
12619          if (p->owner && p->owner->cdr)
12620             ast_cdr_setuserfield(p->owner, c);
12621          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
12622             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
12623          transmit_response(p, "200 OK", req);
12624       } else {
12625          transmit_response(p, "403 Unauthorized", req);
12626       }
12627       return;
12628    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
12629       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
12630       transmit_response(p, "200 OK", req);
12631       return;
12632    }
12633 
12634    /* Other type of INFO message, not really understood by Asterisk */
12635    /* if (get_msg_text(buf, sizeof(buf), req)) { */
12636 
12637    /* Nothing in the header is interesting, now check if content-length is 0 */ 
12638    if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 
12639       transmit_response(p, "200 OK", req); 
12640       return; 
12641    } /* else ... there issomething in the message body, do something with it if you need to */ 
12642 
12643    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
12644    transmit_response(p, "415 Unsupported media type", req);
12645    return;
12646 }

static int handle_request_invite ( struct sip_pvt p,
struct sip_request req,
int  debug,
int  seqno,
struct sockaddr_in *  sin,
int *  recount,
char *  e,
int *  nounlock 
) [static]

Handle incoming INVITE request.

Note:
If the INVITE has a Replaces header, it is part of an attended transfer. If so, we do not go through the dial plan but tries to find the active call and masquerade into it

XXX: we should also check here does the other side supports t38 at all !!! XXX

Definition at line 15442 of file chan_sip.c.

References __sip_ack(), 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_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_set_alt_peer(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_setstate(), ast_skip_blanks(), 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(), ast_channel::call_forward, sip_pvt::callid, sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, sip_pvt::context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, exten, sip_pvt::exten, extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rdnis(), get_sip_pvt_byid_locked(), sip_pvt::glareinvite, handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_CONFIRMED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), ast_channel::name, option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::peername, sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_request::rlPart2, sip_pvt::rtp, S_OR, SDP_AUDIO, SDP_VIDEO, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sip_uri_cmp(), sipdebug, sip_pvt::sipoptions, t38properties::state, 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_provisional_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(), sip_pvt::username, sip_pvt::vrtp, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.

Referenced by handle_request().

15443 {
15444    int res = 1;
15445    int gotdest;
15446    const char *p_replaces;
15447    char *replace_id = NULL;
15448    int refer_locked = 0;
15449    const char *required;
15450    unsigned int required_profile = 0;
15451    struct ast_channel *c = NULL;    /* New channel */
15452    int reinvite = 0;
15453 
15454    /* Find out what they support */
15455    if (!p->sipoptions) {
15456       const char *supported = get_header(req, "Supported");
15457       if (!ast_strlen_zero(supported))
15458          parse_sip_options(p, supported);
15459    }
15460 
15461    /* Find out what they require */
15462    required = get_header(req, "Require");
15463    if (!ast_strlen_zero(required)) {
15464       required_profile = parse_sip_options(NULL, required);
15465       if (required_profile && !(required_profile & SIP_OPT_REPLACES)) {
15466          /* At this point we only support REPLACES */
15467          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required);
15468          ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required);
15469          p->invitestate = INV_COMPLETED;
15470          if (!p->lastinvite)
15471             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15472          res = -1;
15473          goto request_invite_cleanup;
15474       }
15475    }
15476 
15477    /* Check if this is a loop */
15478    if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED)) {
15479       /* This is a call to ourself.  Send ourselves an error code and stop
15480          processing immediately, as SIP really has no good mechanism for
15481          being able to call yourself */
15482       /* If pedantic is on, we need to check the tags. If they're different, this is
15483          in fact a forked call through a SIP proxy somewhere. */
15484       int different;
15485       if (pedanticsipchecking)
15486          different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2);
15487       else
15488          different = strcmp(p->initreq.rlPart2, req->rlPart2);
15489       if (!different) {
15490          transmit_response(p, "482 Loop Detected", req);
15491          p->invitestate = INV_COMPLETED;
15492          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15493          res = 0;
15494          goto request_invite_cleanup;
15495       } else {
15496          /* This is a spiral. What we need to do is to just change the outgoing INVITE
15497           * so that it now routes to the new Request URI. Since we created the INVITE ourselves
15498           * that should be all we need to do.
15499           */
15500          char *uri = ast_strdupa(req->rlPart2);
15501          char *at = strchr(uri, '@');
15502          char *peerorhost;
15503          if (option_debug > 2) {
15504             ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2);
15505          }
15506          transmit_response(p, "100 Trying", req);
15507          if (at) {
15508             *at = '\0';
15509          }
15510          /* Parse out "sip:" */
15511          if ((peerorhost = strchr(uri, ':'))) {
15512             *peerorhost++ = '\0';
15513          }
15514          ast_string_field_free(p, theirtag);
15515          /* Treat this as if there were a call forward instead...
15516           */
15517          ast_string_field_set(p->owner, call_forward, peerorhost);
15518          ast_queue_control(p->owner, AST_CONTROL_BUSY);
15519          res = 0;
15520          goto request_invite_cleanup;
15521       }
15522    }
15523    
15524    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) {
15525       if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) {
15526          /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we
15527           * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero).
15528           * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set.
15529           * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with
15530           * credentials based on one we challenged earlier.
15531           *
15532           * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous
15533           * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response
15534           * from the previous transaction from the list of outstanding packets.
15535           */
15536          __sip_ack(p, p->pendinginvite, FLAG_RESPONSE, 0);
15537       } else {
15538          /* We already have a pending invite. Sorry. You are on hold. */
15539          p->glareinvite = seqno;
15540          if (p->rtp && find_sdp(req)) {
15541             struct sockaddr_in sin;
15542             if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &sin)) {
15543                ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n");
15544             } else {
15545                ast_rtp_set_alt_peer(p->rtp, &sin);
15546             }
15547             if (p->vrtp) {
15548                if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &sin)) {
15549                   ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n");
15550                } else {
15551                   ast_rtp_set_alt_peer(p->vrtp, &sin);
15552                }
15553             }
15554          }
15555          transmit_response_reliable(p, "491 Request Pending", req);
15556          if (option_debug)
15557             ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
15558          /* Don't destroy dialog here */
15559          res = 0;
15560          goto request_invite_cleanup;
15561       }
15562    }
15563 
15564    p_replaces = get_header(req, "Replaces");
15565    if (!ast_strlen_zero(p_replaces)) {
15566       /* We have a replaces header */
15567       char *ptr;
15568       char *fromtag = NULL;
15569       char *totag = NULL;
15570       char *start, *to;
15571       int error = 0;
15572 
15573       if (p->owner) {
15574          if (option_debug > 2)
15575             ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
15576          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
15577          /* Do not destroy existing call */
15578          res = -1;
15579          goto request_invite_cleanup;
15580       }
15581 
15582       if (sipdebug && option_debug > 2)
15583          ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
15584       /* Create a buffer we can manipulate */
15585       replace_id = ast_strdupa(p_replaces);
15586       ast_uri_decode(replace_id);
15587 
15588       if (!p->refer && !sip_refer_allocate(p)) {
15589          transmit_response_reliable(p, "500 Server Internal Error", req);
15590          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
15591          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15592          p->invitestate = INV_COMPLETED;
15593          res = -1;
15594          goto request_invite_cleanup;
15595       }
15596 
15597       /*  Todo: (When we find phones that support this)
15598          if the replaces header contains ";early-only"
15599          we can only replace the call in early
15600          stage, not after it's up.
15601 
15602          If it's not in early mode, 486 Busy.
15603       */
15604       
15605       /* Skip leading whitespace */
15606       replace_id = ast_skip_blanks(replace_id);
15607 
15608       start = replace_id;
15609       while ( (ptr = strsep(&start, ";")) ) {
15610          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
15611          if ( (to = strcasestr(ptr, "to-tag=") ) )
15612             totag = to + 7;   /* skip the keyword */
15613          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
15614             fromtag = to + 9; /* skip the keyword */
15615             fromtag = strsep(&fromtag, "&"); /* trim what ? */
15616          }
15617       }
15618 
15619       if (sipdebug && option_debug > 3) 
15620          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>");
15621 
15622 
15623       /* Try to find call that we are replacing 
15624          If we have a Replaces  header, we need to cancel that call if we succeed with this call 
15625       */
15626       if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
15627          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
15628          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
15629          error = 1;
15630       } else {
15631          refer_locked = 1;
15632       }
15633 
15634       /* At this point, bot the pvt and the owner of the call to be replaced is locked */
15635 
15636       /* The matched call is the call from the transferer to Asterisk .
15637          We want to bridge the bridged part of the call to the 
15638          incoming invite, thus taking over the refered call */
15639 
15640       if (p->refer->refer_call == p) {
15641          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
15642          p->refer->refer_call = NULL;
15643          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
15644          error = 1;
15645       }
15646 
15647       if (!error && !p->refer->refer_call->owner) {
15648          /* Oops, someting wrong anyway, no owner, no call */
15649          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
15650          /* Check for better return code */
15651          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req);
15652          error = 1;
15653       }
15654 
15655       if (!error && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP ) {
15656          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
15657          transmit_response_reliable(p, "603 Declined (Replaces)", req);
15658          error = 1;
15659       }
15660 
15661       if (error) {   /* Give up this dialog */
15662          append_history(p, "Xfer", "INVITE/Replace Failed.");
15663          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15664          ast_mutex_unlock(&p->lock);
15665          if (p->refer->refer_call) {
15666             ast_mutex_unlock(&p->refer->refer_call->lock);
15667             if (p->refer->refer_call->owner) {
15668                ast_channel_unlock(p->refer->refer_call->owner);
15669             }
15670          }
15671          refer_locked = 0;
15672          p->invitestate = INV_COMPLETED;
15673          res = -1;
15674          goto request_invite_cleanup;
15675       }
15676    }
15677 
15678 
15679    /* Check if this is an INVITE that sets up a new dialog or
15680       a re-invite in an existing dialog */
15681 
15682    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
15683       int newcall = (p->initreq.headers ? TRUE : FALSE);
15684 
15685       if (sip_cancel_destroy(p))
15686          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
15687       /* This also counts as a pending invite */
15688       p->pendinginvite = seqno;
15689       check_via(p, req);
15690 
15691       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
15692       if (!p->owner) {  /* Not a re-invite */
15693          if (debug)
15694             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
15695          if (newcall)
15696             append_history(p, "Invite", "New call: %s", p->callid);
15697          parse_ok_contact(p, req);
15698       } else { /* Re-invite on existing call */
15699          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
15700          /* Handle SDP here if we already have an owner */
15701          if (find_sdp(req)) {
15702             if (process_sdp(p, req)) {
15703                transmit_response_reliable(p, "488 Not acceptable here", req);
15704                if (!p->lastinvite)
15705                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15706                res = -1;
15707                goto request_invite_cleanup;
15708             }
15709             ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE);
15710          } else {
15711             p->jointcapability = p->capability;
15712             if (option_debug > 2)
15713                ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
15714             /* Some devices signal they want to be put off hold by sending a re-invite
15715                *without* an SDP, which is supposed to mean "Go back to your state"
15716                and since they put os on remote hold, we go back to off hold */
15717             if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
15718                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
15719                /* Activate a re-invite */
15720                ast_queue_frame(p->owner, &ast_null_frame);
15721                change_hold_state(p, req, FALSE, 0);
15722             }
15723          }
15724          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */
15725             append_history(p, "ReInv", "Re-invite received");
15726       }
15727    } else if (debug)
15728       ast_verbose("Ignoring this INVITE request\n");
15729 
15730    
15731    if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) {
15732       /* This is a new invite */
15733       /* Handle authentication if this is our first invite */
15734       res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
15735       if (res == AUTH_CHALLENGE_SENT) {
15736          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
15737          res = 0;
15738          goto request_invite_cleanup;
15739       }
15740       if (res < 0) { /* Something failed in authentication */
15741          if (res == AUTH_FAKE_AUTH) {
15742             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
15743             transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
15744          } else {
15745             ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
15746             transmit_response_reliable(p, "403 Forbidden", req);
15747          }
15748          p->invitestate = INV_COMPLETED;  
15749          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15750          ast_string_field_free(p, theirtag);
15751          res = 0;
15752          goto request_invite_cleanup;
15753 
15754       }
15755 
15756       /* We have a succesful authentication, process the SDP portion if there is one */
15757       if (find_sdp(req)) {
15758          if (process_sdp(p, req)) {
15759             /* Unacceptable codecs */
15760             transmit_response_reliable(p, "488 Not acceptable here", req);
15761             p->invitestate = INV_COMPLETED;  
15762             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15763             if (option_debug)
15764                ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n");
15765             res = -1;
15766             goto request_invite_cleanup;
15767          }
15768       } else { /* No SDP in invite, call control session */
15769          p->jointcapability = p->capability;
15770          if (option_debug > 1)
15771             ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n");
15772       }
15773 
15774       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
15775       /* This seems redundant ... see !p-owner above */
15776       if (p->owner)
15777          ast_queue_frame(p->owner, &ast_null_frame);
15778 
15779 
15780       /* Initialize the context if it hasn't been already */
15781       if (ast_strlen_zero(p->context))
15782          ast_string_field_set(p, context, default_context);
15783 
15784 
15785       /* Check number of concurrent calls -vs- incoming limit HERE */
15786       if (option_debug)
15787          ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username);
15788       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
15789          if (res < 0) {
15790             ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
15791             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
15792             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15793             p->invitestate = INV_COMPLETED;  
15794          }
15795          res = 0;
15796          goto request_invite_cleanup;
15797       }
15798       gotdest = get_destination(p, NULL); /* Get destination right away */
15799       get_rdnis(p, NULL);        /* Get redirect information */
15800       extract_uri(p, req);       /* Get the Contact URI */
15801       build_contact(p);       /* Build our contact header */
15802 
15803       if (p->rtp) {
15804          ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
15805          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
15806       }
15807 
15808       if (!replace_id && gotdest) { /* No matching extension found */
15809          if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP))
15810             transmit_response_reliable(p, "484 Address Incomplete", req);
15811          else {
15812             char *decoded_exten = ast_strdupa(p->exten);
15813             
15814             transmit_response_reliable(p, "404 Not Found", req);
15815             ast_uri_decode(decoded_exten);
15816             ast_log(LOG_NOTICE, "Call from '%s' to extension"
15817                " '%s' rejected because extension not found.\n",
15818                S_OR(p->username, p->peername), decoded_exten);
15819          }
15820          p->invitestate = INV_COMPLETED;  
15821          update_call_counter(p, DEC_CALL_LIMIT);
15822          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15823          res = 0;
15824          goto request_invite_cleanup;
15825       } else {
15826          /* If no extension was specified, use the s one */
15827          /* Basically for calling to IP/Host name only */
15828          if (ast_strlen_zero(p->exten))
15829             ast_string_field_set(p, exten, "s");
15830          /* Initialize our tag */   
15831 
15832          make_our_tag(p->tag, sizeof(p->tag));
15833          /* First invitation - create the channel */
15834          c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL));
15835          *recount = 1;
15836 
15837          /* Save Record-Route for any later requests we make on this dialogue */
15838          build_route(p, req, 0);
15839 
15840          if (c) {
15841             /* Pre-lock the call */
15842             ast_channel_lock(c);
15843          }
15844       }
15845    } else {
15846       if (option_debug > 1 && sipdebug) {
15847          if (!ast_test_flag(req, SIP_PKT_IGNORE))
15848             ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid);
15849          else
15850             ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
15851       }
15852       if (!ast_test_flag(req, SIP_PKT_IGNORE))
15853          reinvite = 1;
15854       c = p->owner;
15855    }
15856 
15857    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
15858       p->lastinvite = seqno;
15859 
15860    if (replace_id) {    /* Attended transfer or call pickup - we're the target */
15861       /* Go and take over the target call */
15862       if (sipdebug && option_debug > 3)
15863          ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid);
15864 
15865       res = handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin, nounlock);
15866       refer_locked = 0;
15867       goto request_invite_cleanup;
15868    }
15869 
15870 
15871    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
15872       enum ast_channel_state c_state = c->_state;
15873 
15874       if (c_state != AST_STATE_UP && reinvite &&
15875          (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
15876          /* If these conditions are true, and the channel is still in the 'ringing'
15877           * state, then this likely means that we have a situation where the initial
15878           * INVITE transaction has completed *but* the channel's state has not yet been
15879           * changed to UP. The reason this could happen is if the reinvite is received
15880           * on the SIP socket prior to an application calling ast_read on this channel
15881           * to read the answer frame we earlier queued on it. In this case, the reinvite
15882           * is completely legitimate so we need to handle this the same as if the channel 
15883           * were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
15884           */
15885          c_state = AST_STATE_UP;
15886       }
15887 
15888       switch(c_state) {
15889       case AST_STATE_DOWN:
15890          if (option_debug > 1)
15891             ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name);
15892          transmit_provisional_response(p, "100 Trying", req, 0);
15893          p->invitestate = INV_PROCEEDING;
15894          ast_setstate(c, AST_STATE_RING);
15895          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
15896             enum ast_pbx_result res;
15897 
15898             res = ast_pbx_start(c);
15899 
15900             switch(res) {
15901             case AST_PBX_FAILED:
15902                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
15903                p->invitestate = INV_COMPLETED;
15904                if (ast_test_flag(req, SIP_PKT_IGNORE))
15905                   transmit_response(p, "503 Unavailable", req);
15906                else
15907                   transmit_response_reliable(p, "503 Unavailable", req);
15908                break;
15909             case AST_PBX_CALL_LIMIT:
15910                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
15911                p->invitestate = INV_COMPLETED;
15912                if (ast_test_flag(req, SIP_PKT_IGNORE))
15913                   transmit_response(p, "480 Temporarily Unavailable", req);
15914                else
15915                   transmit_response_reliable(p, "480 Temporarily Unavailable", req);
15916                break;
15917             case AST_PBX_SUCCESS:
15918                /* nothing to do */
15919                break;
15920             }
15921 
15922             if (res) {
15923 
15924                /* Unlock locks so ast_hangup can do its magic */
15925                ast_mutex_unlock(&c->lock);
15926                *nounlock = 1;
15927                ast_mutex_unlock(&p->lock);
15928                ast_hangup(c);
15929                ast_mutex_lock(&p->lock);
15930                c = NULL;
15931             }
15932          } else { /* Pickup call in call group */
15933             ast_channel_unlock(c);
15934             *nounlock = 1;
15935             ast_mutex_unlock(&p->lock);
15936             if (ast_pickup_call(c)) {
15937                ast_mutex_lock(&p->lock);
15938                ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
15939                if (ast_test_flag(req, SIP_PKT_IGNORE))
15940                   transmit_response(p, "503 Unavailable", req);   /* OEJ - Right answer? */
15941                else
15942                   transmit_response_reliable(p, "503 Unavailable", req);
15943                sip_alreadygone(p);
15944                /* Unlock locks so ast_hangup can do its magic */
15945                ast_mutex_unlock(&p->lock);
15946                c->hangupcause = AST_CAUSE_CALL_REJECTED;
15947             } else {
15948                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
15949             }
15950             ast_hangup(c);
15951             ast_mutex_lock(&p->lock);
15952             p->invitestate = INV_COMPLETED;
15953             c = NULL;
15954          }
15955          break;
15956       case AST_STATE_RING:
15957          transmit_provisional_response(p, "100 Trying", req, 0);
15958          p->invitestate = INV_PROCEEDING;
15959          break;
15960       case AST_STATE_RINGING:
15961          transmit_provisional_response(p, "180 Ringing", req, 0);
15962          p->invitestate = INV_PROCEEDING;
15963          break;
15964       case AST_STATE_UP:
15965          if (option_debug > 1)
15966             ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name);
15967 
15968          transmit_response(p, "100 Trying", req);
15969 
15970          if (p->t38.state == T38_PEER_REINVITE) {
15971             struct ast_channel *bridgepeer = NULL;
15972             struct sip_pvt *bridgepvt = NULL;
15973             
15974             if ((bridgepeer = ast_bridged_channel(p->owner))) {
15975                /* 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*/
15976                /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */
15977                if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
15978                   bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
15979                   if (bridgepvt->t38.state == T38_DISABLED) {
15980                      if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
15981                         /* Send re-invite to the bridged channel */
15982                         sip_handle_t38_reinvite(bridgepeer, p, 1);
15983                      } else { /* Something is wrong with peers udptl struct */
15984                         ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
15985                         ast_mutex_lock(&bridgepvt->lock);
15986                         bridgepvt->t38.state = T38_DISABLED;
15987                         ast_mutex_unlock(&bridgepvt->lock);
15988                         if (option_debug > 1)
15989                            ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name);
15990                         if (ast_test_flag(req, SIP_PKT_IGNORE))
15991                            transmit_response(p, "488 Not acceptable here", req);
15992                         else
15993                            transmit_response_reliable(p, "488 Not acceptable here", req);
15994                      
15995                      }
15996                   } else {
15997                      /* The other side is already setup for T.38 most likely so we need to acknowledge this too */
15998                      ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
15999                      transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
16000                      p->t38.state = T38_ENABLED;
16001                      if (option_debug)
16002                         ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
16003                   }
16004                } else {
16005                   /* Other side is not a SIP channel */
16006                   if (ast_test_flag(req, SIP_PKT_IGNORE))
16007                      transmit_response(p, "488 Not acceptable here", req);
16008                   else
16009                      transmit_response_reliable(p, "488 Not acceptable here", req);
16010                   p->t38.state = T38_DISABLED;
16011                   if (option_debug > 1)
16012                      ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
16013 
16014                   if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */
16015                      sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16016                }
16017             } else {
16018                /* we are not bridged in a call */
16019                ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
16020                transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL);
16021                p->t38.state = T38_ENABLED;
16022                if (option_debug)
16023                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
16024             }
16025          } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */
16026             /* If this is not a re-invite or something to ignore - it's critical */
16027             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
16028             transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL)));
16029          }
16030          p->invitestate = INV_TERMINATED;
16031          break;
16032       default:
16033          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
16034          transmit_response(p, "100 Trying", req);
16035          break;
16036       }
16037    } else {
16038       if (p && (p->autokillid == -1)) {
16039          const char *msg;
16040 
16041          if (!p->jointcapability)
16042             msg = "488 Not Acceptable Here (codec error)";
16043          else {
16044             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
16045             msg = "503 Unavailable";
16046          }
16047          if (ast_test_flag(req, SIP_PKT_IGNORE))
16048             transmit_response(p, msg, req);
16049          else
16050             transmit_response_reliable(p, msg, req);
16051          p->invitestate = INV_COMPLETED;
16052          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16053       }
16054    }
16055    return res;
16056 
16057 request_invite_cleanup:
16058 
16059    if (refer_locked && p->refer && p->refer->refer_call) {
16060       ast_mutex_unlock(&p->refer->refer_call->lock);
16061       if (p->refer->refer_call->owner) {
16062          ast_channel_unlock(p->refer->refer_call->owner);
16063       }
16064    }
16065 
16066    return res;
16067 }

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

Handle incoming MESSAGE request.

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

16721 {
16722    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
16723       if (ast_test_flag(req, SIP_PKT_DEBUG))
16724          ast_verbose("Receiving message!\n");
16725       receive_message(p, req);
16726    } else
16727       transmit_response(p, "202 Accepted", req);
16728    return 1;
16729 }

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

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

Referenced by handle_request().

14855 {
14856    /* This is mostly a skeleton for future improvements */
14857    /* Mostly created to return proper answers on notifications on outbound REFER's */
14858    int res = 0;
14859    const char *event = get_header(req, "Event");
14860    char *eventid = NULL;
14861    char *sep;
14862 
14863    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
14864       *sep++ = '\0';
14865       eventid = sep;
14866    }
14867    
14868    if (option_debug > 1 && sipdebug)
14869       ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event);
14870 
14871    if (strcmp(event, "refer")) {
14872       /* We don't understand this event. */
14873       /* Here's room to implement incoming voicemail notifications :-) */
14874       transmit_response(p, "489 Bad event", req);
14875       res = -1;
14876    } else {
14877       /* Save nesting depth for now, since there might be other events we will
14878          support in the future */
14879 
14880       /* Handle REFER notifications */
14881 
14882       char buf[1024];
14883       char *cmd, *code;
14884       int respcode;
14885       int success = TRUE;
14886 
14887       /* EventID for each transfer... EventID is basically the REFER cseq 
14888 
14889        We are getting notifications on a call that we transfered
14890        We should hangup when we are getting a 200 OK in a sipfrag
14891        Check if we have an owner of this event */
14892       
14893       /* Check the content type */
14894       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
14895          /* We need a sipfrag */
14896          transmit_response(p, "400 Bad request", req);
14897          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14898          return -1;
14899       }
14900 
14901       /* Get the text of the attachment */
14902       if (get_msg_text(buf, sizeof(buf), req)) {
14903          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
14904          transmit_response(p, "400 Bad request", req);
14905          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14906          return -1;
14907       }
14908 
14909       /*
14910       From the RFC...
14911       A minimal, but complete, implementation can respond with a single
14912          NOTIFY containing either the body:
14913                SIP/2.0 100 Trying
14914       
14915          if the subscription is pending, the body:
14916                SIP/2.0 200 OK
14917          if the reference was successful, the body:
14918                SIP/2.0 503 Service Unavailable
14919          if the reference failed, or the body:
14920                SIP/2.0 603 Declined
14921 
14922          if the REFER request was accepted before approval to follow the
14923          reference could be obtained and that approval was subsequently denied
14924          (see Section 2.4.7).
14925       
14926       If there are several REFERs in the same dialog, we need to
14927       match the ID of the event header...
14928       */
14929       if (option_debug > 2)
14930          ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
14931       cmd = ast_skip_blanks(buf);
14932       code = cmd;
14933       /* We are at SIP/2.0 */
14934       while(*code && (*code > 32)) {   /* Search white space */
14935          code++;
14936       }
14937       *code++ = '\0';
14938       code = ast_skip_blanks(code);
14939       sep = code;
14940       sep++;
14941       while(*sep && (*sep > 32)) {  /* Search white space */
14942          sep++;
14943       }
14944       *sep++ = '\0';       /* Response string */
14945       respcode = atoi(code);
14946       switch (respcode) {
14947       case 100:   /* Trying: */
14948       case 101:   /* dialog establishment */
14949          /* Don't do anything yet */
14950          break;
14951       case 183:   /* Ringing: */
14952          /* Don't do anything yet */
14953          break;
14954       case 200:   /* OK: The new call is up, hangup this call */
14955          /* Hangup the call that we are replacing */
14956          break;
14957       case 301: /* Moved permenantly */
14958       case 302: /* Moved temporarily */
14959          /* Do we get the header in the packet in this case? */
14960          success = FALSE;
14961          break;
14962       case 503:   /* Service Unavailable: The new call failed */
14963             /* Cancel transfer, continue the call */
14964          success = FALSE;
14965          break;
14966       case 603:   /* Declined: Not accepted */
14967             /* Cancel transfer, continue the current call */
14968          success = FALSE;
14969          break;
14970       }
14971       if (!success) {
14972          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
14973       }
14974       
14975       /* Confirm that we received this packet */
14976       transmit_response(p, "200 OK", req);
14977    };
14978 
14979    if (!p->lastinvite)
14980       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
14981 
14982    return res;
14983 }

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

Handle incoming OPTIONS request.

Definition at line 14986 of file chan_sip.c.

References ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), context, sip_pvt::context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().

Referenced by handle_request().

14987 {
14988    int res;
14989 
14990 
14991    /* XXX Should we authenticate OPTIONS? XXX */
14992 
14993    if (p->lastinvite) {
14994       /* if this is a request in an active dialog, just confirm that the dialog exists. */
14995       transmit_response_with_allow(p, "200 OK", req, 0);
14996       return 0;
14997    }
14998 
14999    res = get_destination(p, req);
15000    build_contact(p);
15001 
15002    if (ast_strlen_zero(p->context))
15003       ast_string_field_set(p, context, default_context);
15004 
15005    if (ast_shutting_down())
15006       transmit_response_with_allow(p, "503 Unavailable", req, 0);
15007    else if (res < 0)
15008       transmit_response_with_allow(p, "404 Not Found", req, 0);
15009    else 
15010       transmit_response_with_allow(p, "200 OK", req, 0);
15011 
15012    /* Destroy if this OPTIONS was the opening request, but not if
15013       it's in the middle of a normal call flow. */
15014    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15015 
15016    return res;
15017 }

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 16236 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_indicate(), 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_pvt::callid, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), context, sip_pvt::context, copy_request(), FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, local_attended_transfer(), sip_refer::localtransfer, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDDESTROY, SIP_OUTGOING, sip_park(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_refer_allocate(), SIPBUFSIZE, sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by handle_request().

16237 {
16238    struct sip_dual current;   /* Chan1: Call between asterisk and transferer */
16239                /* Chan2: Call between asterisk and transferee */
16240 
16241    int res = 0;
16242 
16243    if (ast_test_flag(req, SIP_PKT_DEBUG))
16244       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");
16245 
16246    if (!p->owner) {
16247       /* This is a REFER outside of an existing SIP dialog */
16248       /* We can't handle that, so decline it */
16249       if (option_debug > 2)
16250          ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
16251       transmit_response(p, "603 Declined (No dialog)", req);
16252       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
16253          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
16254          sip_alreadygone(p);
16255          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
16256       }
16257       return 0;
16258    }  
16259 
16260 
16261    /* Check if transfer is allowed from this device */
16262    if (p->allowtransfer == TRANSFER_CLOSED ) {
16263       /* Transfer not allowed, decline */
16264       transmit_response(p, "603 Declined (policy)", req);
16265       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
16266       /* Do not destroy SIP session */
16267       return 0;
16268    }
16269 
16270    if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
16271       /* Already have a pending REFER */  
16272       transmit_response(p, "491 Request pending", req);
16273       append_history(p, "Xfer", "Refer failed. Request pending.");
16274       return 0;
16275    }
16276 
16277    /* Allocate memory for call transfer data */
16278    if (!p->refer && !sip_refer_allocate(p)) {
16279       transmit_response(p, "500 Internal Server Error", req);
16280       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
16281       return -3;
16282    }
16283 
16284    res = get_refer_info(p, req); /* Extract headers */
16285 
16286    p->refer->status = REFER_SENT;
16287 
16288    if (res != 0) {
16289       switch (res) {
16290       case -2: /* Syntax error */
16291          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
16292          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
16293          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
16294             ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n");
16295          break;
16296       case -3:
16297          transmit_response(p, "603 Declined (Non sip: uri)", req);
16298          append_history(p, "Xfer", "Refer failed. Non SIP uri");
16299          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
16300             ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n");
16301          break;
16302       default:
16303          /* Refer-to extension not found, fake a failed transfer */
16304          transmit_response(p, "202 Accepted", req);
16305          append_history(p, "Xfer", "Refer failed. Bad extension.");
16306          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
16307          ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
16308          if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug)
16309             ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
16310          break;
16311       } 
16312       return 0;
16313    }
16314    if (ast_strlen_zero(p->context))
16315       ast_string_field_set(p, context, default_context);
16316 
16317    /* If we do not support SIP domains, all transfers are local */
16318    if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
16319       p->refer->localtransfer = 1;
16320       if (sipdebug && option_debug > 2)
16321          ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
16322    } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
16323       /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
16324       p->refer->localtransfer = 1;
16325    } else if (sipdebug && option_debug > 2)
16326          ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
16327    
16328    /* Is this a repeat of a current request? Ignore it */
16329    /* Don't know what else to do right now. */
16330    if (ignore) 
16331       return res;
16332 
16333    /* If this is a blind transfer, we have the following
16334       channels to work with:
16335       - chan1, chan2: The current call between transferer and transferee (2 channels)
16336       - target_channel: A new call from the transferee to the target (1 channel)
16337       We need to stay tuned to what happens in order to be able
16338       to bring back the call to the transferer */
16339 
16340    /* If this is a attended transfer, we should have all call legs within reach:
16341       - chan1, chan2: The call between the transferer and transferee (2 channels)
16342       - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
16343    We want to bridge chan2 with targetcall_pvt!
16344    
16345       The replaces call id in the refer message points
16346       to the call leg between Asterisk and the transferer.
16347       So we need to connect the target and the transferee channel
16348       and hangup the two other channels silently 
16349    
16350       If the target is non-local, the call ID could be on a remote
16351       machine and we need to send an INVITE with replaces to the
16352       target. We basically handle this as a blind transfer
16353       and let the sip_call function catch that we need replaces
16354       header in the INVITE.
16355    */
16356 
16357 
16358    /* Get the transferer's channel */
16359    current.chan1 = p->owner;
16360 
16361    /* Find the other part of the bridge (2) - transferee */
16362    current.chan2 = ast_bridged_channel(current.chan1);
16363    
16364    if (sipdebug && option_debug > 2)
16365       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>");
16366 
16367    if (!current.chan2 && !p->refer->attendedtransfer) {
16368       /* No bridged channel, propably IVR or echo or similar... */
16369       /* Guess we should masquerade or something here */
16370       /* Until we figure it out, refuse transfer of such calls */
16371       if (sipdebug && option_debug > 2)
16372          ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n");
16373       p->refer->status = REFER_FAILED;
16374       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
16375       transmit_response(p, "603 Declined", req);
16376       return -1;
16377    }
16378 
16379    if (current.chan2) {
16380       if (sipdebug && option_debug > 3)
16381          ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
16382 
16383       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
16384    }
16385 
16386    ast_set_flag(&p->flags[0], SIP_GOTREFER); 
16387 
16388    /* From here on failures will be indicated with NOTIFY requests */
16389    transmit_response(p, "202 Accepted", req);
16390 
16391    /* Attended transfer: Find all call legs and bridge transferee with target*/
16392    if (p->refer->attendedtransfer) {
16393       if ((res = local_attended_transfer(p, &current, req, seqno)))
16394          return res; /* We're done with the transfer */
16395       /* Fall through for remote transfers that we did not find locally */
16396       if (sipdebug && option_debug > 3)
16397          ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
16398       /* Fallthrough if we can't find the call leg internally */
16399    }
16400 
16401 
16402    /* Parking a call */
16403    if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
16404       /* Must release c's lock now, because it will not longer be accessible after the transfer! */
16405       *nounlock = 1;
16406       ast_channel_unlock(current.chan1);
16407       copy_request(&current.req, req);
16408       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
16409       p->refer->status = REFER_200OK;
16410       append_history(p, "Xfer", "REFER to call parking.");
16411       if (sipdebug && option_debug > 3)
16412          ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
16413       if ((res = sip_park(current.chan2, current.chan1, req, seqno))) {
16414          transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE);
16415       }
16416       return res;
16417    } 
16418 
16419    /* Blind transfers and remote attended xfers */
16420    if (current.chan1 && current.chan2) {
16421       if (option_debug > 2)
16422          ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name);
16423       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
16424    }
16425    if (current.chan2) {
16426       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
16427       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
16428       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
16429       /* One for the new channel */
16430       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
16431       /* Attended transfer to remote host, prepare headers for the INVITE */
16432       if (p->refer->referred_by) 
16433          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
16434    }
16435    /* Generate a Replaces string to be used in the INVITE during attended transfer */
16436    if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) {
16437       char tempheader[SIPBUFSIZE];
16438       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 
16439             p->refer->replaces_callid_totag ? ";to-tag=" : "", 
16440             p->refer->replaces_callid_totag, 
16441             p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
16442             p->refer->replaces_callid_fromtag);
16443       if (current.chan2)
16444          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
16445    }
16446    /* Must release lock now, because it will not longer
16447          be accessible after the transfer! */
16448    *nounlock = 1;
16449    ast_channel_unlock(current.chan1);
16450 
16451    /* Connect the call */
16452 
16453    /* FAKE ringing if not attended transfer */
16454    if (!p->refer->attendedtransfer)
16455       transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 
16456       
16457    /* For blind transfer, this will lead to a new call */
16458    /* For attended transfer to remote host, this will lead to
16459          a new SIP call with a replaces header, if the dial plan allows it 
16460    */
16461    if (!current.chan2) {
16462       /* We have no bridge, so we're talking with Asterisk somehow */
16463       /* We need to masquerade this call */
16464       /* What to do to fix this situation:
16465          * Set up the new call in a new channel 
16466          * Let the new channel masq into this channel
16467          Please add that code here :-)
16468       */
16469       p->refer->status = REFER_FAILED;
16470       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
16471       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
16472       append_history(p, "Xfer", "Refer failed (only bridged calls).");
16473       return -1;
16474    }
16475    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
16476 
16477    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
16478       servers - generate an INVITE with Replaces. Either way, let the dial plan decided  */
16479    /* indicate before masquerade so the indication actually makes it to the real channel
16480       when using local channels with MOH passthru */
16481    ast_indicate(current.chan2, AST_CONTROL_UNHOLD);
16482    res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
16483 
16484    if (!res) {
16485       /* Success  - we have a new channel */
16486       if (option_debug > 2)
16487          ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
16488       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
16489       if (p->refer->localtransfer)
16490          p->refer->status = REFER_200OK;
16491       if (p->owner)
16492          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
16493       append_history(p, "Xfer", "Refer succeeded.");
16494       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
16495       /* Do not hangup call, the other side do that when we say 200 OK */
16496       /* We could possibly implement a timer here, auto congestion */
16497       res = 0;
16498    } else {
16499       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
16500       if (option_debug > 2)
16501          ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
16502       append_history(p, "Xfer", "Refer failed.");
16503       /* Failure of some kind */
16504       p->refer->status = REFER_FAILED;
16505       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
16506       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
16507       res = -1;
16508    }
16509    return res;
16510 }

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

References append_history, ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_pvt::callid, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_request::headers, sip_pvt::initreq, LOG_NOTICE, sip_request::method, register_verify(), SIP_PKT_DEBUG, SIP_REGISTER, and sip_scheddestroy().

Referenced by handle_request().

17055 {
17056    enum check_auth_result res;
17057 
17058    /* If this is not the intial request, and the initial request isn't
17059     * a register, something screwy happened, so bail */
17060    if (p->initreq.headers && p->initreq.method != SIP_REGISTER) {
17061       ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid);
17062       return -1;
17063    }
17064 
17065    /* Use this as the basis */
17066    if (ast_test_flag(req, SIP_PKT_DEBUG))
17067       ast_verbose("Using latest REGISTER request as basis request\n");
17068    copy_request(&p->initreq, req);
17069    check_via(p, req);
17070    if ((res = register_verify(p, sin, req, e)) < 0) {
17071       const char *reason;
17072 
17073       switch (res) {
17074       case AUTH_SECRET_FAILED:
17075          reason = "Wrong password";
17076          break;
17077       case AUTH_USERNAME_MISMATCH:
17078          reason = "Username/auth name mismatch";
17079          break;
17080       case AUTH_NOT_FOUND:
17081          reason = "No matching peer found";
17082          break;
17083       case AUTH_UNKNOWN_DOMAIN:
17084          reason = "Not a local domain";
17085          break;
17086       case AUTH_PEER_NOT_DYNAMIC:
17087          reason = "Peer is not supposed to register";
17088          break;
17089       case AUTH_ACL_FAILED:
17090          reason = "Device does not match ACL";
17091          break;
17092       default:
17093          reason = "Unknown failure";
17094          break;
17095       }
17096       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
17097          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
17098          reason);
17099       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
17100    } else
17101       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
17102 
17103    if (res < 1) {
17104       /* Destroy the session, but keep us around for just a bit in case they don't
17105          get our 200 OK */
17106       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17107    }
17108    return res;
17109 }

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

References __get_header(), add_extensionstate_update(), append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::callid, check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, FALSE, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::subscribeuri, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), TRUE, sip_pvt::useragent, sip_pvt::username, XMIT_UNRELIABLE, and XPIDF_XML.

Referenced by handle_request().

16733 {
16734    int gotdest = 0;
16735    int res = 0;
16736    int firststate = AST_EXTENSION_REMOVED;
16737    struct sip_peer *authpeer = NULL;
16738    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
16739    int resubscribe = (p->subscribed != NONE) && !ast_test_flag(req, SIP_PKT_IGNORE);
16740    char *temp, *event;
16741 
16742    if (p->initreq.headers) {  
16743       /* We already have a dialog */
16744       if (p->initreq.method != SIP_SUBSCRIBE) {
16745          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
16746          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
16747          transmit_response(p, "403 Forbidden (within dialog)", req);
16748          /* Do not destroy session, since we will break the call if we do */
16749          if (option_debug)
16750             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);
16751          return 0;
16752       } else if (ast_test_flag(req, SIP_PKT_DEBUG)) {
16753          if (option_debug) {
16754             if (resubscribe)
16755                ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
16756             else
16757                ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid);
16758          }
16759       }
16760    }
16761 
16762    /* Check if we have a global disallow setting on subscriptions. 
16763       if so, we don't have to check peer/user settings after auth, which saves a lot of processing
16764    */
16765    if (!global_allowsubscribe) {
16766       transmit_response(p, "403 Forbidden (policy)", req);
16767       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
16768       return 0;
16769    }
16770 
16771    if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) {  /* Set up dialog, new subscription */
16772       const char *to = get_header(req, "To");
16773       char totag[128];
16774 
16775       /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
16776       if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
16777          if (ast_test_flag(req, SIP_PKT_DEBUG))
16778             ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
16779          transmit_response(p, "481 Subscription does not exist", req);
16780          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
16781          return 0;
16782       }
16783 
16784       /* Use this as the basis */
16785       if (ast_test_flag(req, SIP_PKT_DEBUG))
16786          ast_verbose("Creating new subscription\n");
16787 
16788       copy_request(&p->initreq, req);
16789       check_via(p, req);
16790       build_route(p, req, 0);
16791    } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE))
16792       ast_verbose("Ignoring this SUBSCRIBE request\n");
16793 
16794    /* Find parameters to Event: header value and remove them for now */
16795    if (ast_strlen_zero(eventheader)) {
16796       transmit_response(p, "489 Bad Event", req);
16797       if (option_debug > 1)
16798          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n");
16799       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
16800       return 0;
16801    }
16802 
16803    if ( (strchr(eventheader, ';'))) {
16804       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
16805       temp = strchr(event, ';');       
16806       *temp = '\0';           /* Remove any options for now */
16807                      /* We might need to use them later :-) */
16808    } else
16809       event = (char *) eventheader;    /* XXX is this legal ? */
16810 
16811    /* Handle authentication if we're new and not a retransmission. We can't just
16812     * use if !(ast_test_flag(req, SIP_PKT_IGNORE), because then we'll end up sending
16813     * a 200 OK if someone retransmits without sending auth */
16814    if (p->subscribed == NONE || resubscribe) {
16815       res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer);
16816 
16817       /* if an authentication response was sent, we are done here */
16818       if (res == AUTH_CHALLENGE_SENT) {
16819          if (authpeer)
16820             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
16821          return 0;
16822       }
16823       if (res < 0) {
16824          if (res == AUTH_FAKE_AUTH) {
16825             ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
16826             transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
16827          } else {
16828             ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
16829             transmit_response_reliable(p, "403 Forbidden", req);
16830          }
16831          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
16832          if (authpeer)
16833             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
16834          return 0;
16835       }
16836    }
16837 
16838    /* Check if this user/peer is allowed to subscribe at all */
16839    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
16840       transmit_response(p, "403 Forbidden (policy)", req);
16841       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
16842       if (authpeer)
16843          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
16844       return 0;
16845    }
16846 
16847    if (strcmp(event, "message-summary")) {
16848       /* Get destination right away */
16849       gotdest = get_destination(p, NULL);
16850    }
16851 
16852    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
16853    parse_ok_contact(p, req);
16854 
16855    build_contact(p);
16856    if (gotdest) {
16857       transmit_response(p, "404 Not Found", req);
16858       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
16859       if (authpeer)
16860          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
16861       return 0;
16862    }
16863 
16864    /* Initialize tag for new subscriptions */   
16865    if (ast_strlen_zero(p->tag))
16866       make_our_tag(p->tag, sizeof(p->tag));
16867 
16868    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
16869       unsigned int pidf_xml;
16870       const char *accept;
16871       int start = 0;
16872       enum subscriptiontype subscribed = NONE;
16873       const char *unknown_acceptheader = NULL;
16874 
16875       if (authpeer)  /* No need for authpeer here */
16876          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
16877 
16878       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
16879       accept = __get_header(req, "Accept", &start);
16880       while ((subscribed == NONE) && !ast_strlen_zero(accept)) {
16881          pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0;
16882 
16883          /* Older versions of Polycom firmware will claim pidf+xml, but really
16884           * they only support xpidf+xml. */
16885          if (pidf_xml && strstr(p->useragent, "Polycom")) {
16886             subscribed = XPIDF_XML;
16887          } else if (pidf_xml) {
16888             subscribed = PIDF_XML;         /* RFC 3863 format */
16889          } else if (strstr(accept, "application/dialog-info+xml")) {
16890             subscribed = DIALOG_INFO_XML;
16891             /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
16892          } else if (strstr(accept, "application/cpim-pidf+xml")) {
16893             subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
16894          } else if (strstr(accept, "application/xpidf+xml")) {
16895             subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
16896          } else {
16897             unknown_acceptheader = accept;
16898          }
16899          /* check to see if there is another Accept header present */
16900          accept = __get_header(req, "Accept", &start);
16901       }
16902 
16903       if (!start) {
16904          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
16905             transmit_response(p, "489 Bad Event", req);
16906             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: "
16907                "stateid: %d, laststate: %d, dialogver: %d, subscribecont: "
16908                "'%s', subscribeuri: '%s'\n",
16909                p->stateid,
16910                p->laststate,
16911                p->dialogver,
16912                p->subscribecontext,
16913                p->subscribeuri);
16914             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
16915             return 0;
16916          }
16917          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
16918             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
16919       } else if (subscribed == NONE) {
16920          /* Can't find a format for events that we know about */
16921          char mybuf[200];
16922          if (!ast_strlen_zero(unknown_acceptheader)) {
16923             snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader);
16924          } else {
16925             snprintf(mybuf, sizeof(mybuf), "489 Bad Event");
16926          }
16927          transmit_response(p, mybuf, req);
16928          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:"
16929             "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d,"
16930             "dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
16931             unknown_acceptheader,
16932             (int)p->subscribed,
16933             p->stateid,
16934             p->laststate,
16935             p->dialogver,
16936             p->subscribecontext,
16937             p->subscribeuri);
16938          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
16939          return 0;
16940       } else {
16941          p->subscribed = subscribed;
16942       }
16943    } else if (!strcmp(event, "message-summary")) {
16944       int start = 0;
16945       int found_supported = 0;
16946       const char *acceptheader;
16947 
16948       acceptheader = __get_header(req, "Accept", &start);
16949       while (!found_supported && !ast_strlen_zero(acceptheader)) {
16950          found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1;
16951          if (!found_supported && (option_debug > 2)) {
16952             ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
16953          }
16954          acceptheader = __get_header(req, "Accept", &start);
16955       }
16956       if (start && !found_supported) {
16957          /* Format requested that we do not support */
16958          transmit_response(p, "406 Not Acceptable", req);
16959          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
16960          if (authpeer)  /* No need for authpeer here */
16961             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
16962          return 0;
16963       }
16964       /* Looks like they actually want a mailbox status 
16965         This version of Asterisk supports mailbox subscriptions
16966         The subscribed URI needs to exist in the dial plan
16967         In most devices, this is configurable to the voicemailmain extension you use
16968       */
16969       if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
16970          transmit_response(p, "404 Not found (no mailbox)", req);
16971          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
16972          ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
16973          if (authpeer)  /* No need for authpeer here */
16974             ASTOBJ_UNREF(authpeer, sip_destroy_peer);
16975          return 0;
16976       }
16977 
16978       p->subscribed = MWI_NOTIFICATION;
16979       if (authpeer->mwipvt && authpeer->mwipvt != p)  /* Destroy old PVT if this is a new one */
16980          /* We only allow one subscription per peer */
16981          sip_destroy(authpeer->mwipvt);
16982       authpeer->mwipvt = p;      /* Link from peer to pvt */
16983       p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */
16984    } else { /* At this point, Asterisk does not understand the specified event */
16985       transmit_response(p, "489 Bad Event", req);
16986       if (option_debug > 1)
16987          ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
16988       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
16989       if (authpeer)  /* No need for authpeer here */
16990          ASTOBJ_UNREF(authpeer, sip_destroy_peer);
16991       return 0;
16992    }
16993 
16994    if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
16995       if (p->stateid > -1)
16996          ast_extension_state_del(p->stateid, add_extensionstate_update);
16997       p->stateid = ast_extension_state_add(p->context, p->exten, add_extensionstate_update, p);
16998    }
16999 
17000    if (!ast_test_flag(req, SIP_PKT_IGNORE) && p)
17001       p->lastinvite = seqno;
17002    if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) {
17003       p->expiry = atoi(get_header(req, "Expires"));
17004 
17005       /* check if the requested expiry-time is within the approved limits from sip.conf */
17006       if (p->expiry > max_expiry)
17007          p->expiry = max_expiry;
17008       if (p->expiry < min_expiry && p->expiry > 0)
17009          p->expiry = min_expiry;
17010 
17011       if (sipdebug || option_debug > 1) {
17012          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
17013             ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
17014          else
17015             ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
17016       }
17017       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
17018          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
17019       if (p->expiry > 0)
17020          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
17021 
17022       if (p->subscribed == MWI_NOTIFICATION) {
17023          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
17024          transmit_response(p, "200 OK", req);
17025          if (p->relatedpeer) {   /* Send first notification */
17026             ASTOBJ_WRLOCK(p->relatedpeer);
17027             sip_send_mwi_to_peer(p->relatedpeer, TRUE);
17028             ASTOBJ_UNLOCK(p->relatedpeer);
17029          }
17030       } else {
17031 
17032          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
17033 
17034             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));
17035             transmit_response(p, "404 Not found", req);
17036             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
17037             return 0;
17038          }
17039          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
17040          transmit_response(p, "200 OK", req);
17041          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
17042          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
17043          /* hide the 'complete' exten/context in the refer_to field for later display */
17044          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
17045 
17046       }
17047       if (!p->expiry)
17048          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
17049    }
17050    return 1;
17051 }

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

Handle SIP response in dialogue.

Definition at line 14114 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), append_history, ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::call_forward, sip_pvt::context, do_proxy_auth(), sip_pvt::exten, FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, notify_extenstate_update(), option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_FORWARD_LOOP_DETECTED, SIP_PAGE2_STATECHANGEQUEUE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, sip_pvt::theirtag, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.

14115 {
14116    struct ast_channel *owner;
14117    int sipmethod;
14118    int res = 1;
14119    int ack_res;
14120    const char *c = get_header(req, "Cseq");
14121    /* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */
14122    char *c_copy = ast_strdupa(c);
14123    /* Skip the Cseq and its subsequent spaces */
14124    const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
14125 
14126    if (!msg)
14127       msg = "";
14128 
14129    sipmethod = find_sip_method(msg);
14130 
14131    owner = p->owner;
14132    if (owner) 
14133       owner->hangupcause = hangup_sip2cause(resp);
14134 
14135    /* Acknowledge whatever it is destined for */
14136    if ((resp >= 100) && (resp <= 199)) {
14137       ack_res = __sip_semi_ack(p, seqno, 0, sipmethod);
14138    } else {
14139       ack_res = __sip_ack(p, seqno, 0, sipmethod);
14140    }
14141 
14142    if (ack_res == FALSE) {
14143       append_history(p, "Ignore", "Ignoring this retransmit\n");
14144       return;
14145    }
14146 
14147    /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
14148    if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 
14149       p->pendinginvite = 0;
14150 
14151    /* Get their tag if we haven't already */
14152    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
14153       char tag[128];
14154 
14155       gettag(req, "To", tag, sizeof(tag));
14156       ast_string_field_set(p, theirtag, tag);
14157    }
14158 
14159    /* RFC 3261 Section 15 specifies that if we receive a 408 or 481
14160     * in response to a BYE, then we should end the current dialog
14161     * and session.  It is known that at least one phone manufacturer
14162     * potentially will send a 404 in response to a BYE, so we'll be
14163     * liberal in what we accept and end the dialog and session if we
14164     * receive any of those responses to a BYE.
14165     */
14166    if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) {
14167       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
14168       return;
14169    }
14170 
14171    if (p->relatedpeer && p->method == SIP_OPTIONS) {
14172       /* We don't really care what the response is, just that it replied back. 
14173          Well, as long as it's not a 100 response...  since we might
14174          need to hang around for something more "definitive" */
14175       if (resp != 100)
14176          handle_response_peerpoke(p, resp, req);
14177    } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
14178       switch(resp) {
14179       case 100:   /* 100 Trying */
14180       case 101:   /* 101 Dialog establishment */
14181          if (sipmethod == SIP_INVITE) 
14182             handle_response_invite(p, resp, rest, req, seqno);
14183          break;
14184       case 183:   /* 183 Session Progress */
14185          if (sipmethod == SIP_INVITE) 
14186             handle_response_invite(p, resp, rest, req, seqno);
14187          break;
14188       case 180:   /* 180 Ringing */
14189          if (sipmethod == SIP_INVITE) 
14190             handle_response_invite(p, resp, rest, req, seqno);
14191          break;
14192       case 182:       /* 182 Queued */
14193          if (sipmethod == SIP_INVITE)
14194             handle_response_invite(p, resp, rest, req, seqno);
14195          break;
14196       case 200:   /* 200 OK */
14197          p->authtries = 0; /* Reset authentication counter */
14198          if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
14199             /* We successfully transmitted a message 
14200                or a video update request in INFO */
14201             /* Nothing happens here - the message is inside a dialog */
14202          } else if (sipmethod == SIP_INVITE) {
14203             handle_response_invite(p, resp, rest, req, seqno);
14204          } else if (sipmethod == SIP_NOTIFY) {
14205             /* They got the notify, this is the end */
14206             if (p->owner) {
14207                if (!p->refer) {
14208                   ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
14209                   ast_queue_hangup(p->owner);
14210                } else if (option_debug > 3) 
14211                   ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n");
14212             } else {
14213                if (p->subscribed == NONE) 
14214                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14215                if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
14216                   /* Ready to send the next state we have on queue */
14217                   ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
14218                   notify_extenstate_update((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
14219                }
14220             }
14221          } else if (sipmethod == SIP_REGISTER) 
14222             res = handle_response_register(p, resp, rest, req, seqno);
14223          else if (sipmethod == SIP_BYE) {    /* Ok, we're ready to go */
14224             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
14225             ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
14226          } else if (sipmethod == SIP_SUBSCRIBE)
14227             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
14228          break;
14229       case 202:   /* Transfer accepted */
14230          if (sipmethod == SIP_REFER) 
14231             handle_response_refer(p, resp, rest, req, seqno);
14232          break;
14233       case 401: /* Not www-authorized on SIP method */
14234          if (sipmethod == SIP_INVITE)
14235             handle_response_invite(p, resp, rest, req, seqno);
14236          else if (sipmethod == SIP_REFER)
14237             handle_response_refer(p, resp, rest, req, seqno);
14238          else if (p->registry && sipmethod == SIP_REGISTER)
14239             res = handle_response_register(p, resp, rest, req, seqno);
14240          else if (sipmethod == SIP_BYE) {
14241             if (ast_strlen_zero(p->authname)) {
14242                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
14243                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
14244                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14245             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) {
14246                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
14247                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14248                /* We fail to auth bye on our own call, but still needs to tear down the call. 
14249                   Life, they call it. */
14250             }
14251          } else {
14252             ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To"));
14253             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14254          }
14255          break;
14256       case 403: /* Forbidden - we failed authentication */
14257          if (sipmethod == SIP_INVITE)
14258             handle_response_invite(p, resp, rest, req, seqno);
14259          else if (p->registry && sipmethod == SIP_REGISTER) 
14260             res = handle_response_register(p, resp, rest, req, seqno);
14261          else {
14262             ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
14263             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14264          }
14265          break;
14266       case 404: /* Not found */
14267          if (p->registry && sipmethod == SIP_REGISTER)
14268             res = handle_response_register(p, resp, rest, req, seqno);
14269          else if (sipmethod == SIP_INVITE)
14270             handle_response_invite(p, resp, rest, req, seqno);
14271          else if (owner)
14272             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
14273          break;
14274       case 407: /* Proxy auth required */
14275          if (sipmethod == SIP_INVITE)
14276             handle_response_invite(p, resp, rest, req, seqno);
14277          else if (sipmethod == SIP_REFER)
14278             handle_response_refer(p, resp, rest, req, seqno);
14279          else if (p->registry && sipmethod == SIP_REGISTER)
14280             res = handle_response_register(p, resp, rest, req, seqno);
14281          else if (sipmethod == SIP_BYE) {
14282             if (ast_strlen_zero(p->authname)) {
14283                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
14284                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
14285                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14286             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) {
14287                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
14288                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14289             }
14290          } else   /* We can't handle this, giving up in a bad way */
14291             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14292 
14293          break;
14294       case 408: /* Request timeout - terminate dialog */
14295          if (sipmethod == SIP_INVITE)
14296             handle_response_invite(p, resp, rest, req, seqno);
14297          else if (sipmethod == SIP_REGISTER) 
14298             res = handle_response_register(p, resp, rest, req, seqno);
14299          else if (sipmethod == SIP_BYE) {
14300             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14301             if (option_debug)
14302                ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
14303          } else {
14304             if (owner)
14305                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
14306             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14307          }
14308          break;
14309       case 481: /* Call leg does not exist */
14310          if (sipmethod == SIP_INVITE) {
14311             handle_response_invite(p, resp, rest, req, seqno);
14312          } else if (sipmethod == SIP_REFER) {
14313             handle_response_refer(p, resp, rest, req, seqno);
14314          } else if (sipmethod == SIP_BYE) {
14315             /* The other side has no transaction to bye,
14316             just assume it's all right then */
14317             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
14318          } else if (sipmethod == SIP_CANCEL) {
14319             /* The other side has no transaction to cancel,
14320             just assume it's all right then */
14321             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
14322          } else if (sipmethod == SIP_NOTIFY) {
14323             /* The other side has no active Subscribe for this Callid. 
14324              * Remove this Dialog and old Subscription */
14325             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14326          } else {
14327             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
14328             /* Guessing that this is not an important request */
14329          }
14330          break;
14331       case 487:
14332          if (sipmethod == SIP_INVITE)
14333             handle_response_invite(p, resp, rest, req, seqno);
14334          break;
14335       case 488: /* Not acceptable here - codec error */
14336       case 606: /* Not Acceptable */
14337          if (sipmethod == SIP_INVITE)
14338             handle_response_invite(p, resp, rest, req, seqno);
14339          break;
14340       case 491: /* Pending */
14341          if (sipmethod == SIP_INVITE)
14342             handle_response_invite(p, resp, rest, req, seqno);
14343          else {
14344             if (option_debug)
14345                ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
14346             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14347          }
14348          break;
14349       case 501: /* Not Implemented */
14350          if (sipmethod == SIP_INVITE)
14351             handle_response_invite(p, resp, rest, req, seqno);
14352          else if (sipmethod == SIP_REFER)
14353             handle_response_refer(p, resp, rest, req, seqno);
14354          else
14355             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg);
14356          break;
14357       case 603:   /* Declined transfer */
14358          if (sipmethod == SIP_REFER) {
14359             handle_response_refer(p, resp, rest, req, seqno);
14360             break;
14361          }
14362          /* Fallthrough */
14363       default:
14364          if ((resp >= 300) && (resp < 700)) {
14365             /* Fatal response */
14366             if ((option_verbose > 2) && (resp != 487))
14367                ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
14368    
14369             if (sipmethod == SIP_INVITE)
14370                stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
14371 
14372             /* XXX Locking issues?? XXX */
14373             switch(resp) {
14374             case 300: /* Multiple Choices */
14375             case 301: /* Moved permenantly */
14376             case 302: /* Moved temporarily */
14377             case 305: /* Use Proxy */
14378                parse_moved_contact(p, req);
14379                /* Fall through */
14380             case 486: /* Busy here */
14381             case 600: /* Busy everywhere */
14382             case 603: /* Decline */
14383                if (p->owner)
14384                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
14385                break;
14386             case 482: /* Loop Detected */
14387                /*
14388                   \note Asterisk has historically tried to do a call forward when it
14389                   gets a 482, but that behavior isn't necessarily the best course of
14390                   action. Go ahead and do it anyway by default, but allow the option
14391                   to immediately pass to the next line in the dialplan. */
14392                if (p->owner && ast_test_flag(&p->flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED)) {
14393                   if (option_debug) {
14394                      ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
14395                   }
14396                   ast_string_field_build(p->owner, call_forward,
14397                                "Local/%s@%s", p->username, p->context);
14398                }
14399                /* Fall through */
14400             case 480: /* Temporarily Unavailable */
14401             case 404: /* Not Found */
14402             case 410: /* Gone */
14403             case 400: /* Bad Request */
14404             case 500: /* Server error */
14405                if (sipmethod == SIP_REFER) {
14406                   handle_response_refer(p, resp, rest, req, seqno);
14407                   break;
14408                }
14409                /* Fall through */
14410             case 502: /* Bad gateway */
14411             case 503: /* Service Unavailable */
14412             case 504: /* Server Timeout */
14413                if (owner)
14414                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
14415                break;
14416             default:
14417                /* Send hangup */ 
14418                if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE)
14419                   ast_queue_hangup(p->owner);
14420                break;
14421             }
14422             /* ACK on invite */
14423             if (sipmethod == SIP_INVITE) 
14424                transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
14425             if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 
14426                sip_alreadygone(p);
14427             if (!p->owner)
14428                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14429          } else if ((resp >= 100) && (resp < 200)) {
14430             if (sipmethod == SIP_INVITE) {
14431                if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p))
14432                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
14433                if (find_sdp(req))
14434                   process_sdp(p, req);
14435                if (p->owner) {
14436                   /* Queue a progress frame */
14437                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
14438                }
14439             }
14440          } else
14441             ast_log(LOG_NOTICE, "Don't 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));
14442       }
14443    } else { 
14444       /* Responses to OUTGOING SIP requests on INCOMING calls 
14445          get handled here. As well as out-of-call message responses */
14446       if (ast_test_flag(req, SIP_PKT_DEBUG))
14447          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
14448 
14449       if (sipmethod == SIP_INVITE && resp == 200) {
14450          /* Tags in early session is replaced by the tag in 200 OK, which is 
14451          the final reply to our INVITE */
14452          char tag[128];
14453 
14454          gettag(req, "To", tag, sizeof(tag));
14455          ast_string_field_set(p, theirtag, tag);
14456       }
14457 
14458       switch(resp) {
14459       case 200:
14460          if (sipmethod == SIP_INVITE) {
14461             handle_response_invite(p, resp, rest, req, seqno);
14462          } else if (sipmethod == SIP_CANCEL) {
14463             if (option_debug)
14464                ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n");
14465 
14466             /* Wait for 487, then destroy */
14467          } else if (sipmethod == SIP_NOTIFY) {
14468             /* They got the notify, this is the end */
14469             if (p->owner) {
14470                if (p->refer) {
14471                   if (option_debug)
14472                      ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n");
14473                } else
14474                   ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
14475                /* ast_queue_hangup(p->owner); Disabled */
14476             } else {
14477                if (!p->subscribed && !p->refer)
14478                   ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14479                if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
14480                   /* Ready to send the next state we have on queue */
14481                   ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
14482                   notify_extenstate_update((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
14483                }
14484             }
14485          } else if (sipmethod == SIP_BYE)
14486             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14487          else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO)
14488             /* We successfully transmitted a message or
14489                a video update request in INFO */
14490             ;
14491          else if (sipmethod == SIP_BYE) 
14492             /* Ok, we're ready to go */
14493             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14494          break;
14495       case 202:   /* Transfer accepted */
14496          if (sipmethod == SIP_REFER) 
14497             handle_response_refer(p, resp, rest, req, seqno);
14498          break;
14499       case 401:   /* www-auth */
14500       case 407:
14501          if (sipmethod == SIP_REFER)
14502             handle_response_refer(p, resp, rest, req, seqno);
14503          else if (sipmethod == SIP_INVITE) 
14504             handle_response_invite(p, resp, rest, req, seqno);
14505          else if (sipmethod == SIP_BYE) {
14506             char *auth, *auth2;
14507 
14508             auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate");
14509             auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization");
14510             if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) {
14511                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
14512                ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14513             }
14514          }
14515          break;
14516       case 481:   /* Call leg does not exist */
14517          if (sipmethod == SIP_INVITE) {
14518             /* Re-invite failed */
14519             handle_response_invite(p, resp, rest, req, seqno);
14520          } else if (sipmethod == SIP_BYE) {
14521             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14522          } else if (sipmethod == SIP_NOTIFY) {
14523             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14524          } else if (sipdebug) {
14525             ast_log  (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
14526          }
14527          break;
14528       case 501: /* Not Implemented */
14529          if (sipmethod == SIP_INVITE) 
14530             handle_response_invite(p, resp, rest, req, seqno);
14531          else if (sipmethod == SIP_REFER) 
14532             handle_response_refer(p, resp, rest, req, seqno);
14533          break;
14534       case 603:   /* Declined transfer */
14535          if (sipmethod == SIP_REFER) {
14536             handle_response_refer(p, resp, rest, req, seqno);
14537             break;
14538          }
14539          /* Fallthrough */
14540       default: /* Errors without handlers */
14541          if ((resp >= 100) && (resp < 200)) {
14542             if (sipmethod == SIP_INVITE) {   /* re-invite */
14543                if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p))
14544                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
14545             }
14546          }
14547          if ((resp >= 300) && (resp < 700)) {
14548             if ((option_verbose > 2) && (resp != 487))
14549                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));
14550             switch(resp) {
14551             case 488: /* Not acceptable here - codec error */
14552             case 603: /* Decline */
14553             case 500: /* Server error */
14554             case 502: /* Bad gateway */
14555             case 503: /* Service Unavailable */
14556             case 504: /* Server timeout */
14557 
14558                /* re-invite failed */
14559                if (sipmethod == SIP_INVITE && sip_cancel_destroy(p))
14560                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
14561                break;
14562             }
14563          }
14564          break;
14565       }
14566    }
14567 }

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.

Definition at line 13518 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_random(), ast_rtp_set_rtptimers_onhold(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, sip_invite_param::auth_type, authenticate(), sip_pvt::authtries, build_route(), sip_pvt::callid, check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, ast_channel::name, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, sched, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_OUTGOING_CALL, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_reinvite_retry(), sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::theirtag, transmit_reinvite_with_sdp(), transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), sip_pvt::vrtp, sip_pvt::waitid, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.

Referenced by handle_response().

13519 {
13520    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
13521    int res = 0;
13522    int xmitres = 0;
13523    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
13524    struct ast_channel *bridgepeer = NULL;
13525 
13526    if (option_debug > 3) {
13527       if (reinvite)
13528          ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
13529       else
13530          ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp);
13531    }
13532 
13533    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */
13534       if (option_debug)
13535          ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
13536       return;
13537    }
13538 
13539    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
13540    /* Don't auto congest anymore since we've gotten something useful back */
13541    AST_SCHED_DEL(sched, p->initid);
13542 
13543    /* RFC3261 says we must treat every 1xx response (but not 100)
13544       that we don't recognize as if it was 183.
13545    */
13546    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183)
13547       resp = 183;
13548 
13549    /* Any response between 100 and 199 is PROCEEDING */
13550    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
13551       p->invitestate = INV_PROCEEDING;
13552  
13553    /* Final response, not 200 ? */
13554    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
13555       p->invitestate = INV_COMPLETED;
13556       
13557 
13558    switch (resp) {
13559    case 100:   /* Trying */
13560    case 101:   /* Dialog establishment */
13561       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
13562          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
13563       check_pendings(p);
13564       break;
13565 
13566    case 180:   /* 180 Ringing */
13567    case 182:       /* 182 Queued */
13568       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
13569          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
13570       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
13571          ast_queue_control(p->owner, AST_CONTROL_RINGING);
13572          if (p->owner->_state != AST_STATE_UP) {
13573             ast_setstate(p->owner, AST_STATE_RINGING);
13574          }
13575       }
13576       if (find_sdp(req)) {
13577          if (p->invitestate != INV_CANCELLED)
13578             p->invitestate = INV_EARLY_MEDIA;
13579          res = process_sdp(p, req);
13580          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
13581             /* Queue a progress frame only if we have SDP in 180 or 182 */
13582             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
13583          }
13584       }
13585       check_pendings(p);
13586       break;
13587 
13588    case 183:   /* Session progress */
13589       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
13590          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
13591       if (find_sdp(req)) {
13592          if (p->invitestate != INV_CANCELLED)
13593             p->invitestate = INV_EARLY_MEDIA;
13594          res = process_sdp(p, req);
13595          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
13596             /* Queue a progress frame */
13597             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
13598          }
13599       } else {
13600          /* Alcatel PBXs are known to send 183s with no SDP after sending
13601           * a 100 Trying response. We're just going to treat this sort of thing
13602           * the same as we would treat a 180 Ringing
13603           */
13604          if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
13605             ast_queue_control(p->owner, AST_CONTROL_RINGING);
13606          }
13607       }
13608       check_pendings(p);
13609       break;
13610 
13611    case 200:   /* 200 OK on invite - someone's answering our call */
13612       if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
13613          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
13614       p->authtries = 0;
13615       if (find_sdp(req)) {
13616          if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE))
13617             if (!reinvite)
13618                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
13619                /* For re-invites, we try to recover */
13620                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
13621       }
13622 
13623       /* Parse contact header for continued conversation */
13624       /* When we get 200 OK, we know which device (and IP) to contact for this call */
13625       /* This is important when we have a SIP proxy between us and the phone */
13626       if (outgoing) {
13627          update_call_counter(p, DEC_CALL_RINGING);
13628          parse_ok_contact(p, req);
13629          /* Save Record-Route for any later requests we make on this dialogue */
13630          if (!reinvite)
13631             build_route(p, req, 1);
13632 
13633          if(set_address_from_contact(p)) {
13634             /* Bad contact - we don't know how to reach this device */
13635             /* We need to ACK, but then send a bye */
13636             if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE))
13637                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
13638          } 
13639 
13640       }
13641       
13642       if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */
13643          struct sip_pvt *bridgepvt = NULL;
13644 
13645          if (!bridgepeer->tech) {
13646             ast_log(LOG_WARNING, "Ooooh.. no tech!  That's REALLY bad\n");
13647             break;
13648          }
13649          if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
13650             bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
13651             if (bridgepvt->udptl) {
13652                if (p->t38.state == T38_PEER_REINVITE) {
13653                   sip_handle_t38_reinvite(bridgepeer, p, 0);
13654                   ast_rtp_set_rtptimers_onhold(p->rtp);
13655                   if (p->vrtp)
13656                      ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */
13657                }
13658             } else {
13659                if (option_debug > 1)
13660                   ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n");
13661                ast_mutex_lock(&bridgepvt->lock);
13662                bridgepvt->t38.state = T38_DISABLED;
13663                ast_mutex_unlock(&bridgepvt->lock);
13664                if (option_debug)
13665                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type);
13666                p->t38.state = T38_DISABLED;
13667                if (option_debug > 1)
13668                   ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
13669             }
13670          } else {
13671             /* Other side is not a SIP channel */
13672             if (option_debug > 1)
13673                ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n");
13674             p->t38.state = T38_DISABLED;
13675             if (option_debug > 1)
13676                ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
13677          }
13678       }
13679       if (p->t38.state == T38_LOCAL_REINVITE) {
13680          /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */
13681          p->t38.state = T38_ENABLED;
13682          if (option_debug)
13683             ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
13684       }
13685 
13686       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
13687          if (!reinvite) {
13688             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
13689          } else { /* RE-invite */
13690             ast_queue_frame(p->owner, &ast_null_frame);
13691          }
13692       } else {
13693           /* It's possible we're getting an 200 OK after we've tried to disconnect
13694               by sending CANCEL */
13695          /* First send ACK, then send bye */
13696          if (!ast_test_flag(req, SIP_PKT_IGNORE))
13697             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
13698       }
13699       /* If I understand this right, the branch is different for a non-200 ACK only */
13700       p->invitestate = INV_TERMINATED;
13701       ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
13702       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
13703       check_pendings(p);
13704       break;
13705    case 407: /* Proxy authentication */
13706    case 401: /* Www auth */
13707       /* First we ACK */
13708       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
13709       if (p->options)
13710          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
13711 
13712       /* Then we AUTH */
13713       ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
13714       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
13715          char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate");
13716          char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization");
13717          if (p->authtries < MAX_AUTHTRIES)
13718             p->invitestate = INV_CALLING;
13719          if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) {
13720             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
13721             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13722             sip_alreadygone(p);
13723             if (p->owner)
13724                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
13725          }
13726       }
13727       break;
13728 
13729    case 403: /* Forbidden */
13730       /* First we ACK */
13731       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
13732       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
13733       if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner)
13734          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
13735       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13736       sip_alreadygone(p);
13737       break;
13738 
13739    case 404: /* Not found */
13740       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
13741       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
13742          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
13743       sip_alreadygone(p);
13744       break;
13745 
13746    case 408: /* Request timeout */
13747    case 481: /* Call leg does not exist */
13748       /* Could be REFER caused INVITE with replaces */
13749       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
13750       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
13751       if (p->owner)
13752          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
13753       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13754       break;
13755    case 487: /* Cancelled transaction */
13756       /* We have sent CANCEL on an outbound INVITE 
13757          This transaction is already scheduled to be killed by sip_hangup().
13758       */
13759       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
13760       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
13761          ast_queue_hangup(p->owner);
13762          append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
13763       } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
13764          update_call_counter(p, DEC_CALL_LIMIT);
13765          append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
13766          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13767          sip_alreadygone(p);
13768       }
13769       break;
13770    case 488: /* Not acceptable here */
13771    case 606: /* Not Acceptable */
13772       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
13773       if (reinvite && p->udptl) {
13774          p->t38.state = T38_DISABLED;
13775          /* Try to reset RTP timers */
13776          ast_rtp_set_rtptimers_onhold(p->rtp);
13777          /* Trigger a reinvite back to audio */
13778          transmit_reinvite_with_sdp(p);
13779 
13780          if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */
13781             struct sip_pvt *bridgepvt = NULL;
13782             if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
13783                bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
13784                if (bridgepvt->udptl) {
13785                   sip_handle_t38_reinvite(bridgepeer, p, 0);
13786                }
13787             }
13788          }
13789       } else {
13790          /* We can't set up this call, so give up */
13791          if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE))
13792             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
13793          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
13794          /* If there's no dialog to end, then mark p as already gone */
13795          if (!reinvite)
13796             sip_alreadygone(p);
13797       }
13798       break;
13799    case 491: /* Pending */
13800       /* we really should have to wait a while, then retransmit
13801        * We should support the retry-after at some point 
13802        * At this point, we treat this as a congestion if the call is not in UP state 
13803        */
13804       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
13805       if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) {
13806          if (p->owner->_state != AST_STATE_UP) {
13807             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
13808             ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
13809          } else {
13810             /* This is a re-invite that failed.
13811              * Reset the flag after a while 
13812              */
13813             int wait;
13814             /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds,
13815              * if not owner of call, wait 0 to 2 seconds */
13816             if (ast_test_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL)) {
13817                wait = 2100 + ast_random() % 2000;
13818             } else {
13819                wait = ast_random() % 2000;
13820             }
13821 
13822             if (p->waitid != -1) {
13823                if (option_debug > 2)
13824                   ast_log(LOG_DEBUG, "Reinvite race during existing reinvite race. Abandoning previous reinvite retry.\n");
13825                AST_SCHED_DEL(sched, p->waitid);
13826                p->waitid = -1;
13827             }
13828 
13829             p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p);
13830             if (option_debug > 2)
13831                ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait);
13832          }
13833       }
13834       break;
13835 
13836    case 501: /* Not implemented */
13837       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
13838       if (p->owner)
13839          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
13840       break;
13841    }
13842    if (xmitres == XMIT_ERROR)
13843       ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
13844 }

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

Handle qualification responses (OPTIONS).

Definition at line 14042 of file chan_sip.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, global_flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::name, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, sip_destroy_peer(), SIP_NEEDDESTROY, SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().

Referenced by handle_response().

14043 {
14044    struct sip_peer *peer = p->relatedpeer;
14045    int statechanged, is_reachable, was_reachable;
14046    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
14047 
14048    /*
14049     * Compute the response time to a ping (goes in peer->lastms.)
14050     * -1 means did not respond, 0 means unknown,
14051     * 1..maxms is a valid response, >maxms means late response.
14052     */
14053    if (pingtime < 1) /* zero = unknown, so round up to 1 */
14054       pingtime = 1;
14055 
14056    /* Now determine new state and whether it has changed.
14057     * Use some helper variables to simplify the writing
14058     * of the expressions.
14059     */
14060    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
14061    is_reachable = pingtime <= peer->maxms;
14062    statechanged = peer->lastms == 0 /* yes, unknown before */
14063       || was_reachable != is_reachable;
14064 
14065    peer->lastms = pingtime;
14066    peer->call = NULL;
14067    if (statechanged) {
14068       const char *s = is_reachable ? "Reachable" : "Lagged";
14069       char str_lastms[20];
14070       snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime);
14071 
14072       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
14073          peer->name, s, pingtime, peer->maxms);
14074       ast_device_state_changed("SIP/%s", peer->name);
14075       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) {
14076          ast_update_realtime("sippeers", "name", peer->name, "lastms", str_lastms, NULL);
14077       }
14078       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
14079          "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
14080          peer->name, s, pingtime);
14081    }
14082 
14083    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
14084       struct sip_peer *peer_ptr = peer;
14085       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
14086    }
14087 
14088    ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
14089 
14090    /* Try again eventually */
14091    peer->pokeexpire = ast_sched_add(sched,
14092       is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
14093       sip_poke_peer_s, ASTOBJ_REF(peer));
14094 
14095    if (peer->pokeexpire == -1) {
14096       ASTOBJ_UNREF(peer, sip_destroy_peer);
14097    }
14098 }

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

Definition at line 13849 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::authname, sip_pvt::authtries, sip_pvt::callid, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.

Referenced by handle_response().

13850 {
13851    char *auth = "Proxy-Authenticate";
13852    char *auth2 = "Proxy-Authorization";
13853 
13854    /* If no refer structure exists, then do nothing */
13855    if (!p->refer)
13856       return;
13857 
13858    switch (resp) {
13859    case 202:   /* Transfer accepted */
13860       /* We need  to do something here */
13861       /* The transferee is now sending INVITE to target */
13862       p->refer->status = REFER_ACCEPTED;
13863       /* Now wait for next message */
13864       if (option_debug > 2)
13865          ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
13866       /* We should hang along, waiting for NOTIFY's here */
13867       break;
13868 
13869    case 401:   /* Not www-authorized on SIP method */
13870    case 407:   /* Proxy auth */
13871       if (ast_strlen_zero(p->authname)) {
13872          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
13873             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
13874          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
13875       }
13876       if (resp == 401) {
13877          auth = "WWW-Authenticate";
13878          auth2 = "Authorization";
13879       }
13880       if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
13881          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
13882          p->refer->status = REFER_NOAUTH;
13883          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
13884       }
13885       break;
13886    case 481: /* Call leg does not exist */
13887 
13888       /* A transfer with Replaces did not work */
13889       /* OEJ: We should Set flag, cancel the REFER, go back
13890       to original call - but right now we can't */
13891       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
13892       if (p->owner)
13893          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
13894       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
13895       break;
13896 
13897    case 500:   /* Server error */
13898    case 501:   /* Method not implemented */
13899       /* Return to the current call onhold */
13900       /* Status flag needed to be reset */
13901       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
13902       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
13903       p->refer->status = REFER_FAILED;
13904       break;
13905    case 603:   /* Transfer declined */
13906       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
13907       p->refer->status = REFER_FAILED;
13908       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
13909       break;
13910    }
13911 }

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

Handle responses on REGISTER to services.

Definition at line 13914 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, sip_pvt::callid, sip_registry::contact, 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_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_pvt::our_contact, sip_pvt::peername, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, S_OR, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, sip_registry::timeout, sip_pvt::username, and sip_registry::username.

Referenced by handle_response().

13915 {
13916    int expires, expires_ms;
13917    struct sip_registry *r;
13918    r=p->registry;
13919 
13920    switch (resp) {
13921    case 401:   /* Unauthorized */
13922       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
13923          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
13924          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13925          }
13926       break;
13927    case 403:   /* Forbidden */
13928       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
13929       if (global_regattempts_max)
13930          p->registry->regattempts = global_regattempts_max+1;
13931       AST_SCHED_DEL(sched, r->timeout);
13932       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13933       break;
13934    case 404:   /* Not found */
13935       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
13936       if (global_regattempts_max)
13937          p->registry->regattempts = global_regattempts_max+1;
13938       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13939       r->call = NULL;
13940       AST_SCHED_DEL(sched, r->timeout);
13941       break;
13942    case 407:   /* Proxy auth */
13943       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
13944          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
13945          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13946       }
13947       break;
13948    case 408:   /* Request timeout */
13949       /* Got a timeout response, so reset the counter of failed responses */
13950       if (r) {
13951          r->regattempts = 0;
13952       } else {
13953          ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid);
13954       }
13955       break;
13956    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
13957       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
13958       if (global_regattempts_max)
13959          p->registry->regattempts = global_regattempts_max+1;
13960       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13961       r->call = NULL;
13962       AST_SCHED_DEL(sched, r->timeout);
13963       break;
13964    case 200:   /* 200 OK */
13965       if (!r) {
13966          ast_log(LOG_WARNING, "Got 200 OK on REGISTER, but there isn't a registry entry for '%s' (we probably already got the OK)\n", S_OR(p->peername, p->username));
13967          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
13968          return 0;
13969       }
13970 
13971       r->regstate = REG_STATE_REGISTERED;
13972       r->regtime = time(NULL);      /* Reset time of last succesful registration */
13973       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
13974       r->regattempts = 0;
13975       if (option_debug)
13976          ast_log(LOG_DEBUG, "Registration successful\n");
13977       if (r->timeout > -1) {
13978          if (option_debug)
13979             ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
13980       }
13981       AST_SCHED_DEL(sched, r->timeout);
13982       r->call = NULL;
13983       p->registry = NULL;
13984       /* Let this one hang around until we have all the responses */
13985       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13986       /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */
13987 
13988       /* set us up for re-registering */
13989       /* figure out how long we got registered for */
13990       AST_SCHED_DEL(sched, r->expire);
13991       /* according to section 6.13 of RFC, contact headers override
13992          expires headers, so check those first */
13993       expires = 0;
13994 
13995       /* XXX todo: try to save the extra call */
13996       if (!ast_strlen_zero(get_header(req, "Contact"))) {
13997          const char *contact = NULL;
13998          const char *tmptmp = NULL;
13999          int start = 0;
14000          for(;;) {
14001             contact = __get_header(req, "Contact", &start);
14002             /* this loop ensures we get a contact header about our register request */
14003             if(!ast_strlen_zero(contact)) {
14004                if( (tmptmp=strstr(contact, p->our_contact))) {
14005                   contact=tmptmp;
14006                   break;
14007                }
14008             } else
14009                break;
14010          }
14011          tmptmp = strcasestr(contact, "expires=");
14012          if (tmptmp) {
14013             if (sscanf(tmptmp + 8, "%30d;", &expires) != 1)
14014                expires = 0;
14015          }
14016 
14017       }
14018       if (!expires) 
14019          expires=atoi(get_header(req, "expires"));
14020       if (!expires)
14021          expires=default_expiry;
14022 
14023       expires_ms = expires * 1000;
14024       if (expires <= EXPIRY_GUARD_LIMIT)
14025          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
14026       else
14027          expires_ms -= EXPIRY_GUARD_SECS * 1000;
14028       if (sipdebug)
14029          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
14030 
14031       r->refresh= (int) expires_ms / 1000;
14032 
14033       /* Schedule re-registration before we expire */
14034       AST_SCHED_DEL(sched, r->expire);
14035       r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 
14036       ASTOBJ_UNREF(r, sip_registry_destroy);
14037    }
14038    return 1;
14039 }

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

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

Referenced by sip_hangup().

03782 {
03783    switch (cause) {
03784       case AST_CAUSE_UNALLOCATED:      /* 1 */
03785       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
03786       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
03787          return "404 Not Found";
03788       case AST_CAUSE_CONGESTION:    /* 34 */
03789       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
03790          return "503 Service Unavailable";
03791       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
03792          return "408 Request Timeout";
03793       case AST_CAUSE_NO_ANSWER:     /* 19 */
03794       case AST_CAUSE_UNREGISTERED:        /* 20 */
03795          return "480 Temporarily unavailable";
03796       case AST_CAUSE_CALL_REJECTED:    /* 21 */
03797          return "403 Forbidden";
03798       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
03799          return "410 Gone";
03800       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
03801          return "480 Temporarily unavailable";
03802       case AST_CAUSE_INVALID_NUMBER_FORMAT:
03803          return "484 Address incomplete";
03804       case AST_CAUSE_USER_BUSY:
03805          return "486 Busy here";
03806       case AST_CAUSE_FAILURE:
03807          return "500 Server internal failure";
03808       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
03809          return "501 Not Implemented";
03810       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
03811          return "503 Service Unavailable";
03812       /* Used in chan_iax2 */
03813       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03814          return "502 Bad Gateway";
03815       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
03816          return "488 Not Acceptable Here";
03817          
03818       case AST_CAUSE_NOTDEFINED:
03819       default:
03820          if (option_debug)
03821             ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
03822          return NULL;
03823    }
03824 
03825    /* Never reached */
03826    return 0;
03827 }

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 3669 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_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.

Referenced by handle_response().

03670 {
03671    /* Possible values taken from causes.h */
03672 
03673    switch(cause) {
03674       case 401:   /* Unauthorized */
03675          return AST_CAUSE_CALL_REJECTED;
03676       case 403:   /* Not found */
03677          return AST_CAUSE_CALL_REJECTED;
03678       case 404:   /* Not found */
03679          return AST_CAUSE_UNALLOCATED;
03680       case 405:   /* Method not allowed */
03681          return AST_CAUSE_INTERWORKING;
03682       case 407:   /* Proxy authentication required */
03683          return AST_CAUSE_CALL_REJECTED;
03684       case 408:   /* No reaction */
03685          return AST_CAUSE_NO_USER_RESPONSE;
03686       case 409:   /* Conflict */
03687          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
03688       case 410:   /* Gone */
03689          return AST_CAUSE_NUMBER_CHANGED;
03690       case 411:   /* Length required */
03691          return AST_CAUSE_INTERWORKING;
03692       case 413:   /* Request entity too large */
03693          return AST_CAUSE_INTERWORKING;
03694       case 414:   /* Request URI too large */
03695          return AST_CAUSE_INTERWORKING;
03696       case 415:   /* Unsupported media type */
03697          return AST_CAUSE_INTERWORKING;
03698       case 420:   /* Bad extension */
03699          return AST_CAUSE_NO_ROUTE_DESTINATION;
03700       case 480:   /* No answer */
03701          return AST_CAUSE_NO_ANSWER;
03702       case 481:   /* No answer */
03703          return AST_CAUSE_INTERWORKING;
03704       case 482:   /* Loop detected */
03705          return AST_CAUSE_INTERWORKING;
03706       case 483:   /* Too many hops */
03707          return AST_CAUSE_NO_ANSWER;
03708       case 484:   /* Address incomplete */
03709          return AST_CAUSE_INVALID_NUMBER_FORMAT;
03710       case 485:   /* Ambigous */
03711          return AST_CAUSE_UNALLOCATED;
03712       case 486:   /* Busy everywhere */
03713          return AST_CAUSE_BUSY;
03714       case 487:   /* Request terminated */
03715          return AST_CAUSE_INTERWORKING;
03716       case 488:   /* No codecs approved */
03717          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03718       case 491:   /* Request pending */
03719          return AST_CAUSE_INTERWORKING;
03720       case 493:   /* Undecipherable */
03721          return AST_CAUSE_INTERWORKING;
03722       case 500:   /* Server internal failure */
03723          return AST_CAUSE_FAILURE;
03724       case 501:   /* Call rejected */
03725          return AST_CAUSE_FACILITY_REJECTED;
03726       case 502:   
03727          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03728       case 503:   /* Service unavailable */
03729          return AST_CAUSE_CONGESTION;
03730       case 504:   /* Gateway timeout */
03731          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
03732       case 505:   /* SIP version not supported */
03733          return AST_CAUSE_INTERWORKING;
03734       case 600:   /* Busy everywhere */
03735          return AST_CAUSE_USER_BUSY;
03736       case 603:   /* Decline */
03737          return AST_CAUSE_CALL_REJECTED;
03738       case 604:   /* Does not exist anywhere */
03739          return AST_CAUSE_UNALLOCATED;
03740       case 606:   /* Not acceptable */
03741          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03742       default:
03743          return AST_CAUSE_NORMAL;
03744    }
03745    /* Never reached */
03746    return 0;
03747 }

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

Initialize SIP request.

Definition at line 6711 of file chan_sip.c.

References sip_methods, and cfsip_methods::text.

06712 {
06713    /* Initialize a request */
06714    memset(req, 0, sizeof(*req));
06715         req->method = sipmethod;
06716    req->header[0] = req->data;
06717    snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
06718    req->len = strlen(req->header[0]);
06719    req->headers++;
06720    return 0;
06721 }

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

Initialize SIP response, based on SIP request.

Definition at line 6698 of file chan_sip.c.

References SIP_RESPONSE.

06699 {
06700    /* Initialize a response */
06701    memset(resp, 0, sizeof(*resp));
06702    resp->method = SIP_RESPONSE;
06703    resp->header[0] = resp->data;
06704    snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg);
06705    resp->len = strlen(resp->header[0]);
06706    resp->headers++;
06707    return 0;
06708 }

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

References ast_log(), ast_test_flag, ast_verbose(), sip_pvt::callid, 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().

01760 {
01761    if (p->initreq.headers && option_debug) {
01762       ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
01763    }
01764    /* Use this as the basis */
01765    copy_request(&p->initreq, req);
01766    parse_request(&p->initreq);
01767    if (ast_test_flag(req, SIP_PKT_DEBUG))
01768       ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
01769 }

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

Initiate new SIP request to peer/user.

Definition at line 7866 of file chan_sip.c.

References add_header(), add_route(), 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::callid, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_pvt::fromdomain, FROMDOMAIN_INVALID, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, sip_pvt::portinuri, sip_pvt::route, sip_pvt::rpid, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, SIPBUFSIZE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::tohost, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url.

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

07867 {
07868    char invite_buf[256] = "";
07869    char *invite = invite_buf;
07870    size_t invite_max = sizeof(invite_buf);
07871    char from[256];
07872    char to[256];
07873    char tmp[SIPBUFSIZE/2];
07874    char tmp2[SIPBUFSIZE/2];
07875    const char *l = NULL, *n = NULL, *d = NULL;
07876    const char *urioptions = "";
07877 
07878    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
07879       const char *s = p->username;  /* being a string field, cannot be NULL */
07880 
07881       /* Test p->username against allowed characters in AST_DIGIT_ANY
07882          If it matches the allowed characters list, then sipuser = ";user=phone"
07883          If not, then sipuser = ""
07884       */
07885       /* + is allowed in first position in a tel: uri */
07886       if (*s == '+')
07887          s++;
07888       for (; *s; s++) {
07889          if (!strchr(AST_DIGIT_ANYNUM, *s) )
07890             break;
07891       }
07892       /* If we have only digits, add ;user=phone to the uri */
07893       if (!*s)
07894          urioptions = ";user=phone";
07895    }
07896 
07897 
07898    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
07899 
07900    d = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
07901    if (p->owner) {
07902       l = p->owner->cid.cid_num;
07903       n = p->owner->cid.cid_name;
07904    }
07905    /* if we are not sending RPID and user wants his callerid restricted */
07906    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
07907        ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
07908       l = CALLERID_UNKNOWN;
07909       n = l;
07910       d = FROMDOMAIN_INVALID;
07911    }
07912    if (ast_strlen_zero(l))
07913       l = default_callerid;
07914    if (ast_strlen_zero(n))
07915       n = l;
07916    /* Allow user to be overridden */
07917    if (!ast_strlen_zero(p->fromuser))
07918       l = p->fromuser;
07919    else /* Save for any further attempts */
07920       ast_string_field_set(p, fromuser, l);
07921 
07922    /* Allow user to be overridden */
07923    if (!ast_strlen_zero(p->fromname))
07924       n = p->fromname;
07925    else /* Save for any further attempts */
07926       ast_string_field_set(p, fromname, n);
07927 
07928    if (pedanticsipchecking) {
07929       ast_uri_encode(n, tmp, sizeof(tmp), 0);
07930       n = tmp;
07931       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
07932       l = tmp2;
07933    }
07934 
07935    if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
07936       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag);
07937    else
07938       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag);
07939 
07940    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
07941    if (!ast_strlen_zero(p->fullcontact)) {
07942       /* If we have full contact, trust it */
07943       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
07944    } else {
07945       /* Otherwise, use the username while waiting for registration */
07946       ast_build_string(&invite, &invite_max, "sip:");
07947       if (!ast_strlen_zero(p->username)) {
07948          n = p->username;
07949          if (pedanticsipchecking) {
07950             ast_uri_encode(n, tmp, sizeof(tmp), 0);
07951             n = tmp;
07952          }
07953          ast_build_string(&invite, &invite_max, "%s@", n);
07954       }
07955       ast_build_string(&invite, &invite_max, "%s", p->tohost);
07956       if (p->portinuri)
07957          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
07958       ast_build_string(&invite, &invite_max, "%s", urioptions);
07959    }
07960 
07961    /* If custom URI options have been provided, append them */
07962    if (p->options && !ast_strlen_zero(p->options->uri_options))
07963       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
07964    
07965    ast_string_field_set(p, uri, invite_buf);
07966 
07967    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
07968       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
07969       snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag);
07970    } else if (p->options && p->options->vxml_url) {
07971       /* If there is a VXML URL append it to the SIP URL */
07972       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
07973    } else 
07974       snprintf(to, sizeof(to), "<%s>", p->uri);
07975    
07976    init_req(req, sipmethod, p->uri);
07977    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
07978 
07979    add_header(req, "Via", p->via);
07980    /* This will be a no-op most of the time. However, under certain circumstances,
07981     * NOTIFY messages will use this function for preparing the request and should
07982     * have Route headers present.
07983     */
07984    add_route(req, p->route);
07985    /* Build Remote Party-ID and From */
07986    if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
07987       build_rpid(p);
07988       add_header(req, "From", p->rpid_from);
07989    } else 
07990       add_header(req, "From", from);
07991    add_header(req, "To", to);
07992    ast_string_field_set(p, exten, l);
07993    build_contact(p);
07994    add_header(req, "Contact", p->our_contact);
07995    add_header(req, "Call-ID", p->callid);
07996    add_header(req, "CSeq", tmp);
07997    if (!ast_strlen_zero(global_useragent))
07998       add_header(req, "User-Agent", global_useragent);
07999    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
08000    if (!ast_strlen_zero(p->rpid))
08001       add_header(req, "Remote-Party-ID", p->rpid);
08002 }

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

Convert Insecure setting to printable string.

Definition at line 11474 of file chan_sip.c.

Referenced by _sip_show_peer().

11475 {
11476    if (port && invite)
11477       return "port,invite";
11478    else if (port)
11479       return "port";
11480    else if (invite)
11481       return "invite";
11482    else
11483       return "no";
11484 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 9268 of file chan_sip.c.

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

Referenced by build_route().

09269 {
09270    if (!route)
09271       ast_verbose("list_route: no route\n");
09272    else {
09273       for (;route; route = route->next)
09274          ast_verbose("list_route: hop: <%s>\n", route->hop);
09275    }
09276 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 20297 of file chan_sip.c.

References app_dtmfmode, app_sipaddheader, 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, descrip_dtmfmode, descrip_sipaddheader, 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, synopsis_dtmfmode, synopsis_sipaddheader, and userl.

20298 {
20299    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
20300    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
20301    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
20302 
20303    if (!(sched = sched_context_create())) {
20304       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
20305       return AST_MODULE_LOAD_FAILURE;
20306    }
20307 
20308    if (!(io = io_context_create())) {
20309       ast_log(LOG_ERROR, "Unable to create I/O context\n");
20310       sched_context_destroy(sched);
20311       return AST_MODULE_LOAD_FAILURE;
20312    }
20313 
20314    sip_reloadreason = CHANNEL_MODULE_LOAD;
20315 
20316    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
20317       return AST_MODULE_LOAD_DECLINE;
20318 
20319    /* Make sure we can register our sip channel type */
20320    if (ast_channel_register(&sip_tech)) {
20321       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
20322       io_context_destroy(io);
20323       sched_context_destroy(sched);
20324       return AST_MODULE_LOAD_FAILURE;
20325    }
20326 
20327    /* Register all CLI functions for SIP */
20328    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
20329 
20330    /* Tell the RTP subdriver that we're here */
20331    ast_rtp_proto_register(&sip_rtp);
20332 
20333    /* Tell the UDPTL subdriver that we're here */
20334    ast_udptl_proto_register(&sip_udptl);
20335 
20336    /* Register dialplan applications */
20337    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
20338    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
20339 
20340    /* Register dialplan functions */
20341    ast_custom_function_register(&sip_header_function);
20342    ast_custom_function_register(&sippeer_function);
20343    ast_custom_function_register(&sipchaninfo_function);
20344    ast_custom_function_register(&checksipdomain_function);
20345 
20346    /* Register manager commands */
20347    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
20348          "List SIP peers (text format)", mandescr_show_peers);
20349    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
20350          "Show SIP peer (text format)", mandescr_show_peer);
20351 
20352    sip_poke_all_peers();   
20353    sip_send_all_registers();
20354    
20355    /* And start the monitor for the first time */
20356    restart_monitor();
20357 
20358    return AST_MODULE_LOAD_SUCCESS;
20359 }

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

References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_hangup(), ast_indicate(), 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, ast_channel::name, 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(), and TRUE.

Referenced by handle_request_refer().

16072 {
16073    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
16074                /* Chan 2: Call from Asterisk to target */
16075    int res = 0;
16076    struct sip_pvt *targetcall_pvt;
16077 
16078    /* Check if the call ID of the replaces header does exist locally */
16079    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
16080       transferer->refer->replaces_callid_fromtag))) {
16081       if (transferer->refer->localtransfer) {
16082          /* We did not find the refered call. Sorry, can't accept then */
16083          /* Let's fake a response from someone else in order
16084             to follow the standard */
16085          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
16086          append_history(transferer, "Xfer", "Refer failed");
16087          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);  
16088          transferer->refer->status = REFER_FAILED;
16089          return -1;
16090       }
16091       /* Fall through for remote transfers that we did not find locally */
16092       if (option_debug > 2)
16093          ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
16094       return 0;
16095    }
16096 
16097    /* Ok, we can accept this transfer */
16098    append_history(transferer, "Xfer", "Refer accepted");
16099    if (!targetcall_pvt->owner) { /* No active channel */
16100       if (option_debug > 3)
16101          ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n");
16102       /* Cancel transfer */
16103       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
16104       append_history(transferer, "Xfer", "Refer failed");
16105       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
16106       transferer->refer->status = REFER_FAILED;
16107       ast_mutex_unlock(&targetcall_pvt->lock);
16108       return -1;
16109    }
16110 
16111    /* We have a channel, find the bridge */
16112    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
16113    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
16114 
16115    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
16116       /* Wrong state of new channel */
16117       if (option_debug > 3) {
16118          if (target.chan2) 
16119             ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
16120          else if (target.chan1->_state != AST_STATE_RING)
16121             ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n");
16122          else
16123             ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n");
16124       }
16125    }
16126 
16127    /* Transfer */
16128    if (option_debug > 3 && sipdebug) {
16129       if (current->chan2)  /* We have two bridges */
16130          ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
16131       else        /* One bridge, propably transfer of IVR/voicemail etc */
16132          ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
16133    }
16134 
16135    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
16136 
16137    /* Perform the transfer */
16138    res = attempt_transfer(current, &target);
16139    ast_mutex_unlock(&targetcall_pvt->lock);
16140    if (res) {
16141       /* Failed transfer */
16142       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
16143       append_history(transferer, "Xfer", "Refer failed");
16144       transferer->refer->status = REFER_FAILED;
16145       if (targetcall_pvt->owner)
16146          ast_channel_unlock(targetcall_pvt->owner);
16147       /* Right now, we have to hangup, sorry. Bridge is destroyed */
16148       if (res != -2)
16149          ast_hangup(transferer->owner);
16150       else
16151          ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
16152    } else {
16153       /* Transfer succeeded! */
16154 
16155       /* Tell transferer that we're done. */
16156       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
16157       append_history(transferer, "Xfer", "Refer succeeded");
16158       transferer->refer->status = REFER_200OK;
16159       if (targetcall_pvt->owner) {
16160          if (option_debug)
16161             ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
16162          ast_channel_unlock(targetcall_pvt->owner);
16163       }
16164       ast_indicate(target.chan1, AST_CONTROL_UNHOLD);
16165       if (target.chan2) {
16166          ast_indicate(target.chan2, AST_CONTROL_UNHOLD);
16167       }
16168    }
16169    return 1;
16170 }

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

References t.

Referenced by sipsock_read().

05388 {
05389    int h = 0, t = 0; 
05390    int lws = 0; 
05391 
05392    for (; h < len;) { 
05393       /* Eliminate all CRs */ 
05394       if (msgbuf[h] == '\r') { 
05395          h++; 
05396          continue; 
05397       } 
05398       /* Check for end-of-line */ 
05399       if (msgbuf[h] == '\n') { 
05400          /* Check for end-of-message */ 
05401          if (h + 1 == len) 
05402             break; 
05403          /* Check for a continuation line */ 
05404          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
05405             /* Merge continuation line */ 
05406             h++; 
05407             continue; 
05408          } 
05409          /* Propagate LF and start new line */ 
05410          msgbuf[t++] = msgbuf[h++]; 
05411          lws = 0;
05412          continue; 
05413       } 
05414       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
05415          if (lws) { 
05416             h++; 
05417             continue; 
05418          } 
05419          msgbuf[t++] = msgbuf[h++]; 
05420          lws = 1; 
05421          continue; 
05422       } 
05423       msgbuf[t++] = msgbuf[h++]; 
05424       if (lws) 
05425          lws = 0; 
05426    } 
05427    msgbuf[t] = '\0'; 
05428    return t; 
05429 }

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

Make our SIP dialog tag.

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

04865 {
04866    snprintf(tagbuf, len, "as%08lx", ast_random());
04867 }

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

Show SIP peers in the manager API.

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

11727 {
11728    const char *a[4];
11729    const char *peer;
11730    int ret;
11731 
11732    peer = astman_get_header(m,"Peer");
11733    if (ast_strlen_zero(peer)) {
11734       astman_send_error(s, m, "Peer: <name> missing.");
11735       return 0;
11736    }
11737    a[0] = "sip";
11738    a[1] = "show";
11739    a[2] = "peer";
11740    a[3] = peer;
11741 
11742    ret = _sip_show_peer(1, -1, s, m, 4, a);
11743    astman_append(s, "\r\n\r\n" );
11744    return ret;
11745 }

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

Show SIP peers in the manager API.

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

11271 {
11272    const char *id = astman_get_header(m,"ActionID");
11273    const char *a[] = {"sip", "show", "peers"};
11274    char idtext[256] = "";
11275    int total = 0;
11276 
11277    if (!ast_strlen_zero(id))
11278       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
11279 
11280    astman_send_ack(s, m, "Peer status list will follow");
11281    /* List the peers in separate manager events */
11282    _sip_show_peers(-1, &total, s, m, 3, a);
11283    /* Send final confirmation */
11284    astman_append(s,
11285    "Event: PeerlistComplete\r\n"
11286    "ListItems: %d\r\n"
11287    "%s"
11288    "\r\n", total, idtext);
11289    return 0;
11290 }

static void markall_extenstate_updates ( void   )  [static]

Definition at line 9717 of file chan_sip.c.

References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, sip_extenstate_update::list, and update().

Referenced by do_monitor().

09718 {
09719    struct sip_extenstate_update *update = NULL;
09720 
09721    if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
09722       /* avoid holding the lock if possible */
09723       return;
09724    }
09725 
09726    AST_LIST_LOCK(&sip_extenstate_updates);
09727    AST_LIST_TRAVERSE(&sip_extenstate_updates, update, list) {
09728       update->marked = 1;
09729    }
09730    AST_LIST_UNLOCK(&sip_extenstate_updates);
09731 }

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

References sip_request::len, sip_methods, and text.

Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().

01786 {
01787    int len = strlen(sip_methods[id].text);
01788    int l_name = name ? strlen(name) : 0;
01789    /* true if the string is long enough, and ends with whitespace, and matches */
01790    return (l_name >= len && name[len] < 33 &&
01791       !strncasecmp(sip_methods[id].text, name, len));
01792 }

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

Convert NAT setting to text string.

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

11174 {
11175    switch(nat) {
11176    case SIP_NAT_NEVER:
11177       return "No";
11178    case SIP_NAT_ROUTE:
11179       return "Route";
11180    case SIP_NAT_ALWAYS:
11181       return "Always";
11182    case SIP_NAT_RFC3581:
11183       return "RFC3581";
11184    default:
11185       return "Unknown";
11186    }
11187 }

static int notify_extenstate_update ( 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 9760 of file chan_sip.c.

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

Referenced by check_extenstate_updates(), and handle_response().

09761 {
09762    struct sip_pvt *p = data;
09763 
09764    ast_mutex_lock(&p->lock);
09765 
09766    switch(state) {
09767    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
09768    case AST_EXTENSION_REMOVED:   /* Extension is gone */
09769       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
09770          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
09771       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
09772       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);
09773       p->stateid = -1;
09774       p->subscribed = NONE;
09775       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
09776       break;
09777    default: /* Tell user */
09778       p->laststate = state;
09779       break;
09780    }
09781    if (p->subscribed != NONE) {  /* Only send state NOTIFY if we know the format */
09782       if (!p->pendinginvite) {
09783          transmit_state_notify(p, state, 1, FALSE);
09784       } else {
09785          /* We already have a NOTIFY sent that is not answered. Queue the state up.
09786             if many state changes happen meanwhile, we will only send a notification of the last one */
09787          ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
09788       }
09789    }
09790    if (option_verbose > 1)
09791       ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username,
09792             ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
09793 
09794    
09795    ast_mutex_unlock(&p->lock);
09796 
09797    return 0;
09798 }

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

Copy SIP request, parse it.

Definition at line 2387 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

02388 {
02389    memset(dst, 0, sizeof(*dst));
02390    memcpy(dst->data, src->data, sizeof(dst->data));
02391    dst->len = src->len;
02392    parse_request(dst);
02393 }

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

Parse 302 Moved temporalily response.

Definition at line 13397 of file chan_sip.c.

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

Referenced by handle_response().

13398 {
13399    char tmp[SIPBUFSIZE];
13400    char *s, *e, *uri, *t;
13401    char *domain;
13402 
13403    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
13404    if ((t = strchr(tmp, ',')))
13405       *t = '\0';
13406    s = get_in_brackets(tmp);
13407    uri = ast_strdupa(s);
13408    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
13409       if (!strncasecmp(s, "sip:", 4))
13410          s += 4;
13411       e = strchr(s, ';');
13412       if (e)
13413          *e = '\0';
13414       if (option_debug)
13415          ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
13416       if (p->owner)
13417          ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
13418    } else {
13419       e = strchr(tmp, '@');
13420       if (e) {
13421          *e++ = '\0';
13422          domain = e;
13423       } else {
13424          /* No username part */
13425          domain = tmp;
13426       }
13427       e = strchr(s, ';');  /* Strip of parameters in the username part */
13428       if (e)
13429          *e = '\0';
13430       e = strchr(domain, ';');   /* Strip of parameters in the domain part */
13431       if (e)
13432          *e = '\0';
13433    
13434       if (!strncasecmp(s, "sip:", 4))
13435          s += 4;
13436       ast_uri_decode(s);
13437       if (option_debug > 1)
13438          ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
13439       if (p->owner) {
13440          pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri);
13441          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
13442          ast_string_field_set(p->owner, call_forward, s);
13443       }
13444    }
13445 }

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

References ast_copy_string(), ast_string_field_set, sip_peer::fullcontact, get_header(), get_in_brackets(), SIPBUFSIZE, and TRUE.

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

08978 {
08979    char contact[SIPBUFSIZE]; 
08980    char *c;
08981 
08982    /* Look for brackets */
08983    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
08984    c = get_in_brackets(contact);
08985 
08986    /* Save full contact to call pvt for later bye or re-invite */
08987    ast_string_field_set(pvt, fullcontact, c);
08988 
08989    /* Save URI for later ACKs, BYE or RE-invites */
08990    ast_string_field_set(pvt, okcontacturi, c);
08991 
08992    /* We should return false for URI:s we can't handle,
08993       like sips:, tel:, mailto:,ldap: etc */
08994    return TRUE;      
08995 }

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

References __get_header(), sip_peer::addr, ahp, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_sched_when(), AST_SENSE_ALLOW, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::contactha, EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), global_contact_ha, hp, inaddrcmp(), LOG_NOTICE, manager_event(), sip_peer::name, option_verbose, PARSE_REGISTER_DENIED, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_peer::portinuri, sip_pvt::recv, register_peer_exten(), sched, sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.

Referenced by register_verify().

09067 {
09068    char contact[SIPBUFSIZE]; 
09069    char data[SIPBUFSIZE];
09070    const char *expires = get_header(req, "Expires");
09071    int expiry = atoi(expires);
09072    char *curi, *n, *pt;
09073    int port;
09074    const char *useragent;
09075    struct hostent *hp;
09076    struct ast_hostent ahp;
09077    struct sockaddr_in oldsin, testsin;
09078    char *firstcuri = NULL;
09079    int start = 0;
09080    int wildcard_found = 0;
09081    int single_binding_found = 0;
09082 
09083    ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
09084 
09085    if (ast_strlen_zero(expires)) {  /* No expires header */
09086       expires = strcasestr(contact, ";expires=");
09087       if (expires) {
09088          /* XXX bug here, we overwrite the string */
09089          expires = strsep((char **) &expires, ";"); /* trim ; and beyond */
09090          if (sscanf(expires + 9, "%30d", &expiry) != 1)
09091             expiry = default_expiry;
09092       } else {
09093          /* Nothing has been specified */
09094          expiry = default_expiry;
09095       }
09096    }
09097 
09098    do {
09099       /* Look for brackets */
09100       curi = contact;
09101       if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
09102          strsep(&curi, ";");  /* This is Header options, not URI options */
09103       curi = get_in_brackets(contact);
09104       if (!firstcuri) {
09105          firstcuri = ast_strdupa(curi);
09106       }
09107 
09108       if (!strcasecmp(curi, "*")) {
09109          wildcard_found = 1;
09110       } else {
09111          single_binding_found = 1;
09112       }
09113 
09114       if (wildcard_found && (ast_strlen_zero(expires) || expiry != 0 || single_binding_found)) {
09115          /* Contact header parameter "*" detected, so punt if: Expires header is missing,
09116           * Expires value is not zero, or another Contact header is present. */
09117          return PARSE_REGISTER_FAILED;
09118       }
09119 
09120       ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
09121    } while (!ast_strlen_zero(contact));
09122    curi = firstcuri;
09123 
09124    /* if they did not specify Contact: or Expires:, they are querying
09125       what we currently have stored as their contact address, so return
09126       it
09127    */
09128    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
09129       /* If we have an active registration, tell them when the registration is going to expire */
09130       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact))
09131          pvt->expiry = ast_sched_when(sched, peer->expire);
09132       return PARSE_REGISTER_QUERY;
09133    } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */
09134       /* This means remove all registrations and return OK */
09135       if (!AST_SCHED_DEL(sched, peer->expire)) {
09136          struct sip_peer *peer_ptr = peer;
09137          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
09138       }
09139 
09140       expire_register(ASTOBJ_REF(peer));
09141 
09142       if (option_verbose > 2)
09143          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name);
09144 
09145       return PARSE_REGISTER_UPDATE;
09146    }
09147 
09148    /* Store whatever we got as a contact from the client */
09149    ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact));
09150 
09151    /* For the 200 OK, we should use the received contact */
09152    ast_string_field_build(pvt, our_contact, "<%s>", curi);
09153 
09154    /* Make sure it's a SIP URL */
09155    if (strncasecmp(curi, "sip:", 4)) {
09156       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
09157    } else
09158       curi += 4;
09159    /* Ditch q */
09160    curi = strsep(&curi, ";");
09161    /* Grab host */
09162    n = strchr(curi, '@');
09163    if (!n) {
09164       n = curi;
09165       curi = NULL;
09166    } else
09167       *n++ = '\0';
09168    pt = strchr(n, ':');
09169    if (pt) {
09170       *pt++ = '\0';
09171       port = atoi(pt);
09172       peer->portinuri = 1;
09173    } else {
09174       port = STANDARD_SIP_PORT;
09175       peer->portinuri = 0;
09176    }
09177    oldsin = peer->addr;
09178 
09179    if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
09180       /* use the data provided in the Contact header for call routing */
09181       /* XXX This could block for a long time XXX */
09182       hp = ast_gethostbyname(n, &ahp);
09183       if (!hp)  {
09184          ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
09185          *peer->fullcontact = '\0';
09186          ast_string_field_set(pvt, our_contact, "");
09187          return PARSE_REGISTER_FAILED;
09188       }
09189 
09190       peer->addr.sin_family = AF_INET;
09191       memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
09192       peer->addr.sin_port = htons(port);
09193    } else {
09194       /* Don't trust the contact field.  Just use what they came to us
09195          with */
09196       peer->addr = pvt->recv;
09197    }
09198 
09199    /* Check that they're allowed to register at this IP */
09200    memcpy(&testsin.sin_addr, &peer->addr.sin_addr, sizeof(testsin.sin_addr));
09201    if (ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW ||
09202          ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) {
09203       ast_log(LOG_WARNING, "Host '%s' disallowed by contact ACL (violating IP %s)\n", n, ast_inet_ntoa(testsin.sin_addr));
09204       *peer->fullcontact = '\0';
09205       ast_string_field_set(pvt, our_contact, "");
09206       return PARSE_REGISTER_DENIED;
09207    }
09208 
09209    /* Save SIP options profile */
09210    peer->sipoptions = pvt->sipoptions;
09211 
09212    if (curi && ast_strlen_zero(peer->username))
09213       ast_copy_string(peer->username, curi, sizeof(peer->username));
09214 
09215    if (!AST_SCHED_DEL(sched, peer->expire)) {
09216       struct sip_peer *peer_ptr = peer;
09217       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
09218    }
09219    if (expiry > max_expiry)
09220       expiry = max_expiry;
09221    if (expiry < min_expiry)
09222       expiry = min_expiry;
09223    if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
09224       peer->expire = -1;
09225    } else {
09226       peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
09227       if (peer->expire == -1) {
09228          struct sip_peer *peer_ptr = peer;
09229          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
09230       }
09231    }
09232    pvt->expiry = expiry;
09233    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);
09234    if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
09235       ast_db_put("SIP/Registry", peer->name, data);
09236    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
09237 
09238    /* Is this a new IP address for us? */
09239    if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) {
09240       ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port));
09241    }
09242    sip_poke_peer(peer);
09243    register_peer_exten(peer, 1);
09244    
09245    /* Save User agent */
09246    useragent = get_header(req, "User-Agent");
09247    if (strcasecmp(useragent, peer->useragent)) {   /* XXX copy if they are different ? */
09248       ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent));
09249       if (option_verbose > 3)
09250          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);  
09251    }
09252    return PARSE_REGISTER_UPDATE;
09253 }

static int parse_request ( struct sip_request req  )  [static]

Parse a SIP message.

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

Definition at line 5434 of file chan_sip.c.

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

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

05435 {
05436    /* Divide fields by NULL's */
05437    char *c;
05438    int f = 0;
05439 
05440    c = req->data;
05441 
05442    /* First header starts immediately */
05443    req->header[f] = c;
05444    while(*c) {
05445       if (*c == '\n') {
05446          /* We've got a new header */
05447          *c = 0;
05448 
05449          if (sipdebug && option_debug > 3)
05450             ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
05451          if (ast_strlen_zero(req->header[f])) {
05452             /* Line by itself means we're now in content */
05453             c++;
05454             break;
05455          }
05456          if (f >= SIP_MAX_HEADERS - 1) {
05457             ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n");
05458          } else {
05459             f++;
05460             req->header[f] = c + 1;
05461          }
05462       } else if (*c == '\r') {
05463          /* Ignore but eliminate \r's */
05464          *c = 0;
05465       }
05466       c++;
05467    }
05468 
05469    req->headers = f;
05470 
05471    /* Check a non-newline-terminated last header */
05472    if (!ast_strlen_zero(req->header[f])) {
05473       if (sipdebug && option_debug > 3)
05474          ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f]));
05475       req->headers++;
05476    }
05477 
05478    /* Now we process any body content */
05479    f = 0;
05480    req->line[f] = c;
05481    while (*c) {
05482       if (*c == '\n') {
05483          /* We've got a new line */
05484          *c = 0;
05485          if (sipdebug && option_debug > 3)
05486             ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
05487          if (f == SIP_MAX_LINES - 1) {
05488             ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n");
05489             break;
05490          } else {
05491             f++;
05492             req->line[f] = c + 1;
05493          }
05494       } else if (*c == '\r') {
05495          /* Ignore and eliminate \r's */
05496          *c = 0;
05497       }
05498       c++;
05499    }
05500 
05501    req->lines = f;
05502 
05503    /* Check a non-newline-terminated last line */
05504    if (!ast_strlen_zero(req->line[f])) {
05505       if (sipdebug && option_debug > 3)
05506          ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f]));
05507       req->lines++;
05508    }
05509 
05510    if (*c) 
05511       ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c);
05512 
05513    /* Split up the first line parts */
05514    return determine_firstline_parts(req);
05515 }

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

Parse supported header in incoming packet.

Definition at line 1809 of file chan_sip.c.

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

Referenced by handle_request_invite().

01810 {
01811    char *next, *sep;
01812    char *temp;
01813    unsigned int profile = 0;
01814    int i, found;
01815 
01816    if (ast_strlen_zero(supported) )
01817       return 0;
01818    temp = ast_strdupa(supported);
01819 
01820    if (option_debug > 2 && sipdebug)
01821       ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported);
01822 
01823    for (next = temp; next; next = sep) {
01824       found = FALSE;
01825       if ( (sep = strchr(next, ',')) != NULL)
01826          *sep++ = '\0';
01827       next = ast_skip_blanks(next);
01828       if (option_debug > 2 && sipdebug)
01829          ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next);
01830       for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) {
01831          if (!strcasecmp(next, sip_options[i].text)) {
01832             profile |= sip_options[i].id;
01833             found = TRUE;
01834             if (option_debug > 2 && sipdebug)
01835                ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next);
01836             break;
01837          }
01838       }
01839       if (!found && option_debug > 2 && sipdebug) {
01840          if (!strncasecmp(next, "x-", 2))
01841             ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next);
01842          else
01843             ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next);
01844       }
01845    }
01846 
01847    if (pvt)
01848       pvt->sipoptions = profile;
01849    return profile;
01850 }

static struct sip_via * parse_via ( const char *  header  )  [static]

Parse a Via header.

This function parses the Via header and processes it according to section 18.2 of RFC 3261 and RFC 3581. Since we don't have a transport layer, we only care about the maddr and ttl parms. The received and rport params are not parsed.

Note:
This function fails to parse some odd combinations of SWS in parameter lists.
 VIA syntax. RFC 3261 section 25.1
 Via               =  ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm)
 via-parm          =  sent-protocol LWS sent-by *( SEMI via-params )
 via-params        =  via-ttl / via-maddr
                   / via-received / via-branch
                   / via-extension
 via-ttl           =  "ttl" EQUAL ttl
 via-maddr         =  "maddr" EQUAL host
 via-received      =  "received" EQUAL (IPv4address / IPv6address)
 via-branch        =  "branch" EQUAL token
 via-extension     =  generic-param
 sent-protocol     =  protocol-name SLASH protocol-version
                   SLASH transport
 protocol-name     =  "SIP" / token
 protocol-version  =  token
 transport         =  "UDP" / "TCP" / "TLS" / "SCTP"
                   / other-transport
 sent-by           =  host [ COLON port ]
 ttl               =  1*3DIGIT ; 0 to 255

Definition at line 5051 of file chan_sip.c.

References ast_calloc, ast_log(), ast_skip_blanks(), ast_strdup, ast_strlen_zero(), free_via(), LOG_ERROR, and sip_via::via.

Referenced by process_via().

05052 {
05053    struct sip_via *v = ast_calloc(1, sizeof(*v));
05054    char *via, *parm;
05055 
05056    if (!v) {
05057       return NULL;
05058    }
05059 
05060    v->via = ast_strdup(header);
05061    v->ttl = 1;
05062 
05063    via = v->via;
05064 
05065    if (ast_strlen_zero(via)) {
05066       ast_log(LOG_ERROR, "received request without a Via header\n");
05067       free_via(v);
05068       return NULL;
05069    }
05070 
05071    /* seperate the first via-parm */
05072    via = strsep(&via, ",");
05073 
05074    /* chop off sent-protocol */
05075    v->protocol = strsep(&via, " \t\r\n");
05076    if (ast_strlen_zero(v->protocol)) {
05077       ast_log(LOG_ERROR, "missing sent-protocol in Via header\n");
05078       free_via(v);
05079       return NULL;
05080    }
05081    v->protocol = ast_skip_blanks(v->protocol);
05082 
05083    if (via) {
05084       via = ast_skip_blanks(via);
05085    }
05086 
05087    /* chop off sent-by */
05088    v->sent_by = strsep(&via, "; \t\r\n");
05089    if (ast_strlen_zero(v->sent_by)) {
05090       ast_log(LOG_ERROR, "missing sent-by in Via header\n");
05091       free_via(v);
05092       return NULL;
05093    }
05094    v->sent_by = ast_skip_blanks(v->sent_by);
05095 
05096    /* store the port */
05097    if ((parm = strchr(v->sent_by, ':'))) {
05098       char *endptr;
05099 
05100       v->port = strtol(++parm, &endptr, 10);
05101    }
05102 
05103    /* evaluate any via-parms */
05104    while ((parm = strsep(&via, "; \t\r\n"))) {
05105       char *c;
05106       if ((c = strstr(parm, "maddr="))) {
05107          v->maddr = ast_skip_blanks(c + sizeof("maddr=") - 1);
05108       } else if ((c = strstr(parm, "branch="))) {
05109          v->branch = ast_skip_blanks(c + sizeof("branch=") - 1);
05110       } else if ((c = strstr(parm, "ttl="))) {
05111          char *endptr;
05112          c = ast_skip_blanks(c + sizeof("ttl=") - 1);
05113          v->ttl = strtol(c, &endptr, 10);
05114 
05115          /* make sure we got a valid ttl value */
05116          if (c == endptr) {
05117             v->ttl = 1;
05118          }
05119       }
05120    }
05121 
05122    return v;
05123 }

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

References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.

11193 {
11194    int res = 0;
11195    if (peer->maxms) {
11196       if (peer->lastms < 0) {
11197          ast_copy_string(status, "UNREACHABLE", statuslen);
11198       } else if (peer->lastms > peer->maxms) {
11199          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
11200          res = 1;
11201       } else if (peer->lastms) {
11202          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
11203          res = 1;
11204       } else {
11205          ast_copy_string(status, "UNKNOWN", statuslen);
11206       }
11207    } else { 
11208       ast_copy_string(status, "Unmonitored", statuslen);
11209       /* Checking if port is 0 */
11210       res = -1;
11211    }
11212    return res;
11213 }

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

11668 {
11669    int x, codec;
11670 
11671    for(x = 0; x < 32 ; x++) {
11672       codec = ast_codec_pref_index(pref, x);
11673       if (!codec)
11674          break;
11675       ast_cli(fd, "%s", ast_getformatname(codec));
11676       ast_cli(fd, ":%d", pref->framing[x]);
11677       if (x < 31 && ast_codec_pref_index(pref, x + 1))
11678          ast_cli(fd, ",");
11679    }
11680    if (!x)
11681       ast_cli(fd, "none");
11682 }

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

Print call group and pickup group.

Definition at line 11451 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

11452 {
11453    char buf[256];
11454    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
11455 }

static void process_request_queue ( struct sip_pvt p,
int *  recount,
int *  nounlock 
) [static]

Definition at line 17359 of file chan_sip.c.

References ast_free, AST_LIST_REMOVE_HEAD, ast_log(), handle_request(), LOG_DEBUG, sip_request::next, option_debug, and sip_pvt::request_queue.

Referenced by sipsock_read().

17360 {
17361    struct sip_request *req;
17362 
17363    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
17364       if (handle_request(p, req, &p->recv, recount, nounlock) == -1) {
17365          /* Request failed */
17366          if (option_debug) {
17367             ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
17368          }
17369       }
17370       ast_free(req);
17371    }
17372 }

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 host IP

< RTP video host IP

< UDPTL host IP

< RTP Audio port number

< RTP Video port number

< UDPTL Image port number

< media socket address

< video socket address

< image socket address

< Buffers for codec handling

< Negotiated capability

Definition at line 5706 of file chan_sip.c.

References ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_get_peer(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::callid, t38properties::capability, sip_pvt::capability, change_hold_state(), debug, t38properties::direct, FALSE, sip_pvt::flags, get_sdp_iterate(), get_sdp_line(), ast_hostent::hp, 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, sip_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, sip_pvt::noncodeccapability, offered_media::offered, sip_pvt::offered_media, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, portno, sip_pvt::prefs, process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_video(), process_sdp_c(), ast_channel::readformat, sip_pvt::rtp, S_OR, SDP_AUDIO, SDP_IMAGE, sip_request::sdp_start, SDP_VIDEO, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_NAT, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_UDP_EC_NONE, TRUE, type, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_NONE, sip_pvt::vrtp, and ast_channel::writeformat.

05707 {
05708    /* Iterators for SDP parsing */
05709    int start = req->sdp_start;
05710    int next = start;
05711    int iterator = start;
05712 
05713    /* Temporary vars for SDP parsing */
05714    char type = '\0';
05715    const char *value = NULL;
05716    const char *m = NULL;           /* SDP media offer */
05717    const char *nextm = NULL;
05718    int len = -1;
05719 
05720    /* Host information */
05721    struct ast_hostent audiohp;
05722    struct ast_hostent videohp;
05723    struct ast_hostent imagehp;
05724    struct ast_hostent sessionhp;
05725    struct hostent *hp = NULL; /*!< RTP Audio host IP */
05726    struct hostent *vhp = NULL;   /*!< RTP video host IP */
05727    struct hostent *ihp = NULL;   /*!< UDPTL host IP */
05728    int portno = -1;     /*!< RTP Audio port number */
05729    int vportno = -1;    /*!< RTP Video port number */
05730    int udptlportno = -1;      /*!< UDPTL Image port number */
05731    struct sockaddr_in sin = { 0, }; /*!< media socket address */
05732    struct sockaddr_in vsin = { 0, };   /*!< video socket address */
05733    struct sockaddr_in isin = { 0, };   /*!< image socket address */
05734 
05735    /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 
05736    int peercapability = 0, peernoncodeccapability = 0;
05737    int vpeercapability = 0, vpeernoncodeccapability = 0;
05738    struct ast_rtp *newaudiortp, *newvideortp;      /*!< Buffers for codec handling */
05739    int newjointcapability;             /*!< Negotiated capability */
05740    int newpeercapability;
05741    int newnoncodeccapability;
05742    const char *codecs;
05743    int codec;
05744 
05745    /* Others */
05746    int sendonly = -1;
05747    int vsendonly = -1;
05748    int numberofports;
05749    int numberofmediastreams = 0;
05750    int last_rtpmap_codec = 0;
05751    int debug = sip_debug_test_pvt(p);
05752 
05753    /* Initial check */
05754    if (!p->rtp) {
05755       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
05756       return -1;
05757    }
05758 
05759    /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */
05760 #ifdef LOW_MEMORY
05761    newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size());
05762 #else
05763    newaudiortp = alloca(ast_rtp_alloc_size());
05764 #endif
05765    memset(newaudiortp, 0, ast_rtp_alloc_size());
05766    ast_rtp_new_init(newaudiortp);
05767    ast_rtp_pt_clear(newaudiortp);
05768 
05769 #ifdef LOW_MEMORY
05770    newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size());
05771 #else
05772    newvideortp = alloca(ast_rtp_alloc_size());
05773 #endif
05774    memset(newvideortp, 0, ast_rtp_alloc_size());
05775    ast_rtp_new_init(newvideortp);
05776    ast_rtp_pt_clear(newvideortp);
05777 
05778 
05779    /* Update our last rtprx when we receive an SDP, too */
05780    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
05781 
05782    ast_set_flag(&p->flags[0], SIP_NOVIDEO);
05783 
05784    memset(p->offered_media, 0, sizeof(p->offered_media));
05785 
05786 
05787    /* Scan for the first media stream (m=) line to limit scanning of globals */
05788    nextm = get_sdp_iterate(&next, req, "m");
05789    if (ast_strlen_zero(nextm)) {
05790       ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n");
05791       return -1;
05792    }
05793 
05794    /* Scan session level SDP parameters (lines before first media stream) */
05795    while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
05796       int processed = FALSE;
05797       switch (type) {
05798       case 'c':
05799          if (process_sdp_c(value, &sessionhp)) {
05800             processed = TRUE;
05801             hp = &sessionhp.hp;
05802             vhp = hp;
05803             ihp = hp;
05804          }
05805          break;
05806       case 'a':
05807          if (process_sdp_a_sendonly(value, &sendonly)) {
05808             processed = TRUE;
05809             vsendonly = sendonly;
05810          }
05811          else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec))
05812             processed = TRUE;
05813          else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec))
05814             processed = TRUE;
05815          else if (process_sdp_a_image(value, p))
05816             processed = TRUE;
05817          break;
05818       }
05819 
05820       if (option_debug > 2)
05821          ast_log(LOG_DEBUG, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED.");
05822    }
05823 
05824 
05825    /* Scan media stream (m=) specific parameters loop */
05826    while (!ast_strlen_zero(nextm)) {
05827       int audio = FALSE;
05828       int video = FALSE;
05829       int image = FALSE;
05830       int x;
05831 
05832       numberofports = 1;
05833       len = -1;
05834       start = next;
05835       m = nextm;
05836       iterator = next;
05837       nextm = get_sdp_iterate(&next, req, "m");
05838 
05839       /* Search for audio media definition */
05840       if ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
05841           (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0)) {
05842          /* Found audio stream in this media definition */
05843          audio = TRUE;
05844          p->offered_media[SDP_AUDIO].offered = TRUE;
05845          numberofmediastreams++;
05846          portno = x;
05847 
05848          /* Scan through the RTP payload types specified in a "m=" line: */
05849          codecs = m + len;
05850          ast_copy_string(p->offered_media[SDP_AUDIO].text, codecs, sizeof(p->offered_media[SDP_AUDIO].text));
05851          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
05852             if (sscanf(codecs, "%30d%n", &codec, &len) != 1) {
05853                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
05854                return -1;
05855             }
05856             if (debug)
05857                ast_verbose("Found RTP audio format %d\n", codec);
05858             ast_rtp_set_m_type(newaudiortp, codec);
05859          }
05860       /* Search for video media definition */
05861       } else if ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
05862             (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len >= 0)) {
05863          /* Found video stream in this media definition */
05864          video = TRUE;
05865          ast_clear_flag(&p->flags[0], SIP_NOVIDEO);
05866          p->offered_media[SDP_VIDEO].offered = TRUE;
05867          numberofmediastreams++;
05868          vportno = x;
05869 
05870          /* Scan through the RTP payload types specified in a "m=" line: */
05871          codecs = m + len;
05872          ast_copy_string(p->offered_media[SDP_VIDEO].text, codecs, sizeof(p->offered_media[SDP_VIDEO].text));
05873          for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
05874             if (sscanf(codecs, "%30d%n", &codec, &len) != 1) {
05875                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
05876                return -1;
05877             }
05878             if (debug)
05879                ast_verbose("Found RTP video format %d\n", codec);
05880             ast_rtp_set_m_type(newvideortp, codec);
05881          }
05882       /* Search for image media definition */
05883       } else if (p->udptl && ((sscanf(m, "image %30d udptl t38%n", &x, &len) == 1 && len > 0) || 
05884                (sscanf(m, "image %30d UDPTL t38%n", &x, &len) == 1 && len >= 0))) {
05885          /* Found image stream in this media definition */
05886          image = TRUE;
05887          if (debug)
05888             ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
05889          p->offered_media[SDP_IMAGE].offered = TRUE;
05890          udptlportno = x;
05891          numberofmediastreams++;
05892          
05893          if (p->owner && p->lastinvite) {
05894             if (p->t38.state != T38_LOCAL_REINVITE) {
05895                p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */
05896                if (option_debug > 1)
05897                   ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" );
05898             }
05899          } else {
05900             p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */
05901             p->t38.direct = 1;
05902             if (option_debug > 1)
05903                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
05904          }
05905 
05906          /* default EC to none, the remote end should respond
05907           * with the EC they want to use */
05908          p->t38.peercapability &= ~T38FAX_UDP_EC_NONE;
05909          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
05910       } else {
05911          ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m);
05912          continue;
05913       }
05914 
05915       /* Check for number of ports */
05916       if (numberofports > 1)
05917          ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
05918       
05919 
05920 
05921       /* Media stream specific parameters */
05922       while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
05923          int processed = FALSE;
05924 
05925          switch (type) {
05926          case 'c':
05927             if (audio) {
05928                if (process_sdp_c(value, &audiohp)) {
05929                   processed = TRUE;
05930                   hp = &audiohp.hp;
05931                }
05932             }
05933             else if (video) {
05934                if (process_sdp_c(value, &videohp)) {
05935                   processed = TRUE;
05936                   vhp = &videohp.hp;
05937                }
05938             } else if (image) {
05939                if (process_sdp_c(value, &imagehp)) {
05940                   processed = TRUE;
05941                   ihp = &imagehp.hp;
05942                }
05943             }
05944             break;
05945          case 'a':
05946             /* Audio specific scanning */
05947             if (audio) {
05948                if (process_sdp_a_sendonly(value, &sendonly))
05949                   processed = TRUE;
05950                else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec))
05951                   processed = TRUE;
05952             }
05953             /* Video specific scanning */
05954             else if (video) {
05955                if (process_sdp_a_sendonly(value, &vsendonly))
05956                   processed = TRUE;
05957                else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec))
05958                   processed = TRUE;
05959             }
05960             /* Image (T.38 FAX) specific scanning */
05961             else if (image) {
05962                if (process_sdp_a_image(value, p))
05963                   processed = TRUE;
05964             }
05965             break;
05966          }
05967 
05968          if (option_debug > 2)
05969             ast_log(LOG_DEBUG, "Processing media-level (%s) SDP %c=%s... %s\n",
05970                   (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image",
05971                   type, value,
05972                   (processed == TRUE)? "OK." : "UNSUPPORTED.");
05973       }
05974    }
05975 
05976    /* Sanity checks */
05977    if (!hp && !vhp && !ihp) {
05978       ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
05979       return -1;
05980    }
05981 
05982    if (portno == -1 && vportno == -1 && udptlportno == -1)
05983       /* No acceptable offer found in SDP  - we have no ports */
05984       /* Do not change RTP or VRTP if this is a re-invite */
05985       return -2;
05986 
05987    if (numberofmediastreams > 2)
05988       /* We have too many fax, audio and/or video media streams, fail this offer */
05989       return -3;
05990 
05991    if (udptlportno == -1) {
05992       p->t38.state = T38_DISABLED;
05993       if (option_debug > 2)
05994          ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
05995    }
05996 
05997    
05998    /* Now gather all of the codecs that we are asked for: */
05999    ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability);
06000    ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability);
06001 
06002    newjointcapability = p->capability & (peercapability | vpeercapability);
06003    newpeercapability = (peercapability | vpeercapability);
06004    newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
06005       
06006       
06007    if (debug) {
06008       /* shame on whoever coded this.... */
06009       char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE];
06010 
06011       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n",
06012              ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability),
06013              ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability),
06014              ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
06015              ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability));
06016 
06017       ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
06018              ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0),
06019              ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0),
06020              ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0));
06021 
06022       ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n",
06023          p->t38.capability,
06024          p->t38.peercapability,
06025          p->t38.jointcapability);
06026 
06027    }
06028    if (!newjointcapability) {
06029       /* If T.38 was not negotiated either, totally bail out... */
06030       if (!p->t38.jointcapability || !udptlportno) {
06031          ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
06032          /* Do NOT Change current setting */
06033          return -1;
06034       } else {
06035          if (option_debug > 2)
06036             ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n");
06037       }
06038    }
06039 
06040    /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
06041       they are acceptable */
06042    p->jointcapability = newjointcapability;          /* Our joint codec profile */
06043    p->peercapability = newpeercapability;            /* The other sides capability in latest offer */
06044    p->jointnoncodeccapability = newnoncodeccapability;   /* DTMF capabilities */
06045 
06046    ast_rtp_pt_copy(p->rtp, newaudiortp);
06047    if (p->vrtp)
06048       ast_rtp_pt_copy(p->vrtp, newvideortp);
06049 
06050    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
06051       ast_clear_flag(&p->flags[0], SIP_DTMF);
06052       if (newnoncodeccapability & AST_RTP_DTMF) {
06053          /* XXX Would it be reasonable to drop the DSP at this point? XXX */
06054          ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
06055          /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
06056          ast_rtp_setdtmf(p->rtp, 1);
06057          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
06058       } else {
06059          ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
06060       }
06061    }
06062 
06063    /* Setup audio port number */
06064    if (p->rtp) {
06065       if (portno > 0) {
06066          sin.sin_family = AF_INET;
06067          sin.sin_port = htons(portno);
06068          memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
06069          ast_rtp_set_peer(p->rtp, &sin);
06070          if (debug)
06071             ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06072       } else if (udptlportno > 0) {
06073          if (debug)
06074             ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n");
06075       } else {
06076          ast_rtp_stop(p->rtp);
06077          if (debug)
06078             ast_verbose("Peer doesn't provide audio\n");
06079       }
06080    }
06081 
06082    /* Setup video port number */
06083    if (p->vrtp) {
06084       if (vportno > 0) {
06085          vsin.sin_family = AF_INET;
06086          vsin.sin_port = htons(vportno);
06087          memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr));
06088          ast_rtp_set_peer(p->vrtp, &vsin);
06089          if (debug) 
06090             ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port));
06091       } else {
06092          ast_rtp_stop(p->vrtp);
06093          if (debug)
06094             ast_verbose("Peer doesn't provide video\n");
06095       }
06096    }
06097 
06098    /* Setup image port number */
06099    if (p->udptl) {
06100       if (udptlportno > 0) {
06101          isin.sin_family = AF_INET;
06102          isin.sin_port = htons(udptlportno);
06103          if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) {
06104             struct sockaddr_in peer = { 0, };
06105             ast_rtp_get_peer(p->rtp, &peer);
06106             if (peer.sin_addr.s_addr) {
06107                memcpy(&isin.sin_addr, &peer.sin_addr, sizeof(isin.sin_addr));
06108                if (debug)
06109                   ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(isin.sin_addr));
06110             }
06111          } else
06112             memcpy(&isin.sin_addr, ihp->h_addr, sizeof(isin.sin_addr));
06113          ast_udptl_set_peer(p->udptl, &isin);
06114          if (debug)
06115             ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(isin.sin_addr), ntohs(isin.sin_port));
06116       } else {
06117          ast_udptl_stop(p->udptl);
06118          if (debug)
06119             ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n");
06120       }
06121    }
06122 
06123 
06124    /* Ok, we're going with this offer */
06125    if (option_debug > 1) {
06126       char buf[SIPBUFSIZE];
06127       ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability));
06128    }
06129 
06130    if (!p->owner)    /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
06131       return 0;
06132 
06133    if (option_debug > 3)
06134       ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n");
06135 
06136    if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
06137       if (debug) {
06138          char s1[SIPBUFSIZE], s2[SIPBUFSIZE];
06139          ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 
06140             ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability),
06141             ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats));
06142       }
06143       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability);
06144       ast_set_read_format(p->owner, p->owner->readformat);
06145       ast_set_write_format(p->owner, p->owner->writeformat);
06146    }
06147 
06148    /* sendonly processing */
06149    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) && (!sendonly || sendonly == -1)) {
06150       ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
06151       /* Activate a re-invite */
06152       ast_queue_frame(p->owner, &ast_null_frame);
06153    } else if (!(sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) || (sendonly && sendonly != -1)) {
06154       ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 
06155                    S_OR(p->mohsuggest, NULL),
06156                    !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
06157       if (sendonly)
06158          ast_rtp_stop(p->rtp);
06159       /* RTCP needs to go ahead, even if we're on hold!!! */
06160       /* Activate a re-invite */
06161       ast_queue_frame(p->owner, &ast_null_frame);
06162    }
06163 
06164    /* Manager Hold and Unhold events must be generated, if necessary */
06165    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) && (!sendonly || sendonly == -1))
06166       change_hold_state(p, req, FALSE, sendonly);
06167    else if (!(sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) || (sendonly && sendonly != -1))
06168       change_hold_state(p, req, TRUE, sendonly);
06169 
06170    return 0;
06171 }

static int process_sdp_a_audio ( const char *  a,
struct sip_pvt p,
struct ast_rtp newaudiortp,
int *  last_rtpmap_codec 
) [static]

Definition at line 6213 of file chan_sip.c.

References ast_codec_pref_setsize(), ast_log(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_set_rtpmap_type(), ast_rtp_unset_m_type(), ast_strdupa, ast_test_flag, ast_verbose(), sip_pvt::autoframing, debug, FALSE, sip_pvt::flags, format, LOG_DEBUG, MAX_RTP_PT, option_debug, sip_pvt::rtp, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), SIP_G726_NONSTANDARD, and TRUE.

Referenced by process_sdp().

06214 {
06215    int found = FALSE;
06216    int codec;
06217    char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
06218    int debug = sip_debug_test_pvt(p);
06219 
06220    if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) {
06221       char *tmp = strrchr(a, ':');
06222       long int framing = 0;
06223       if (tmp) {
06224          tmp++;
06225          framing = strtol(tmp, NULL, 10);
06226          if (framing == LONG_MIN || framing == LONG_MAX) {
06227             framing = 0;
06228             if (option_debug)
06229                ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a);
06230          }
06231       }
06232       if (framing && p->autoframing) {
06233          struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
06234          int codec_n;
06235          int format = 0;
06236          for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) {
06237             format = ast_rtp_codec_getformat(codec_n);
06238             if (!format)    /* non-codec or not found */
06239                continue;
06240             if (option_debug)
06241                ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing);
06242             ast_codec_pref_setsize(pref, format, framing);
06243          }
06244          ast_rtp_codec_setpref(p->rtp, pref);
06245       }
06246       found = TRUE;
06247    } else if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) {
06248       /* We have a rtpmap to handle */
06249       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
06250          /* Note: should really look at the 'freq' and '#chans' params too */
06251          if (ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype,
06252             ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) {
06253             if (debug)
06254                ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec);
06255             (*last_rtpmap_codec)++;
06256             found = TRUE;
06257          }
06258       } else {
06259          if (debug)
06260             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
06261       }
06262 
06263       if (!found) {
06264          /* Remove this codec since it's an unknown media type for us */
06265          ast_rtp_unset_m_type(newaudiortp, codec);
06266          if (debug)
06267             ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
06268       }
06269    }
06270 
06271    return found;
06272 }

static int process_sdp_a_image ( const char *  a,
struct sip_pvt p 
) [static]

Definition at line 6307 of file chan_sip.c.

References ast_log(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), t38properties::capability, FALSE, t38properties::jointcapability, LOG_DEBUG, option_debug, t38properties::peercapability, s, sip_pvt::t38, 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, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by process_sdp().

06308 {
06309    int found = FALSE;
06310    char s[256];
06311    int x;
06312 
06313    /* Scan trough the a= lines for T38 attributes and set apropriate fileds */
06314    if ((sscanf(a, "T38FaxMaxBuffer:%30d", &x) == 1)) {
06315       found = TRUE;
06316       if (option_debug > 2)
06317          ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x);
06318    } else if ((sscanf(a, "T38MaxBitRate:%30d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30d", &x) == 1)) {
06319       found = TRUE;
06320       if (option_debug > 2)
06321          ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x);
06322       switch (x) {
06323       case 14400:
06324          p->t38.peercapability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
06325          break;
06326       case 12000:
06327          p->t38.peercapability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
06328          break;
06329       case 9600:
06330          p->t38.peercapability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
06331          break;
06332       case 7200:
06333          p->t38.peercapability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
06334          break;
06335       case 4800:
06336          p->t38.peercapability |= T38FAX_RATE_4800 | T38FAX_RATE_2400;
06337          break;
06338       case 2400:
06339          p->t38.peercapability |= T38FAX_RATE_2400;
06340          break;
06341       }
06342    } else if ((sscanf(a, "T38FaxVersion:%30d", &x) == 1)) {
06343       found = TRUE;
06344       if (option_debug > 2)
06345          ast_log(LOG_DEBUG, "FaxVersion: %d\n",x);
06346       if (x == 0)
06347          p->t38.peercapability |= T38FAX_VERSION_0;
06348       else if (x == 1)
06349          p->t38.peercapability |= T38FAX_VERSION_1;
06350    } else if ((sscanf(a, "T38FaxMaxDatagram:%30d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30d", &x) == 1)) {
06351       found = TRUE;
06352       if (option_debug > 2)
06353          ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x);
06354       ast_udptl_set_far_max_datagram(p->udptl, x);
06355       ast_udptl_set_local_max_datagram(p->udptl, x);
06356    } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) {
06357       found = TRUE;
06358       if ((sscanf(a, "T38FaxFillBitRemoval:%30d", &x) == 1)) {
06359           if (option_debug > 2)
06360          ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x);
06361           if (x == 1)
06362          p->t38.peercapability |= T38FAX_FILL_BIT_REMOVAL;
06363       } else {
06364           if (option_debug > 2)
06365          ast_log(LOG_DEBUG, "FillBitRemoval\n");
06366           p->t38.peercapability |= T38FAX_FILL_BIT_REMOVAL;
06367       }
06368    } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) {
06369       found = TRUE;
06370       if ((sscanf(a, "T38FaxTranscodingMMR:%30d", &x) == 1)) {
06371           if (option_debug > 2)
06372          ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x);
06373           if (x == 1)
06374          p->t38.peercapability |= T38FAX_TRANSCODING_MMR;
06375       } else {
06376           if (option_debug > 2)
06377          ast_log(LOG_DEBUG, "Transcoding MMR\n");
06378           p->t38.peercapability |= T38FAX_TRANSCODING_MMR;
06379       }
06380    } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) {
06381       found = TRUE;
06382       if ((sscanf(a, "T38FaxTranscodingJBIG:%30d", &x) == 1)) {
06383           if (option_debug > 2)
06384          ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x);
06385           if (x == 1)
06386          p->t38.peercapability |= T38FAX_TRANSCODING_JBIG;
06387       } else {
06388           if (option_debug > 2)
06389          ast_log(LOG_DEBUG, "Transcoding JBIG\n");
06390           p->t38.peercapability |= T38FAX_TRANSCODING_JBIG;
06391       }
06392    } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) {
06393       found = TRUE;
06394       if (option_debug > 2)
06395          ast_log(LOG_DEBUG, "RateManagement: %s\n", s);
06396       if (!strcasecmp(s, "localTCF"))
06397          p->t38.peercapability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF;
06398       else if (!strcasecmp(s, "transferredTCF"))
06399          p->t38.peercapability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
06400    } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) {
06401       found = TRUE;
06402       if (option_debug > 2)
06403          ast_log(LOG_DEBUG, "UDP EC: %s\n", s);
06404       if (!strcasecmp(s, "t38UDPRedundancy")) {
06405          p->t38.peercapability |= T38FAX_UDP_EC_REDUNDANCY;
06406          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
06407       } else if (!strcasecmp(s, "t38UDPFEC")) {
06408          p->t38.peercapability |= T38FAX_UDP_EC_FEC;
06409          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
06410       } else {
06411          p->t38.peercapability |= T38FAX_UDP_EC_NONE;
06412          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
06413       }
06414    }
06415 
06416    if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */
06417       int t38speed = p->t38.peercapability & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400);
06418 
06419       p->t38.jointcapability = (p->t38.peercapability & 255); /* Put everything beside supported speeds settings */
06420       p->t38.jointcapability |= (t38speed & p->t38.capability); /* Put the lower of our's and peer's speed */
06421    }
06422 
06423    return found;
06424 }

static int process_sdp_a_sendonly ( const char *  a,
int *  sendonly 
) [static]

Definition at line 6193 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by process_sdp().

06194 {
06195    int found = FALSE;
06196 
06197    if (!strcasecmp(a, "sendonly")) {
06198       if (*sendonly == -1)
06199          *sendonly = 1;
06200       found = TRUE;
06201    } else if (!strcasecmp(a, "inactive")) {
06202       if (*sendonly == -1)
06203          *sendonly = 2;
06204       found = TRUE;
06205    }  else if (!strcasecmp(a, "sendrecv")) {
06206       if (*sendonly == -1)
06207          *sendonly = 0;
06208       found = TRUE;
06209    }
06210    return found;
06211 }

static int process_sdp_a_video ( const char *  a,
struct sip_pvt p,
struct ast_rtp newvideortp,
int *  last_rtpmap_codec 
) [static]

Definition at line 6274 of file chan_sip.c.

References ast_rtp_set_rtpmap_type(), ast_rtp_unset_m_type(), ast_strdupa, ast_verbose(), debug, FALSE, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), TRUE, and sip_pvt::vrtp.

Referenced by process_sdp().

06275 {
06276    int found = FALSE;
06277    int codec;
06278    char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
06279    int debug = sip_debug_test_pvt(p);
06280 
06281    if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) {
06282       /* We have a rtpmap to handle */
06283       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
06284          /* Note: should really look at the 'freq' and '#chans' params too */
06285          if (p->vrtp && ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) {
06286             if (debug)
06287                ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec);
06288             (*last_rtpmap_codec)++;
06289             found = TRUE;
06290          }
06291       } else {
06292          if (debug)
06293             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
06294       }
06295 
06296       if (!found) {
06297          /* Remove this codec since it's an unknown media type for us */
06298          ast_rtp_unset_m_type(newvideortp, codec);
06299          if (debug)
06300             ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
06301       }
06302    }
06303 
06304    return found;
06305 }

static int process_sdp_c ( const char *  c,
struct ast_hostent hp 
) [static]

Definition at line 6174 of file chan_sip.c.

References ast_gethostbyname(), ast_log(), FALSE, hp, and TRUE.

Referenced by process_sdp().

06175 {
06176    char host[258];
06177    struct hostent *hp;
06178 
06179    /* Check for Media-description-level-address */
06180    if (sscanf(c, "IN IP4 %255s", host) != 1) {
06181       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
06182       return FALSE;
06183    } else {
06184       if (!(hp = ast_gethostbyname(host, ast_hp))) {
06185          ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c);
06186          return FALSE;
06187       }
06188       return TRUE;
06189    }
06190    return FALSE;
06191 }

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

Process the Via header according to RFC 3261 section 18.2.2.

Parameters:
p a sip_pvt structure that will be modified according to the received header
req a sip request with a Via header to process
This function will update the destination of the response according to the Via header in the request and RFC 3261 section 18.2.2. We do not have a transport layer so we ignore certain values like the 'received' param (we set the destination address to the addres the request came from in the respprep() function).

Return values:
-1 error
0 success

Definition at line 5152 of file chan_sip.c.

References addr_is_multicast(), ahp, ast_gethostbyname(), ast_log(), free_via(), get_header(), hp, LOG_ERROR, sip_via::maddr, parse_via(), sip_via::port, sip_pvt::sa, sipsock, STANDARD_SIP_PORT, sip_via::ttl, and sip_via::via.

Referenced by respprep().

05153 {
05154    struct sip_via *via = parse_via(get_header(req, "Via"));
05155 
05156    if (!via) {
05157       ast_log(LOG_ERROR, "error processing via header\n");
05158       return -1;
05159    }
05160 
05161    if (via->maddr) {
05162       struct hostent *hp;
05163       struct ast_hostent ahp;
05164 
05165       hp = ast_gethostbyname(via->maddr, &ahp);
05166       if (hp == NULL)  {
05167          ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr);
05168          ast_log(LOG_ERROR, "error processing via header\n");
05169          free_via(via);
05170          return -1;
05171       }
05172 
05173       p->sa.sin_family = AF_INET;
05174       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
05175 
05176       if (addr_is_multicast(&p->sa.sin_addr)) {
05177          setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl));
05178       }
05179    }
05180 
05181    p->sa.sin_port = htons(via->port ? via->port : STANDARD_SIP_PORT);
05182 
05183    free_via(via);
05184    return 0;
05185 }

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

Definition at line 17424 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), sip_request::next, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sched, and scheduler_process_request_queue().

Referenced by sipsock_read().

17425 {
17426    struct sip_request *newreq;
17427 
17428    if (!(newreq = ast_calloc(1, sizeof(*newreq)))) {
17429       return -1;
17430    }
17431 
17432    copy_request(newreq, req);
17433    AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next);
17434    if (p->request_queue_sched_id == -1) {
17435       p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p);
17436    }
17437 
17438    return 0;
17439 }

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

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

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

Note:
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 2798 of file chan_sip.c.

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

02799 {
02800    struct sip_peer *peer=NULL;
02801    struct ast_variable *var = NULL;
02802    struct ast_config *peerlist = NULL;
02803    struct ast_variable *tmp;
02804    struct ast_flags flags = {0};
02805    const char *iabuf = NULL;
02806    char portstring[6]; /*up to five digits plus null terminator*/
02807    const char *insecure; 
02808    char *cat = NULL;
02809    unsigned short portnum;
02810 
02811    /* First check on peer name */
02812    if (newpeername) {
02813       var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL);
02814       if (!var && sin)
02815          var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02816       if (!var) {
02817          var = ast_load_realtime("sippeers", "name", newpeername, NULL);
02818          /*!\note
02819           * If this one loaded something, then we need to ensure that the host
02820           * field matched.  The only reason why we can't have this as a criteria
02821           * is because we only have the IP address and the host field might be
02822           * set as a name (and the reverse PTR might not match).
02823           */
02824          if (var && sin) {
02825             for (tmp = var; tmp; tmp = tmp->next) {
02826                if (!strcasecmp(tmp->name, "host")) {
02827                   struct hostent *hp;
02828                   struct ast_hostent ahp;
02829                   if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02830                      /* No match */
02831                      ast_variables_destroy(var);
02832                      var = NULL;
02833                   }
02834                   break;
02835                }
02836             }
02837          }
02838       }
02839    }
02840 
02841    if (!var && sin) {   /* Then check on IP address */
02842       iabuf = ast_inet_ntoa(sin->sin_addr);
02843       portnum = ntohs(sin->sin_port);
02844       sprintf(portstring, "%d", portnum);
02845       var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */
02846       if (!var)
02847          var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL);  /* Then check for registered hosts */
02848       if (!var) { 
02849          peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/
02850          if(peerlist){ 
02851             while((cat = ast_category_browse(peerlist, cat)))
02852             {
02853                insecure = ast_variable_retrieve(peerlist, cat, "insecure");
02854                set_insecure_flags(&flags, insecure, -1);
02855                if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
02856                   var = ast_category_root(peerlist, cat);
02857                   break;
02858                }
02859             }
02860          }
02861          if(!var) {
02862             ast_config_destroy(peerlist);
02863             peerlist = NULL; /*for safety's sake*/
02864             cat = NULL;
02865             peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/
02866             if(peerlist) {
02867                while((cat = ast_category_browse(peerlist, cat)))
02868                {
02869                   insecure = ast_variable_retrieve(peerlist, cat, "insecure");
02870                   set_insecure_flags(&flags, insecure, -1);
02871                   if(ast_test_flag(&flags, SIP_INSECURE_PORT)) {
02872                      var = ast_category_root(peerlist, cat);
02873                      break;
02874                   }
02875                }
02876             }
02877          }
02878       }
02879    }
02880 
02881    if (!var) {
02882       if(peerlist)
02883          ast_config_destroy(peerlist);
02884       return NULL;
02885    }
02886 
02887    for (tmp = var; tmp; tmp = tmp->next) {
02888       /* If this is type=user, then skip this object. */
02889       if (!strcasecmp(tmp->name, "type") &&
02890           !strcasecmp(tmp->value, "user")) {
02891          ast_variables_destroy(var);
02892          return NULL;
02893       } else if (!newpeername && !strcasecmp(tmp->name, "name")) {
02894          newpeername = tmp->value;
02895       } else if (!strcasecmp(tmp->name, "lastms")) {
02896          seen_lastms = 1;
02897       }
02898    }
02899 
02900    if (!newpeername) {  /* Did not find peer in realtime */
02901       ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf);
02902       if(peerlist)
02903          ast_config_destroy(peerlist);
02904       else
02905          ast_variables_destroy(var);
02906       return NULL;
02907    }
02908 
02909    /* Peer found in realtime, now build it in memory */
02910    peer = build_peer(newpeername, var, NULL, 1, devstate_only);
02911    if (!peer) {
02912       if(peerlist)
02913          ast_config_destroy(peerlist);
02914       else
02915          ast_variables_destroy(var);
02916       return NULL;
02917    }
02918 
02919    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) {
02920       /* Cache peer */
02921       ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
02922       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
02923          if (!AST_SCHED_DEL(sched, peer->expire)) {
02924             struct sip_peer *peer_ptr = peer;
02925             ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
02926          }
02927          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer));
02928          if (peer->expire == -1) {
02929             struct sip_peer *peer_ptr = peer;
02930             ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
02931          }
02932       }
02933       ASTOBJ_CONTAINER_LINK(&peerl,peer);
02934    }
02935    ast_set_flag(&peer->flags[0], SIP_REALTIME);
02936    if(peerlist)
02937       ast_config_destroy(peerlist);
02938    else
02939       ast_variables_destroy(var);
02940    return peer;
02941 }

static void realtime_update_peer ( const char *  peername,
struct sockaddr_in *  sin,
const char *  username,
const char *  fullcontact,
int  expirey,
int  lastms 
) [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 2677 of file chan_sip.c.

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

02678 {
02679    char port[10];
02680    char ipaddr[INET_ADDRSTRLEN];
02681    char regseconds[20];
02682    char str_lastms[20];
02683 
02684    char *sysname = ast_config_AST_SYSTEM_NAME;
02685    char *syslabel = NULL;
02686 
02687    time_t nowtime = time(NULL) + expirey;
02688    const char *fc = fullcontact ? "fullcontact" : NULL;
02689 
02690    snprintf(str_lastms, sizeof(str_lastms), "%d", lastms);
02691    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
02692    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
02693    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02694    
02695    if (ast_strlen_zero(sysname)) /* No system name, disable this */
02696       sysname = NULL;
02697    else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
02698       syslabel = "regserver";
02699 
02700    if (fc)
02701       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02702          "port", port, "regseconds", regseconds,
02703          "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
02704    else
02705       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
02706          "port", port, "regseconds", regseconds,
02707          "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
02708    if (seen_lastms) {
02709       /* We cannot do this in the same statement as above, because the lack of
02710        * this field could cause the whole statement to fail. */
02711       ast_update_realtime("sippeers", "name", peername, "lastms", str_lastms, NULL);
02712    }
02713 }

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

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

02992 {
02993    struct ast_variable *var;
02994    struct ast_variable *tmp;
02995    struct sip_user *user = NULL;
02996 
02997    var = ast_load_realtime("sipusers", "name", username, NULL);
02998 
02999    if (!var)
03000       return NULL;
03001 
03002    for (tmp = var; tmp; tmp = tmp->next) {
03003       if (!strcasecmp(tmp->name, "type") &&
03004          !strcasecmp(tmp->value, "peer")) {
03005          ast_variables_destroy(var);
03006          return NULL;
03007       }
03008    }
03009 
03010    user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
03011    
03012    if (!user) {   /* No user found */
03013       ast_variables_destroy(var);
03014       return NULL;
03015    }
03016 
03017    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
03018       ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
03019       suserobjs++;
03020       ASTOBJ_CONTAINER_LINK(&userl,user);
03021    } else {
03022       /* Move counter from s to r... */
03023       suserobjs--;
03024       ruserobjs++;
03025    }
03026    ast_set_flag(&user->flags[0], SIP_REALTIME);
03027    ast_variables_destroy(var);
03028    return user;
03029 }

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

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

Referenced by handle_request_message().

11076 {
11077    char buf[1024];
11078    struct ast_frame f;
11079    const char *content_type = get_header(req, "Content-Type");
11080 
11081    if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
11082       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
11083       if (!p->owner)
11084          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11085       return;
11086    }
11087 
11088    if (get_msg_text(buf, sizeof(buf), req)) {
11089       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
11090       transmit_response(p, "202 Accepted", req);
11091       if (!p->owner)
11092          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11093       return;
11094    }
11095 
11096    if (p->owner) {
11097       if (sip_debug_test_pvt(p))
11098          ast_verbose("Message received: '%s'\n", buf);
11099       memset(&f, 0, sizeof(f));
11100       f.frametype = AST_FRAME_TEXT;
11101       f.subclass = 0;
11102       f.offset = 0;
11103       f.data = buf;
11104       f.datalen = strlen(buf) + 1;
11105       ast_queue_frame(p->owner, &f);
11106       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
11107    } else { /* Message outside of a call, we do not support that */
11108       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);
11109       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
11110       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11111    }
11112    return;
11113 }

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

Convert transfer status to string.

Definition at line 1744 of file chan_sip.c.

References referstatusstrings, and text.

Referenced by __sip_show_channels().

01745 {
01746    int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0]));
01747    int x;
01748 
01749    for (x = 0; x < i; x++) {
01750       if (referstatusstrings[x].status ==  rstatus)
01751          return (char *) referstatusstrings[x].text;
01752    }
01753    return "";
01754 }

static void reg_source_db ( struct sip_peer peer  )  [static]

Get registration details from Asterisk DB.

Definition at line 8905 of file chan_sip.c.

References sip_peer::addr, ast_copy_string(), ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, sip_peer::name, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, TRUE, sip_peer::username, and username.

08906 {
08907    char data[256];
08908    struct in_addr in;
08909    int expiry;
08910    int port;
08911    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
08912 
08913    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
08914       return;
08915    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
08916       return;
08917 
08918    scan = data;
08919    addr = strsep(&scan, ":");
08920    port_str = strsep(&scan, ":");
08921    expiry_str = strsep(&scan, ":");
08922    username = strsep(&scan, ":");
08923    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
08924 
08925    if (!inet_aton(addr, &in))
08926       return;
08927 
08928    if (port_str)
08929       port = atoi(port_str);
08930    else
08931       return;
08932 
08933    if (expiry_str)
08934       expiry = atoi(expiry_str);
08935    else
08936       return;
08937 
08938    if (username)
08939       ast_copy_string(peer->username, username, sizeof(peer->username));
08940    if (contact)
08941       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
08942 
08943    if (option_debug > 1)
08944       ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
08945              peer->name, peer->username, ast_inet_ntoa(in), port, expiry);
08946 
08947    memset(&peer->addr, 0, sizeof(peer->addr));
08948    peer->addr.sin_family = AF_INET;
08949    peer->addr.sin_addr = in;
08950    peer->addr.sin_port = htons(port);
08951    if (sipsock < 0) {
08952       /* SIP isn't up yet, so schedule a poke only, pretty soon */
08953       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
08954          struct sip_peer *peer_ptr = peer;
08955          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08956       }
08957       peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer));
08958       if (peer->pokeexpire == -1) {
08959          struct sip_peer *peer_ptr = peer;
08960          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08961       }
08962    } else
08963       sip_poke_peer(peer);
08964    if (!AST_SCHED_DEL(sched, peer->expire)) {
08965       struct sip_peer *peer_ptr = peer;
08966       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08967    }
08968    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
08969    if (peer->expire == -1) {
08970       struct sip_peer *peer_ptr = peer;
08971       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08972    }
08973    register_peer_exten(peer, TRUE);
08974 }

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

Automatically add peer extension to dial plan.

Definition at line 2716 of file chan_sip.c.

References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_log(), ast_strdup, ast_strlen_zero(), context, ext, LOG_WARNING, sip_peer::name, sip_peer::regexten, and S_OR.

02717 {
02718    char multi[256];
02719    char *stringp, *ext, *context;
02720 
02721    /* XXX note that global_regcontext is both a global 'enable' flag and
02722     * the name of the global regexten context, if not specified
02723     * individually.
02724     */
02725    if (ast_strlen_zero(global_regcontext))
02726       return;
02727 
02728    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
02729    stringp = multi;
02730    while ((ext = strsep(&stringp, "&"))) {
02731       if ((context = strchr(ext, '@'))) {
02732          *context++ = '\0';   /* split ext@context */
02733          if (!ast_context_find(context)) {
02734             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
02735             continue;
02736          }
02737       } else {
02738          context = global_regcontext;
02739       }
02740       if (onoff) {
02741          if (!ast_exists_extension(NULL, context, ext, 1, NULL)) {
02742             ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
02743                 ast_strdup(peer->name), ast_free_ptr, "SIP");
02744          }
02745       } else {
02746          ast_context_remove_extension(context, ext, 1, NULL);
02747       }
02748    }
02749 }

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

References ast_apply_ha(), ast_copy_flags, ast_copy_string(), ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_peer::expire, exten, find_peer(), sip_pvt::flags, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, manager_event(), sip_peer::md5secret, sip_peer::name, name, parse_register_contact(), PARSE_REGISTER_DENIED, 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, t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.

09902 {
09903    enum check_auth_result res = AUTH_NOT_FOUND;
09904    struct sip_peer *peer;
09905    char tmp[256];
09906    char *name, *c;
09907    char *t;
09908    char *domain;
09909 
09910    /* Terminate URI */
09911    t = uri;
09912    while(*t && (*t > 32) && (*t != ';'))
09913       t++;
09914    *t = '\0';
09915    
09916    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
09917    if (pedanticsipchecking)
09918       ast_uri_decode(tmp);
09919 
09920    c = get_in_brackets(tmp);
09921    c = strsep(&c, ";"); /* Ditch ;user=phone */
09922 
09923    if (!strncasecmp(c, "sip:", 4)) {
09924       name = c + 4;
09925    } else {
09926       name = c;
09927       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
09928    }
09929 
09930    /* Strip off the domain name */
09931    if ((c = strchr(name, '@'))) {
09932       *c++ = '\0';
09933       domain = c;
09934       if ((c = strchr(domain, ':')))   /* Remove :port */
09935          *c = '\0';
09936       if (!AST_LIST_EMPTY(&domain_list)) {
09937          if (!check_sip_domain(domain, NULL, 0)) {
09938             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
09939             return AUTH_UNKNOWN_DOMAIN;
09940          }
09941       }
09942    }
09943 
09944    ast_string_field_set(p, exten, name);
09945    build_contact(p);
09946    if (ast_test_flag(req, SIP_PKT_IGNORE)) {
09947       /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */
09948       const char *expires = get_header(req, "Expires");
09949       int expire = atoi(expires);
09950 
09951       if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */
09952          if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) {
09953             expire = atoi(expires + 9);
09954          }
09955       }
09956       if (!ast_strlen_zero(expires) && expire == 0) {
09957          transmit_response_with_date(p, "200 OK", req);
09958          return 0;
09959       }
09960    }
09961    peer = find_peer(name, NULL, 1, 0);
09962    if (!(peer && ast_apply_ha(peer->ha, sin))) {
09963       /* Peer fails ACL check */
09964       if (peer) {
09965          ASTOBJ_UNREF(peer, sip_destroy_peer);
09966          res = AUTH_ACL_FAILED;
09967       } else
09968          res = AUTH_NOT_FOUND;
09969    }
09970    if (peer) {
09971       /* Set Frame packetization */
09972       if (p->rtp) {
09973          ast_rtp_codec_setpref(p->rtp, &peer->prefs);
09974          p->autoframing = peer->autoframing;
09975       }
09976       if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
09977          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
09978          res = AUTH_PEER_NOT_DYNAMIC;
09979       } else {
09980          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
09981          transmit_response(p, "100 Trying", req);
09982          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) {
09983             if (sip_cancel_destroy(p))
09984                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
09985 
09986             /* We have a succesful registration attemp with proper authentication,
09987                now, update the peer */
09988             switch (parse_register_contact(p, peer, req)) {
09989             case PARSE_REGISTER_DENIED:
09990                transmit_response_with_date(p, "603 Denied", req);
09991                peer->lastmsgssent = -1;
09992                res = 0;
09993                break;
09994             case PARSE_REGISTER_FAILED:
09995                ast_log(LOG_WARNING, "Failed to parse contact info\n");
09996                transmit_response_with_date(p, "400 Bad Request", req);
09997                peer->lastmsgssent = -1;
09998                res = 0;
09999                break;
10000             case PARSE_REGISTER_QUERY:
10001                ast_string_field_set(p, fullcontact, peer->fullcontact);
10002                transmit_response_with_date(p, "200 OK", req);
10003                peer->lastmsgssent = -1;
10004                res = 0;
10005                break;
10006             case PARSE_REGISTER_UPDATE:
10007                ast_string_field_set(p, fullcontact, peer->fullcontact);
10008                update_peer(peer, p->expiry);
10009                /* Say OK and ask subsystem to retransmit msg counter */
10010                transmit_response_with_date(p, "200 OK", req);
10011                if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
10012                   peer->lastmsgssent = -1;
10013                res = 0;
10014                break;
10015             }
10016          } 
10017       }
10018    }
10019    if (!peer && autocreatepeer) {
10020       /* Create peer if we have autocreate mode enabled */
10021       peer = temp_peer(name);
10022       if (peer) {
10023          ASTOBJ_CONTAINER_LINK(&peerl, peer);
10024          if (sip_cancel_destroy(p))
10025             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
10026          switch (parse_register_contact(p, peer, req)) {
10027          case PARSE_REGISTER_DENIED:
10028             ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
10029             transmit_response_with_date(p, "403 Forbidden (ACL)", req);
10030             peer->lastmsgssent = -1;
10031             res = 0;
10032             break;
10033          case PARSE_REGISTER_FAILED:
10034             ast_log(LOG_WARNING, "Failed to parse contact info\n");
10035             transmit_response_with_date(p, "400 Bad Request", req);
10036             peer->lastmsgssent = -1;
10037             res = 0;
10038             break;
10039          case PARSE_REGISTER_QUERY:
10040             ast_string_field_set(p, fullcontact, peer->fullcontact);
10041             transmit_response_with_date(p, "200 OK", req);
10042             peer->lastmsgssent = -1;
10043             res = 0;
10044             break;
10045          case PARSE_REGISTER_UPDATE:
10046             ast_string_field_set(p, fullcontact, peer->fullcontact);
10047             /* Say OK and ask subsystem to retransmit msg counter */
10048             transmit_response_with_date(p, "200 OK", req);
10049             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
10050             peer->lastmsgssent = -1;
10051             res = 0;
10052             break;
10053          }
10054       }
10055    }
10056    if (!peer && global_alwaysauthreject) {
10057       /* If we found a peer, we transmit a 100 Trying.  Therefore, if we're
10058        * trying to avoid leaking information, we MUST also transmit the same
10059        * response when we DON'T find a peer. */
10060       transmit_response(p, "100 Trying", req);
10061       /* Insert a fake delay between the 100 and the subsequent failure. */
10062       sched_yield();
10063    }
10064    if (!res) {
10065       ast_device_state_changed("SIP/%s", peer->name);
10066    }
10067    if (res < 0) {
10068       switch (res) {
10069       case AUTH_SECRET_FAILED:
10070          /* Wrong password in authentication. Go away, don't try again until you fixed it */
10071          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
10072          break;
10073       case AUTH_USERNAME_MISMATCH:
10074          /* Username and digest username does not match.
10075             Asterisk uses the From: username for authentication. We need the
10076             users to use the same authentication user name until we support
10077             proper authentication by digest auth name */
10078       case AUTH_NOT_FOUND:
10079       case AUTH_PEER_NOT_DYNAMIC:
10080       case AUTH_ACL_FAILED:
10081          if (global_alwaysauthreject) {
10082             transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
10083          } else {
10084             /* URI not found */
10085             if (res == AUTH_PEER_NOT_DYNAMIC)
10086                transmit_response(p, "403 Forbidden", &p->initreq);
10087             else
10088                transmit_response(p, "404 Not found", &p->initreq);
10089          }
10090          break;
10091       default:
10092          break;
10093       }
10094    }
10095    if (peer)
10096       ASTOBJ_UNREF(peer, sip_destroy_peer);
10097 
10098    return res;
10099 }

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

Convert registration state status to string.

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

08367 {
08368    switch(regstate) {
08369    case REG_STATE_FAILED:
08370       return "Failed";
08371    case REG_STATE_UNREGISTERED:
08372       return "Unregistered";
08373    case REG_STATE_REGSENT:
08374       return "Request Sent";
08375    case REG_STATE_AUTHSENT:
08376       return "Auth. Sent";
08377    case REG_STATE_REGISTERED:
08378       return "Registered";
08379    case REG_STATE_REJECTED:
08380       return "Rejected";
08381    case REG_STATE_TIMEOUT:
08382       return "Timeout";
08383    case REG_STATE_NOAUTH:
08384       return "No Authentication";
08385    default:
08386       return "Unknown";
08387    }
08388 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 20183 of file chan_sip.c.

References sip_reload().

20184 {
20185    return sip_reload(0, 0, NULL);
20186 }

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

< Set up call forward on 482 Loop Detected

Definition at line 19016 of file chan_sip.c.

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

19017 {
19018    struct ast_config *cfg, *ucfg;
19019    struct ast_variable *v;
19020    struct sip_peer *peer;
19021    struct sip_user *user;
19022    struct ast_hostent ahp;
19023    char *cat, *stringp, *context, *oldregcontext;
19024    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
19025    struct hostent *hp;
19026    int format;
19027    struct ast_flags dummy[2];
19028    int auto_sip_domains = FALSE;
19029    struct sockaddr_in old_bindaddr = bindaddr;
19030    int registry_count = 0, peer_count = 0, user_count = 0;
19031    unsigned int temp_tos = 0;
19032    struct ast_flags debugflag = {0};
19033 
19034    cfg = ast_config_load(config);
19035 
19036    /* We *must* have a config file otherwise stop immediately */
19037    if (!cfg) {
19038       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
19039       return -1;
19040    }
19041    
19042    if (option_debug > 3)
19043       ast_log(LOG_DEBUG, "--------------- SIP reload started\n");
19044 
19045    clear_realm_authentication(authl);
19046    clear_sip_domains();
19047    authl = NULL;
19048 
19049    ast_free_ha(global_contact_ha);
19050    global_contact_ha = NULL;
19051 
19052    /* First, destroy all outstanding registry calls */
19053    /* This is needed, since otherwise active registry entries will not be destroyed */
19054    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
19055       ASTOBJ_RDLOCK(iterator);
19056       if (iterator->call) {
19057          if (option_debug > 2)
19058             ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
19059          /* This will also remove references to the registry */
19060          sip_destroy(iterator->call);
19061       }
19062       ASTOBJ_UNLOCK(iterator);
19063    
19064    } while(0));
19065 
19066    /* Then, actually destroy users and registry */
19067    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
19068    if (option_debug > 3)
19069       ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
19070    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
19071    if (option_debug > 3)
19072       ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n");
19073    ASTOBJ_CONTAINER_MARKALL(&peerl);
19074 
19075    /* Initialize copy of current global_regcontext for later use in removing stale contexts */
19076    ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts));
19077    oldregcontext = oldcontexts;
19078 
19079    /* Clear all flags before setting default values */
19080    /* Preserve debugging settings for console */
19081    ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
19082    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
19083    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
19084    ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE);
19085 
19086    /* Reset IP addresses  */
19087    memset(&bindaddr, 0, sizeof(bindaddr));
19088    ast_free_ha(localaddr);
19089    memset(&localaddr, 0, sizeof(localaddr));
19090    memset(&externip, 0, sizeof(externip));
19091    memset(&default_prefs, 0 , sizeof(default_prefs));
19092    outboundproxyip.sin_port = htons(STANDARD_SIP_PORT);
19093    outboundproxyip.sin_family = AF_INET;  /* Type of address: IPv4 */
19094    ourport = STANDARD_SIP_PORT;
19095    srvlookup = DEFAULT_SRVLOOKUP;
19096    global_tos_sip = DEFAULT_TOS_SIP;
19097    global_tos_audio = DEFAULT_TOS_AUDIO;
19098    global_tos_video = DEFAULT_TOS_VIDEO;
19099    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
19100    externexpire = 0;       /* Expiration for DNS re-issuing */
19101    externrefresh = 10;
19102    memset(&outboundproxyip, 0, sizeof(outboundproxyip));
19103 
19104    /* Reset channel settings to default before re-configuring */
19105    allow_external_domains = DEFAULT_ALLOW_EXT_DOM;          /* Allow external invites */
19106    global_regcontext[0] = '\0';
19107    expiry = DEFAULT_EXPIRY;
19108    global_notifyringing = DEFAULT_NOTIFYRINGING;
19109    global_limitonpeers = FALSE;
19110    global_prematuremediafilter = FALSE;
19111    global_directrtpsetup = FALSE;      /* Experimental feature, disabled by default */
19112    global_notifyhold = FALSE;
19113    global_alwaysauthreject = 0;
19114    global_allowsubscribe = FALSE;
19115    ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent));
19116    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
19117    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME))
19118       ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
19119    else
19120       ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm));
19121    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
19122    compactheaders = DEFAULT_COMPACTHEADERS;
19123    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
19124    global_regattempts_max = 0;
19125    pedanticsipchecking = DEFAULT_PEDANTIC;
19126    global_mwitime = DEFAULT_MWITIME;
19127    autocreatepeer = DEFAULT_AUTOCREATEPEER;
19128    global_autoframing = 0;
19129    global_allowguest = DEFAULT_ALLOWGUEST;
19130    global_rtptimeout = 0;
19131    global_rtpholdtimeout = 0;
19132    global_rtpkeepalive = 0;
19133    global_allowtransfer = TRANSFER_OPENFORALL;  /* Merrily accept all transfers by default */
19134    global_rtautoclear = 120;
19135    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for peers, users: TRUE */
19136    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP);     /* Default for peers, users: TRUE */
19137    ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE);
19138 
19139    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */
19140    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
19141    default_subscribecontext[0] = '\0';
19142    default_language[0] = '\0';
19143    default_fromdomain[0] = '\0';
19144    default_qualify = DEFAULT_QUALIFY;
19145    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
19146    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
19147    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
19148    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
19149    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);        /*!< Default DTMF setting: RFC2833 */
19150    ast_set_flag(&global_flags[0], SIP_NAT_RFC3581);         /*!< NAT support if requested by device with rport */
19151    ast_set_flag(&global_flags[0], SIP_CAN_REINVITE);        /*!< Allow re-invites */
19152    ast_set_flag(&global_flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED); /*!< Set up call forward on 482 Loop Detected */
19153 
19154    /* Debugging settings, always default to off */
19155    dumphistory = FALSE;
19156    recordhistory = FALSE;
19157    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
19158 
19159    /* Misc settings for the channel */
19160    global_relaxdtmf = FALSE;
19161    global_callevents = FALSE;
19162    global_t1min = DEFAULT_T1MIN;
19163    global_shrinkcallerid = 1;
19164 
19165    global_matchexterniplocally = FALSE;
19166 
19167    /* Copy the default jb config over global_jbconf */
19168    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
19169 
19170    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT);
19171 
19172    /* Read the [general] config section of sip.conf (or from realtime config) */
19173    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
19174       if (handle_common_options(&global_flags[0], &dummy[0], v))
19175          continue;
19176       /* handle jb conf */
19177       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
19178          continue;
19179 
19180       /* Create the interface list */
19181       if (!strcasecmp(v->name, "context")) {
19182          ast_copy_string(default_context, v->value, sizeof(default_context));
19183       } else if (!strcasecmp(v->name, "subscribecontext")) {
19184          ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext));
19185       } else if (!strcasecmp(v->name, "allowguest")) {
19186          global_allowguest = ast_true(v->value) ? 1 : 0;
19187       } else if (!strcasecmp(v->name, "realm")) {
19188          ast_copy_string(global_realm, v->value, sizeof(global_realm));
19189       } else if (!strcasecmp(v->name, "useragent")) {
19190          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
19191          if (option_debug)
19192             ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
19193       } else if (!strcasecmp(v->name, "allowtransfer")) {
19194          global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
19195       } else if (!strcasecmp(v->name, "rtcachefriends")) {
19196          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);   
19197       } else if (!strcasecmp(v->name, "rtsavesysname")) {
19198          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME);   
19199       } else if (!strcasecmp(v->name, "rtupdate")) {
19200          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE);   
19201       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
19202          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE);  
19203       } else if (!strcasecmp(v->name, "t1min")) {
19204          global_t1min = atoi(v->value);
19205       } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) {
19206          global_dynamic_exclude_static = ast_true(v->value);
19207       } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
19208          global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha);
19209       } else if (!strcasecmp(v->name, "rtautoclear")) {
19210          int i = atoi(v->value);
19211          if (i > 0)
19212             global_rtautoclear = i;
19213          else
19214             i = 0;
19215          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
19216       } else if (!strcasecmp(v->name, "usereqphone")) {
19217          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);   
19218       } else if (!strcasecmp(v->name, "prematuremedia")) {
19219          global_prematuremediafilter = ast_true(v->value);
19220       } else if (!strcasecmp(v->name, "relaxdtmf")) {
19221          global_relaxdtmf = ast_true(v->value);
19222       } else if (!strcasecmp(v->name, "checkmwi")) {
19223          if ((sscanf(v->value, "%30d", &global_mwitime) != 1) || (global_mwitime < 0)) {
19224             ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d.  Using default (10).\n", v->value, v->lineno);
19225             global_mwitime = DEFAULT_MWITIME;
19226          }
19227       } else if (!strcasecmp(v->name, "vmexten")) {
19228          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
19229       } else if (!strcasecmp(v->name, "rtptimeout")) {
19230          if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
19231             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
19232             global_rtptimeout = 0;
19233          }
19234       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
19235          if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
19236             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
19237             global_rtpholdtimeout = 0;
19238          }
19239       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
19240          if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
19241             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
19242             global_rtpkeepalive = 0;
19243          }
19244       } else if (!strcasecmp(v->name, "compactheaders")) {
19245          compactheaders = ast_true(v->value);
19246       } else if (!strcasecmp(v->name, "notifymimetype")) {
19247          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
19248       } else if (!strncasecmp(v->name, "limitonpeer", 11)) {
19249          global_limitonpeers = ast_true(v->value);
19250       } else if (!strcasecmp(v->name, "directrtpsetup")) {
19251          global_directrtpsetup = ast_true(v->value);
19252       } else if (!strcasecmp(v->name, "notifyringing")) {
19253          global_notifyringing = ast_true(v->value);
19254       } else if (!strcasecmp(v->name, "notifyhold")) {
19255          global_notifyhold = ast_true(v->value);
19256       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
19257          global_alwaysauthreject = ast_true(v->value);
19258       } else if (!strcasecmp(v->name, "mohinterpret") 
19259          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
19260          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
19261       } else if (!strcasecmp(v->name, "mohsuggest")) {
19262          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
19263       } else if (!strcasecmp(v->name, "language")) {
19264          ast_copy_string(default_language, v->value, sizeof(default_language));
19265       } else if (!strcasecmp(v->name, "regcontext")) {
19266          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
19267          stringp = newcontexts;
19268          /* Let's remove any contexts that are no longer defined in regcontext */
19269          cleanup_stale_contexts(stringp, oldregcontext);
19270          /* Create contexts if they don't exist already */
19271          while ((context = strsep(&stringp, "&"))) {
19272             if (!ast_context_find(context))
19273                ast_context_create(NULL, context,"SIP");
19274          }
19275          ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
19276       } else if (!strcasecmp(v->name, "callerid")) {
19277          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
19278       } else if (!strcasecmp(v->name, "fromdomain")) {
19279          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
19280       } else if (!strcasecmp(v->name, "outboundproxy")) {
19281          if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0)
19282             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
19283       } else if (!strcasecmp(v->name, "outboundproxyport")) {
19284          /* Port needs to be after IP */
19285          sscanf(v->value, "%30d", &format);
19286          outboundproxyip.sin_port = htons(format);
19287       } else if (!strcasecmp(v->name, "autocreatepeer")) {
19288          autocreatepeer = ast_true(v->value);
19289       } else if (!strcasecmp(v->name, "srvlookup")) {
19290          srvlookup = ast_true(v->value);
19291       } else if (!strcasecmp(v->name, "pedantic")) {
19292          pedanticsipchecking = ast_true(v->value);
19293       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
19294          max_expiry = atoi(v->value);
19295          if (max_expiry < 1)
19296             max_expiry = DEFAULT_MAX_EXPIRY;
19297       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
19298          min_expiry = atoi(v->value);
19299          if (min_expiry < 1)
19300             min_expiry = DEFAULT_MIN_EXPIRY;
19301       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
19302          default_expiry = atoi(v->value);
19303          if (default_expiry < 1)
19304             default_expiry = DEFAULT_DEFAULT_EXPIRY;
19305       } else if (!strcasecmp(v->name, "sipdebug")) {  /* XXX maybe ast_set2_flags ? */
19306          if (ast_true(v->value))
19307             ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG);
19308       } else if (!strcasecmp(v->name, "dumphistory")) {
19309          dumphistory = ast_true(v->value);
19310       } else if (!strcasecmp(v->name, "recordhistory")) {
19311          recordhistory = ast_true(v->value);
19312       } else if (!strcasecmp(v->name, "registertimeout")) {
19313          global_reg_timeout = atoi(v->value);
19314          if (global_reg_timeout < 1)
19315             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
19316       } else if (!strcasecmp(v->name, "registerattempts")) {
19317          global_regattempts_max = atoi(v->value);
19318       } else if (!strcasecmp(v->name, "bindaddr")) {
19319          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
19320             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
19321          } else {
19322             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
19323          }
19324       } else if (!strcasecmp(v->name, "localnet")) {
19325          struct ast_ha *na;
19326          if (!(na = ast_append_ha("d", v->value, localaddr)))
19327             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
19328          else
19329             localaddr = na;
19330       } else if (!strcasecmp(v->name, "localmask")) {
19331          ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n");
19332       } else if (!strcasecmp(v->name, "externip")) {
19333          if (!(hp = ast_gethostbyname(v->value, &ahp))) 
19334             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
19335          else
19336             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
19337          externexpire = 0;
19338       } else if (!strcasecmp(v->name, "externhost")) {
19339          ast_copy_string(externhost, v->value, sizeof(externhost));
19340          if (!(hp = ast_gethostbyname(externhost, &ahp))) 
19341             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
19342          else
19343             memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
19344          externexpire = time(NULL);
19345       } else if (!strcasecmp(v->name, "externrefresh")) {
19346          if (sscanf(v->value, "%30d", &externrefresh) != 1) {
19347             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
19348             externrefresh = 10;
19349          }
19350       } else if (!strcasecmp(v->name, "allow")) {
19351          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1);
19352       } else if (!strcasecmp(v->name, "disallow")) {
19353          ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0);
19354       } else if (!strcasecmp(v->name, "autoframing")) {
19355          global_autoframing = ast_true(v->value);
19356       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
19357          allow_external_domains = ast_true(v->value);
19358       } else if (!strcasecmp(v->name, "autodomain")) {
19359          auto_sip_domains = ast_true(v->value);
19360       } else if (!strcasecmp(v->name, "domain")) {
19361          char *domain = ast_strdupa(v->value);
19362          char *context = strchr(domain, ',');
19363 
19364          if (context)
19365             *context++ = '\0';
19366 
19367          if (option_debug && ast_strlen_zero(context))
19368             ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
19369          if (ast_strlen_zero(domain))
19370             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
19371          else
19372             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
19373       } else if (!strcasecmp(v->name, "register")) {
19374          if (sip_register(v->value, v->lineno) == 0)
19375             registry_count++;
19376       } else if (!strcasecmp(v->name, "tos")) {
19377          if (!ast_str2tos(v->value, &temp_tos)) {
19378             global_tos_sip = temp_tos;
19379             global_tos_audio = temp_tos;
19380             global_tos_video = temp_tos;
19381             ast_log(LOG_WARNING, "tos value at line %d is deprecated.  See doc/ip-tos.txt for more information.\n", v->lineno);
19382          } else
19383             ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno);
19384       } else if (!strcasecmp(v->name, "tos_sip")) {
19385          if (ast_str2tos(v->value, &global_tos_sip))
19386             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno);
19387       } else if (!strcasecmp(v->name, "tos_audio")) {
19388          if (ast_str2tos(v->value, &global_tos_audio))
19389             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno);
19390       } else if (!strcasecmp(v->name, "tos_video")) {
19391          if (ast_str2tos(v->value, &global_tos_video))
19392             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno);
19393       } else if (!strcasecmp(v->name, "bindport")) {
19394          if (sscanf(v->value, "%5d", &ourport) == 1) {
19395             bindaddr.sin_port = htons(ourport);
19396          } else {
19397             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
19398          }
19399       } else if (!strcasecmp(v->name, "qualify")) {
19400          if (!strcasecmp(v->value, "no")) {
19401             default_qualify = 0;
19402          } else if (!strcasecmp(v->value, "yes")) {
19403             default_qualify = DEFAULT_MAXMS;
19404          } else if (sscanf(v->value, "%30d", &default_qualify) != 1) {
19405             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
19406             default_qualify = 0;
19407          }
19408       } else if (!strcasecmp(v->name, "callevents")) {
19409          global_callevents = ast_true(v->value);
19410       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
19411          default_maxcallbitrate = atoi(v->value);
19412          if (default_maxcallbitrate < 0)
19413             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
19414       } else if (!strcasecmp(v->name, "matchexterniplocally")) {
19415          global_matchexterniplocally = ast_true(v->value);
19416       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
19417          if (ast_true(v->value)) {
19418             global_shrinkcallerid = 1;
19419          } else if (ast_false(v->value)) {
19420             global_shrinkcallerid = 0;
19421          } else {
19422             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
19423          }
19424       }
19425    }
19426 
19427    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
19428       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
19429       allow_external_domains = 1;
19430    }
19431    
19432    /* Build list of authentication to various SIP realms, i.e. service providers */
19433    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
19434       /* Format for authentication is auth = username:password@realm */
19435       if (!strcasecmp(v->name, "auth"))
19436          authl = add_realm_authentication(authl, v->value, v->lineno);
19437    }
19438    
19439    ucfg = ast_config_load("users.conf");
19440    if (ucfg) {
19441       struct ast_variable *gen;
19442       int genhassip, genregistersip;
19443       const char *hassip, *registersip;
19444       
19445       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
19446       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
19447       gen = ast_variable_browse(ucfg, "general");
19448       cat = ast_category_browse(ucfg, NULL);
19449       while (cat) {
19450          if (strcasecmp(cat, "general")) {
19451             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
19452             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
19453             if (ast_true(hassip) || (!hassip && genhassip)) {
19454                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
19455                if (user) {
19456                   ASTOBJ_CONTAINER_LINK(&userl,user);
19457                   ASTOBJ_UNREF(user, sip_destroy_user);
19458                   user_count++;
19459                }
19460                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0);
19461                if (peer) {
19462                   ast_device_state_changed("SIP/%s", peer->name);
19463                   ASTOBJ_CONTAINER_LINK(&peerl,peer);
19464                   ASTOBJ_UNREF(peer, sip_destroy_peer);
19465                   peer_count++;
19466                }
19467             }
19468             if (ast_true(registersip) || (!registersip && genregistersip)) {
19469                char tmp[256];
19470                const char *host = ast_variable_retrieve(ucfg, cat, "host");
19471                const char *username = ast_variable_retrieve(ucfg, cat, "username");
19472                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
19473                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
19474                const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser");
19475                if (!host)
19476                   host = ast_variable_retrieve(ucfg, "general", "host");
19477                if (!username)
19478                   username = ast_variable_retrieve(ucfg, "general", "username");
19479                if (!secret)
19480                   secret = ast_variable_retrieve(ucfg, "general", "secret");
19481                if (!contact)
19482                   contact = "s";
19483                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
19484                   if (!ast_strlen_zero(secret)) {
19485                      if (!ast_strlen_zero(authuser)) {
19486                         snprintf(tmp, sizeof(tmp), "%s:%s:%s@%s/%s", username, secret, authuser, host, contact);
19487                      } else {
19488                         snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact);
19489                      }
19490                   } else if (!ast_strlen_zero(authuser)) {
19491                      snprintf(tmp, sizeof(tmp), "%s::%s@%s/%s", username, authuser, host, contact);
19492                   } else {
19493                      snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact);
19494                   }
19495                   if (sip_register(tmp, 0) == 0)
19496                      registry_count++;
19497                }
19498             }
19499          }
19500          cat = ast_category_browse(ucfg, cat);
19501       }
19502       ast_config_destroy(ucfg);
19503    }
19504    
19505 
19506    /* Load peers, users and friends */
19507    cat = NULL;
19508    while ( (cat = ast_category_browse(cfg, cat)) ) {
19509       const char *utype;
19510       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
19511          continue;
19512       utype = ast_variable_retrieve(cfg, cat, "type");
19513       if (!utype) {
19514          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
19515          continue;
19516       } else {
19517          int is_user = 0, is_peer = 0;
19518          if (!strcasecmp(utype, "user"))
19519             is_user = 1;
19520          else if (!strcasecmp(utype, "friend"))
19521             is_user = is_peer = 1;
19522          else if (!strcasecmp(utype, "peer"))
19523             is_peer = 1;
19524          else {
19525             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
19526             continue;
19527          }
19528          if (is_user) {
19529             user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
19530             if (user) {
19531                ASTOBJ_CONTAINER_LINK(&userl,user);
19532                ASTOBJ_UNREF(user, sip_destroy_user);
19533                user_count++;
19534             }
19535          }
19536          if (is_peer) {
19537             peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0);
19538             if (peer) {
19539                ASTOBJ_CONTAINER_LINK(&peerl,peer);
19540                ASTOBJ_UNREF(peer, sip_destroy_peer);
19541                peer_count++;
19542             }
19543          }
19544       }
19545    }
19546    if (ast_find_ourip(&__ourip, bindaddr)) {
19547       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
19548       ast_config_destroy(cfg);
19549       return 0;
19550    }
19551    if (!ntohs(bindaddr.sin_port))
19552       bindaddr.sin_port = ntohs(STANDARD_SIP_PORT);
19553    bindaddr.sin_family = AF_INET;
19554    ast_mutex_lock(&netlock);
19555    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
19556       close(sipsock);
19557       sipsock = -1;
19558    }
19559    if (sipsock < 0) {
19560       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
19561       if (sipsock < 0) {
19562          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
19563          ast_config_destroy(cfg);
19564          ast_mutex_unlock(&netlock);
19565          return -1;
19566       } else {
19567          /* Allow SIP clients on the same host to access us: */
19568          const int reuseFlag = 1;
19569 
19570          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
19571                (const char*)&reuseFlag,
19572                sizeof reuseFlag);
19573 
19574          ast_enable_packet_fragmentation(sipsock);
19575 
19576          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
19577             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
19578             ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
19579             strerror(errno));
19580             close(sipsock);
19581             sipsock = -1;
19582          } else {
19583             if (option_verbose > 1) { 
19584                ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 
19585                ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
19586                ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip));
19587             }
19588             if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 
19589                ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip));
19590          }
19591       }
19592    } else if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) {
19593       ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip));
19594    }
19595    ast_mutex_unlock(&netlock);
19596 
19597    /* Add default domains - host name, IP address and IP:port */
19598    /* Only do this if user added any sip domain with "localdomains" */
19599    /* In order to *not* break backwards compatibility */
19600    /*    Some phones address us at IP only, some with additional port number */
19601    if (auto_sip_domains) {
19602       char temp[MAXHOSTNAMELEN];
19603 
19604       /* First our default IP address */
19605       if (bindaddr.sin_addr.s_addr)
19606          add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL);
19607       else
19608          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
19609 
19610       /* Our extern IP address, if configured */
19611       if (externip.sin_addr.s_addr)
19612          add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL);
19613 
19614       /* Extern host name (NAT traversal support) */
19615       if (!ast_strlen_zero(externhost))
19616          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
19617       
19618       /* Our host name */
19619       if (!gethostname(temp, sizeof(temp)))
19620          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
19621    }
19622 
19623    /* Release configuration from memory */
19624    ast_config_destroy(cfg);
19625 
19626    /* Load the list of manual NOTIFY types to support */
19627    if (notify_types)
19628       ast_config_destroy(notify_types);
19629    notify_types = ast_config_load(notify_config);
19630 
19631    /* Done, tell the manager */
19632    manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "Channel: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\nUser_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count);
19633 
19634    return 0;
19635 }

static void remove_provisional_keepalive_sched ( struct sip_pvt pvt  )  [static]

Definition at line 2483 of file chan_sip.c.

References ao2_ref(), AST_SCHED_DEL, sip_pvt::provisional_keepalive_data, provisional_keepalive_data::pvt, sched, provisional_keepalive_data::sched_id, and unref_provisional_keepalive().

Referenced by __sip_destroy(), send_response(), sip_hangup(), and update_provisional_keepalive().

02484 {
02485    int res;
02486    if (!pvt->provisional_keepalive_data) {
02487       return;
02488    }
02489    res = AST_SCHED_DEL(sched, pvt->provisional_keepalive_data->sched_id);
02490    if (res == -1) {
02491       /* If we could not remove this item. remove pvt's reference
02492        * this data and mark it for removal for the next time the
02493        * scheduler uses it. The scheduler has it's own ref to this
02494        * data and will detect it should not reschedule the event
02495        * since the sched_id is -1 and pvt == NULL */
02496       pvt->provisional_keepalive_data = unref_provisional_keepalive(pvt->provisional_keepalive_data);
02497    } else {
02498       /* If we successfully canceled the scheduler entry, we need to
02499        * remove its reference to the data. */
02500       ao2_ref(pvt->provisional_keepalive_data, -1);
02501    }
02502 }

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

References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), sip_pvt::domain, get_header(), keys, sip_registry::nonce, sip_pvt::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, sip_pvt::qop, sip_registry::qop, sip_pvt::realm, sip_registry::realm, and sip_pvt::registry.

Referenced by do_proxy_auth(), and do_register_auth().

12898 {
12899    char tmp[512];
12900    char *c;
12901    char oldnonce[256];
12902 
12903    /* table of recognised keywords, and places where they should be copied */
12904    const struct x {
12905       const char *key;
12906       int field_index;
12907    } *i, keys[] = {
12908       { "realm=", ast_string_field_index(p, realm) },
12909       { "nonce=", ast_string_field_index(p, nonce) },
12910       { "opaque=", ast_string_field_index(p, opaque) },
12911       { "qop=", ast_string_field_index(p, qop) },
12912       { "domain=", ast_string_field_index(p, domain) },
12913       { NULL, 0 },
12914    };
12915 
12916    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
12917    if (ast_strlen_zero(tmp)) 
12918       return -1;
12919    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
12920       ast_log(LOG_WARNING, "missing Digest.\n");
12921       return -1;
12922    }
12923    c = tmp + strlen("Digest ");
12924    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
12925    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
12926       for (i = keys; i->key != NULL; i++) {
12927          char *src, *separator;
12928          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
12929             continue;
12930          /* Found. Skip keyword, take text in quotes or up to the separator. */
12931          c += strlen(i->key);
12932          if (*c == '"') {
12933             src = ++c;
12934             separator = "\"";
12935          } else {
12936             src = c;
12937             separator = ",";
12938          }
12939          strsep(&c, separator); /* clear separator and move ptr */
12940          ast_string_field_index_set(p, i->field_index, src);
12941          break;
12942       }
12943       if (i->key == NULL) /* not found, try ',' */
12944          strsep(&c, ",");
12945    }
12946    /* Reset nonce count */
12947    if (strcmp(p->nonce, oldnonce)) 
12948       p->noncecount = 0;
12949 
12950    /* Save auth data for following registrations */
12951    if (p->registry) {
12952       struct sip_registry *r = p->registry;
12953 
12954       if (strcmp(r->nonce, p->nonce)) {
12955          ast_string_field_set(r, realm, p->realm);
12956          ast_string_field_set(r, nonce, p->nonce);
12957          ast_string_field_set(r, domain, p->domain);
12958          ast_string_field_set(r, opaque, p->opaque);
12959          ast_string_field_set(r, qop, p->qop);
12960          r->noncecount = 0;
12961       }
12962    }
12963    return build_reply_digest(p, sipmethod, digest, digest_len); 
12964 }

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

References add_header(), add_route(), ast_copy_string(), ast_log(), ast_random(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), sip_pvt::callid, copy_header(), DEFAULT_MAX_FORWARDS, FALSE, sip_pvt::flags, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::invite_branch, sip_pvt::lastmsg, LOG_DEBUG, sip_route::next, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::our_contact, sip_request::rlPart2, sip_pvt::route, sip_pvt::rpid, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_OUTGOING, sipdebug, sip_pvt::tag, text, cfsip_methods::text, sip_pvt::theirtag, TRUE, sip_pvt::uri, and sip_pvt::via.

06849 {
06850    struct sip_request *orig = &p->initreq;
06851    char stripped[80];
06852    char tmp[80];
06853    char newto[256];
06854    const char *c;
06855    const char *ot, *of;
06856    int is_strict = FALSE;     /*!< Strict routing flag */
06857 
06858    memset(req, 0, sizeof(struct sip_request));
06859    
06860    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
06861    
06862    if (!seqno) {
06863       p->ocseq++;
06864       seqno = p->ocseq;
06865    }
06866    
06867    /* A CANCEL must have the same branch as the INVITE that it is canceling. */
06868    if (sipmethod == SIP_CANCEL) {
06869       p->branch = p->invite_branch;
06870       build_via(p);
06871    } else if (newbranch && (sipmethod == SIP_INVITE)) {
06872       p->branch ^= ast_random();
06873       p->invite_branch = p->branch;
06874       build_via(p);
06875    } else if (newbranch) {
06876       p->branch ^= ast_random();
06877       build_via(p);
06878    }
06879 
06880    /* Check for strict or loose router */
06881    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
06882       is_strict = TRUE;
06883       if (sipdebug)
06884          ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
06885    }
06886 
06887    if (sipmethod == SIP_CANCEL)
06888       c = p->initreq.rlPart2; /* Use original URI */
06889    else if (sipmethod == SIP_ACK) {
06890       /* Use URI from Contact: in 200 OK (if INVITE) 
06891       (we only have the contacturi on INVITEs) */
06892       if (!ast_strlen_zero(p->okcontacturi))
06893          c = is_strict ? p->route->hop : p->okcontacturi;
06894       else
06895          c = p->initreq.rlPart2;
06896    } else if (!ast_strlen_zero(p->okcontacturi)) 
06897       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
06898    else if (!ast_strlen_zero(p->uri)) 
06899       c = p->uri;
06900    else {
06901       char *n;
06902       /* We have no URI, use To: or From:  header as URI (depending on direction) */
06903       ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
06904             sizeof(stripped));
06905       n = get_in_brackets(stripped);
06906       c = strsep(&n, ";"); /* trim ; and beyond */
06907    }  
06908    init_req(req, sipmethod, c);
06909 
06910    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
06911 
06912    add_header(req, "Via", p->via);
06913    if (p->route) {
06914       set_destination(p, p->route->hop);
06915       add_route(req, is_strict ? p->route->next : p->route);
06916    }
06917 
06918    ot = get_header(orig, "To");
06919    of = get_header(orig, "From");
06920 
06921    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
06922       as our original request, including tag (or presumably lack thereof) */
06923    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
06924       /* Add the proper tag if we don't have it already.  If they have specified
06925          their tag, use it.  Otherwise, use our own tag */
06926       if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
06927          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
06928       else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
06929          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
06930       else
06931          snprintf(newto, sizeof(newto), "%s", ot);
06932       ot = newto;
06933    }
06934 
06935    if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06936       add_header(req, "From", of);
06937       add_header(req, "To", ot);
06938    } else {
06939       add_header(req, "From", ot);
06940       add_header(req, "To", of);
06941    }
06942    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
06943    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
06944       add_header(req, "Contact", p->our_contact);
06945 
06946    copy_header(req, orig, "Call-ID");
06947    add_header(req, "CSeq", tmp);
06948 
06949    if (!ast_strlen_zero(global_useragent))
06950       add_header(req, "User-Agent", global_useragent);
06951    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
06952 
06953    if (!ast_strlen_zero(p->rpid))
06954       add_header(req, "Remote-Party-ID", p->rpid);
06955 
06956    return 0;
06957 }

static int resp_needs_contact ( const char *  msg,
enum sipmethod  method 
) [inline, static]

Test if this response needs a contact header.

Definition at line 6724 of file chan_sip.c.

References SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INFO, SIP_INVITE, SIP_MESSAGE, SIP_NOTIFY, SIP_OPTIONS, SIP_PING, SIP_PRACK, SIP_PUBLISH, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, and SIP_UPDATE.

Referenced by respprep().

06724                                                                              {
06725    /* Requirements for Contact header inclusion in responses generated
06726     * from the header tables found in the following RFCs.  Where the
06727     * Contact header was marked mandatory (m) or optional (o) this
06728     * function returns 1.
06729     *
06730     * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER)
06731     * - RFC 2976 (INFO)
06732     * - RFC 3262 (PRACK)
06733     * - RFC 3265 (SUBSCRIBE, NOTIFY)
06734     * - RFC 3311 (UPDATE)
06735     * - RFC 3428 (MESSAGE)
06736     * - RFC 3515 (REFER)
06737     * - RFC 3903 (PUBLISH)
06738     */
06739 
06740    switch (method) {
06741       /* 1xx, 2xx, 3xx, 485 */
06742       case SIP_INVITE:
06743       case SIP_UPDATE:
06744       case SIP_SUBSCRIBE:
06745       case SIP_NOTIFY:
06746          if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3))
06747             return 1;
06748          break;
06749 
06750       /* 2xx, 3xx, 485 */
06751       case SIP_REGISTER:
06752       case SIP_OPTIONS:
06753          if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3))
06754             return 1;
06755          break;
06756 
06757       /* 3xx, 485 */
06758       case SIP_BYE:
06759       case SIP_PRACK:
06760       case SIP_MESSAGE:
06761       case SIP_PUBLISH:
06762          if (msg[0] == '3' || !strncmp(msg, "485", 3))
06763             return 1;
06764          break;
06765 
06766       /* 2xx, 3xx, 4xx, 5xx, 6xx */
06767       case SIP_REFER:
06768          if (msg[0] >= '2' && msg[0] <= '6')
06769             return 1;
06770          break;
06771 
06772       /* contact will not be included for everything else */
06773       case SIP_ACK:
06774       case SIP_CANCEL:
06775       case SIP_INFO:
06776       case SIP_PING:
06777       default:
06778          return 0;
06779    }
06780    return 0;
06781 }

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

References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_log(), ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, sip_pvt::fullcontact, get_header(), init_resp(), sip_pvt::method, sip_pvt::our_contact, process_via(), sip_pvt::recv, resp_needs_contact(), sip_pvt::sa, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, SUPPORTED_EXTENSIONS, sip_pvt::tag, and sip_pvt::theirtag.

06786 {
06787    char newto[256];
06788    const char *ot;
06789 
06790    init_resp(resp, msg);
06791    copy_via_headers(p, resp, req, "Via");
06792    if (msg[0] == '1' || msg[0] == '2')
06793       copy_all_header(resp, req, "Record-Route");
06794    copy_header(resp, req, "From");
06795    ot = get_header(req, "To");
06796    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
06797       /* Add the proper tag if we don't have it already.  If they have specified
06798          their tag, use it.  Otherwise, use our own tag */
06799       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
06800          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
06801       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
06802          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
06803       else
06804          ast_copy_string(newto, ot, sizeof(newto));
06805       ot = newto;
06806    }
06807    add_header(resp, "To", ot);
06808    copy_header(resp, req, "Call-ID");
06809    copy_header(resp, req, "CSeq");
06810    if (!ast_strlen_zero(global_useragent))
06811       add_header(resp, "User-Agent", global_useragent);
06812    add_header(resp, "Allow", ALLOWED_METHODS);
06813    add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
06814    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
06815       /* For registration responses, we also need expiry and
06816          contact info */
06817       char tmp[256];
06818 
06819       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
06820       add_header(resp, "Expires", tmp);
06821       if (p->expiry) {  /* Only add contact if we have an expiry time */
06822          char contact[SIPBUFSIZE];
06823          const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact;
06824          char *brackets = strchr(contact_uri, '<');
06825          snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry);
06826          add_header(resp, "Contact", contact);  /* Not when we unregister */
06827       }
06828    } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) {
06829       add_header(resp, "Contact", p->our_contact);
06830    }
06831 
06832    /* default to routing the response to the address where the request
06833     * came from.  Since we don't have a transport layer, we do this here.
06834     * The process_via() function will update the port to either the port
06835     * specified in the via header or the default port later on (per RFC
06836     * 3261 section 18.2.2).
06837     */
06838    p->sa = p->recv;
06839 
06840    if (process_via(p, req)) {
06841       ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n");
06842    }
06843 
06844    return 0;
06845 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

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

17830 {
17831    /* If we're supposed to be stopped -- stay stopped */
17832    if (monitor_thread == AST_PTHREADT_STOP)
17833       return 0;
17834    ast_mutex_lock(&monlock);
17835    if (monitor_thread == pthread_self()) {
17836       ast_mutex_unlock(&monlock);
17837       ast_log(LOG_WARNING, "Cannot kill myself\n");
17838       return -1;
17839    }
17840    if (monitor_thread != AST_PTHREADT_NULL) {
17841       /* Wake up the thread */
17842       pthread_kill(monitor_thread, SIGURG);
17843    } else {
17844       /* Start a new monitor */
17845       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
17846          ast_mutex_unlock(&monlock);
17847          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
17848          return -1;
17849       }
17850    }
17851    ast_mutex_unlock(&monlock);
17852    return 0;
17853 }

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

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

Definition at line 2015 of file chan_sip.c.

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

02016 {
02017    struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL;
02018    int reschedule = DEFAULT_RETRANS;
02019    int xmitres = 0;
02020 
02021    /* Lock channel PVT */
02022    ast_mutex_lock(&pkt->owner->lock);
02023 
02024    if (pkt->retrans < MAX_RETRANS) {
02025       pkt->retrans++;
02026       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
02027          if (sipdebug && option_debug > 3)
02028             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);
02029       } else {
02030          int siptimer_a;
02031 
02032          if (sipdebug && option_debug > 3)
02033             ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
02034          if (!pkt->timer_a)
02035             pkt->timer_a = 2 ;
02036          else
02037             pkt->timer_a = 2 * pkt->timer_a;
02038 
02039          /* For non-invites, a maximum of 4 secs */
02040          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
02041          if (pkt->method != SIP_INVITE && siptimer_a > 4000)
02042             siptimer_a = 4000;
02043 
02044          /* Reschedule re-transmit */
02045          reschedule = siptimer_a;
02046          if (option_debug > 3)
02047             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);
02048       }
02049 
02050       if (sip_debug_test_pvt(pkt->owner)) {
02051          const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
02052          ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n",
02053             pkt->retrans, sip_nat_mode(pkt->owner),
02054             ast_inet_ntoa(dst->sin_addr),
02055             ntohs(dst->sin_port), pkt->data);
02056       }
02057 
02058       append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data);
02059       xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
02060       if (xmitres == XMIT_ERROR) {
02061          ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid);
02062       } else {
02063          ast_mutex_unlock(&pkt->owner->lock);
02064          return  reschedule;
02065       }
02066    }
02067    /* Too many retries */
02068    if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) {
02069       if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */
02070          ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s from %s for packet seqno %d (%s %s %s)\n", pkt->owner->callid, pkt->owner->from, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response: " : "Request: ", sip_methods[pkt->method].text);
02071    } else if ((pkt->method == SIP_OPTIONS) && sipdebug) {
02072          ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s)  -- See doc/sip-retransmit.txt.\n", pkt->owner->callid);
02073    }
02074    if (xmitres == XMIT_ERROR) {
02075       ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid);
02076       append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
02077    } else
02078       append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)");
02079 
02080    pkt->retransid = -1;
02081 
02082    if (ast_test_flag(pkt, FLAG_FATAL)) {
02083       while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
02084          DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */
02085       }
02086 
02087       if (pkt->owner->owner && !pkt->owner->owner->hangupcause)
02088          pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
02089 
02090       if (pkt->owner->owner) {
02091          sip_alreadygone(pkt->owner);
02092          ast_log(LOG_WARNING, "Hanging up call %s from channel %s . No reply to our critical packet after %d retries (see doc/sip-retransmit.txt).\n", pkt->owner->callid, pkt->owner->owner->name, pkt->retrans);
02093          ast_queue_hangup(pkt->owner->owner);
02094          ast_channel_unlock(pkt->owner->owner);
02095       } else {
02096          /* If no channel owner, destroy now */
02097 
02098          /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
02099          if (pkt->method != SIP_OPTIONS) {
02100             ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY);
02101             sip_alreadygone(pkt->owner);
02102             if (option_debug)
02103                append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
02104          }
02105       }
02106    }
02107 
02108    if (pkt->method == SIP_BYE) {
02109       /* We're not getting answers on SIP BYE's.  Tear down the call anyway. */
02110       sip_alreadygone(pkt->owner);
02111       if (pkt->owner->owner)
02112          ast_channel_unlock(pkt->owner->owner);
02113       append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
02114       ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY);
02115    }
02116 
02117    /* In any case, go ahead and remove the packet */
02118    for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
02119       if (cur == pkt)
02120          break;
02121    }
02122    if (cur) {
02123       if (prev)
02124          prev->next = cur->next;
02125       else
02126          pkt->owner->packets = cur->next;
02127       ast_mutex_unlock(&pkt->owner->lock);
02128       free(cur);
02129       pkt = NULL;
02130    } else
02131       ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
02132    if (pkt)
02133       ast_mutex_unlock(&pkt->owner->lock);
02134    return 0;
02135 }

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

Definition at line 17374 of file chan_sip.c.

References ast_channel_trylock, ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lock, and sip_pvt::owner.

Referenced by queue_request().

17375 {
17376    struct sip_pvt *p = (struct sip_pvt *) data;
17377    int recount = 0;
17378    int nounlock = 0;
17379    int lockretry;
17380 
17381    for (lockretry = 10; lockretry > 0; lockretry--) {
17382       ast_mutex_lock(&p->lock);
17383 
17384       /* lock the owner if it has one -- we may need it */
17385       /* because this is deadlock-prone, we need to try and unlock if failed */
17386       if (!p->owner || !ast_channel_trylock(p->owner)) {
17387          break;   /* locking succeeded */
17388       }
17389 
17390       if (lockretry != 1) {
17391          ast_mutex_unlock(&p->lock);
17392          /* Sleep for a very short amount of time */
17393          usleep(1);
17394       }
17395    }
17396 
17397    if (!lockretry) {
17398       int retry = !AST_LIST_EMPTY(&p->request_queue);
17399 
17400       /* we couldn't get the owner lock, which is needed to process
17401          the queued requests, so return a non-zero value, which will
17402          cause the scheduler to run this request again later if there
17403          still requests to be processed
17404       */
17405       ast_mutex_unlock(&p->lock);
17406       return retry;
17407    };
17408 
17409    process_request_queue(p, &recount, &nounlock);
17410    p->request_queue_sched_id = -1;
17411 
17412    if (p->owner && !nounlock) {
17413       ast_channel_unlock(p->owner);
17414    }
17415    ast_mutex_unlock(&p->lock);
17416 
17417    if (recount) {
17418       ast_update_use_count();
17419    }
17420 
17421    return 0;
17422 }

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

Definition at line 2459 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

02460 {
02461    struct provisional_keepalive_data *d = (struct provisional_keepalive_data *) data;
02462 
02463    return send_provisional_keepalive_full(d, 0);
02464 }

static int send_provisional_keepalive_full ( struct provisional_keepalive_data data,
int  with_sdp 
) [static]

This is called by the scheduler to resend the last provisional message in a dialog.

Definition at line 2406 of file chan_sip.c.

References ao2_ref(), ast_channel_trylock, ast_channel_unlock, ast_mutex_lock(), ast_mutex_unlock(), sip_request::data, sip_pvt::initreq, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::last_provisional, sip_pvt::lock, sip_pvt::owner, PROVIS_KEEPALIVE_TIMEOUT, S_OR, transmit_response(), transmit_response_with_sdp(), and XMIT_UNRELIABLE.

Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().

02407 {
02408    const char *msg = NULL;
02409    int res = 0;
02410    struct sip_pvt *pvt = data->pvt;
02411 
02412    if (!pvt) {
02413       ao2_ref(data, -1); /* not rescheduling so drop ref. in this case the dialog has already dropped this ref */
02414       return res;
02415    }
02416 
02417    ast_mutex_lock(&pvt->lock);
02418    while (pvt->owner && ast_channel_trylock(pvt->owner)) {
02419       ast_mutex_unlock(&pvt->lock);
02420       sched_yield();
02421       if ((pvt = data->pvt)) {
02422          ast_mutex_lock(&pvt->lock);
02423       } else {
02424          ao2_ref(data, -1);
02425          return res;
02426       }
02427    }
02428 
02429    if (data->sched_id == -1 || pvt->invitestate >= INV_COMPLETED) {
02430       goto provisional_keepalive_cleanup;
02431    }
02432 
02433    if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) {
02434       msg = "183 Session Progress";
02435    }
02436 
02437    if (with_sdp) {
02438       transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE);
02439    } else {
02440       transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq);
02441    }
02442 
02443    res = PROVIS_KEEPALIVE_TIMEOUT; /* reschedule the keepalive event */
02444 
02445 provisional_keepalive_cleanup:
02446    if (!res) { /* not rescheduling, so drop ref */
02447       data->sched_id = -1; /* if we don't re-schedule, make sure to remove the sched id */
02448       ao2_ref(data, -1); /* release the scheduler's reference to this data */
02449    }
02450 
02451    if (pvt->owner) {
02452       ast_channel_unlock(pvt->owner);
02453    }
02454    ast_mutex_unlock(&pvt->lock);
02455 
02456    return res;
02457 }

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

Definition at line 2466 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

02467 {
02468    struct provisional_keepalive_data *d = (struct provisional_keepalive_data *) data;
02469 
02470    return send_provisional_keepalive_full(d, 1);
02471 }

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 2567 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, finalize_content(), sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_methods, SIP_NAT_ROUTE, SIP_NO_HISTORY, cfsip_methods::text, and XMIT_CRITICAL.

02568 {
02569    int res;
02570 
02571    finalize_content(req);
02572    add_blank(req);
02573    if (sip_debug_test_pvt(p)) {
02574       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
02575          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);
02576       else
02577          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);
02578    }
02579    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02580       struct sip_request tmp;
02581       parse_copy(&tmp, req);
02582       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
02583    }
02584    res = (reliable) ?
02585       __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02586       __sip_xmit(p, req->data, req->len);
02587    return res;
02588 }

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 2532 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, finalize_content(), sip_pvt::flags, get_header(), sip_pvt::initreq, sip_request::len, sip_request::method, parse_copy(), remove_provisional_keepalive_sched(), sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.

02533 {
02534    int res;
02535 
02536    finalize_content(req);
02537    add_blank(req);
02538    if (sip_debug_test_pvt(p)) {
02539       const struct sockaddr_in *dst = sip_real_dst(p);
02540 
02541       ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
02542          reliable ? "Reliably " : "", sip_nat_mode(p),
02543          ast_inet_ntoa(dst->sin_addr),
02544          ntohs(dst->sin_port), req->data);
02545    }
02546    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
02547       struct sip_request tmp;
02548       parse_copy(&tmp, req);
02549       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 
02550          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text);
02551    }
02552 
02553    /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */
02554    if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) {
02555       remove_provisional_keepalive_sched(p);
02556    }
02557 
02558    res = (reliable) ?
02559        __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
02560       __sip_xmit(p, req->data, req->len);
02561    if (res > 0)
02562       return 0;
02563    return res;
02564 }

static int set_address_from_contact ( struct sip_pvt pvt  )  [static]

Change the other partys IP address based on given contact.

Definition at line 9052 of file chan_sip.c.

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

Referenced by handle_response_invite().

09053 {
09054    if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
09055       /* NAT: Don't trust the contact field.  Just use what they came to us
09056          with. */
09057       pvt->sa = pvt->recv;
09058       return 0;
09059    }
09060 
09061    return __set_address_from_contact(pvt->fullcontact, &pvt->sa);
09062 }

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

Set destination from SIP URI.

Definition at line 6634 of file chan_sip.c.

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

Referenced by reqprep().

06635 {
06636    char *h, *maddr, hostname[256];
06637    int port, hn;
06638    struct hostent *hp;
06639    struct ast_hostent ahp;
06640    int debug=sip_debug_test_pvt(p);
06641 
06642    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
06643    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
06644 
06645    if (debug)
06646       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
06647 
06648    /* Find and parse hostname */
06649    h = strchr(uri, '@');
06650    if (h)
06651       ++h;
06652    else {
06653       h = uri;
06654       if (strncasecmp(h, "sip:", 4) == 0)
06655          h += 4;
06656       else if (strncasecmp(h, "sips:", 5) == 0)
06657          h += 5;
06658    }
06659    hn = strcspn(h, ":;>") + 1;
06660    if (hn > sizeof(hostname)) 
06661       hn = sizeof(hostname);
06662    ast_copy_string(hostname, h, hn);
06663    /* XXX bug here if string has been trimmed to sizeof(hostname) */
06664    h += hn - 1;
06665 
06666    /* Is "port" present? if not default to STANDARD_SIP_PORT */
06667    if (*h == ':') {
06668       /* Parse port */
06669       ++h;
06670       port = strtol(h, &h, 10);
06671    }
06672    else
06673       port = STANDARD_SIP_PORT;
06674 
06675    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
06676    maddr = strstr(h, "maddr=");
06677    if (maddr) {
06678       maddr += 6;
06679       hn = strspn(maddr, "0123456789.") + 1;
06680       if (hn > sizeof(hostname))
06681          hn = sizeof(hostname);
06682       ast_copy_string(hostname, maddr, hn);
06683    }
06684    
06685    hp = ast_gethostbyname(hostname, &ahp);
06686    if (hp == NULL)  {
06687       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
06688       return;
06689    }
06690    p->sa.sin_family = AF_INET;
06691    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
06692    p->sa.sin_port = htons(port);
06693    if (debug)
06694       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
06695 }

static void set_insecure_flags ( struct ast_flags flags,
const char *  value,
int  lineno 
) [static]

Parse the "insecure" setting from sip.conf or from realtime.

Parameters:
flags a pointer to an ast_flags structure
value the value of the SIP insecure setting
lineno linenumber in sip.conf or -1 for realtime

Definition at line 18176 of file chan_sip.c.

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

Referenced by handle_common_options().

18177 {
18178    static int dep_insecure_very = 0;
18179    static int dep_insecure_yes = 0;
18180 
18181    if (ast_strlen_zero(value))
18182       return;
18183 
18184    if (!strcasecmp(value, "very")) {
18185       ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
18186       if(!dep_insecure_very) {
18187          if(lineno != -1)
18188             ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno);
18189          else
18190             ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n");
18191          dep_insecure_very = 1;
18192       }
18193    }
18194    else if (ast_true(value)) {
18195       ast_set_flag(flags, SIP_INSECURE_PORT);
18196       if(!dep_insecure_yes) {
18197          if(lineno != -1)
18198             ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno);
18199          else
18200             ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value);
18201          dep_insecure_yes = 1;
18202       }
18203    }
18204    else if (!ast_false(value)) {
18205       char buf[64];
18206       char *word, *next;
18207       ast_copy_string(buf, value, sizeof(buf));
18208       next = buf;
18209       while ((word = strsep(&next, ","))) {
18210          if (!strcasecmp(word, "port"))
18211             ast_set_flag(flags, SIP_INSECURE_PORT);
18212          else if (!strcasecmp(word, "invite"))
18213             ast_set_flag(flags, SIP_INSECURE_INVITE);
18214          else
18215             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
18216       }
18217    }
18218 }

static void set_nonce_randdata ( struct sip_pvt p,
int  forceupdate 
) [static]

builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.

Definition at line 9390 of file chan_sip.c.

References ast_random(), ast_string_field_build, ast_strlen_zero(), sip_pvt::randdata, and sip_pvt::stalenonce.

Referenced by check_auth(), and transmit_fake_auth_response().

09391 {
09392    if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) {
09393       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
09394       p->stalenonce = 0;
09395    }
09396 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

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

18612 {
18613    if (peer->expire == 0) {
18614       /* Don't reset expire or port time during reload 
18615          if we have an active registration 
18616       */
18617       peer->expire = -1;
18618       peer->pokeexpire = -1;
18619       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
18620    }
18621    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
18622    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
18623    strcpy(peer->context, default_context);
18624    strcpy(peer->subscribecontext, default_subscribecontext);
18625    strcpy(peer->language, default_language);
18626    strcpy(peer->mohinterpret, default_mohinterpret);
18627    strcpy(peer->mohsuggest, default_mohsuggest);
18628    peer->addr.sin_family = AF_INET;
18629    peer->defaddr.sin_family = AF_INET;
18630    peer->capability = global_capability;
18631    peer->maxcallbitrate = default_maxcallbitrate;
18632    peer->rtptimeout = global_rtptimeout;
18633    peer->rtpholdtimeout = global_rtpholdtimeout;
18634    peer->rtpkeepalive = global_rtpkeepalive;
18635    peer->allowtransfer = global_allowtransfer;
18636    peer->autoframing = global_autoframing;
18637    strcpy(peer->vmexten, default_vmexten);
18638    peer->secret[0] = '\0';
18639    peer->md5secret[0] = '\0';
18640    peer->cid_num[0] = '\0';
18641    peer->cid_name[0] = '\0';
18642    peer->fromdomain[0] = '\0';
18643    peer->fromuser[0] = '\0';
18644    peer->regexten[0] = '\0';
18645    peer->mailbox[0] = '\0';
18646    peer->callgroup = 0;
18647    peer->pickupgroup = 0;
18648    peer->maxms = default_qualify;
18649    peer->prefs = default_prefs;
18650 }

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

Add a SIP header to an outbound INVITE.

Definition at line 19984 of file chan_sip.c.

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

Referenced by load_module().

19985 {
19986    int no = 0;
19987    int ok = FALSE;
19988    char varbuf[30];
19989    char *inbuf = (char *) data;
19990    
19991    if (ast_strlen_zero(inbuf)) {
19992       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
19993       return 0;
19994    }
19995    ast_channel_lock(chan);
19996 
19997    /* Check for headers */
19998    while (!ok && no <= 50) {
19999       no++;
20000       snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no);
20001 
20002       /* Compare without the leading underscores */
20003       if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) )
20004          ok = TRUE;
20005    }
20006    if (ok) {
20007       pbx_builtin_setvar_helper (chan, varbuf, inbuf);
20008       if (sipdebug)
20009          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
20010    } else {
20011       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
20012    }
20013    ast_channel_unlock(chan);
20014    return 0;
20015 }

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

Support routine for find_peer.

Definition at line 2944 of file chan_sip.c.

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

Referenced by find_peer().

02945 {
02946    /* We know name is the first field, so we can cast */
02947    struct sip_peer *p = (struct sip_peer *) name;
02948    return   !(!inaddrcmp(&p->addr, sin) || 
02949                (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) &&
02950                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
02951 }

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

References __ourip, ast_calloc, ast_copy_flags, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_rtp_codec_setpref(), ast_rtp_destroy(), 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_free_memory, ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), errno, free, sip_pvt::fromdomain, global_flags, iflist, iflock, INITIAL_CSEQ, io, LOG_DEBUG, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

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

04872 {
04873    struct sip_pvt *p;
04874 
04875    if (!(p = ast_calloc(1, sizeof(*p))))
04876       return NULL;
04877 
04878    if (ast_string_field_init(p, 512)) {
04879       free(p);
04880       return NULL;
04881    }
04882 
04883    ast_mutex_init(&p->lock);
04884 
04885    p->method = intended_method;
04886    p->initid = -1;
04887    p->waitid = -1;
04888    p->autokillid = -1;
04889    p->request_queue_sched_id = -1;
04890    p->subscribed = NONE;
04891    p->stateid = -1;
04892    p->prefs = default_prefs;     /* Set default codecs for this call */
04893 
04894    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
04895       p->timer_t1 = 500;   /* Default SIP retransmission timer T1 (RFC 3261) */
04896 
04897    if (sin) {
04898       p->sa = *sin;
04899       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
04900          p->ourip = __ourip;
04901    } else
04902       p->ourip = __ourip;
04903 
04904    /* Copy global flags to this PVT at setup. */
04905    ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
04906    ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
04907 
04908    ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY);
04909 
04910    p->branch = ast_random();  
04911    make_our_tag(p->tag, sizeof(p->tag));
04912    p->ocseq = INITIAL_CSEQ;
04913 
04914    if (sip_methods[intended_method].need_rtp) {
04915       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04916       /* If the global videosupport flag is on, we always create a RTP interface for video */
04917       if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
04918          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
04919       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
04920          p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
04921       if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
04922          ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n",
04923             ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
04924          /* If rtp was successfully allocated, but vrtp was not, then we need to be sure to free rtp here */
04925          if (p->rtp) {
04926             ast_rtp_destroy(p->rtp);
04927          }
04928          if (p->udptl) {
04929             ast_udptl_destroy(p->udptl);
04930          }
04931          ast_mutex_destroy(&p->lock);
04932          if (p->chanvars) {
04933             ast_variables_destroy(p->chanvars);
04934             p->chanvars = NULL;
04935          }
04936          ast_string_field_free_memory(p);
04937          free(p);
04938          return NULL;
04939       }
04940       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04941       ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04942       ast_rtp_settos(p->rtp, global_tos_audio);
04943       ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
04944       ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
04945       ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
04946       if (p->vrtp) {
04947          ast_rtp_settos(p->vrtp, global_tos_video);
04948          ast_rtp_setdtmf(p->vrtp, 0);
04949          ast_rtp_setdtmfcompensate(p->vrtp, 0);
04950          ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
04951          ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
04952          ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
04953       }
04954       if (p->udptl)
04955          ast_udptl_settos(p->udptl, global_tos_audio);
04956       p->maxcallbitrate = default_maxcallbitrate;
04957       p->autoframing = global_autoframing;
04958       ast_rtp_codec_setpref(p->rtp, &p->prefs);
04959    }
04960 
04961    if (useglobal_nat && sin) {
04962       /* Setup NAT structure according to global settings if we have an address */
04963       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
04964       p->recv = *sin;
04965       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
04966    }
04967 
04968    if (p->method != SIP_REGISTER)
04969       ast_string_field_set(p, fromdomain, default_fromdomain);
04970    build_via(p);
04971    if (!callid)
04972       build_callid_pvt(p);
04973    else
04974       ast_string_field_set(p, callid, callid);
04975    /* Assign default music on hold class */
04976    ast_string_field_set(p, mohinterpret, default_mohinterpret);
04977    ast_string_field_set(p, mohsuggest, default_mohsuggest);
04978    p->capability = global_capability;
04979    p->allowtransfer = global_allowtransfer;
04980    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
04981        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
04982       p->noncodeccapability |= AST_RTP_DTMF;
04983    if (p->udptl) {
04984       p->t38.capability = global_t38_capability;
04985       if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
04986          p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
04987       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
04988          p->t38.capability |= T38FAX_UDP_EC_FEC;
04989       else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
04990          p->t38.capability |= T38FAX_UDP_EC_NONE;
04991       p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
04992       p->t38.jointcapability = p->t38.capability;
04993    }
04994    ast_string_field_set(p, context, default_context);
04995 
04996    AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue);
04997 
04998    /* Add to active dialog list */
04999    ast_mutex_lock(&iflock);
05000    p->next = iflist;
05001    iflist = p;
05002    ast_mutex_unlock(&iflock);
05003    if (option_debug)
05004       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");
05005    return p;
05006 }

static void sip_alreadygone ( struct sip_pvt dialog  )  [static]

Definition at line 1771 of file chan_sip.c.

References ast_log(), ast_set_flag, sip_pvt::callid, sip_pvt::flags, LOG_DEBUG, option_debug, and SIP_ALREADYGONE.

Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_indicate(), and sip_sipredirect().

01772 {
01773    if (option_debug > 2)
01774       ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
01775    ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
01776 }

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

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, ast_channel::tech_pvt, transmit_response_with_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.

04024 {
04025    int res = 0;
04026    struct sip_pvt *p = ast->tech_pvt;
04027 
04028    ast_mutex_lock(&p->lock);
04029    if (ast->_state != AST_STATE_UP) {
04030       try_suggested_sip_codec(p);   
04031 
04032       ast_setstate(ast, AST_STATE_UP);
04033       if (option_debug)
04034          ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name);
04035 
04036       ast_rtp_new_source(p->rtp);
04037       res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
04038       ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
04039    }
04040    ast_mutex_unlock(&p->lock);
04041    return res;
04042 }

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

References ast_channel::_state, sip_invite_param::addsipheaders, AST_CAUSE_USER_BUSY, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, sip_pvt::cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, ast_var_t::entries, sip_pvt::flags, ast_channel::hangupcause, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, sip_pvt::maxtime, ast_channel::name, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, SIPBUFSIZE, sipdebug, sip_pvt::t38, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.

03281 {
03282    int res, xmitres = 0;
03283    struct sip_pvt *p;
03284    struct varshead *headp;
03285    struct ast_var_t *current;
03286    const char *referer = NULL;   /* SIP refererer */  
03287 
03288    p = ast->tech_pvt;
03289    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
03290       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
03291       return -1;
03292    }
03293 
03294    /* Check whether there is vxml_url, distinctive ring variables */
03295    headp=&ast->varshead;
03296    AST_LIST_TRAVERSE(headp,current,entries) {
03297       /* Check whether there is a VXML_URL variable */
03298       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
03299          p->options->vxml_url = ast_var_value(current);
03300       } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
03301          p->options->uri_options = ast_var_value(current);
03302       } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) {
03303          /* Check whether there is a ALERT_INFO variable */
03304          p->options->distinctive_ring = ast_var_value(current);
03305       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
03306          /* Check whether there is a variable with a name starting with SIPADDHEADER */
03307          p->options->addsipheaders = 1;
03308       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
03309          /* This is a transfered call */
03310          p->options->transfer = 1;
03311       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
03312          /* This is the referer */
03313          referer = ast_var_value(current);
03314       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
03315          /* We're replacing a call. */
03316          p->options->replaces = ast_var_value(current);
03317       }
03318    }
03319    
03320    res = 0;
03321    ast_set_flag(&p->flags[0], SIP_OUTGOING);
03322 
03323    if (p->options->transfer) {
03324       char buf[SIPBUFSIZE/2];
03325 
03326       if (referer) {
03327          if (sipdebug && option_debug > 2)
03328             ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer);
03329          snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
03330       } else 
03331          snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
03332       ast_string_field_set(p, cid_name, buf);
03333    } 
03334    if (option_debug)
03335       ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username);
03336 
03337    res = update_call_counter(p, INC_CALL_RINGING);
03338    if ( res != -1 ) {
03339       p->callingpres = ast->cid.cid_pres;
03340       p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec);
03341       p->jointnoncodeccapability = p->noncodeccapability;
03342 
03343       /* If there are no audio formats left to offer, punt */
03344       if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
03345          ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
03346          res = -1;
03347       } else {
03348          p->t38.jointcapability = p->t38.capability;
03349          if (option_debug > 1)
03350             ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability);
03351          xmitres = transmit_invite(p, SIP_INVITE, 1, 2);
03352          if (xmitres == XMIT_ERROR)
03353             return -1;  /* Transmission error */
03354 
03355          p->invitestate = INV_CALLING;
03356 
03357          /* Initialize auto-congest time */
03358          AST_SCHED_DEL(sched, p->initid);
03359          p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p);
03360       }
03361    } else {
03362       ast->hangupcause = AST_CAUSE_USER_BUSY;
03363    }
03364    return res;
03365 }

static int sip_cancel_destroy ( struct sip_pvt p  )  [static]

Cancel destruction of SIP dialog.

Definition at line 2277 of file chan_sip.c.

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

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

02278 {
02279    int res = 0;
02280    if (p->autokillid > -1) {
02281       if (!(res = ast_sched_del(sched, p->autokillid))) {
02282          append_history(p, "CancelDestroy", "");
02283          p->autokillid = -1;
02284       }
02285    }
02286    return res;
02287 }

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

See if we pass debug IP filter.

Definition at line 1853 of file chan_sip.c.

References sipdebug.

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

01854 {
01855    if (!sipdebug)
01856       return 0;
01857    if (debugaddr.sin_addr.s_addr) {
01858       if (((ntohs(debugaddr.sin_port) != 0)
01859          && (debugaddr.sin_port != addr->sin_port))
01860          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
01861          return 0;
01862    }
01863    return 1;
01864 }

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

Test PVT for debugging output.

Definition at line 1879 of file chan_sip.c.

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

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

01880 {
01881    if (!sipdebug)
01882       return 0;
01883    return sip_debug_test_addr(sip_real_dst(p));
01884 }

static void sip_destroy ( struct sip_pvt p  )  [static]

Destroy SIP call structure.

Definition at line 3659 of file chan_sip.c.

References __sip_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflock, LOG_DEBUG, and option_debug.

Referenced by __sip_autodestruct(), handle_request_subscribe(), reload_config(), sip_destroy_peer(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

03660 {
03661    ast_mutex_lock(&iflock);
03662    if (option_debug > 2)
03663       ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid);
03664    __sip_destroy(p, 1);
03665    ast_mutex_unlock(&iflock);
03666 }

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

Destroy peer object from memory.

Definition at line 2752 of file chan_sip.c.

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

Referenced by __sip_destroy(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), unload_module(), and update_call_counter().

02753 {
02754    if (option_debug > 2)
02755       ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
02756 
02757    /* Delete it, it needs to disappear */
02758    if (peer->call)
02759       sip_destroy(peer->call);
02760 
02761    if (peer->mwipvt)    /* We have an active subscription, delete it */
02762       sip_destroy(peer->mwipvt);
02763 
02764    if (peer->chanvars) {
02765       ast_variables_destroy(peer->chanvars);
02766       peer->chanvars = NULL;
02767    }
02768 
02769    register_peer_exten(peer, FALSE);
02770    ast_free_ha(peer->ha);
02771    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT))
02772       apeerobjs--;
02773    else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && ast_test_flag(&peer->flags[0], SIP_REALTIME))
02774       rpeerobjs--;
02775    else
02776       speerobjs--;
02777    clear_realm_authentication(peer->auth);
02778    peer->auth = NULL;
02779    free(peer);
02780 }

static void sip_destroy_user ( struct sip_user user  )  [static]

Remove user object from in-memory storage.

Definition at line 2972 of file chan_sip.c.

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

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

02973 {
02974    if (option_debug > 2)
02975       ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
02976    ast_free_ha(user->ha);
02977    if (user->chanvars) {
02978       ast_variables_destroy(user->chanvars);
02979       user->chanvars = NULL;
02980    }
02981    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && ast_test_flag(&user->flags[0], SIP_REALTIME))
02982       ruserobjs--;
02983    else
02984       suserobjs--;
02985    free(user);
02986 }

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

18006 {
18007    char *host;
18008    char *tmp;
18009 
18010    struct hostent *hp;
18011    struct ast_hostent ahp;
18012    struct sip_peer *p;
18013 
18014    int res = AST_DEVICE_INVALID;
18015 
18016    /* make sure data is not null. Maybe unnecessary, but better be safe */
18017    host = ast_strdupa(data ? data : "");
18018    if ((tmp = strchr(host, '@')))
18019       host = tmp + 1;
18020 
18021    if (option_debug > 2) 
18022       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
18023 
18024    /* If find_peer asks for a realtime peer, then this breaks rtautoclear.  This
18025     * is because when a peer tries to autoexpire, the last thing it does is to
18026     * queue up an event telling the system that the devicestate has changed
18027     * (presumably to unavailable).  If we ask for a realtime peer here, this would
18028     * load it BACK into memory, thus defeating the point of trying to trying to
18029     * clear dead hosts out of memory.
18030     */
18031    if ((p = find_peer(host, NULL, 0, 1))) {
18032       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
18033          /* we have an address for the peer */
18034       
18035          /* Check status in this order
18036             - Hold
18037             - Ringing
18038             - Busy (enforced only by call limit)
18039             - Inuse (we have a call)
18040             - Unreachable (qualify)
18041             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
18042             for registered devices */
18043 
18044          if (p->onHold)
18045             /* First check for hold or ring states */
18046             res = AST_DEVICE_ONHOLD;
18047          else if (p->inRinging) {
18048             if (p->inRinging == p->inUse)
18049                res = AST_DEVICE_RINGING;
18050             else
18051                res = AST_DEVICE_RINGINUSE;
18052          } else if (p->call_limit && (p->inUse == p->call_limit))
18053             /* check call limit */
18054             res = AST_DEVICE_BUSY;
18055          else if (p->call_limit && p->inUse)
18056             /* Not busy, but we do have a call */
18057             res = AST_DEVICE_INUSE;
18058          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 
18059             /* We don't have a call. Are we reachable at all? Requires qualify= */
18060             res = AST_DEVICE_UNAVAILABLE;
18061          else  /* Default reply if we're registered and have no other data */
18062             res = AST_DEVICE_NOT_INUSE;
18063       } else {
18064          /* there is no address, it's unavailable */
18065          res = AST_DEVICE_UNAVAILABLE;
18066       }
18067       ASTOBJ_UNREF(p,sip_destroy_peer);
18068    } else {
18069       char *port = strchr(host, ':');
18070       if (port)
18071          *port = '\0';
18072       hp = ast_gethostbyname(host, &ahp);
18073       if (hp)
18074          res = AST_DEVICE_UNKNOWN;
18075    }
18076 
18077    return res;
18078 }

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

Turn on SIP debugging (CLI command).

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

12704 {
12705    int oldsipdebug = sipdebug_console;
12706    if (argc != 3) {
12707       if (argc != 5) 
12708          return RESULT_SHOWUSAGE;
12709       else if (strcmp(argv[3], "ip") == 0)
12710          return sip_do_debug_ip(fd, argc, argv);
12711       else if (strcmp(argv[3], "peer") == 0)
12712          return sip_do_debug_peer(fd, argc, argv);
12713       else
12714          return RESULT_SHOWUSAGE;
12715    }
12716    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
12717    memset(&debugaddr, 0, sizeof(debugaddr));
12718    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
12719    return RESULT_SUCCESS;
12720 }

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

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

12723 {
12724    int oldsipdebug = sipdebug_console;
12725    char *newargv[6] = { "sip", "set", "debug", NULL };
12726    if (argc != 2) {
12727       if (argc != 4) 
12728          return RESULT_SHOWUSAGE;
12729       else if (strcmp(argv[2], "ip") == 0) {
12730          newargv[3] = argv[2];
12731          newargv[4] = argv[3];
12732          return sip_do_debug_ip(fd, argc + 1, newargv);
12733       } else if (strcmp(argv[2], "peer") == 0) {
12734          newargv[3] = argv[2];
12735          newargv[4] = argv[3];
12736          return sip_do_debug_peer(fd, argc + 1, newargv);
12737       } else
12738          return RESULT_SHOWUSAGE;
12739    }
12740    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
12741    memset(&debugaddr, 0, sizeof(debugaddr));
12742    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
12743    return RESULT_SUCCESS;
12744 }

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

Enable SIP Debugging in CLI.

Definition at line 12649 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, and SIP_PAGE2_DEBUG_CONSOLE.

Referenced by sip_do_debug(), and sip_do_debug_deprecated().

12650 {
12651    struct hostent *hp;
12652    struct ast_hostent ahp;
12653    int port = 0;
12654    char *p, *arg;
12655 
12656    /* sip set debug ip <ip> */
12657    if (argc != 5)
12658       return RESULT_SHOWUSAGE;
12659    p = arg = argv[4];
12660    strsep(&p, ":");
12661    if (p)
12662       port = atoi(p);
12663    hp = ast_gethostbyname(arg, &ahp);
12664    if (hp == NULL)
12665       return RESULT_SHOWUSAGE;
12666 
12667    debugaddr.sin_family = AF_INET;
12668    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
12669    debugaddr.sin_port = htons(port);
12670    if (port == 0)
12671       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
12672    else
12673       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
12674 
12675    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
12676 
12677    return RESULT_SUCCESS;
12678 }

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

12682 {
12683    struct sip_peer *peer;
12684    if (argc != 5)
12685       return RESULT_SHOWUSAGE;
12686    peer = find_peer(argv[4], NULL, 1, 0);
12687    if (peer) {
12688       if (peer->addr.sin_addr.s_addr) {
12689          debugaddr.sin_family = AF_INET;
12690          debugaddr.sin_addr = peer->addr.sin_addr;
12691          debugaddr.sin_port = peer->addr.sin_port;
12692          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
12693          ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
12694       } else
12695          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
12696       ASTOBJ_UNREF(peer,sip_destroy_peer);
12697    } else
12698       ast_cli(fd, "No such peer '%s'\n", argv[4]);
12699    return RESULT_SUCCESS;
12700 }

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

Enable SIP History logging (CLI).

Definition at line 12829 of file chan_sip.c.

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

12830 {
12831    if (argc != 2) {
12832       return RESULT_SHOWUSAGE;
12833    }
12834    recordhistory = TRUE;
12835    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
12836    return RESULT_SUCCESS;
12837 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

Definition at line 20130 of file chan_sip.c.

References AST_SCHED_DEL, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNREF, peerl, reload_config(), sched, sip_destroy_peer(), and SIP_REALTIME.

Referenced by do_monitor().

20131 {
20132    reload_config(reason);
20133 
20134    /* before peers are removed from the peer container, cancel any scheduled pokes */
20135    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
20136       ASTOBJ_RDLOCK(iterator);
20137       if (ast_test_flag(&iterator->flags[0], SIP_REALTIME)) {
20138          if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) {
20139             struct sip_peer *peer_ptr = iterator;
20140             ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
20141          }
20142       }
20143       ASTOBJ_UNLOCK(iterator);
20144    } while (0) );
20145 
20146    /* Prune peers who still are supposed to be deleted */
20147    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
20148    if (option_debug > 3)
20149       ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
20150 
20151    /* Send qualify (OPTIONS) to all peers */
20152    sip_poke_all_peers();
20153 
20154    /* Register with all services */
20155    sip_send_all_registers();
20156 
20157    if (option_debug > 3)
20158       ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
20159 
20160    return 0;
20161 }

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

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

Definition at line 19929 of file chan_sip.c.

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

Referenced by load_module().

19930 {
19931    struct sip_pvt *p;
19932    char *mode;
19933    if (data)
19934       mode = (char *)data;
19935    else {
19936       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
19937       return 0;
19938    }
19939    ast_channel_lock(chan);
19940    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
19941       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
19942       ast_channel_unlock(chan);
19943       return 0;
19944    }
19945    p = chan->tech_pvt;
19946    if (!p) {
19947       ast_channel_unlock(chan);
19948       return 0;
19949    }
19950    ast_mutex_lock(&p->lock);
19951    if (!strcasecmp(mode,"info")) {
19952       ast_clear_flag(&p->flags[0], SIP_DTMF);
19953       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
19954       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
19955    } else if (!strcasecmp(mode,"rfc2833")) {
19956       ast_clear_flag(&p->flags[0], SIP_DTMF);
19957       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
19958       p->jointnoncodeccapability |= AST_RTP_DTMF;
19959    } else if (!strcasecmp(mode,"inband")) { 
19960       ast_clear_flag(&p->flags[0], SIP_DTMF);
19961       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
19962       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
19963    } else
19964       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
19965    if (p->rtp)
19966       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
19967    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
19968       if (!p->vad) {
19969          p->vad = ast_dsp_new();
19970          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
19971       }
19972    } else {
19973       if (p->vad) {
19974          ast_dsp_free(p->vad);
19975          p->vad = NULL;
19976       }
19977    }
19978    ast_mutex_unlock(&p->lock);
19979    ast_channel_unlock(chan);
19980    return 0;
19981 }

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

References AST_LIST_TRAVERSE, ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, sip_history::list, LOG_DEBUG, LOG_NOTICE, option_debug, sipdebug, and sip_pvt::subscribed.

Referenced by __sip_destroy().

12508 {
12509    int x = 0;
12510    struct sip_history *hist;
12511    static int errmsg = 0;
12512 
12513    if (!dialog)
12514       return;
12515 
12516    if (!option_debug && !sipdebug) {
12517       if (!errmsg) {
12518          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
12519          errmsg = 1;
12520       }
12521       return;
12522    }
12523 
12524    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
12525    if (dialog->subscribed)
12526       ast_log(LOG_DEBUG, "  * Subscription\n");
12527    else
12528       ast_log(LOG_DEBUG, "  * SIP Call\n");
12529    if (dialog->history)
12530       AST_LIST_TRAVERSE(dialog->history, hist, list)
12531          ast_log(LOG_DEBUG, "  %-3.3d. %s\n", ++x, hist->event);
12532    if (!x)
12533       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
12534    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
12535 }

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

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

04140 {
04141    int ret = -1;
04142    struct sip_pvt *p;
04143 
04144    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug)
04145       ast_log(LOG_DEBUG, "New channel is zombie\n");
04146    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug)
04147       ast_log(LOG_DEBUG, "Old channel is zombie\n");
04148 
04149    if (!newchan || !newchan->tech_pvt) {
04150       if (!newchan)
04151          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
04152       else
04153          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
04154       return -1;
04155    }
04156    p = newchan->tech_pvt;
04157 
04158    if (!p) {
04159       ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n");
04160       return -1;
04161    }
04162 
04163    ast_mutex_lock(&p->lock);
04164    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
04165    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
04166    if (p->owner != oldchan)
04167       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
04168    else {
04169       p->owner = newchan;
04170       /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
04171          RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
04172          able to do this if the masquerade happens before the bridge breaks (e.g., AMI
04173          redirect of both channels). Note that a channel can not be masqueraded *into*
04174          a native bridge. So there is no danger that this breaks a native bridge that
04175          should stay up. */
04176       sip_set_rtp_peer(newchan, NULL, NULL, 0, 0);
04177       ret = 0;
04178    }
04179    if (option_debug > 2)
04180       ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
04181 
04182    ast_mutex_unlock(&p->lock);
04183    return ret;
04184 }

static int sip_get_codec ( struct ast_channel chan  )  [static]

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

Definition at line 20074 of file chan_sip.c.

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

20075 {
20076    struct sip_pvt *p = chan->tech_pvt;
20077    return p->jointcapability ? p->jointcapability : p->capability;   
20078 }

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

19786 {
19787    struct sip_pvt *p = NULL;
19788    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
19789 
19790    if (!(p = chan->tech_pvt))
19791       return AST_RTP_GET_FAILED;
19792 
19793    ast_mutex_lock(&p->lock);
19794    if (!(p->rtp)) {
19795       ast_mutex_unlock(&p->lock);
19796       return AST_RTP_GET_FAILED;
19797    }
19798 
19799    *rtp = p->rtp;
19800 
19801    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
19802       res = AST_RTP_TRY_PARTIAL;
19803    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
19804       res = AST_RTP_TRY_NATIVE;
19805    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
19806       res = AST_RTP_GET_FAILED;
19807 
19808    ast_mutex_unlock(&p->lock);
19809 
19810    return res;
19811 }

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

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

19638 {
19639    struct sip_pvt *p;
19640    struct ast_udptl *udptl = NULL;
19641    
19642    p = chan->tech_pvt;
19643    if (!p)
19644       return NULL;
19645    
19646    ast_mutex_lock(&p->lock);
19647    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
19648       udptl = p->udptl;
19649    ast_mutex_unlock(&p->lock);
19650    return udptl;
19651 }

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

19815 {
19816    struct sip_pvt *p = NULL;
19817    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
19818    
19819    if (!(p = chan->tech_pvt))
19820       return AST_RTP_GET_FAILED;
19821 
19822    ast_mutex_lock(&p->lock);
19823    if (!(p->vrtp)) {
19824       ast_mutex_unlock(&p->lock);
19825       return AST_RTP_GET_FAILED;
19826    }
19827 
19828    *rtp = p->vrtp;
19829 
19830    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
19831       res = AST_RTP_TRY_NATIVE;
19832 
19833    ast_mutex_unlock(&p->lock);
19834 
19835    return res;
19836 }

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 19689 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::callid, sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, ast_channel::name, 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_DISABLED, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.

Referenced by handle_request_invite(), and handle_response_invite().

19690 {
19691    struct sip_pvt *p;
19692    int flag = 0;
19693    
19694    p = chan->tech_pvt;
19695    if (!p || !pvt->udptl)
19696       return -1;
19697    
19698    /* Setup everything on the other side like offered/responded from first side */
19699    ast_mutex_lock(&p->lock);
19700 
19701    /*! \todo check if this is not set earlier when setting up the PVT. If not
19702       maybe it should move there. */
19703    p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
19704 
19705    ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
19706    ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
19707    ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
19708    
19709    if (reinvite) {      /* If we are handling sending re-invite to the other side of the bridge */
19710       /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
19711          not really T38 re-invites which are different. In this
19712          case it's used properly, to see if we can reinvite over
19713          NAT 
19714       */
19715       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
19716          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
19717          flag =1;
19718       } else {
19719          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
19720       }
19721       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
19722          if (!p->pendinginvite) {
19723             if (option_debug > 2) {
19724                if (flag)
19725                   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));
19726                else
19727                   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));
19728             }
19729             transmit_reinvite_with_t38_sdp(p);
19730          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
19731             if (option_debug > 2) {
19732                if (flag)
19733                   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));
19734                else
19735                   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));
19736             }
19737             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
19738          }
19739       }
19740       /* Reset lastrtprx timer */
19741       p->lastrtprx = p->lastrtptx = time(NULL);
19742       ast_mutex_unlock(&p->lock);
19743       return 0;
19744    } else if (pvt->t38.state != T38_DISABLED) { /* If we are handling sending 200 OK to the other side of the bridge */
19745       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
19746          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
19747          flag = 1;
19748       } else {
19749          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
19750       }
19751       if (option_debug > 2) {
19752          if (flag)
19753             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));
19754          else
19755             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));
19756       }
19757       pvt->t38.state = T38_ENABLED;
19758       p->t38.state = T38_ENABLED;
19759       if (option_debug > 1) {
19760          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
19761          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
19762       }
19763       transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
19764       p->lastrtprx = p->lastrtptx = time(NULL);
19765       ast_mutex_unlock(&p->lock);
19766       return 0;
19767    } else if (pvt->t38.state == T38_DISABLED) { /* The other side can not talk T.38 with us. We tell it to the the originating T.38 party with a 488 */
19768       p->t38.state = T38_DISABLED;
19769       if (option_debug > 1) {
19770          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
19771          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
19772       }
19773       transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
19774       p->lastrtprx = p->lastrtptx = time(NULL);
19775       ast_mutex_unlock(&p->lock);
19776       return 0;
19777    } else {
19778       ast_log(LOG_ERROR, "Something went wrong with T.38. State is:%d on channel %s and %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>", p->t38.state, chan ? chan->name : "<none>");
19779       ast_mutex_unlock(&p->lock);
19780       return 0;
19781    }
19782 }

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

References __sip_semi_ack(), ast_channel::_state, append_history, ast_cause2str(), ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), AST_SCHED_DEL, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, sip_pkt::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, find_sip_method(), FLAG_RESPONSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, sip_pvt::hangupcause, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, remove_provisional_keepalive_sched(), sched, sip_pkt::seqno, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::username, sip_pvt::vad, and XMIT_RELIABLE.

03833 {
03834    struct sip_pvt *p = ast->tech_pvt;
03835    int needcancel = FALSE;
03836    int needdestroy = 0;
03837    struct ast_channel *oldowner = ast;
03838 
03839    if (!p) {
03840       if (option_debug)
03841          ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n");
03842       return 0;
03843    }
03844 
03845    /* Store hangupcause locally in PVT so we still have it before disconnect */
03846    if (p->owner)
03847       p->hangupcause = p->owner->hangupcause;
03848 
03849    if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
03850       if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03851          if (option_debug && sipdebug)
03852             ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
03853          update_call_counter(p, DEC_CALL_LIMIT);
03854       }
03855       if (option_debug >3)
03856          ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
03857       if (p->autokillid > -1 && sip_cancel_destroy(p))
03858          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
03859       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03860       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
03861       ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY);
03862       p->owner->tech_pvt = NULL;
03863       p->owner = NULL;  /* Owner will be gone after we return, so take it away */
03864       ast_module_unref(ast_module_info->self);
03865       return 0;
03866    }
03867    if (option_debug) {
03868       if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug)
03869                ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid);
03870       else  {
03871          if (option_debug)
03872             ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
03873       }
03874    }
03875    if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 
03876       ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n");
03877 
03878    ast_mutex_lock(&p->lock);
03879    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
03880       if (option_debug && sipdebug)
03881          ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
03882       update_call_counter(p, DEC_CALL_LIMIT);
03883    }
03884 
03885    /* Determine how to disconnect */
03886    if (p->owner != ast) {
03887       ast_log(LOG_WARNING, "Huh?  We aren't the owner? Can't hangup call.\n");
03888       ast_mutex_unlock(&p->lock);
03889       return 0;
03890    }
03891    /* If the call is not UP, we need to send CANCEL instead of BYE */
03892    if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) {
03893       needcancel = TRUE;
03894       if (option_debug > 3)
03895          ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
03896    }
03897 
03898    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
03899 
03900    append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown");
03901 
03902    /* Disconnect */
03903    if (p->vad)
03904       ast_dsp_free(p->vad);
03905 
03906    p->owner = NULL;
03907    ast->tech_pvt = NULL;
03908 
03909    ast_module_unref(ast_module_info->self);
03910 
03911    /* Do not destroy this pvt until we have timeout or
03912       get an answer to the BYE or INVITE/CANCEL 
03913       If we get no answer during retransmit period, drop the call anyway.
03914       (Sorry, mother-in-law, you can't deny a hangup by sending
03915       603 declined to BYE...)
03916    */
03917    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE))
03918       needdestroy = 1;  /* Set destroy flag at end of this function */
03919    else if (p->invitestate != INV_CALLING)
03920       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03921 
03922    /* Start the process if it's not already started */
03923    if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
03924       if (needcancel) { /* Outgoing call, not up */
03925          if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
03926             /* stop retransmitting an INVITE that has not received a response */
03927             struct sip_pkt *cur;
03928 
03929             /* if we can't send right now, mark it pending */
03930             if (p->invitestate == INV_CALLING) {
03931                /* We can't send anything in CALLING state */
03932                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
03933                /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */
03934                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03935                append_history(p, "DELAY", "Not sending cancel, waiting for timeout");
03936             } else {
03937                for (cur = p->packets; cur; cur = cur->next) {
03938                   __sip_semi_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), cur->method ? cur->method : find_sip_method(cur->data));
03939                }
03940                p->invitestate = INV_CANCELLED;
03941                /* Send a new request: CANCEL */
03942                transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
03943                /* Actually don't destroy us yet, wait for the 487 on our original 
03944                   INVITE, but do set an autodestruct just in case we never get it. */
03945                needdestroy = 0;
03946                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03947             }
03948          } else { /* Incoming call, not up */
03949             const char *res;
03950             remove_provisional_keepalive_sched(p);
03951             if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause)))
03952                transmit_response_reliable(p, res, &p->initreq);
03953             else 
03954                transmit_response_reliable(p, "603 Declined", &p->initreq);
03955             p->invitestate = INV_TERMINATED;
03956          }
03957       } else { /* Call is in UP state, send BYE */
03958          if (!p->pendinginvite) {
03959             char *audioqos = "";
03960             char *videoqos = "";
03961             if (p->rtp)
03962                audioqos = ast_rtp_get_quality(p->rtp, NULL);
03963             if (p->vrtp)
03964                videoqos = ast_rtp_get_quality(p->vrtp, NULL);
03965             /* Send a hangup */
03966             if (oldowner->_state == AST_STATE_UP) {
03967                transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
03968             }
03969 
03970             /* Get RTCP quality before end of call */
03971             if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
03972                if (p->rtp)
03973                   append_history(p, "RTCPaudio", "Quality:%s", audioqos);
03974                if (p->vrtp)
03975                   append_history(p, "RTCPvideo", "Quality:%s", videoqos);
03976             }
03977             if (p->rtp && oldowner)
03978                pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos);
03979             if (p->vrtp && oldowner)
03980                pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos);
03981          } else {
03982             /* Note we will need a BYE when this all settles out
03983                but we can't send one while we have "INVITE" outstanding. */
03984             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
03985             ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
03986             AST_SCHED_DEL(sched, p->waitid);
03987             if (sip_cancel_destroy(p))
03988                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
03989          }
03990       }
03991    }
03992    if (needdestroy)
03993       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
03994    ast_mutex_unlock(&p->lock);
03995    return 0;
03996 }

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

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

04256 {
04257    struct sip_pvt *p = ast->tech_pvt;
04258    int res = 0;
04259 
04260    ast_mutex_lock(&p->lock);
04261    switch(condition) {
04262    case AST_CONTROL_RINGING:
04263       if (ast->_state == AST_STATE_RING) {
04264          p->invitestate = INV_EARLY_MEDIA;
04265          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
04266              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
04267             /* Send 180 ringing if out-of-band seems reasonable */
04268             transmit_provisional_response(p, "180 Ringing", &p->initreq, 0);
04269             ast_set_flag(&p->flags[0], SIP_RINGING);
04270             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
04271                break;
04272          } else {
04273             /* Well, if it's not reasonable, just send in-band */
04274          }
04275       }
04276       res = -1;
04277       break;
04278    case AST_CONTROL_BUSY:
04279       if (ast->_state != AST_STATE_UP) {
04280          transmit_response_reliable(p, "486 Busy Here", &p->initreq);
04281          p->invitestate = INV_COMPLETED;
04282          sip_alreadygone(p);
04283          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
04284          break;
04285       }
04286       res = -1;
04287       break;
04288    case AST_CONTROL_CONGESTION:
04289       if (ast->_state != AST_STATE_UP) {
04290          transmit_response_reliable(p, "503 Service Unavailable", &p->initreq);
04291          p->invitestate = INV_COMPLETED;
04292          sip_alreadygone(p);
04293          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
04294          break;
04295       }
04296       res = -1;
04297       break;
04298    case AST_CONTROL_PROCEEDING:
04299       if ((ast->_state != AST_STATE_UP) &&
04300           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
04301           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
04302          transmit_response(p, "100 Trying", &p->initreq);
04303          p->invitestate = INV_PROCEEDING;  
04304          break;
04305       }
04306       res = -1;
04307       break;
04308    case AST_CONTROL_PROGRESS:
04309       if ((ast->_state != AST_STATE_UP) &&
04310           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
04311           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
04312          p->invitestate = INV_EARLY_MEDIA;
04313          transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1);
04314          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
04315          break;
04316       }
04317       res = -1;
04318       break;
04319    case AST_CONTROL_HOLD:
04320       ast_rtp_new_source(p->rtp);
04321       ast_moh_start(ast, data, p->mohinterpret);
04322       break;
04323    case AST_CONTROL_UNHOLD:
04324       ast_rtp_new_source(p->rtp);
04325       ast_moh_stop(ast);
04326       break;
04327    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
04328       if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
04329          transmit_info_with_vidupdate(p);
04330          /* ast_rtcp_send_h261fur(p->vrtp); */
04331       } else
04332          res = -1;
04333       break;
04334    case AST_CONTROL_SRCUPDATE:
04335       ast_rtp_new_source(p->rtp);
04336       break;
04337    case AST_CONTROL_SRCCHANGE:
04338       ast_rtp_change_source(p->rtp);
04339       break;
04340    case -1:
04341       res = -1;
04342       break;
04343    default:
04344       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
04345       res = -1;
04346       break;
04347    }
04348    ast_mutex_unlock(&p->lock);
04349    return res;
04350 }

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

Display SIP nat mode.

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

01874 {
01875    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
01876 }

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

References accountcode, sip_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_copy_string(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), ast_exists_extension(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_verbose(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callid, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, sip_pvt::cid_name, sip_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, sip_pvt::context, sip_pvt::domain, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, sip_pvt::exten, f, ast_channel::fds, sip_pvt::flags, sip_pvt::from, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::language, sip_pvt::lock, LOG_DEBUG, ast_channel::name, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::peername, sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, sip_pvt::rdnis, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::uri, sip_pvt::useragent, sip_pvt::username, sip_pvt::vad, ast_variable::value, VERBOSE_PREFIX_3, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

04359 {
04360    struct ast_channel *tmp;
04361    struct ast_variable *v = NULL;
04362    int fmt;
04363    int what;
04364    int needvideo = 0, video = 0;
04365    char *decoded_exten;
04366  
04367    if (option_debug != 0) {
04368      ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null");
04369      ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from);
04370      ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username);
04371      ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername);
04372      ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain);
04373      ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser);
04374      ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname);
04375      ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact);
04376    }
04377 
04378    {
04379       char my_name[128];    /* pick a good name */
04380       const char *f, *fromdomain = NULL;
04381   
04382       if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':'))
04383          fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */
04384       else
04385          fromdomain = i->fromdomain;
04386   
04387       if (!ast_strlen_zero(i->username)) {
04388          if (!ast_strlen_zero(title) && strcmp(i->username, title)) {
04389             /* title not empty and different from username */
04390             snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title);
04391          } else {
04392             /* username not empty, title is empty or equal to username */
04393             snprintf(my_name, sizeof(my_name), "%s", i->username);
04394          }
04395       } else { /* username empty */ 
04396          if (!ast_strlen_zero(i->peername)) {
04397             /* call from unregisted peer */
04398             snprintf(my_name, sizeof(my_name), "%s", i->peername);
04399          } else { /* username and peername empty */
04400             if (!ast_strlen_zero(title)) { /* title not empty */
04401                snprintf(my_name, sizeof(my_name), "%s", title);
04402             } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */
04403                f = i->from;
04404                if (!strncmp(f, "sip:", 4))
04405                   f += 4;
04406                snprintf(my_name, sizeof(my_name), "%s", f);
04407             } else { /* fallback to fromdomain */
04408                snprintf(my_name, sizeof(my_name), "%s", fromdomain);
04409             }
04410          }
04411       }
04412       ast_mutex_unlock(&i->lock);
04413       /* Don't hold a sip pvt lock while we allocate a channel */
04414       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, ast_atomic_fetchadd_int((int *)&chan_idx, +1));
04415 
04416    }
04417    if (!tmp) {
04418       ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
04419       ast_mutex_lock(&i->lock);
04420       return NULL;
04421    }
04422    ast_mutex_lock(&i->lock);
04423 
04424    if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO)
04425       tmp->tech = &sip_tech_info;
04426    else
04427       tmp->tech = &sip_tech;
04428 
04429    /* Select our native format based on codec preference until we receive
04430       something from another device to the contrary. */
04431    if (i->jointcapability) {     /* The joint capabilities of us and peer */
04432       what = i->jointcapability;
04433       video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
04434    } else if (i->capability)  {  /* Our configured capability for this peer */
04435       what = i->capability;
04436       video = i->capability & AST_FORMAT_VIDEO_MASK;
04437    } else {
04438       what = global_capability;  /* Global codec support */
04439       video = global_capability & AST_FORMAT_VIDEO_MASK;
04440    }
04441 
04442    /* Set the native formats for audio  and merge in video */
04443    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video;
04444    if (option_debug > 2) {
04445       char buf[SIPBUFSIZE];
04446       ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats));
04447       ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability));
04448       ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability));
04449       ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1)));
04450       if (i->prefcodec)
04451          ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec));
04452    }
04453 
04454    /* XXX Why are we choosing a codec from the native formats?? */
04455    fmt = ast_best_codec(tmp->nativeformats);
04456 
04457    /* If we have a prefcodec setting, we have an inbound channel that set a 
04458       preferred format for this call. Otherwise, we check the jointcapability
04459       We also check for vrtp. If it's not there, we are not allowed do any video anyway.
04460     */
04461    if (i->vrtp) {
04462       if (i->prefcodec)
04463          needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;  /* Outbound call */
04464       else
04465          needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;  /* Inbound call */
04466    }
04467 
04468    if (option_debug > 2) {
04469       if (needvideo) 
04470          ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n");
04471       else
04472          ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n");
04473    }
04474 
04475 
04476 
04477    if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
04478       i->vad = ast_dsp_new();
04479       ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
04480       if (global_relaxdtmf)
04481          ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
04482    }
04483    if (i->rtp) {
04484       tmp->fds[0] = ast_rtp_fd(i->rtp);
04485       tmp->fds[1] = ast_rtcp_fd(i->rtp);
04486    }
04487    if (needvideo && i->vrtp) {
04488       tmp->fds[2] = ast_rtp_fd(i->vrtp);
04489       tmp->fds[3] = ast_rtcp_fd(i->vrtp);
04490    }
04491    if (i->udptl) {
04492       tmp->fds[5] = ast_udptl_fd(i->udptl);
04493    }
04494    if (state == AST_STATE_RING)
04495       tmp->rings = 1;
04496    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04497    tmp->writeformat = fmt;
04498    tmp->rawwriteformat = fmt;
04499    tmp->readformat = fmt;
04500    tmp->rawreadformat = fmt;
04501    tmp->tech_pvt = i;
04502 
04503    tmp->callgroup = i->callgroup;
04504    tmp->pickupgroup = i->pickupgroup;
04505    tmp->cid.cid_pres = i->callingpres;
04506    if (!ast_strlen_zero(i->accountcode))
04507       ast_string_field_set(tmp, accountcode, i->accountcode);
04508    if (i->amaflags)
04509       tmp->amaflags = i->amaflags;
04510    if (!ast_strlen_zero(i->language))
04511       ast_string_field_set(tmp, language, i->language);
04512    i->owner = tmp;
04513    ast_module_ref(ast_module_info->self);
04514    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04515    /*Since it is valid to have extensions in the dialplan that have unescaped characters in them
04516     * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt
04517     * structure so that there aren't issues when forming URI's
04518     */
04519    if (ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) {
04520       /* encoded in dialplan, so keep extension encoded */
04521       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
04522    } else {
04523       decoded_exten = ast_strdupa(i->exten);
04524       ast_uri_decode(decoded_exten);
04525       ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten));
04526    }
04527 
04528    /* Don't use ast_set_callerid() here because it will
04529     * generate an unnecessary NewCallerID event  */
04530    tmp->cid.cid_ani = ast_strdup(i->cid_num);
04531    if (!ast_strlen_zero(i->rdnis))
04532       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04533    
04534    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
04535       tmp->cid.cid_dnid = ast_strdup(i->exten);
04536 
04537    tmp->priority = 1;
04538    if (!ast_strlen_zero(i->uri))
04539       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
04540    if (!ast_strlen_zero(i->domain))
04541       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
04542    if (!ast_strlen_zero(i->useragent))
04543       pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
04544    if (!ast_strlen_zero(i->callid))
04545       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
04546    if (i->rtp)
04547       ast_jb_configure(tmp, &global_jbconf);
04548 
04549    /* Set channel variables for this call from configuration */
04550    for (v = i->chanvars ; v ; v = v->next)
04551       pbx_builtin_setvar_helper(tmp, v->name, v->value);
04552 
04553    if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
04554       ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04555       tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
04556       ast_hangup(tmp);
04557       tmp = NULL;
04558    }
04559 
04560    if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY))
04561       append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
04562 
04563    return tmp;
04564 }

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

Disable SIP Debugging in CLI.

Definition at line 12810 of file chan_sip.c.

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

12811 {
12812    if (argc != 4)
12813       return RESULT_SHOWUSAGE;
12814    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
12815    ast_cli(fd, "SIP Debugging Disabled\n");
12816    return RESULT_SUCCESS;
12817 }

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

Definition at line 12819 of file chan_sip.c.

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

12820 {
12821    if (argc != 3)
12822       return RESULT_SHOWUSAGE;
12823    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
12824    ast_cli(fd, "SIP Debugging Disabled\n");
12825    return RESULT_SUCCESS;
12826 }

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

Disable SIP History logging (CLI).

Definition at line 12840 of file chan_sip.c.

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

12841 {
12842    if (argc != 3) {
12843       return RESULT_SHOWUSAGE;
12844    }
12845    recordhistory = FALSE;
12846    ast_cli(fd, "SIP History Recording Disabled\n");
12847    return RESULT_SUCCESS;
12848 }

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

Cli command to send SIP notify to peer.

Definition at line 12747 of file chan_sip.c.

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

12748 {
12749    struct ast_variable *varlist;
12750    int i;
12751 
12752    if (argc < 4)
12753       return RESULT_SHOWUSAGE;
12754 
12755    if (!notify_types) {
12756       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
12757       return RESULT_FAILURE;
12758    }
12759 
12760    varlist = ast_variable_browse(notify_types, argv[2]);
12761 
12762    if (!varlist) {
12763       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
12764       return RESULT_FAILURE;
12765    }
12766 
12767    for (i = 3; i < argc; i++) {
12768       struct sip_pvt *p;
12769       struct sip_request req;
12770       struct ast_variable *var;
12771 
12772       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
12773          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
12774          return RESULT_FAILURE;
12775       }
12776 
12777       if (create_addr(p, argv[i], NULL)) {
12778          /* Maybe they're not registered, etc. */
12779          sip_destroy(p);
12780          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
12781          continue;
12782       }
12783 
12784       initreqprep(&req, p, SIP_NOTIFY);
12785 
12786       for (var = varlist; var; var = var->next) {
12787          if (!strcasecmp(var->name, "Content-Length")) {
12788             if (option_debug >= 2) {
12789                ast_log(LOG_DEBUG, "Ignoring pair %s=%s\n", var->name, var->value);
12790             }
12791             continue; /* ignore content-length, it is calculated automatically */
12792          }
12793          add_header(&req, var->name, ast_unescape_semicolon(var->value));
12794       }
12795 
12796       /* Recalculate our side, and recalculate Call ID */
12797       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
12798          p->ourip = __ourip;
12799       build_via(p);
12800       build_callid_pvt(p);
12801       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
12802       transmit_sip_request(p, &req);
12803       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12804    }
12805 
12806    return RESULT_SUCCESS;
12807 }

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

References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by handle_request_refer().

14644 {
14645    struct sip_dual *d;
14646    struct ast_channel *transferee, *transferer;
14647       /* Chan2m: The transferer, chan1m: The transferee */
14648    pthread_t th;
14649    pthread_attr_t attr;
14650 
14651    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
14652    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
14653    if ((!transferer) || (!transferee)) {
14654       if (transferee) {
14655          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
14656          ast_hangup(transferee);
14657       }
14658       if (transferer) {
14659          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
14660          ast_hangup(transferer);
14661       }
14662       return -1;
14663    }
14664 
14665    /* Make formats okay */
14666    transferee->readformat = chan1->readformat;
14667    transferee->writeformat = chan1->writeformat;
14668 
14669    /* Prepare for taking over the channel */
14670    ast_channel_masquerade(transferee, chan1);
14671 
14672    /* Setup the extensions and such */
14673    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
14674    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
14675    transferee->priority = chan1->priority;
14676       
14677    /* We make a clone of the peer channel too, so we can play
14678       back the announcement */
14679 
14680    /* Make formats okay */
14681    transferer->readformat = chan2->readformat;
14682    transferer->writeformat = chan2->writeformat;
14683 
14684    /* Prepare for taking over the channel.  Go ahead and grab this channel
14685     * lock here to avoid a deadlock with callbacks into the channel driver
14686     * that hold the channel lock and want the pvt lock.  */
14687    while (ast_channel_trylock(chan2)) {
14688       struct sip_pvt *pvt = chan2->tech_pvt;
14689       DEADLOCK_AVOIDANCE(&pvt->lock);
14690    }
14691    ast_channel_masquerade(transferer, chan2);
14692    ast_channel_unlock(chan2);
14693 
14694    /* Setup the extensions and such */
14695    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
14696    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
14697    transferer->priority = chan2->priority;
14698 
14699    ast_channel_lock(transferer);
14700    if (ast_do_masquerade(transferer)) {
14701       ast_log(LOG_WARNING, "Masquerade failed :(\n");
14702       ast_channel_unlock(transferer);
14703       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
14704       ast_hangup(transferer);
14705       return -1;
14706    }
14707    ast_channel_unlock(transferer);
14708    if (!transferer || !transferee) {
14709       if (!transferer) { 
14710          if (option_debug)
14711             ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
14712       }
14713       if (!transferee) {
14714          if (option_debug)
14715             ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
14716       }
14717       return -1;
14718    }
14719    if (!(d = ast_calloc(1, sizeof(*d)))) {
14720       return -1;
14721    }
14722 
14723    pthread_attr_init(&attr);
14724    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
14725 
14726    /* Save original request for followup */
14727    copy_request(&d->req, req);
14728    d->chan1 = transferee;  /* Transferee */
14729    d->chan2 = transferer;  /* Transferer */
14730    d->seqno = seqno;
14731    if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
14732       /* Could not start thread */
14733       ast_free(d);   /* We don't need it anymore. If thread is created, d will be free'd
14734                by sip_park_thread() */
14735       pthread_attr_destroy(&attr);
14736       return -1;
14737    }
14738    pthread_attr_destroy(&attr);
14739 
14740    return 0;
14741 }

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

References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, ast_channel::name, 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().

14576 {
14577    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
14578    struct sip_dual *d;
14579    struct sip_request req;
14580    int ext;
14581    int res;
14582 
14583    d = stuff;
14584    transferee = d->chan1;
14585    transferer = d->chan2;
14586    copy_request(&req, &d->req);
14587 
14588    if (!transferee || !transferer) {
14589       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
14590       ast_free(d);
14591       return NULL;
14592    }
14593    if (option_debug > 3) 
14594       ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
14595 
14596    ast_channel_lock(transferee);
14597    if (ast_do_masquerade(transferee)) {
14598       ast_log(LOG_WARNING, "Masquerade failed.\n");
14599       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
14600       ast_channel_unlock(transferee);
14601       ast_free(d);
14602       return NULL;
14603    } 
14604    ast_channel_unlock(transferee);
14605 
14606    res = ast_park_call(transferee, transferer, 0, &ext);
14607    
14608 
14609 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
14610    if (!res) {
14611       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
14612    } else {
14613       /* Then tell the transferer what happened */
14614       sprintf(buf, "Call parked on extension '%d'", ext);
14615       transmit_message_with_text(transferer->tech_pvt, buf);
14616    }
14617 #endif
14618 
14619    /* Any way back to the current call??? */
14620    /* Transmit response to the REFER request */
14621    if (!res)   {
14622       /* Transfer succeeded */
14623       append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
14624       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
14625       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
14626       ast_hangup(transferer); /* This will cause a BYE */
14627       if (option_debug)
14628          ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
14629    } else {
14630       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
14631       append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
14632       if (option_debug)
14633          ast_log(LOG_DEBUG, "SIP Call parked failed \n");
14634       /* Do not hangup call */
14635    }
14636    ast_free(d);
14637    return NULL;
14638 }

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

References ast_device_state_changed(), find_peer(), sip_peer::name, sip_peer::onHold, and sip_pvt::peername.

Referenced by change_hold_state(), and update_call_counter().

09583 {
09584    struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0);
09585 
09586    if (!peer)
09587       return;
09588 
09589    /* If they put someone on hold, increment the value... otherwise decrement it */
09590    if (hold)
09591       peer->onHold++;
09592    else
09593       peer->onHold--;
09594 
09595    /* Request device state update */
09596    ast_device_state_changed("SIP/%s", peer->name);
09597 
09598    return;
09599 }

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

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

Referenced by load_module().

20085 {
20086    int ms = 0;
20087    
20088    if (!speerobjs)   /* No peers, just give up */
20089       return;
20090 
20091    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
20092       ASTOBJ_WRLOCK(iterator);
20093       if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) {
20094          struct sip_peer *peer_ptr = iterator;
20095          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
20096       }
20097       ms += 100;
20098       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator));
20099       if (iterator->pokeexpire == -1) {
20100          struct sip_peer *peer_ptr = iterator;
20101          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
20102       }
20103       ASTOBJ_UNLOCK(iterator);
20104    } while (0)
20105    );
20106 }

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

React to lack of answer to Qualify poke.

Definition at line 17856 of file chan_sip.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_update_realtime(), ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, global_flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, sip_peer::pokeexpire, sched, sip_destroy(), sip_destroy_peer(), SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().

Referenced by sip_poke_peer().

17857 {
17858    struct sip_peer *peer = (struct sip_peer *)data;
17859 
17860    peer->pokeexpire = -1;
17861    if (peer->lastms > -1) {
17862       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
17863       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) {
17864          ast_update_realtime("sippeers", "name", peer->name, "lastms", "-1", NULL);
17865       }
17866       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
17867    }
17868    if (peer->call)
17869       sip_destroy(peer->call);
17870    peer->call = NULL;
17871 
17872    /* Don't send a devstate change if nothing changed. */
17873    if (peer->lastms > -1) {
17874       peer->lastms = -1;
17875       ast_device_state_changed("SIP/%s", peer->name);
17876    }
17877 
17878    /* This function gets called one place outside of the scheduler ... */
17879    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
17880       struct sip_peer *peer_ptr = peer;
17881       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17882    }
17883 
17884    /* There is no need to ASTOBJ_REF() here.  Just let the scheduled callback
17885     * inherit the reference that the current callback already has. */
17886    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
17887    if (peer->pokeexpire == -1) {
17888       ASTOBJ_UNREF(peer, sip_destroy_peer);
17889    }
17890 
17891    return 0;
17892 }

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

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

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

17898 {
17899    struct sip_pvt *p;
17900    int xmitres = 0;
17901 
17902    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
17903       /* IF we have no IP, or this isn't to be monitored, return
17904         imeediately after clearing things out */
17905       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
17906          struct sip_peer *peer_ptr = peer;
17907          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17908       }
17909       peer->lastms = 0;
17910       peer->call = NULL;
17911       return 0;
17912    }
17913    if (peer->call) {
17914       if (sipdebug)
17915          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
17916       sip_destroy(peer->call);
17917    }
17918    if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
17919       return -1;
17920    
17921    p->sa = peer->addr;
17922    p->recv = peer->addr;
17923    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
17924    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
17925 
17926    /* Send OPTIONs to peer's fullcontact */
17927    if (!ast_strlen_zero(peer->fullcontact))
17928       ast_string_field_set(p, fullcontact, peer->fullcontact);
17929 
17930    if (!ast_strlen_zero(peer->tohost))
17931       ast_string_field_set(p, tohost, peer->tohost);
17932    else
17933       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
17934 
17935    /* Recalculate our side, and recalculate Call ID */
17936    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
17937       p->ourip = __ourip;
17938    build_via(p);
17939    build_callid_pvt(p);
17940 
17941    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
17942       struct sip_peer *peer_ptr = peer;
17943       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17944    }
17945 
17946    p->relatedpeer = ASTOBJ_REF(peer);
17947    ast_set_flag(&p->flags[0], SIP_OUTGOING);
17948 #ifdef VOCAL_DATA_HACK
17949    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
17950    xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
17951 #else
17952    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
17953 #endif
17954    gettimeofday(&peer->ps, NULL);
17955    if (xmitres == XMIT_ERROR) {
17956       sip_poke_noanswer(ASTOBJ_REF(peer));   /* Immediately unreachable, network problems */
17957    } else {
17958       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
17959          struct sip_peer *peer_ptr = peer;
17960          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17961       }
17962       peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer));
17963       if (peer->pokeexpire == -1) {
17964          struct sip_peer *peer_ptr = peer;
17965          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17966       }
17967    }
17968 
17969    return 0;
17970 }

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

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

Definition at line 8880 of file chan_sip.c.

References ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, sip_peer::name, peerl, sip_peer::pokeexpire, sip_destroy_peer(), and sip_poke_peer().

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

08881 {
08882    struct sip_peer *peer = (struct sip_peer *) data;
08883    struct sip_peer *foundpeer;
08884 
08885    peer->pokeexpire = -1;
08886 
08887    foundpeer = ASTOBJ_CONTAINER_FIND(&peerl, peer->name);
08888    if (!foundpeer) {
08889       ASTOBJ_UNREF(peer, sip_destroy_peer);
08890       return 0;
08891    } else if (foundpeer->name != peer->name) {
08892       ASTOBJ_UNREF(foundpeer, sip_destroy_peer);
08893       ASTOBJ_UNREF(peer, sip_destroy_peer);
08894       return 0;
08895    }
08896 
08897    ASTOBJ_UNREF(foundpeer, sip_destroy_peer);
08898    sip_poke_peer(peer);
08899    ASTOBJ_UNREF(peer, sip_destroy_peer);
08900 
08901    return 0;
08902 }

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

Remove temporary realtime objects from memory (CLI).

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

11514 {
11515    struct sip_peer *peer;
11516    struct sip_user *user;
11517    int pruneuser = FALSE;
11518    int prunepeer = FALSE;
11519    int multi = FALSE;
11520    char *name = NULL;
11521    regex_t regexbuf;
11522    int havepattern = 0;
11523 
11524    switch (argc) {
11525    case 4:
11526       if (!strcasecmp(argv[3], "user"))
11527          return RESULT_SHOWUSAGE;
11528       if (!strcasecmp(argv[3], "peer"))
11529          return RESULT_SHOWUSAGE;
11530       if (!strcasecmp(argv[3], "like"))
11531          return RESULT_SHOWUSAGE;
11532       if (!strcasecmp(argv[3], "all")) {
11533          multi = TRUE;
11534          pruneuser = prunepeer = TRUE;
11535       } else {
11536          pruneuser = prunepeer = TRUE;
11537          name = argv[3];
11538       }
11539       break;
11540    case 5:
11541       if (!strcasecmp(argv[4], "like"))
11542          return RESULT_SHOWUSAGE;
11543       if (!strcasecmp(argv[3], "all"))
11544          return RESULT_SHOWUSAGE;
11545       if (!strcasecmp(argv[3], "like")) {
11546          multi = TRUE;
11547          name = argv[4];
11548          pruneuser = prunepeer = TRUE;
11549       } else if (!strcasecmp(argv[3], "user")) {
11550          pruneuser = TRUE;
11551          if (!strcasecmp(argv[4], "all"))
11552             multi = TRUE;
11553          else
11554             name = argv[4];
11555       } else if (!strcasecmp(argv[3], "peer")) {
11556          prunepeer = TRUE;
11557          if (!strcasecmp(argv[4], "all"))
11558             multi = TRUE;
11559          else
11560             name = argv[4];
11561       } else
11562          return RESULT_SHOWUSAGE;
11563       break;
11564    case 6:
11565       if (strcasecmp(argv[4], "like"))
11566          return RESULT_SHOWUSAGE;
11567       if (!strcasecmp(argv[3], "user")) {
11568          pruneuser = TRUE;
11569          name = argv[5];
11570       } else if (!strcasecmp(argv[3], "peer")) {
11571          prunepeer = TRUE;
11572          name = argv[5];
11573       } else
11574          return RESULT_SHOWUSAGE;
11575       break;
11576    default:
11577       return RESULT_SHOWUSAGE;
11578    }
11579 
11580    if (multi && name) {
11581       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB)) {
11582          return RESULT_SHOWUSAGE;
11583       }
11584       havepattern = 1;
11585    }
11586 
11587    if (multi) {
11588       if (prunepeer) {
11589          int pruned = 0;
11590 
11591          ASTOBJ_CONTAINER_WRLOCK(&peerl);
11592          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
11593             ASTOBJ_RDLOCK(iterator);
11594             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
11595                ASTOBJ_UNLOCK(iterator);
11596                continue;
11597             };
11598             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
11599                ASTOBJ_MARK(iterator);
11600                pruned++;
11601             }
11602             ASTOBJ_UNLOCK(iterator);
11603          } while (0) );
11604          if (pruned) {
11605             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
11606             ast_cli(fd, "%d peers pruned.\n", pruned);
11607          } else
11608             ast_cli(fd, "No peers found to prune.\n");
11609          ASTOBJ_CONTAINER_UNLOCK(&peerl);
11610       }
11611       if (pruneuser) {
11612          int pruned = 0;
11613 
11614          ASTOBJ_CONTAINER_WRLOCK(&userl);
11615          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
11616             ASTOBJ_RDLOCK(iterator);
11617             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
11618                ASTOBJ_UNLOCK(iterator);
11619                continue;
11620             };
11621             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
11622                ASTOBJ_MARK(iterator);
11623                pruned++;
11624             }
11625             ASTOBJ_UNLOCK(iterator);
11626          } while (0) );
11627          if (pruned) {
11628             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
11629             ast_cli(fd, "%d users pruned.\n", pruned);
11630          } else
11631             ast_cli(fd, "No users found to prune.\n");
11632          ASTOBJ_CONTAINER_UNLOCK(&userl);
11633       }
11634    } else {
11635       if (prunepeer) {
11636          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
11637             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
11638                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
11639                ASTOBJ_CONTAINER_LINK(&peerl, peer);
11640             } else
11641                ast_cli(fd, "Peer '%s' pruned.\n", name);
11642             ASTOBJ_UNREF(peer, sip_destroy_peer);
11643          } else
11644             ast_cli(fd, "Peer '%s' not found.\n", name);
11645       }
11646       if (pruneuser) {
11647          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
11648             if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
11649                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
11650                ASTOBJ_CONTAINER_LINK(&userl, user);
11651             } else
11652                ast_cli(fd, "User '%s' pruned.\n", name);
11653             ASTOBJ_UNREF(user, sip_destroy_user);
11654          } else
11655             ast_cli(fd, "User '%s' not found.\n", name);
11656       }
11657    }
11658 
11659    if (havepattern) {
11660       regfree(&regexbuf);
11661    }
11662 
11663    return RESULT_SUCCESS;
11664 }

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

Read SIP RTP from channel.

Definition at line 4790 of file chan_sip.c.

References ast_channel::_state, ast_bridged_channel(), AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_set_flag, AST_STATE_UP, ast_test_flag, FALSE, sip_pvt::flags, ast_frame::frametype, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtprx, sip_pvt::lock, LOG_DEBUG, ast_channel::name, 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().

04791 {
04792    struct ast_frame *fr;
04793    struct sip_pvt *p = ast->tech_pvt;
04794    int faxdetected = FALSE;
04795 
04796    ast_mutex_lock(&p->lock);
04797    fr = sip_rtp_read(ast, p, &faxdetected);
04798    p->lastrtprx = time(NULL);
04799 
04800    /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
04801    /* 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 */
04802    if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
04803       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
04804          if (!p->pendinginvite) {
04805             if (option_debug > 2)
04806                ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
04807             p->t38.state = T38_LOCAL_REINVITE;
04808             transmit_reinvite_with_t38_sdp(p);
04809             if (option_debug > 1)
04810                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name);
04811          }
04812       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04813          if (option_debug > 2)
04814             ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
04815          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
04816       }
04817    }
04818 
04819    /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
04820    if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
04821       fr = &ast_null_frame;
04822    }
04823 
04824    ast_mutex_unlock(&p->lock);
04825    return fr;
04826 }

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

The real destination address for a write.

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

01868 {
01869    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
01870 }

static int sip_refer_allocate ( struct sip_pvt p  )  [static]

Allocate SIP refer structure.

Definition at line 8685 of file chan_sip.c.

References ast_calloc, and sip_pvt::refer.

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

08686 {
08687    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
08688    return p->refer ? 1 : 0;
08689 }

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

Registration timeout, register again.

Definition at line 8423 of file chan_sip.c.

References __sip_pretend_ack(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_registry::hostname, sip_pvt::lock, LOG_NOTICE, manager_event(), sip_registry::needdns, 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, transmit_register(), TRUE, and sip_registry::username.

Referenced by transmit_register().

08424 {
08425 
08426    /* if we are here, our registration timed out, so we'll just do it over */
08427    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
08428    struct sip_pvt *p;
08429    int res;
08430 
08431    /* if we couldn't get a reference to the registry object, punt */
08432    if (!r)
08433       return 0;
08434 
08435    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
08436    if (r->call) {
08437       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
08438          in the single SIP manager thread. */
08439       p = r->call;
08440       ast_mutex_lock(&p->lock);
08441       if (p->registry)
08442          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
08443       r->call = NULL;
08444       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
08445       /* Pretend to ACK anything just in case */
08446       __sip_pretend_ack(p);
08447       ast_mutex_unlock(&p->lock);
08448    }
08449    /* If we have a limit, stop registration and give up */
08450    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
08451       /* Ok, enough is enough. Don't try any more */
08452       /* We could add an external notification here... 
08453          steal it from app_voicemail :-) */
08454       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
08455       r->regstate = REG_STATE_FAILED;
08456    } else {
08457       r->regstate = REG_STATE_UNREGISTERED;
08458       r->timeout = -1;
08459       r->needdns = TRUE;
08460       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
08461    }
08462    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));
08463    ASTOBJ_UNREF(r, sip_registry_destroy);
08464    return 0;
08465 }

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

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

Definition at line 5308 of file chan_sip.c.

References ast_calloc, ast_copy_string(), ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::authuser, sip_registry::contact, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, regl, secret, sip_registry_destroy(), TRUE, and username.

05309 {
05310    struct sip_registry *reg;
05311    int portnum = 0;
05312    char username[256] = "";
05313    char *hostname=NULL, *secret=NULL, *authuser=NULL;
05314    char *porta=NULL;
05315    char *contact=NULL;
05316 
05317    if (!value)
05318       return -1;
05319    ast_copy_string(username, value, sizeof(username));
05320    /* First split around the last '@' then parse the two components. */
05321    hostname = strrchr(username, '@'); /* allow @ in the first part */
05322    if (hostname)
05323       *hostname++ = '\0';
05324    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
05325       ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
05326       return -1;
05327    }
05328    /* split user[:secret[:authuser]] */
05329    secret = strchr(username, ':');
05330    if (secret) {
05331       *secret++ = '\0';
05332       authuser = strchr(secret, ':');
05333       if (authuser)
05334          *authuser++ = '\0';
05335    }
05336    /* split host[:port][/contact] */
05337    contact = strchr(hostname, '/');
05338    if (contact)
05339       *contact++ = '\0';
05340    if (ast_strlen_zero(contact))
05341       contact = "s";
05342    porta = strchr(hostname, ':');
05343    if (porta) {
05344       *porta++ = '\0';
05345       portnum = atoi(porta);
05346       if (portnum == 0) {
05347          ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05348          return -1;
05349       }
05350    }
05351    if (!(reg = ast_calloc(1, sizeof(*reg)))) {
05352       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
05353       return -1;
05354    }
05355 
05356    if (ast_string_field_init(reg, 256)) {
05357       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
05358       free(reg);
05359       return -1;
05360    }
05361 
05362    regobjs++;
05363    ASTOBJ_INIT(reg);
05364    ast_string_field_set(reg, contact, contact);
05365    if (!ast_strlen_zero(username))
05366       ast_string_field_set(reg, username, username);
05367    if (hostname)
05368       ast_string_field_set(reg, hostname, hostname);
05369    if (authuser)
05370       ast_string_field_set(reg, authuser, authuser);
05371    if (secret)
05372       ast_string_field_set(reg, secret, secret);
05373    reg->expire = -1;
05374    reg->timeout =  -1;
05375    reg->refresh = default_expiry;
05376    reg->portno = portnum;
05377    reg->callid_valid = FALSE;
05378    reg->ocseq = INITIAL_CSEQ;
05379    reg->needdns = TRUE;
05380    ASTOBJ_CONTAINER_LINK(&regl, reg);  /* Add the new registry entry to the list */
05381    ASTOBJ_UNREF(reg,sip_registry_destroy);
05382    return 0;
05383 }

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

References ast_log(), AST_SCHED_DEL, ast_string_field_free_memory, sip_registry::call, sip_registry::expire, free, sip_registry::hostname, LOG_DEBUG, option_debug, sip_pvt::registry, sched, sip_destroy(), sip_registry::timeout, and sip_registry::username.

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

03370 {
03371    /* Really delete */
03372    if (option_debug > 2)
03373       ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
03374 
03375    if (reg->call) {
03376       /* Clear registry before destroying to ensure
03377          we don't get reentered trying to grab the registry lock */
03378       reg->call->registry = NULL;
03379       if (option_debug > 2)
03380          ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
03381       sip_destroy(reg->call);
03382    }
03383    AST_SCHED_DEL(sched, reg->expire);
03384    AST_SCHED_DEL(sched, reg->timeout);
03385    ast_string_field_free_memory(reg);
03386    regobjs--;
03387    free(reg);
03388    
03389 }

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

Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.

Definition at line 13494 of file chan_sip.c.

References ast_channel_trylock, ast_channel_unlock, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, check_pendings(), sip_pvt::flags, sip_pvt::lock, sip_pvt::owner, SIP_NEEDREINVITE, and sip_pvt::waitid.

Referenced by handle_response_invite().

13495 {
13496    struct sip_pvt *p = (struct sip_pvt *) data;
13497    struct ast_channel *owner;
13498 
13499    ast_mutex_lock(&p->lock); /* called from schedule thread which requires a lock */
13500    while ((owner = p->owner) && ast_channel_trylock(owner)) {
13501       ast_mutex_unlock(&p->lock);
13502       usleep(1);
13503       ast_mutex_lock(&p->lock);
13504    }
13505    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
13506    p->waitid = -1;
13507    check_pendings(p);
13508    ast_mutex_unlock(&p->lock);
13509    if (owner) {
13510       ast_channel_unlock(owner);
13511    }
13512 
13513    return 0;
13514 }

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

Force reload of module from cli.

Definition at line 20164 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, restart_monitor(), sip_reload_lock, and TRUE.

Referenced by reload().

20165 {
20166    ast_mutex_lock(&sip_reload_lock);
20167    if (sip_reloading) 
20168       ast_verbose("Previous SIP reload not yet done\n");
20169    else {
20170       sip_reloading = TRUE;
20171       if (fd)
20172          sip_reloadreason = CHANNEL_CLI_RELOAD;
20173       else
20174          sip_reloadreason = CHANNEL_MODULE_RELOAD;
20175    }
20176    ast_mutex_unlock(&sip_reload_lock);
20177    restart_monitor();
20178 
20179    return 0;
20180 }

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

References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_string(), 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, sip_pvt::peername, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.

18083 {
18084    int oldformat;
18085    struct sip_pvt *p;
18086    struct ast_channel *tmpc = NULL;
18087    char *ext, *host;
18088    char tmp[256];
18089    char *dest = data;
18090 
18091    oldformat = format;
18092    if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
18093       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));
18094       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
18095       return NULL;
18096    }
18097    if (option_debug)
18098       ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
18099 
18100    if (ast_strlen_zero(dest)) {
18101       ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
18102       *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
18103       return NULL;
18104    }
18105 
18106    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
18107       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
18108       *cause = AST_CAUSE_SWITCH_CONGESTION;
18109       return NULL;
18110    }
18111 
18112    ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
18113 
18114    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
18115       sip_destroy(p);
18116       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
18117       *cause = AST_CAUSE_SWITCH_CONGESTION;
18118       return NULL;
18119    }
18120 
18121    ast_copy_string(tmp, dest, sizeof(tmp));
18122    host = strchr(tmp, '@');
18123    if (host) {
18124       *host++ = '\0';
18125       ext = tmp;
18126    } else {
18127       ext = strchr(tmp, '/');
18128       if (ext) 
18129          *ext++ = '\0';
18130       host = tmp;
18131    }
18132 
18133    if (create_addr(p, host, NULL)) {
18134       *cause = AST_CAUSE_UNREGISTERED;
18135       if (option_debug > 2)
18136          ast_log(LOG_DEBUG, "Cant create SIP call - target device not registered\n");
18137       sip_destroy(p);
18138       return NULL;
18139    }
18140    if (ast_strlen_zero(p->peername) && ext)
18141       ast_string_field_set(p, peername, ext);
18142    /* Recalculate our side, and recalculate Call ID */
18143    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
18144       p->ourip = __ourip;
18145    build_via(p);
18146    build_callid_pvt(p);
18147    
18148    /* We have an extension to call, don't use the full contact here */
18149    /* This to enable dialing registered peers with extension dialling,
18150       like SIP/peername/extension   
18151       SIP/peername will still use the full contact */
18152    if (ext) {
18153       ast_string_field_set(p, username, ext);
18154       ast_string_field_free(p, fullcontact);
18155    }
18156 #if 0
18157    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
18158 #endif
18159    p->prefcodec = oldformat;           /* Format for this call */
18160    ast_mutex_lock(&p->lock);
18161    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
18162    ast_mutex_unlock(&p->lock);
18163    if (!tmpc)
18164       sip_destroy(p);
18165    ast_update_use_count();
18166    restart_monitor();
18167    return tmpc;
18168 }

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

Update registration with SIP Proxy.

Definition at line 8391 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, sip_registry::hostname, LOG_NOTICE, SIP_NO_HISTORY, sip_registry_destroy(), sipdebug, and sip_registry::username.

Referenced by handle_response_register(), and sip_send_all_registers().

08392 {
08393    /* if we are here, we know that we need to reregister. */
08394    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
08395 
08396    /* if we couldn't get a reference to the registry object, punt */
08397    if (!r)
08398       return 0;
08399 
08400    if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY))
08401       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
08402    /* Since registry's are only added/removed by the the monitor thread, this
08403       may be overkill to reference/dereference at all here */
08404    if (sipdebug)
08405       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
08406 
08407    r->expire = -1;
08408    __sip_do_register(r);
08409    ASTOBJ_UNREF(r, sip_registry_destroy);
08410    return 0;
08411 }

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

References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, 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::name, 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().

04719 {
04720    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
04721    struct ast_frame *f;
04722    
04723    if (!p->rtp) {
04724       /* We have no RTP allocated for this channel */
04725       return &ast_null_frame;
04726    }
04727 
04728    switch(ast->fdno) {
04729    case 0:
04730       f = ast_rtp_read(p->rtp);  /* RTP Audio */
04731       break;
04732    case 1:
04733       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
04734       break;
04735    case 2:
04736       f = ast_rtp_read(p->vrtp); /* RTP Video */
04737       break;
04738    case 3:
04739       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
04740       break;
04741    case 5:
04742       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
04743       break;
04744    default:
04745       f = &ast_null_frame;
04746    }
04747    /* Don't forward RFC2833 if we're not supposed to */
04748    if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) &&
04749        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) {
04750       ast_log(LOG_DEBUG,"Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass);
04751       return &ast_null_frame;
04752    }
04753 
04754       /* We already hold the channel lock */
04755    if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
04756       return f;
04757 
04758    if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
04759       if (!(f->subclass & p->jointcapability)) {
04760          if (option_debug) {
04761             ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n",
04762                ast_getformatname(f->subclass), p->owner->name);
04763          }
04764          return &ast_null_frame;
04765       }
04766       if (option_debug)
04767          ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
04768       p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
04769       ast_set_read_format(p->owner, p->owner->readformat);
04770       ast_set_write_format(p->owner, p->owner->writeformat);
04771    }
04772 
04773    if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
04774       f = ast_dsp_process(p->owner, p->vad, f);
04775       if (f && f->frametype == AST_FRAME_DTMF) {
04776          if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') {
04777             if (option_debug)
04778                ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
04779             *faxdetect = 1;
04780          } else if (option_debug) {
04781             ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
04782          }
04783       }
04784    }
04785    
04786    return f;
04787 }

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

Schedule destruction of SIP dialog.

Definition at line 2260 of file chan_sip.c.

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

Referenced by __sip_autodestruct(), auto_congest(), 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(), notify_extenstate_update(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), sip_sipredirect(), and transmit_fake_auth_response().

02261 {
02262    if (ms < 0) {
02263       if (p->timer_t1 == 0)
02264          p->timer_t1 = 500;   /* Set timer T1 if not set (RFC 3261) */
02265       ms = p->timer_t1 * 64;
02266    }
02267    if (sip_debug_test_pvt(p))
02268       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
02269    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
02270       append_history(p, "SchedDestroy", "%d ms", ms);
02271 
02272    AST_SCHED_DEL(sched, p->autokillid);
02273    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
02274 }

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

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

20110 {
20111    int ms;
20112    int regspacing;
20113    if (!regobjs)
20114       return;
20115    regspacing = default_expiry * 1000/regobjs;
20116    if (regspacing > 100)
20117       regspacing = 100;
20118    ms = regspacing;
20119    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
20120       ASTOBJ_WRLOCK(iterator);
20121       AST_SCHED_DEL(sched, iterator->expire);
20122       ms += regspacing;
20123       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
20124       ASTOBJ_UNLOCK(iterator);
20125    } while (0)
20126    );
20127 }

static int sip_send_mwi_to_peer ( struct sip_peer peer,
int  force 
) [static]

Send message waiting indication to alert peer that they've got voicemail.

Definition at line 17566 of file chan_sip.c.

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

Referenced by do_monitor(), and handle_request_subscribe().

17567 {
17568    /* Called with peerl lock, but releases it */
17569    struct sip_pvt *p;
17570    int newmsgs, oldmsgs;
17571 
17572    /* Do we have an IP address? If not, skip this peer */
17573    if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
17574       return 0;
17575 
17576    /* Check for messages */
17577    ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
17578    
17579    peer->lastmsgcheck = time(NULL);
17580    
17581    /* Return now if it's the same thing we told them last time */
17582    if (!force && ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
17583       return 0;
17584    }
17585    
17586    
17587    peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
17588 
17589    if (peer->mwipvt) {
17590       /* Base message on subscription */
17591       p = peer->mwipvt;
17592    } else {
17593       /* Build temporary dialog for this message */
17594       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 
17595          return -1;
17596       if (create_addr_from_peer(p, peer)) {
17597          /* Maybe they're not registered, etc. */
17598          sip_destroy(p);
17599          return 0;
17600       }
17601       /* Recalculate our side, and recalculate Call ID */
17602       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
17603          p->ourip = __ourip;
17604       build_via(p);
17605       build_callid_pvt(p);
17606       /* Destroy this session after 32 secs */
17607       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17608    }
17609    /* Send MWI */
17610    ast_set_flag(&p->flags[0], SIP_OUTGOING);
17611    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
17612    return 0;
17613 }

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

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

04187 {
04188    struct sip_pvt *p = ast->tech_pvt;
04189    int res = 0;
04190 
04191    ast_mutex_lock(&p->lock);
04192    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
04193    case SIP_DTMF_INBAND:
04194       res = -1; /* Tell Asterisk to generate inband indications */
04195       break;
04196    case SIP_DTMF_RFC2833:
04197       if (p->rtp)
04198          ast_rtp_senddigit_begin(p->rtp, digit);
04199       break;
04200    default:
04201       break;
04202    }
04203    ast_mutex_unlock(&p->lock);
04204 
04205    return res;
04206 }

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

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

04211 {
04212    struct sip_pvt *p = ast->tech_pvt;
04213    int res = 0;
04214 
04215    ast_mutex_lock(&p->lock);
04216    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
04217    case SIP_DTMF_INFO:
04218       transmit_info_with_digit(p, digit, duration);
04219       break;
04220    case SIP_DTMF_RFC2833:
04221       if (p->rtp)
04222          ast_rtp_senddigit_end_with_duration(p->rtp, digit, duration);
04223       break;
04224    case SIP_DTMF_INBAND:
04225       res = -1; /* Tell Asterisk to stop inband indications */
04226       break;
04227    }
04228    ast_mutex_unlock(&p->lock);
04229 
04230    return res;
04231 }

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

References ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().

02654 {
02655    struct sip_pvt *p = ast->tech_pvt;
02656    int debug = sip_debug_test_pvt(p);
02657 
02658    if (debug)
02659       ast_verbose("Sending text %s on %s\n", text, ast->name);
02660    if (!p)
02661       return -1;
02662    /* NOT ast_strlen_zero, because a zero-length message is specifically
02663     * allowed by RFC 3428 (See section 10, Examples) */
02664    if (!text)
02665       return 0;
02666    if (debug)
02667       ast_verbose("Really sending text %s on %s\n", text, ast->name);
02668    transmit_message_with_text(p, text);
02669    return 0;   
02670 }

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

References ast_channel::_state, append_history, ast_bridged_channel(), 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::callid, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.

Referenced by sip_fixup().

19840 {
19841    struct sip_pvt *p;
19842    int changed = 0;
19843 
19844    p = chan->tech_pvt;
19845    if (!p) 
19846       return -1;
19847 
19848    /* Disable early RTP bridge  */
19849    if (!ast_bridged_channel(chan) && !global_directrtpsetup)   /* We are in early state */
19850       return 0;
19851 
19852    ast_mutex_lock(&p->lock);
19853    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
19854       /* If we're destroyed, don't bother */
19855       ast_mutex_unlock(&p->lock);
19856       return 0;
19857    }
19858 
19859    /* if this peer cannot handle reinvites of the media stream to devices
19860       that are known to be behind a NAT, then stop the process now
19861    */
19862    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
19863       ast_mutex_unlock(&p->lock);
19864       return 0;
19865    }
19866 
19867    if (rtp) {
19868       changed |= ast_rtp_get_peer(rtp, &p->redirip);
19869    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
19870       memset(&p->redirip, 0, sizeof(p->redirip));
19871       changed = 1;
19872    }
19873    if (vrtp) {
19874       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
19875    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
19876       memset(&p->vredirip, 0, sizeof(p->vredirip));
19877       changed = 1;
19878    }
19879    if (codecs) {
19880       if (p->redircodecs != codecs && (p->jointcapability & codecs) != p->jointcapability) {
19881          p->redircodecs = codecs;
19882          p->jointcapability &= codecs;
19883          p->capability &= codecs;
19884          changed = 1;
19885       }
19886    }
19887    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
19888       if (chan->_state != AST_STATE_UP) { /* We are in early state */
19889          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
19890             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
19891          if (option_debug)
19892             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));
19893       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
19894          if (option_debug > 2) {
19895             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));
19896          }
19897          transmit_reinvite_with_sdp(p);
19898       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
19899          if (option_debug > 2) {
19900             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));
19901          }
19902          /* We have a pending Invite. Send re-invite when we're done with the invite */
19903          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
19904       }
19905    }
19906    /* Reset lastrtprx timer */
19907    p->lastrtprx = p->lastrtptx = time(NULL);
19908    ast_mutex_unlock(&p->lock);
19909    return 0;
19910 }

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

Definition at line 19653 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::callid, 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.

19654 {
19655    struct sip_pvt *p;
19656    
19657    p = chan->tech_pvt;
19658    if (!p)
19659       return -1;
19660    ast_mutex_lock(&p->lock);
19661    if (udptl)
19662       ast_udptl_get_peer(udptl, &p->udptlredirip);
19663    else
19664       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
19665    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
19666       if (!p->pendinginvite) {
19667          if (option_debug > 2) {
19668             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);
19669          }
19670          transmit_reinvite_with_t38_sdp(p);
19671       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
19672          if (option_debug > 2) {
19673             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);
19674          }
19675          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
19676       }
19677    }
19678    /* Reset lastrtprx timer */
19679    p->lastrtprx = p->lastrtptx = time(NULL);
19680    ast_mutex_unlock(&p->lock);
19681    return 0;
19682 }

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

Show details of one active dialog.

Definition at line 12402 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::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_pvt::flags, sip_route::hop, iflist, iflock, sip_pvt::jointcapability, sip_pvt::lastmsg, len(), sip_pvt::maxcallbitrate, ast_channel::name, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, SIPBUFSIZE, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, transfermode2str(), sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username.

12403 {
12404    struct sip_pvt *cur;
12405    size_t len;
12406    int found = 0;
12407 
12408    if (argc != 4)
12409       return RESULT_SHOWUSAGE;
12410    len = strlen(argv[3]);
12411    ast_mutex_lock(&iflock);
12412    for (cur = iflist; cur; cur = cur->next) {
12413       if (!strncasecmp(cur->callid, argv[3], len)) {
12414          char formatbuf[SIPBUFSIZE/2];
12415          ast_cli(fd,"\n");
12416          if (cur->subscribed != NONE)
12417             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
12418          else
12419             ast_cli(fd, "  * SIP Call\n");
12420          ast_cli(fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
12421          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
12422          ast_cli(fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
12423          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
12424          ast_cli(fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
12425          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
12426          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
12427          ast_cli(fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
12428          ast_cli(fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
12429          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
12430          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
12431          ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
12432          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
12433          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)" );
12434          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
12435          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
12436          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
12437          if (!ast_strlen_zero(cur->username))
12438             ast_cli(fd, "  Username:               %s\n", cur->username);
12439          if (!ast_strlen_zero(cur->peername))
12440             ast_cli(fd, "  Peername:               %s\n", cur->peername);
12441          if (!ast_strlen_zero(cur->uri))
12442             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
12443          if (!ast_strlen_zero(cur->cid_num))
12444             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
12445          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
12446          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
12447          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
12448          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
12449          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
12450          ast_cli(fd, "  SIP Options:            ");
12451          if (cur->sipoptions) {
12452             int x;
12453             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
12454                if (cur->sipoptions & sip_options[x].id)
12455                   ast_cli(fd, "%s ", sip_options[x].text);
12456             }
12457          } else
12458             ast_cli(fd, "(none)\n");
12459          ast_cli(fd, "\n\n");
12460          found++;
12461       }
12462    }
12463    ast_mutex_unlock(&iflock);
12464    if (!found) 
12465       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
12466    return RESULT_SUCCESS;
12467 }

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

Show active SIP channels.

Definition at line 12188 of file chan_sip.c.

References __sip_show_channels().

12189 {
12190         return __sip_show_channels(fd, argc, argv, 0);
12191 }

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

CLI command to list local domains.

Definition at line 11698 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::list, domain::mode, RESULT_SUCCESS, and S_OR.

11699 {
11700    struct domain *d;
11701 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
11702 
11703    if (AST_LIST_EMPTY(&domain_list)) {
11704       ast_cli(fd, "SIP Domain support not enabled.\n\n");
11705       return RESULT_SUCCESS;
11706    } else {
11707       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
11708       AST_LIST_LOCK(&domain_list);
11709       AST_LIST_TRAVERSE(&domain_list, d, list)
11710          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
11711             domain_mode_to_text(d->mode));
11712       AST_LIST_UNLOCK(&domain_list);
11713       ast_cli(fd, "\n");
11714       return RESULT_SUCCESS;
11715    }
11716 }

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

Show history details of one dialog.

Definition at line 12470 of file chan_sip.c.

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

12471 {
12472    struct sip_pvt *cur;
12473    size_t len;
12474    int found = 0;
12475 
12476    if (argc != 4)
12477       return RESULT_SHOWUSAGE;
12478    if (!recordhistory)
12479       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
12480    len = strlen(argv[3]);
12481    ast_mutex_lock(&iflock);
12482    for (cur = iflist; cur; cur = cur->next) {
12483       if (!strncasecmp(cur->callid, argv[3], len)) {
12484          struct sip_history *hist;
12485          int x = 0;
12486 
12487          ast_cli(fd,"\n");
12488          if (cur->subscribed != NONE)
12489             ast_cli(fd, "  * Subscription\n");
12490          else
12491             ast_cli(fd, "  * SIP Call\n");
12492          if (cur->history)
12493             AST_LIST_TRAVERSE(cur->history, hist, list)
12494                ast_cli(fd, "%d. %s\n", ++x, hist->event);
12495          if (x == 0)
12496             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
12497          found++;
12498       }
12499    }
12500    ast_mutex_unlock(&iflock);
12501    if (!found) 
12502       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
12503    return RESULT_SUCCESS;
12504 }

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

References ast_cli(), ast_copy_string(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, TRUE, and userl.

11117 {
11118 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
11119 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
11120    char ilimits[40];
11121    char iused[40];
11122    int showall = FALSE;
11123 
11124    if (argc < 3) 
11125       return RESULT_SHOWUSAGE;
11126 
11127    if (argc == 4 && !strcmp(argv[3],"all")) 
11128          showall = TRUE;
11129    
11130    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
11131    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
11132       ASTOBJ_RDLOCK(iterator);
11133       if (iterator->call_limit)
11134          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
11135       else 
11136          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
11137       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
11138       if (showall || iterator->call_limit)
11139          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
11140       ASTOBJ_UNLOCK(iterator);
11141    } while (0) );
11142 
11143    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
11144 
11145    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
11146       ASTOBJ_RDLOCK(iterator);
11147       if (iterator->call_limit)
11148          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
11149       else 
11150          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
11151       snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
11152       if (showall || iterator->call_limit)
11153          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
11154       ASTOBJ_UNLOCK(iterator);
11155    } while (0) );
11156 
11157    return RESULT_SUCCESS;
11158 #undef FORMAT
11159 #undef FORMAT2
11160 }

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

List all allocated SIP Objects (realtime or static).

Definition at line 11437 of file chan_sip.c.

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

11438 {
11439    char tmp[256];
11440    if (argc != 3)
11441       return RESULT_SHOWUSAGE;
11442    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
11443    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
11444    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
11445    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
11446    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
11447    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
11448    return RESULT_SUCCESS;
11449 }

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

Show one peer in detail.

Definition at line 11750 of file chan_sip.c.

References _sip_show_peer().

11751 {
11752    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
11753 }

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

CLI Show Peers command.

Definition at line 11293 of file chan_sip.c.

References _sip_show_peers().

11294 {
11295    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
11296 }

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

Show SIP Registry (registrations with other SIP proxies.

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

12025 {
12026 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s %-25.25s\n"
12027 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s %-25.25s\n"
12028    char host[80];
12029    char tmpdat[256];
12030    struct tm tm;
12031 
12032 
12033    if (argc != 3)
12034       return RESULT_SHOWUSAGE;
12035    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
12036    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
12037       ASTOBJ_RDLOCK(iterator);
12038       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
12039       if (iterator->regtime) {
12040          ast_localtime(&iterator->regtime, &tm, NULL);
12041          strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
12042       } else {
12043          tmpdat[0] = 0;
12044       }
12045       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
12046       ASTOBJ_UNLOCK(iterator);
12047    } while(0));
12048    return RESULT_SUCCESS;
12049 #undef FORMAT
12050 #undef FORMAT2
12051 }

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

List global settings for the SIP channel.

Definition at line 12054 of file chan_sip.c.

References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FORWARD_LOOP_DETECTED, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, SIPBUFSIZE, and transfermode2str().

12055 {
12056    int realtimepeers;
12057    int realtimeusers;
12058    char codec_buf[SIPBUFSIZE];
12059 
12060    realtimepeers = ast_check_realtime("sippeers");
12061    realtimeusers = ast_check_realtime("sipusers");
12062 
12063    if (argc != 3)
12064       return RESULT_SHOWUSAGE;
12065    ast_cli(fd, "\n\nGlobal Settings:\n");
12066    ast_cli(fd, "----------------\n");
12067    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
12068    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
12069    ast_cli(fd, "  Videosupport:           %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
12070    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
12071    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
12072    ast_cli(fd, "  Allow subscriptions:    %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
12073    ast_cli(fd, "  Allow overlap dialing:  %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
12074    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
12075    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
12076    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
12077    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
12078    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
12079    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
12080    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
12081    ast_cli(fd, "  Call limit peers only:  %s\n", global_limitonpeers ? "Yes" : "No");
12082    ast_cli(fd, "  Direct RTP setup:       %s\n", global_directrtpsetup ? "Yes" : "No");
12083    ast_cli(fd, "  User Agent:             %s\n", global_useragent);
12084    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
12085    ast_cli(fd, "  Reg. context:           %s\n", S_OR(global_regcontext, "(not set)"));
12086    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
12087    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
12088    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
12089    ast_cli(fd, "  Call Events:            %s\n", global_callevents ? "On" : "Off");
12090    ast_cli(fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
12091    ast_cli(fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
12092    ast_cli(fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
12093    ast_cli(fd, "  T38 fax pt UDPTL:       %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No");
12094 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
12095    ast_cli(fd, "  T38 fax pt RTP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No");
12096    ast_cli(fd, "  T38 fax pt TCP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No");
12097 #endif
12098    ast_cli(fd, "  RFC2833 Compensation:   %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No");
12099    if (!realtimepeers && !realtimeusers)
12100       ast_cli(fd, "  SIP realtime:           Disabled\n" );
12101    else
12102       ast_cli(fd, "  SIP realtime:           Enabled\n" );
12103 
12104    ast_cli(fd, "\nGlobal Signalling Settings:\n");
12105    ast_cli(fd, "---------------------------\n");
12106    ast_cli(fd, "  Codecs:                 ");
12107    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
12108    ast_cli(fd, "%s\n", codec_buf);
12109    ast_cli(fd, "  Codec Order:            ");
12110    print_codec_to_cli(fd, &default_prefs);
12111    ast_cli(fd, "\n");
12112    ast_cli(fd, "  T1 minimum:             %d\n", global_t1min);
12113    ast_cli(fd, "  No premature media:     %s\n", global_prematuremediafilter ? "Yes" : "No");
12114    ast_cli(fd, "  Relax DTMF:             %s\n", global_relaxdtmf ? "Yes" : "No");
12115    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
12116    ast_cli(fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
12117    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
12118    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
12119    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
12120    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
12121    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
12122    ast_cli(fd, "  Reg. min duration       %d secs\n", min_expiry);
12123    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
12124    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
12125    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
12126    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
12127    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
12128    ast_cli(fd, "  Notify hold state:      %s\n", global_notifyhold ? "Yes" : "No");
12129    ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
12130    ast_cli(fd, "  Max Call Bitrate:       %d kbps\r\n", default_maxcallbitrate);
12131    ast_cli(fd, "  Auto-Framing:           %s \r\n", global_autoframing ? "Yes" : "No");
12132    ast_cli(fd, "\nDefault Settings:\n");
12133    ast_cli(fd, "-----------------\n");
12134    ast_cli(fd, "  Context:                %s\n", default_context);
12135    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
12136    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
12137    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
12138    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
12139    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" );
12140    ast_cli(fd, "  Language:               %s\n", S_OR(default_language, "(Defaults to English)"));
12141    ast_cli(fd, "  MOH Interpret:          %s\n", default_mohinterpret);
12142    ast_cli(fd, "  MOH Suggest:            %s\n", default_mohsuggest);
12143    ast_cli(fd, "  Voice Mail Extension:   %s\n", default_vmexten);
12144    ast_cli(fd, "  Forward Detected Loops: %s\n", (ast_test_flag(&global_flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED) ? "Yes" : "No"));
12145    
12146    if (realtimepeers || realtimeusers) {
12147       ast_cli(fd, "\nRealtime SIP Settings:\n");
12148       ast_cli(fd, "----------------------\n");
12149       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
12150       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
12151       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
12152       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
12153       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
12154       ast_cli(fd, "  Save sys. name:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No");
12155       ast_cli(fd, "  Auto Clear:             %d (%s)", global_rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled");
12156    }
12157    ast_cli(fd, "\n----\n");
12158    return RESULT_SUCCESS;
12159 }

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

Show active SIP subscriptions.

Definition at line 12194 of file chan_sip.c.

References __sip_show_channels().

12195 {
12196         return __sip_show_channels(fd, argc, argv, 1);
12197 }

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

Show one user in detail.

Definition at line 11969 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, sip_user::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.

11970 {
11971    char cbuf[256];
11972    struct sip_user *user;
11973    struct ast_variable *v;
11974    int load_realtime;
11975 
11976    if (argc < 4)
11977       return RESULT_SHOWUSAGE;
11978 
11979    /* Load from realtime storage? */
11980    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
11981 
11982    user = find_user(argv[3], load_realtime);
11983    if (user) {
11984       ast_cli(fd,"\n\n");
11985       ast_cli(fd, "  * Name       : %s\n", user->name);
11986       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
11987       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
11988       ast_cli(fd, "  Context      : %s\n", user->context);
11989       ast_cli(fd, "  Language     : %s\n", user->language);
11990       if (!ast_strlen_zero(user->accountcode))
11991          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
11992       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
11993       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
11994       ast_cli(fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
11995       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
11996       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
11997       ast_cli(fd, "  Callgroup    : ");
11998       print_group(fd, user->callgroup, 0);
11999       ast_cli(fd, "  Pickupgroup  : ");
12000       print_group(fd, user->pickupgroup, 0);
12001       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
12002       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
12003       ast_cli(fd, "  Codec Order  : (");
12004       print_codec_to_cli(fd, &user->prefs);
12005       ast_cli(fd, ")\n");
12006 
12007       ast_cli(fd, "  Auto-Framing:  %s \n", user->autoframing ? "Yes" : "No");
12008       if (user->chanvars) {
12009          ast_cli(fd, "  Variables    :\n");
12010          for (v = user->chanvars ; v ; v = v->next)
12011             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
12012       }
12013       ast_cli(fd,"\n");
12014       ASTOBJ_UNREF(user,sip_destroy_user);
12015    } else {
12016       ast_cli(fd,"User %s not found.\n", argv[3]);
12017       ast_cli(fd,"\n");
12018    }
12019 
12020    return RESULT_SUCCESS;
12021 }

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

CLI Command 'SIP Show Users'.

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

11217 {
11218    regex_t regexbuf;
11219    int havepattern = FALSE;
11220 
11221 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
11222 
11223    switch (argc) {
11224    case 5:
11225       if (!strcasecmp(argv[3], "like")) {
11226          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
11227             return RESULT_SHOWUSAGE;
11228          havepattern = TRUE;
11229       } else
11230          return RESULT_SHOWUSAGE;
11231    case 3:
11232       break;
11233    default:
11234       return RESULT_SHOWUSAGE;
11235    }
11236 
11237    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
11238    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
11239       ASTOBJ_RDLOCK(iterator);
11240 
11241       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
11242          ASTOBJ_UNLOCK(iterator);
11243          continue;
11244       }
11245 
11246       ast_cli(fd, FORMAT, iterator->name, 
11247          iterator->secret, 
11248          iterator->accountcode,
11249          iterator->context,
11250          iterator->ha ? "Yes" : "No",
11251          nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
11252       ASTOBJ_UNLOCK(iterator);
11253    } while (0)
11254    );
11255 
11256    if (havepattern)
11257       regfree(&regexbuf);
11258 
11259    return RESULT_SUCCESS;
11260 #undef FORMAT
11261 }

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

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

Referenced by sip_transfer().

20024 {
20025    char *cdest;
20026    char *extension, *host, *port;
20027    char tmp[80];
20028    
20029    cdest = ast_strdupa(dest);
20030    
20031    extension = strsep(&cdest, "@");
20032    host = strsep(&cdest, ":");
20033    port = strsep(&cdest, ":");
20034    if (ast_strlen_zero(extension)) {
20035       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
20036       return 0;
20037    }
20038 
20039    /* we'll issue the redirect message here */
20040    if (!host) {
20041       char *localtmp;
20042       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
20043       if (ast_strlen_zero(tmp)) {
20044          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
20045          return 0;
20046       }
20047       if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
20048          char lhost[80], lport[80];
20049          memset(lhost, 0, sizeof(lhost));
20050          memset(lport, 0, sizeof(lport));
20051          localtmp++;
20052          /* This is okey because lhost and lport are as big as tmp */
20053          sscanf(localtmp, "%80[^<>:; ]:%80[^<>:; ]", lhost, lport);
20054          if (ast_strlen_zero(lhost)) {
20055             ast_log(LOG_ERROR, "Can't find the host address\n");
20056             return 0;
20057          }
20058          host = ast_strdupa(lhost);
20059          if (!ast_strlen_zero(lport)) {
20060             port = ast_strdupa(lport);
20061          }
20062       }
20063    }
20064 
20065    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
20066    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
20067 
20068    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
20069    sip_alreadygone(p);
20070    return 0;
20071 }

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

Transfer SIP call.

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

04235 {
04236    struct sip_pvt *p = ast->tech_pvt;
04237    int res;
04238 
04239    if (dest == NULL) /* functions below do not take a NULL */
04240       dest = "";
04241    ast_mutex_lock(&p->lock);
04242    if (ast->_state == AST_STATE_RING)
04243       res = sip_sipredirect(p, dest);
04244    else
04245       res = transmit_refer(p, dest);
04246    ast_mutex_unlock(&p->lock);
04247    return res;
04248 }

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

Definition at line 15353 of file chan_sip.c.

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

Referenced by handle_request_invite().

15354 {
15355    char *uri1 = ast_strdupa(input1);
15356    char *uri2 = ast_strdupa(input2);
15357    char *host1;
15358    char *host2;
15359    char *params1;
15360    char *params2;
15361    char *headers1;
15362    char *headers2;
15363 
15364    /* Strip off "sip:" from the URI. We know this is present
15365     * because it was checked back in parse_request()
15366     */
15367    strsep(&uri1, ":");
15368    strsep(&uri2, ":");
15369 
15370    if ((host1 = strchr(uri1, '@'))) {
15371       *host1++ = '\0';
15372    }
15373    if ((host2 = strchr(uri2, '@'))) {
15374       *host2++ = '\0';
15375    }
15376 
15377    /* Check for mismatched username and passwords. This is the
15378     * only case-sensitive comparison of a SIP URI
15379     */
15380    if ((host1 && !host2) ||
15381          (host2 && !host1) ||
15382          (host1 && host2 && strcmp(uri1, uri2))) {
15383       return 1;
15384    }
15385 
15386    if (!host1)
15387       host1 = uri1;
15388    if (!host2)
15389       host2 = uri2;
15390 
15391    /* Strip off the parameters and headers so we can compare
15392     * host and port
15393     */
15394 
15395    if ((params1 = strchr(host1, ';'))) {
15396       *params1++ = '\0';
15397    }
15398    if ((params2 = strchr(host2, ';'))) {
15399       *params2++ = '\0';
15400    }
15401 
15402    /* Headers come after parameters, but there may be headers without
15403     * parameters, thus the S_OR
15404     */
15405    if ((headers1 = strchr(S_OR(params1, host1), '?'))) {
15406       *headers1++ = '\0';
15407    }
15408    if ((headers2 = strchr(S_OR(params2, host2), '?'))) {
15409       *headers2++ = '\0';
15410    }
15411 
15412    /* Now the host/port are properly isolated. We can get by with a string comparison
15413     * because the SIP URI checking rules have some interesting exceptions that make
15414     * this possible. I will note 2 in particular
15415     * 1. hostnames which resolve to the same IP address as well as a hostname and its
15416     *    IP address are not considered a match with SIP URI's.
15417     * 2. If one URI specifies a port and the other does not, then the URIs do not match.
15418     *    This includes if one URI explicitly contains port 5060 and the other implies it
15419     *    by not having a port specified.
15420     */
15421 
15422    if (strcasecmp(host1, host2)) {
15423       return 1;
15424    }
15425 
15426    /* Headers have easier rules to follow, so do those first */
15427    if (sip_uri_headers_cmp(headers1, headers2)) {
15428       return 1;
15429    }
15430 
15431    /* And now the parameters. Ugh */
15432    return sip_uri_params_cmp(params1, params2);
15433 }

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

helper routine for sip_uri_cmp

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

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

Definition at line 15307 of file chan_sip.c.

References ast_strdupa, and ast_strlen_zero().

Referenced by sip_uri_cmp().

15308 {
15309    char *headers1 = NULL;
15310    char *headers2 = NULL;
15311    int zerolength1 = 0;
15312    int zerolength2 = 0;
15313    int different = 0;
15314    char *header1;
15315 
15316    if (ast_strlen_zero(input1)) {
15317       zerolength1 = 1;
15318    } else {
15319       headers1 = ast_strdupa(input1);
15320    }
15321    
15322    if (ast_strlen_zero(input2)) {
15323       zerolength2 = 1;
15324    } else {
15325       headers2 = ast_strdupa(input2);
15326    }
15327 
15328    if ((zerolength1 && !zerolength2) ||
15329          (zerolength2 && !zerolength1))
15330       return 1;
15331 
15332    if (zerolength1 && zerolength2)
15333       return 0;
15334 
15335    /* At this point, we can definitively state that both inputs are
15336     * not zero-length. First, one more optimization. If the length
15337     * of the headers is not equal, then we definitely have no match
15338     */
15339    if (strlen(headers1) != strlen(headers2)) {
15340       return 1;
15341    }
15342 
15343    for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) {
15344       if (!strcasestr(headers2, header1)) {
15345          different = 1;
15346          break;
15347       }
15348    }
15349 
15350    return different;
15351 }

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

helper routine for sip_uri_cmp to compare URI parameters

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

Parameters:
input1 Parameters from URI 1
input2 Parameters from URI 2
Return values:
0 URIs' parameters match
nonzero URIs' parameters do not match

Definition at line 15182 of file chan_sip.c.

References ast_strdupa, and ast_strlen_zero().

Referenced by sip_uri_cmp().

15183 {
15184    char *params1 = NULL;
15185    char *params2 = NULL;
15186    char *pos1;
15187    char *pos2;
15188    int zerolength1 = 0;
15189    int zerolength2 = 0;
15190    int maddrmatch = 0;
15191    int ttlmatch = 0;
15192    int usermatch = 0;
15193    int methodmatch = 0;
15194 
15195    if (ast_strlen_zero(input1)) {
15196       zerolength1 = 1;
15197    } else {
15198       params1 = ast_strdupa(input1);
15199    }
15200    if (ast_strlen_zero(input2)) {
15201       zerolength2 = 1;
15202    } else {
15203       params2 = ast_strdupa(input2);
15204    }
15205 
15206    /* Quick optimization. If both params are zero-length, then
15207     * they match
15208     */
15209    if (zerolength1 && zerolength2) {
15210       return 0;
15211    }
15212 
15213    for (pos1 = strsep(&params1, ";"); pos1; pos1 = strsep(&params1, ";")) {
15214       char *value1 = pos1;
15215       char *name1 = strsep(&value1, "=");
15216       char *params2dup = NULL;
15217       int matched = 0;
15218       if (!value1) {
15219          value1 = "";
15220       }
15221       /* Checkpoint reached. We have the name and value parsed for param1
15222        * We have to duplicate params2 each time through this loop
15223        * or else the inner loop below will not work properly.
15224        */
15225       if (!zerolength2) {
15226          params2dup = ast_strdupa(params2);
15227       }
15228       for (pos2 = strsep(&params2dup, ";"); pos2; pos2 = strsep(&params2dup, ";")) {
15229          char *name2 = pos2;
15230          char *value2 = strchr(pos2, '=');
15231          if (!value2) {
15232             value2 = "";
15233          } else {
15234             *value2++ = '\0';
15235          }
15236          if (!strcasecmp(name1, name2)) {
15237             if (strcasecmp(value1, value2)) {
15238                goto fail;
15239             } else {
15240                matched = 1;
15241                break;
15242             }
15243          }
15244       }
15245       /* Check to see if the parameter is one of the 'must-match' parameters */
15246       if (!strcasecmp(name1, "maddr")) {
15247          if (matched) {
15248             maddrmatch = 1;
15249          } else {
15250             goto fail;
15251          }
15252       } else if (!strcasecmp(name1, "ttl")) {
15253          if (matched) {
15254             ttlmatch = 1;
15255          } else {
15256             goto fail;
15257          }
15258       } else if (!strcasecmp(name1, "user")) {
15259          if (matched) {
15260             usermatch = 1;
15261          } else {
15262             goto fail;
15263          }
15264       } else if (!strcasecmp(name1, "method")) {
15265          if (matched) {
15266             methodmatch = 1;
15267          } else {
15268             goto fail;
15269          }
15270       }
15271    }
15272 
15273    /* We've made it out of that horrible O(m*n) construct and there are no
15274     * failures yet. We're not done yet, though, because params2 could have
15275     * an maddr, ttl, user, or method header and params1 did not.
15276     */
15277    for (pos2 = strsep(&params2, ";"); pos2; pos2 = strsep(&params2, ";")) {
15278       char *value2 = pos2;
15279       char *name2 = strsep(&value2, "=");
15280       if (!value2) {
15281          value2 = "";
15282       }
15283       if ((!strcasecmp(name2, "maddr") && !maddrmatch) ||
15284             (!strcasecmp(name2, "ttl") && !ttlmatch) ||
15285             (!strcasecmp(name2, "user") && !usermatch) ||
15286             (!strcasecmp(name2, "method") && !methodmatch)) {
15287          goto fail;
15288       }
15289    }
15290    return 0;
15291 
15292 fail:
15293    return 1;
15294 }

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

Send frame to media channel (rtp).

Definition at line 4045 of file chan_sip.c.

References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), t38properties::direct, sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtptx, sip_pvt::lock, ast_channel::nativeformats, sip_pvt::pendinginvite, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PAGE2_T38SUPPORT, SIP_PROGRESS_SENT, t38properties::state, ast_frame::subclass, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, ast_channel::tech_pvt, transmit_provisional_response(), transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, sip_pvt::vrtp, and ast_channel::writeformat.

04046 {
04047    struct sip_pvt *p = ast->tech_pvt;
04048    int res = 0;
04049 
04050    switch (frame->frametype) {
04051    case AST_FRAME_VOICE:
04052       if (!(frame->subclass & ast->nativeformats)) {
04053          char s1[512], s2[512], s3[512];
04054          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n",
04055             frame->subclass, 
04056             ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK),
04057             ast->nativeformats & AST_FORMAT_AUDIO_MASK,
04058             ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat),
04059             ast->readformat,
04060             ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat),
04061             ast->writeformat);
04062          return 0;
04063       }
04064       if (p) {
04065          ast_mutex_lock(&p->lock);
04066          if (p->t38.state == T38_ENABLED && !p->t38.direct) {
04067             /* drop frame, can't sent VOICE frames while in T.38 mode */
04068             ast_mutex_unlock(&p->lock);
04069             break;
04070          } else if (p->rtp) {
04071             /* If channel is not up, activate early media session */
04072             if ((ast->_state != AST_STATE_UP) &&
04073                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
04074                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
04075                ast_rtp_new_source(p->rtp);
04076                if (!global_prematuremediafilter) {
04077                   p->invitestate = INV_EARLY_MEDIA;
04078                   transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1);
04079                   ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
04080                }
04081             }
04082             p->lastrtptx = time(NULL);
04083             res = ast_rtp_write(p->rtp, frame);
04084          }
04085          ast_mutex_unlock(&p->lock);
04086       }
04087       break;
04088    case AST_FRAME_VIDEO:
04089       if (p) {
04090          ast_mutex_lock(&p->lock);
04091          if (p->vrtp) {
04092             /* Activate video early media */
04093             if ((ast->_state != AST_STATE_UP) &&
04094                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
04095                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
04096                p->invitestate = INV_EARLY_MEDIA;
04097                transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1);
04098                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);  
04099             }
04100             p->lastrtptx = time(NULL);
04101             res = ast_rtp_write(p->vrtp, frame);
04102          }
04103          ast_mutex_unlock(&p->lock);
04104       }
04105       break;
04106    case AST_FRAME_IMAGE:
04107       return 0;
04108       break;
04109    case AST_FRAME_MODEM:
04110       if (p) {
04111          ast_mutex_lock(&p->lock);
04112          /* UDPTL requires two-way communication, so early media is not needed here.
04113             we simply forget the frames if we get modem frames before the bridge is up.
04114             Fax will re-transmit.
04115          */
04116          if (ast->_state == AST_STATE_UP) {
04117             if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->t38.state == T38_DISABLED) {
04118                if (!p->pendinginvite) {
04119                   p->t38.state = T38_LOCAL_REINVITE;
04120                   transmit_reinvite_with_t38_sdp(p);
04121                }
04122             } else if (p->t38.state == T38_ENABLED) {
04123                res = ast_udptl_write(p->udptl, frame);
04124             }
04125          }
04126          ast_mutex_unlock(&p->lock);
04127       }
04128       break;
04129    default: 
04130       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
04131       return 0;
04132    }
04133 
04134    return res;
04135 }

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

References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len(), sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, lws2sws(), netlock, option_debug, sip_pvt::owner, parse_request(), process_request_queue(), queue_request(), sip_pvt::recv, S_OR, sched, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().

Referenced by do_monitor().

17447 {
17448    struct sip_request req;
17449    struct sockaddr_in sin = { 0, };
17450    struct sip_pvt *p;
17451    int res;
17452    socklen_t len = sizeof(sin);
17453    int nounlock = 0;
17454    int recount = 0;
17455    int lockretry;
17456 
17457    memset(&req, 0, sizeof(req));
17458    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
17459    if (res < 0) {
17460 #if !defined(__FreeBSD__)
17461       if (errno == EAGAIN)
17462          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
17463       else 
17464 #endif
17465       if (errno != ECONNREFUSED)
17466          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
17467       return 1;
17468    }
17469    if (option_debug && res == sizeof(req.data) - 1)
17470       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
17471 
17472    req.data[res] = '\0';
17473    req.len = res;
17474    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
17475       ast_set_flag(&req, SIP_PKT_DEBUG);
17476    if (pedanticsipchecking)
17477       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
17478    if (ast_test_flag(&req, SIP_PKT_DEBUG))
17479       ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data);
17480 
17481    if(parse_request(&req) == -1) /* Bad packet, can't parse */
17482       return 1;
17483 
17484    req.method = find_sip_method(req.rlPart1);
17485 
17486    if (ast_test_flag(&req, SIP_PKT_DEBUG))
17487       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
17488 
17489    if (req.headers < 2) /* Must have at least two headers */
17490       return 1;
17491 
17492    /* Process request, with netlock held, and with usual deadlock avoidance */
17493    for (lockretry = 10; lockretry > 0; lockretry--) {
17494       ast_mutex_lock(&netlock);
17495 
17496       /* Find the active SIP dialog or create a new one */
17497       p = find_call(&req, &sin, req.method); /* returns p locked */
17498       if (p == NULL) {
17499          if (option_debug)
17500             ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
17501          ast_mutex_unlock(&netlock);
17502          return 1;
17503       }
17504       /* Go ahead and lock the owner if it has one -- we may need it */
17505       /* because this is deadlock-prone, we need to try and unlock if failed */
17506       if (!p->owner || !ast_channel_trylock(p->owner))
17507          break;   /* locking succeeded */
17508       if (lockretry != 1) {
17509          ast_mutex_unlock(&p->lock);
17510          ast_mutex_unlock(&netlock);
17511          /* Sleep for a very short amount of time */
17512          usleep(1);
17513       }
17514    }
17515    p->recv = sin;
17516 
17517    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
17518       append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
17519 
17520    if (!lockretry) {
17521       if (!queue_request(p, &req)) {
17522          /* the request has been queued for later handling */
17523          ast_mutex_unlock(&p->lock);
17524          ast_mutex_unlock(&netlock);
17525          return 1;
17526       }
17527 
17528       /* This is unsafe, since p->owner is not locked. */
17529       if (p->owner)
17530          ast_log(LOG_ERROR, "Channel lock for %s could not be obtained, and request was unable to be queued.\n", S_OR(p->owner->name, "- no channel name ??? - "));
17531       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
17532       if (req.method != SIP_ACK)
17533          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
17534       /* XXX We could add retry-after to make sure they come back */
17535       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
17536       ast_mutex_unlock(&p->lock);
17537       ast_mutex_unlock(&netlock);
17538       return 1;
17539    }
17540 
17541    /* if there are queued requests on this sip_pvt, process them first, so that everything is
17542       handled in order
17543    */
17544    if (!AST_LIST_EMPTY(&p->request_queue)) {
17545       AST_SCHED_DEL(sched, p->request_queue_sched_id);
17546       process_request_queue(p, &recount, &nounlock);
17547    }
17548 
17549    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
17550       /* Request failed */
17551       if (option_debug)
17552          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
17553    }
17554       
17555    if (p->owner && !nounlock)
17556       ast_channel_unlock(p->owner);
17557    ast_mutex_unlock(&p->lock);
17558    ast_mutex_unlock(&netlock);
17559    if (recount)
17560       ast_update_use_count();
17561 
17562    return 1;
17563 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

Definition at line 14101 of file chan_sip.c.

References ast_rtp_stop(), ast_udptl_stop(), sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.

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

14102 {
14103    /* Immediately stop RTP, VRTP and UDPTL as applicable */
14104    if (p->rtp)
14105       ast_rtp_stop(p->rtp);
14106    if (p->vrtp)
14107       ast_rtp_stop(p->vrtp);
14108    if (p->udptl)
14109       ast_udptl_stop(p->udptl);
14110 }

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

Show subscription type in string format.

Definition at line 12162 of file chan_sip.c.

References subscription_types, and type.

Referenced by sip_show_channel().

12163 {
12164    int i;
12165 
12166    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
12167       if (subscription_types[i].type == subtype) {
12168          return subscription_types[i].text;
12169       }
12170    }
12171    return subscription_types[0].text;
12172 }

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

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

07214 {
07215    int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
07216    
07217    if (maxrate & T38FAX_RATE_14400) {
07218       if (option_debug > 1)
07219          ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n");
07220       return 14400;
07221    } else if (maxrate & T38FAX_RATE_12000) {
07222       if (option_debug > 1)
07223          ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n");
07224       return 12000;
07225    } else if (maxrate & T38FAX_RATE_9600) {
07226       if (option_debug > 1)
07227          ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n");
07228       return 9600;
07229    } else if (maxrate & T38FAX_RATE_7200) {
07230       if (option_debug > 1)
07231          ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n");
07232       return 7200;
07233    } else if (maxrate & T38FAX_RATE_4800) {
07234       if (option_debug > 1)
07235          ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n");
07236       return 4800;
07237    } else if (maxrate & T38FAX_RATE_2400) {
07238       if (option_debug > 1)
07239          ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n");
07240       return 2400;
07241    } else {
07242       if (option_debug > 1)
07243          ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n");
07244       return 0;
07245    }
07246 }

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

Create temporary peer (used in autocreatepeer mode).

Definition at line 18653 of file chan_sip.c.

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

Referenced by register_verify().

18654 {
18655    struct sip_peer *peer;
18656 
18657    if (!(peer = ast_calloc(1, sizeof(*peer))))
18658       return NULL;
18659 
18660    apeerobjs++;
18661    ASTOBJ_INIT(peer);
18662    set_peer_defaults(peer);
18663 
18664    ast_copy_string(peer->name, name, sizeof(peer->name));
18665 
18666    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
18667    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
18668    peer->prefs = default_prefs;
18669    reg_source_db(peer);
18670 
18671    return peer;
18672 }

static void temp_pvt_cleanup ( void *   )  [static]

Definition at line 6982 of file chan_sip.c.

References ast_string_field_free_memory, and free.

06983 {
06984    struct sip_pvt *p = data;
06985 
06986    ast_string_field_free_memory(p);
06987 
06988    free(data);
06989 }

static void temp_pvt_init ( void   )  [static]

A per-thread temporary pvt structure.

Definition at line 1263 of file chan_sip.c.

01272 {

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

Convert transfer mode to text string.

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

11164 {
11165    if (mode == TRANSFER_OPENFORALL)
11166       return "open";
11167    else if (mode == TRANSFER_CLOSED)
11168       return "closed";
11169    return "strict";
11170 }

static void transmit_fake_auth_response ( struct sip_pvt p,
int  sipmethod,
struct sip_request req,
enum xmittype  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 9803 of file chan_sip.c.

References ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, keys, sip_pvt::randdata, s, set_nonce_randdata(), SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, ast_dynamic_str::str, transmit_response(), and transmit_response_with_auth().

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

09804 {
09805    /* We have to emulate EXACTLY what we'd get with a good peer
09806     * and a bad password, or else we leak information. */
09807    const char *response = "407 Proxy Authentication Required";
09808    const char *reqheader = "Proxy-Authorization";
09809    const char *respheader = "Proxy-Authenticate";
09810    const char *authtoken;
09811    struct ast_dynamic_str *buf;
09812    char *c;
09813 
09814    /* table of recognised keywords, and their value in the digest */
09815    enum keys { K_NONCE, K_LAST };
09816    struct x {
09817       const char *key;
09818       const char *s;
09819    } *i, keys[] = {
09820       [K_NONCE] = { "nonce=", "" },
09821       [K_LAST] = { NULL, NULL}
09822    };
09823 
09824    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
09825       response = "401 Unauthorized";
09826       reqheader = "Authorization";
09827       respheader = "WWW-Authenticate";
09828    }
09829    authtoken = get_header(req, reqheader);
09830    if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
09831       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
09832        * information */
09833       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
09834       /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
09835       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09836       return;
09837    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
09838       /* We have no auth, so issue challenge and request authentication */
09839       set_nonce_randdata(p, 1);
09840       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
09841       /* Schedule auto destroy in 32 seconds */
09842       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09843       return;
09844    }
09845 
09846    if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
09847       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
09848       return;
09849    }
09850 
09851    /* Make a copy of the response and parse it */
09852    if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
09853       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
09854       return;
09855    }
09856 
09857    c = buf->str;
09858 
09859    while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
09860       for (i = keys; i->key != NULL; i++) {
09861          const char *separator = ",";  /* default */
09862 
09863          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
09864             continue;
09865          }
09866          /* Found. Skip keyword, take text in quotes or up to the separator. */
09867          c += strlen(i->key);
09868          if (*c == '"') { /* in quotes. Skip first and look for last */
09869             c++;
09870             separator = "\"";
09871          }
09872          i->s = c;
09873          strsep(&c, separator);
09874          break;
09875       }
09876       if (i->key == NULL) { /* not found, jump after space or comma */
09877          strsep(&c, " ,");
09878       }
09879    }
09880 
09881    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
09882    if (strcasecmp(p->randdata, keys[K_NONCE].s)) {
09883       if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
09884          set_nonce_randdata(p, 1);
09885       }
09886       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
09887 
09888       /* Schedule auto destroy in 32 seconds */
09889       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09890    } else {
09891       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
09892    }
09893 }

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

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

Referenced by sip_senddigit_end().

08767 {
08768    struct sip_request req;
08769 
08770    reqprep(&req, p, SIP_INFO, 0, 1);
08771    add_digit(&req, digit, duration);
08772    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
08773 }

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 8776 of file chan_sip.c.

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

Referenced by sip_indicate().

08777 {
08778    struct sip_request req;
08779 
08780    reqprep(&req, p, SIP_INFO, 0, 1);
08781    add_vidupdate(&req);
08782    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
08783 }

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

References add_header(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), 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(), ast_var_t::entries, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::invite_branch, sip_pvt::lastinvite, LOG_DEBUG, sip_request::method, ast_channel::name, sip_pvt::ocseq, sip_pvt::offered_media, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.

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

08006 {
08007    struct sip_request req;
08008    
08009    req.method = sipmethod;
08010    if (init) {    /* Seems like init always is 2 */
08011       /* Bump branch even on initial requests */
08012       p->branch ^= ast_random();
08013       p->invite_branch = p->branch;
08014       build_via(p);
08015       if (init > 1)
08016          initreqprep(&req, p, sipmethod);
08017       else
08018          reqprep(&req, p, sipmethod, 0, 0);  
08019    } else
08020       reqprep(&req, p, sipmethod, 0, 1);
08021       
08022    if (p->options && p->options->auth)
08023       add_header(&req, p->options->authheader, p->options->auth);
08024    append_date(&req);
08025    if (sipmethod == SIP_REFER) { /* Call transfer */
08026       if (p->refer) {
08027          char buf[SIPBUFSIZE];
08028          if (!ast_strlen_zero(p->refer->refer_to))
08029             add_header(&req, "Refer-To", p->refer->refer_to);
08030          if (!ast_strlen_zero(p->refer->referred_by)) {
08031             snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
08032             add_header(&req, "Referred-By", buf);
08033          }
08034       }
08035    }
08036    /* This new INVITE is part of an attended transfer. Make sure that the
08037    other end knows and replace the current call with this new call */
08038    if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) {
08039       add_header(&req, "Replaces", p->options->replaces);
08040       add_header(&req, "Require", "replaces");
08041    }
08042 
08043    add_header(&req, "Allow", ALLOWED_METHODS);
08044    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
08045    if (p->options && p->options->addsipheaders && p->owner) {
08046       struct ast_channel *chan = p->owner; /* The owner channel */
08047       struct varshead *headp;
08048    
08049       ast_channel_lock(chan);
08050 
08051       headp = &chan->varshead;
08052 
08053       if (!headp)
08054          ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
08055       else {
08056          const struct ast_var_t *current;
08057          AST_LIST_TRAVERSE(headp, current, entries) {  
08058             /* SIPADDHEADER: Add SIP header to outgoing call */
08059             if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
08060                char *content, *end;
08061                const char *header = ast_var_value(current);
08062                char *headdup = ast_strdupa(header);
08063 
08064                /* Strip of the starting " (if it's there) */
08065                if (*headdup == '"')
08066                   headdup++;
08067                if ((content = strchr(headdup, ':'))) {
08068                   *content++ = '\0';
08069                   content = ast_skip_blanks(content); /* Skip white space */
08070                   /* Strip the ending " (if it's there) */
08071                   end = content + strlen(content) -1; 
08072                   if (*end == '"')
08073                      *end = '\0';
08074                
08075                   add_header(&req, headdup, content);
08076                   if (sipdebug)
08077                      ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
08078                }
08079             }
08080          }
08081       }
08082 
08083       ast_channel_unlock(chan);
08084    }
08085    if (sdp) {
08086       memset(p->offered_media, 0, sizeof(p->offered_media));
08087       if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
08088          ast_udptl_offered_from_local(p->udptl, 1);
08089          if (option_debug)
08090             ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
08091          add_sdp(&req, p, 0, 1);
08092       } else if (p->rtp) 
08093          add_sdp(&req, p, 1, 0);
08094    }
08095 
08096    if (!p->initreq.headers || init > 2)
08097       initialize_initreq(p, &req);
08098    p->lastinvite = p->ocseq;
08099    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
08100 }

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

Transmit text with SIP MESSAGE method.

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

08676 {
08677    struct sip_request req;
08678 
08679    reqprep(&req, p, SIP_MESSAGE, 0, 1);
08680    add_text(&req, text);
08681    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
08682 }

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

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

Referenced by sip_send_mwi_to_peer().

08291 {
08292    struct sip_request req;
08293    char tmp[500];
08294    char *t = tmp;
08295    size_t maxbytes = sizeof(tmp);
08296 
08297    initreqprep(&req, p, SIP_NOTIFY);
08298    add_header(&req, "Event", "message-summary");
08299    add_header(&req, "Content-Type", default_notifymime);
08300 
08301    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
08302    /* if we listen to non-standard SIP port we have to specify the SIP port
08303        in the URI, except domains are used - in this case the SRV records should be
08304        used to redirect the client to the non-standard SIP port */
08305    if ((ourport != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain)) {
08306       ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s:%d\r\n",
08307       S_OR(vmexten, default_vmexten), ast_inet_ntoa(p->ourip), ourport);
08308    } else {
08309       ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
08310       S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
08311    }
08312    /* Cisco has a bug in the SIP stack where it can't accept the
08313       (0/0) notification. This can temporarily be disabled in
08314       sip.conf with the "buggymwi" option */
08315    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)"));
08316 
08317    if (p->subscribed) {
08318       if (p->expiry)
08319          add_header(&req, "Subscription-State", "active");
08320       else  /* Expired */
08321          add_header(&req, "Subscription-State", "terminated;reason=timeout");
08322    }
08323 
08324    if (t > tmp + sizeof(tmp))
08325       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
08326 
08327    add_content(&req, tmp);
08328 
08329    if (!p->initreq.headers) 
08330       initialize_initreq(p, &req);
08331    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
08332 }

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

References add_content(), add_header(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.

Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().

08344 {
08345    struct sip_request req;
08346    char tmp[SIPBUFSIZE/2];
08347 
08348    reqprep(&req, p, SIP_NOTIFY, 0, 1);
08349    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
08350    add_header(&req, "Event", tmp);
08351    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
08352    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
08353    add_header(&req, "Allow", ALLOWED_METHODS);
08354    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
08355 
08356    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
08357    add_content(&req, tmp);
08358 
08359    if (!p->initreq.headers)
08360       initialize_initreq(p, &req);
08361 
08362    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
08363 }

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

Definition at line 7117 of file chan_sip.c.

References transmit_response(), transmit_response_with_sdp(), update_provisional_keepalive(), and XMIT_UNRELIABLE.

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

07118 {
07119    int res;
07120 
07121    if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE) : transmit_response(p, msg, req))) {
07122       p->last_provisional = msg;
07123       update_provisional_keepalive(p, with_sdp);
07124    }
07125 
07126    return res;
07127 }

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

References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, 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::our_contact, 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, sip_pvt::theirtag, and XMIT_RELIABLE.

Referenced by sip_transfer().

08697 {
08698    struct sip_request req = { 
08699       .headers = 0,  
08700    };
08701    char from[256];
08702    const char *of;
08703    char *c;
08704    char referto[256];
08705    char *ttag, *ftag;
08706    char *theirtag = ast_strdupa(p->theirtag);
08707 
08708    if (option_debug || sipdebug)
08709       ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
08710 
08711    /* Are we transfering an inbound or outbound call ? */
08712    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
08713       of = get_header(&p->initreq, "To");
08714       ttag = theirtag;
08715       ftag = p->tag;
08716    } else {
08717       of = get_header(&p->initreq, "From");
08718       ftag = theirtag;
08719       ttag = p->tag;
08720    }
08721 
08722    ast_copy_string(from, of, sizeof(from));
08723    of = get_in_brackets(from);
08724    ast_string_field_set(p, from, of);
08725    if (strncasecmp(of, "sip:", 4))
08726       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
08727    else
08728       of += 4;
08729    /* Get just the username part */
08730    if ((c = strchr(dest, '@')))
08731       c = NULL;
08732    else if ((c = strchr(of, '@')))
08733       *c++ = '\0';
08734    if (c) 
08735       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
08736    else
08737       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
08738 
08739    /* save in case we get 407 challenge */
08740    sip_refer_allocate(p);
08741    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
08742    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
08743    p->refer->status = REFER_SENT;   /* Set refer status */
08744 
08745    reqprep(&req, p, SIP_REFER, 0, 1);
08746 
08747    add_header(&req, "Refer-To", referto);
08748    add_header(&req, "Allow", ALLOWED_METHODS);
08749    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
08750    if (!ast_strlen_zero(p->our_contact))
08751       add_header(&req, "Referred-By", p->our_contact);
08752 
08753    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
08754    /* We should propably wait for a NOTIFY here until we ack the transfer */
08755    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
08756 
08757    /*! \todo In theory, we should hang around and wait for a reply, before
08758    returning to the dial plan here. Don't know really how that would
08759    affect the transfer() app or the pbx, but, well, to make this
08760    useful we should have a STATUS code on transfer().
08761    */
08762 }

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

References __ourip, add_header(), 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, sip_pvt::authname, sip_registry::authuser, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, sip_registry::contact, create_addr(), DEFAULT_MAX_FORWARDS, sip_registry::domain, exten, FALSE, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromuser, sip_request::headers, sip_registry::hostname, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, make_our_tag(), sip_registry::md5secret, sip_registry::needdns, sip_pvt::nonce, sip_registry::nonce, sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, option_debug, sip_pvt::our_contact, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, sip_registry::secret, 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_pvt::theirtag, sip_registry::timeout, sip_pvt::tohost, TRUE, sip_pvt::uri, sip_registry::us, username, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.

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

08469 {
08470    struct sip_request req;
08471    char from[256];
08472    char to[256];
08473    char tmp[80];
08474    char addr[80];
08475    struct sip_pvt *p;
08476    char *fromdomain;
08477 
08478    /* exit if we are already in process with this registrar ?*/
08479    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
08480       if (r) {
08481          ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
08482       }
08483       return 0;
08484    }
08485 
08486    if (r->call) { /* We have a registration */
08487       if (!auth) {
08488          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
08489          return 0;
08490       } else {
08491          p = r->call;
08492          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
08493          ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
08494       }
08495    } else {
08496       /* Build callid for registration if we haven't registered before */
08497       if (!r->callid_valid) {
08498          build_callid_registry(r, __ourip, default_fromdomain);
08499          r->callid_valid = TRUE;
08500       }
08501       /* Allocate SIP packet for registration */
08502       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
08503          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
08504          return 0;
08505       }
08506       if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
08507          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
08508       /* Find address to hostname if we haven't tried to connect
08509        * or a connection error has occurred */
08510       if (create_addr(p, r->hostname, r->needdns ? NULL : &r->us)) {
08511          /* we have what we hope is a temporary network error,
08512           * probably DNS.  We need to reschedule a registration try */
08513          sip_destroy(p);
08514 
08515          if (r->timeout > -1)
08516             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
08517          else
08518             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);
08519 
08520          AST_SCHED_DEL(sched, r->timeout);
08521          r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
08522          r->regattempts++;
08523          return 0;
08524       }
08525       if (r->needdns) {
08526          memcpy(&r->us, &p->sa, sizeof(r->us));
08527       }
08528       r->needdns = FALSE;
08529       /* Copy back Call-ID in case create_addr changed it */
08530       ast_string_field_set(r, callid, p->callid);
08531       if (r->portno) {
08532          p->sa.sin_port = htons(r->portno);
08533          p->recv.sin_port = htons(r->portno);
08534       } else   /* Set registry port to the port set from the peer definition/srv or default */
08535          r->portno = ntohs(p->sa.sin_port);
08536       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
08537       r->call=p;        /* Save pointer to SIP packet */
08538       p->registry = ASTOBJ_REF(r);  /* Add pointer to registry in packet */
08539       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
08540          ast_string_field_set(p, peersecret, r->secret);
08541       if (!ast_strlen_zero(r->md5secret))
08542          ast_string_field_set(p, peermd5secret, r->md5secret);
08543       /* User name in this realm  
08544       - if authuser is set, use that, otherwise use username */
08545       if (!ast_strlen_zero(r->authuser)) {   
08546          ast_string_field_set(p, peername, r->authuser);
08547          ast_string_field_set(p, authname, r->authuser);
08548       } else if (!ast_strlen_zero(r->username)) {
08549          ast_string_field_set(p, peername, r->username);
08550          ast_string_field_set(p, authname, r->username);
08551          ast_string_field_set(p, fromuser, r->username);
08552       }
08553       if (!ast_strlen_zero(r->username))
08554          ast_string_field_set(p, username, r->username);
08555       /* Save extension in packet */
08556       ast_string_field_set(p, exten, r->contact);
08557 
08558       /*
08559         check which address we should use in our contact header 
08560         based on whether the remote host is on the external or
08561         internal network so we can register through nat
08562        */
08563       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
08564          p->ourip = bindaddr.sin_addr;
08565       build_contact(p);
08566    }
08567 
08568    /* set up a timeout */
08569    if (auth == NULL)  {
08570       if (r->timeout > -1)
08571          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
08572       AST_SCHED_DEL(sched, r->timeout);
08573       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
08574       if (option_debug)
08575          ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
08576    }
08577 
08578    if ((fromdomain = strchr(r->username, '@'))) {
08579       /* the domain name is just behind '@' */
08580       fromdomain++ ;
08581       /* We have a domain in the username for registration */
08582       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
08583       if (!ast_strlen_zero(p->theirtag))
08584          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
08585       else
08586          snprintf(to, sizeof(to), "<sip:%s>", r->username);
08587 
08588       /* If the registration username contains '@', then the domain should be used as
08589          the equivalent of "fromdomain" for the registration */
08590       if (ast_strlen_zero(p->fromdomain)) {
08591          ast_string_field_set(p, fromdomain, fromdomain);
08592       }
08593    } else {
08594       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
08595       if (!ast_strlen_zero(p->theirtag))
08596          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
08597       else
08598          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
08599    }
08600    
08601    /* Fromdomain is what we are registering to, regardless of actual
08602       host name from SRV */
08603    if (!ast_strlen_zero(p->fromdomain)) {
08604       if (r->portno && r->portno != STANDARD_SIP_PORT)
08605          snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
08606       else
08607          snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
08608    } else {
08609       if (r->portno && r->portno != STANDARD_SIP_PORT)
08610          snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
08611       else
08612          snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
08613    }
08614    ast_string_field_set(p, uri, addr);
08615 
08616    p->branch ^= ast_random();
08617 
08618    init_req(&req, sipmethod, addr);
08619 
08620    /* Add to CSEQ */
08621    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
08622    p->ocseq = r->ocseq;
08623 
08624    build_via(p);
08625    add_header(&req, "Via", p->via);
08626    add_header(&req, "From", from);
08627    add_header(&req, "To", to);
08628    add_header(&req, "Call-ID", p->callid);
08629    add_header(&req, "CSeq", tmp);
08630    if (!ast_strlen_zero(global_useragent))
08631       add_header(&req, "User-Agent", global_useragent);
08632    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
08633 
08634    
08635    if (auth)   /* Add auth header */
08636       add_header(&req, authheader, auth);
08637    else if (!ast_strlen_zero(r->nonce)) {
08638       char digest[1024];
08639 
08640       /* We have auth data to reuse, build a digest header! */
08641       if (sipdebug)
08642          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
08643       ast_string_field_set(p, realm, r->realm);
08644       ast_string_field_set(p, nonce, r->nonce);
08645       ast_string_field_set(p, domain, r->domain);
08646       ast_string_field_set(p, opaque, r->opaque);
08647       ast_string_field_set(p, qop, r->qop);
08648       r->noncecount++;
08649       p->noncecount = r->noncecount;
08650 
08651       memset(digest,0,sizeof(digest));
08652       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
08653          add_header(&req, "Authorization", digest);
08654       else
08655          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
08656    
08657    }
08658 
08659    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
08660    add_header(&req, "Expires", tmp);
08661    add_header(&req, "Contact", p->our_contact);
08662    add_header(&req, "Event", "registration");
08663 
08664    initialize_initreq(p, &req);
08665    if (sip_debug_test_pvt(p))
08666       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
08667    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
08668    r->regattempts++; /* Another attempt */
08669    if (option_debug > 3)
08670       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
08671    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
08672 }

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 7713 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(), handle_response_invite(), and sip_set_rtp_peer().

07714 {
07715    struct sip_request req;
07716 
07717    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
07718    
07719    add_header(&req, "Allow", ALLOWED_METHODS);
07720    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07721    if (sipdebug)
07722       add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
07723    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
07724       append_history(p, "ReInv", "Re-invite sent");
07725    memset(p->offered_media, 0, sizeof(p->offered_media));
07726    add_sdp(&req, p, 1, 0);
07727    /* Use this as the basis */
07728    initialize_initreq(p, &req);
07729    p->lastinvite = p->ocseq;
07730    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
07731    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
07732 }

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

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

Referenced by sip_handle_t38_reinvite(), sip_read(), sip_set_udptl_peer(), and sip_write().

07739 {
07740    struct sip_request req;
07741 
07742    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
07743    
07744    add_header(&req, "Allow", ALLOWED_METHODS);
07745    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07746    if (sipdebug)
07747       add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)");
07748    memset(p->offered_media, 0, sizeof(p->offered_media));
07749    add_sdp(&req, p, 0, 1);
07750 
07751    /* Use this as the basis */
07752    initialize_initreq(p, &req);
07753    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
07754    p->lastinvite = p->ocseq;
07755    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
07756 }

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

Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).

Definition at line 8788 of file chan_sip.c.

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

08789 {
08790    struct sip_request resp;
08791 
08792    if (sipmethod == SIP_ACK)
08793       p->invitestate = INV_CONFIRMED;
08794 
08795    reqprep(&resp, p, sipmethod, seqno, newbranch);
08796    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
08797 }

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

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

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

08801 {
08802    struct sip_request resp;
08803 
08804    reqprep(&resp, p, sipmethod, seqno, newbranch);
08805    if (!ast_strlen_zero(p->realm)) {
08806       char digest[1024];
08807 
08808       memset(digest, 0, sizeof(digest));
08809       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
08810          if (p->options && p->options->auth_type == PROXY_AUTH)
08811             add_header(&resp, "Proxy-Authorization", digest);
08812          else if (p->options && p->options->auth_type == WWW_AUTH)
08813             add_header(&resp, "Authorization", digest);
08814          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
08815             add_header(&resp, "Proxy-Authorization", digest);
08816       } else
08817          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
08818    }
08819    /* If we are hanging up and know a cause for that, send it in clear text to make
08820       debugging easier. */
08821    if (sipmethod == SIP_BYE)  {
08822       char buf[10];
08823 
08824       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause));
08825       snprintf(buf, sizeof(buf), "%d", p->hangupcause);
08826       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
08827    }
08828 
08829    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
08830 }

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

Transmit response, no retransmits.

Definition at line 7043 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

07044 {
07045    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
07046 }

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 7061 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_handle_t38_reinvite(), sip_hangup(), sip_indicate(), and sip_sipredirect().

07062 {
07063    return __transmit_response(p, msg, req, XMIT_CRITICAL);
07064 }

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

References __ourip, __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_reset_all, ast_string_field_set, ast_test_flag, ast_threadstorage_get(), build_via(), check_via(), do_setnat(), sip_pvt::fromdomain, global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, ts_temp_pvt, and XMIT_UNRELIABLE.

06993 {
06994    struct sip_pvt *p = NULL;
06995 
06996    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
06997       ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
06998       return -1;
06999    }
07000 
07001    /* if the structure was just allocated, initialize it */
07002    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
07003       ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
07004       if (ast_string_field_init(p, 512))
07005          return -1;
07006    }
07007 
07008    /* Initialize the bare minimum */
07009    p->method = intended_method;
07010 
07011    if (sin) {
07012       p->sa = *sin;
07013       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
07014          p->ourip = __ourip;
07015    } else
07016       p->ourip = __ourip;
07017 
07018    p->branch = ast_random();
07019    make_our_tag(p->tag, sizeof(p->tag));
07020    p->ocseq = INITIAL_CSEQ;
07021 
07022    if (useglobal_nat && sin) {
07023       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
07024       p->recv = *sin;
07025       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
07026    }
07027    check_via(p, req);
07028 
07029    ast_string_field_set(p, fromdomain, default_fromdomain);
07030    build_via(p);
07031    ast_string_field_set(p, callid, callid);
07032 
07033    /* Use this temporary pvt structure to send the message */
07034    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
07035 
07036    /* Free the string fields, but not the pool space */
07037    ast_string_field_reset_all(p);
07038 
07039    return 0;
07040 }

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

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

Referenced by handle_request(), and handle_request_options().

07089 {
07090    struct sip_request resp;
07091    respprep(&resp, p, msg, req);
07092    add_header(&resp, "Accept", "application/sdp");
07093    return send_response(p, &resp, reliable, 0);
07094 }

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

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

Referenced by check_auth(), and transmit_fake_auth_response().

07098 {
07099    struct sip_request resp;
07100    char tmp[512];
07101    int seqno = 0;
07102 
07103    if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) {
07104       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
07105       return -1;
07106    }
07107    /* Stale means that they sent us correct authentication, but 
07108       based it on an old challenge (nonce) */
07109    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
07110    respprep(&resp, p, msg, req);
07111    add_header(&resp, header, tmp);
07112    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
07113    return send_response(p, &resp, reliable, seqno);
07114 }

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

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

Referenced by register_verify().

07080 {
07081    struct sip_request resp;
07082    respprep(&resp, p, msg, req);
07083    append_date(&resp);
07084    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
07085 }

static int transmit_response_with_sdp ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable 
) [static]

Used for 200 OK and 183 early media.

Returns:
Will return XMIT_ERROR for network errors.

Definition at line 7637 of file chan_sip.c.

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

Referenced by handle_invite_replaces(), handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().

07638 {
07639    struct sip_request resp;
07640    int seqno;
07641    if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) {
07642       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
07643       return -1;
07644    }
07645    respprep(&resp, p, msg, req);
07646    if (p->rtp) {
07647       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
07648          if (option_debug)
07649             ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n");
07650          ast_rtp_codec_setpref(p->rtp, &p->prefs);
07651       }
07652       try_suggested_sip_codec(p);
07653       if (p->t38.state == T38_PEER_DIRECT || p->t38.state == T38_ENABLED) {
07654          p->t38.state = T38_ENABLED;
07655          add_sdp(&resp, p, 1, 1);
07656       } else {
07657          add_sdp(&resp, p, 1, 0);
07658       }
07659    } else 
07660       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
07661    if (reliable && !p->pendinginvite)
07662       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
07663    return send_response(p, &resp, reliable, seqno);
07664 }

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

References add_sdp(), ast_log(), sip_pvt::callid, get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.

Referenced by handle_request_invite(), and sip_handle_t38_reinvite().

07599 {
07600    struct sip_request resp;
07601    int seqno;
07602    
07603    if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) {
07604       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
07605       return -1;
07606    }
07607    respprep(&resp, p, msg, req);
07608    if (p->udptl) {
07609       add_sdp(&resp, p, 0, 1);
07610    } else 
07611       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
07612    if (retrans && !p->pendinginvite)
07613       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
07614    return send_response(p, &resp, retrans, seqno);
07615 }

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

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

Referenced by handle_request_invite().

07050 {
07051    struct sip_request resp;
07052    respprep(&resp, p, msg, req);
07053    append_date(&resp);
07054    add_header(&resp, "Unsupported", unsupported);
07055    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
07056 }

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

08336 {
08337    if (!p->initreq.headers)   /* Initialize first request before sending */
08338       initialize_initreq(p, req);
08339    return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
08340 }

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

References add_content(), add_header(), ast_build_string(), ast_copy_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, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.

Referenced by __sip_autodestruct(), handle_request_subscribe(), and notify_extenstate_update().

08104 {
08105    char tmp[4000], from[256], to[256];
08106    char *t = tmp, *c, *mfrom, *mto;
08107    size_t maxbytes = sizeof(tmp);
08108    struct sip_request req;
08109    char hint[AST_MAX_EXTENSION];
08110    char *statestring = "terminated";
08111    const struct cfsubscription_types *subscriptiontype;
08112    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
08113    char *pidfstate = "--";
08114    char *pidfnote= "Ready";
08115 
08116    memset(from, 0, sizeof(from));
08117    memset(to, 0, sizeof(to));
08118    memset(tmp, 0, sizeof(tmp));
08119 
08120    switch (state) {
08121    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
08122       statestring = (global_notifyringing) ? "early" : "confirmed";
08123       local_state = NOTIFY_INUSE;
08124       pidfstate = "busy";
08125       pidfnote = "Ringing";
08126       break;
08127    case AST_EXTENSION_RINGING:
08128       statestring = "early";
08129       local_state = NOTIFY_INUSE;
08130       pidfstate = "busy";
08131       pidfnote = "Ringing";
08132       break;
08133    case AST_EXTENSION_INUSE:
08134       statestring = "confirmed";
08135       local_state = NOTIFY_INUSE;
08136       pidfstate = "busy";
08137       pidfnote = "On the phone";
08138       break;
08139    case AST_EXTENSION_BUSY:
08140       statestring = "confirmed";
08141       local_state = NOTIFY_CLOSED;
08142       pidfstate = "busy";
08143       pidfnote = "On the phone";
08144       break;
08145    case AST_EXTENSION_UNAVAILABLE:
08146       statestring = "terminated";
08147       local_state = NOTIFY_CLOSED;
08148       pidfstate = "away";
08149       pidfnote = "Unavailable";
08150       break;
08151    case AST_EXTENSION_ONHOLD:
08152       statestring = "confirmed";
08153       local_state = NOTIFY_CLOSED;
08154       pidfstate = "busy";
08155       pidfnote = "On Hold";
08156       break;
08157    case AST_EXTENSION_NOT_INUSE:
08158    default:
08159       /* Default setting */
08160       break;
08161    }
08162 
08163    subscriptiontype = find_subscription_type(p->subscribed);
08164    
08165    /* Check which device/devices we are watching  and if they are registered */
08166    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
08167       char *hint2 = hint, *individual_hint = NULL;
08168       int hint_count = 0, unavailable_count = 0;
08169 
08170       while ((individual_hint = strsep(&hint2, "&"))) {
08171          hint_count++;
08172 
08173          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
08174             unavailable_count++;
08175       }
08176 
08177       /* If none of the hinted devices are registered, we will
08178        * override notification and show no availability.
08179        */
08180       if (hint_count > 0 && hint_count == unavailable_count) {
08181          local_state = NOTIFY_CLOSED;
08182          pidfstate = "away";
08183          pidfnote = "Not online";
08184       }
08185    }
08186 
08187    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
08188    c = get_in_brackets(from);
08189    if (strncasecmp(c, "sip:", 4)) {
08190       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
08191       return -1;
08192    }
08193    mfrom = strsep(&c, ";");   /* trim ; and beyond */
08194 
08195    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
08196    c = get_in_brackets(to);
08197    if (strncasecmp(c, "sip:", 4)) {
08198       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
08199       return -1;
08200    }
08201    mto = strsep(&c, ";");  /* trim ; and beyond */
08202 
08203    reqprep(&req, p, SIP_NOTIFY, 0, 1);
08204 
08205    
08206    add_header(&req, "Event", subscriptiontype->event);
08207    add_header(&req, "Content-Type", subscriptiontype->mediatype);
08208    switch(state) {
08209    case AST_EXTENSION_DEACTIVATED:
08210       if (timeout)
08211          add_header(&req, "Subscription-State", "terminated;reason=timeout");
08212       else {
08213          add_header(&req, "Subscription-State", "terminated;reason=probation");
08214          add_header(&req, "Retry-After", "60");
08215       }
08216       break;
08217    case AST_EXTENSION_REMOVED:
08218       add_header(&req, "Subscription-State", "terminated;reason=noresource");
08219       break;
08220    default:
08221       if (p->expiry)
08222          add_header(&req, "Subscription-State", "active");
08223       else  /* Expired */
08224          add_header(&req, "Subscription-State", "terminated;reason=timeout");
08225    }
08226    switch (p->subscribed) {
08227    case XPIDF_XML:
08228    case CPIM_PIDF_XML:
08229       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
08230       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
08231       ast_build_string(&t, &maxbytes, "<presence>\n");
08232       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
08233       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
08234       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
08235       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
08236       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
08237       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
08238       break;
08239    case PIDF_XML: /* Eyebeam supports this format */
08240       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
08241       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);
08242       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
08243       if (pidfstate[0] != '-')
08244          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
08245       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
08246       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
08247       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
08248       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
08249       if (pidfstate[0] == 'b') /* Busy? Still open ... */
08250          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
08251       else
08252          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
08253       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
08254       break;
08255    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
08256       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
08257       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);
08258       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
08259          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
08260       else
08261          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
08262       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
08263       if (state == AST_EXTENSION_ONHOLD) {
08264          ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
08265                                          "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n"
08266                                          "</target>\n</local>\n", mto);
08267       }
08268       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
08269       break;
08270    case NONE:
08271    default:
08272       break;
08273    }
08274 
08275    if (t > tmp + sizeof(tmp))
08276       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
08277 
08278    add_content(&req, tmp);
08279    p->pendinginvite = p->ocseq;  /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
08280 
08281    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
08282 }

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

Definition at line 3999 of file chan_sip.c.

References ast_getformatbyname(), ast_log(), sip_pvt::capability, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().

Referenced by sip_answer(), and transmit_response_with_sdp().

04000 {
04001    int fmt;
04002    const char *codec;
04003 
04004    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
04005    if (!codec) 
04006       return;
04007 
04008    fmt = ast_getformatbyname(codec);
04009    if (fmt) {
04010       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
04011       if (p->jointcapability & fmt) {
04012          p->jointcapability &= fmt;
04013          p->capability &= fmt;
04014       } else
04015          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
04016    } else
04017       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
04018    return;  
04019 }

static int unload_module ( void   )  [static]

PBX unload module API.

Definition at line 20362 of file chan_sip.c.

References __sip_destroy(), app_dtmfmode, app_sipaddheader, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free, ast_free_ha(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, global_contact_ha, iflist, iflock, sip_extenstate_update::list, localaddr, monlock, 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, update(), and userl.

20363 {
20364    struct sip_pvt *p, *pl;
20365    struct sip_extenstate_update *update;
20366 
20367    /* First, take us out of the channel type list */
20368    ast_channel_unregister(&sip_tech);
20369 
20370    /* Unregister dial plan functions */
20371    ast_custom_function_unregister(&sipchaninfo_function);
20372    ast_custom_function_unregister(&sippeer_function);
20373    ast_custom_function_unregister(&sip_header_function);
20374    ast_custom_function_unregister(&checksipdomain_function);
20375 
20376    /* Unregister dial plan applications */
20377    ast_unregister_application(app_dtmfmode);
20378    ast_unregister_application(app_sipaddheader);
20379 
20380    /* Unregister CLI commands */
20381    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
20382 
20383    /* Disconnect from the RTP subsystem */
20384    ast_rtp_proto_unregister(&sip_rtp);
20385 
20386    /* Disconnect from UDPTL */
20387    ast_udptl_proto_unregister(&sip_udptl);
20388 
20389    /* Unregister AMI actions */
20390    ast_manager_unregister("SIPpeers");
20391    ast_manager_unregister("SIPshowpeer");
20392 
20393    ast_mutex_lock(&iflock);
20394    /* Hangup all interfaces if they have an owner */
20395    for (p = iflist; p ; p = p->next) {
20396       if (p->owner)
20397          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
20398    }
20399    ast_mutex_unlock(&iflock);
20400 
20401    ast_mutex_lock(&monlock);
20402    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
20403       pthread_cancel(monitor_thread);
20404       pthread_kill(monitor_thread, SIGURG);
20405       pthread_join(monitor_thread, NULL);
20406    }
20407    monitor_thread = AST_PTHREADT_STOP;
20408    ast_mutex_unlock(&monlock);
20409 
20410 restartdestroy:
20411    ast_mutex_lock(&iflock);
20412    /* Destroy all the interfaces and free their memory */
20413    p = iflist;
20414    while (p) {
20415       pl = p;
20416       p = p->next;
20417       if (__sip_destroy(pl, TRUE) < 0) {
20418          /* Something is still bridged, let it react to getting a hangup */
20419          iflist = p;
20420          ast_mutex_unlock(&iflock);
20421          usleep(1);
20422          goto restartdestroy;
20423       }
20424    }
20425    iflist = NULL;
20426    ast_mutex_unlock(&iflock);
20427 
20428    /* Free memory for local network address mask */
20429    ast_free_ha(localaddr);
20430 
20431    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
20432    ASTOBJ_CONTAINER_DESTROY(&userl);
20433    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
20434    ASTOBJ_CONTAINER_DESTROY(&peerl);
20435    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
20436    ASTOBJ_CONTAINER_DESTROY(&regl);
20437 
20438    AST_LIST_LOCK(&sip_extenstate_updates);
20439    AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) {
20440       AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list);
20441       ast_free(update);
20442    }
20443    AST_LIST_TRAVERSE_SAFE_END
20444    AST_LIST_UNLOCK(&sip_extenstate_updates);
20445 
20446    clear_realm_authentication(authl);
20447    clear_sip_domains();
20448    ast_free_ha(global_contact_ha);
20449    close(sipsock);
20450    sched_context_destroy(sched);
20451       
20452    return 0;
20453 }

static void unmark_extenstate_update ( struct sip_pvt pvt  )  [static]

Definition at line 9695 of file chan_sip.c.

References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, sip_extenstate_update::list, sip_extenstate_update::pvt, and update().

Referenced by do_monitor().

09696 {
09697    struct sip_extenstate_update *update = NULL;
09698 
09699    if (AST_LIST_EMPTY(&sip_extenstate_updates)) {
09700       /* avoid holding the lock if possible */
09701       return;
09702    }
09703 
09704    AST_LIST_LOCK(&sip_extenstate_updates);
09705    AST_LIST_TRAVERSE(&sip_extenstate_updates, update, list) {
09706       if (update->pvt == pvt) {
09707          update->marked = 0;
09708       }
09709    }
09710    AST_LIST_UNLOCK(&sip_extenstate_updates);
09711 }

static void* unref_provisional_keepalive ( struct provisional_keepalive_data data  )  [static]

Definition at line 2473 of file chan_sip.c.

References ao2_ref(), and sip_request::data.

Referenced by __sip_destroy(), and remove_provisional_keepalive_sched().

02474 {
02475    if (data) {
02476       data->sched_id = -1;
02477       data->pvt = NULL;
02478       ao2_ref(data, -1);
02479    }
02480    return NULL;
02481 }

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

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

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

03545 {
03546    char name[256];
03547    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
03548    int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL);
03549    struct sip_user *u = NULL;
03550    struct sip_peer *p = NULL;
03551 
03552    if (option_debug > 2)
03553       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
03554 
03555    /* Test if we need to check call limits, in order to avoid 
03556       realtime lookups if we do not need it */
03557    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
03558       return 0;
03559 
03560    ast_copy_string(name, fup->username, sizeof(name));
03561 
03562    /* Check the list of users only for incoming calls */
03563    if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1)))  {
03564       inuse = &u->inUse;
03565       call_limit = &u->call_limit;
03566       inringing = NULL;
03567    } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */
03568       inuse = &p->inUse;
03569       call_limit = &p->call_limit;
03570       inringing = &p->inRinging;
03571       ast_copy_string(name, fup->peername, sizeof(name));
03572    } 
03573    if (!p && !u) {
03574       if (option_debug > 1)
03575          ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
03576       return 0;
03577    }
03578 
03579    switch(event) {
03580    /* incoming and outgoing affects the inUse counter */
03581    case DEC_CALL_LIMIT:
03582       if ( *inuse > 0 ) {
03583          if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
03584             (*inuse)--;
03585             ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
03586          }
03587       } else {
03588          *inuse = 0;
03589       }
03590       if (inringing) {
03591          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03592             if (*inringing > 0)
03593                (*inringing)--;
03594             else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03595                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
03596             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03597          }
03598       }
03599       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) {
03600          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
03601          sip_peer_hold(fup, 0);
03602       }
03603       if (option_debug > 1 || sipdebug) {
03604          ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
03605       }
03606       break;
03607 
03608    case INC_CALL_RINGING:
03609    case INC_CALL_LIMIT:
03610       if (*call_limit > 0 ) {
03611          /* Let call limit affect only outgoing calls */
03612          if (outgoing && (*inuse >= *call_limit)) {
03613             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);
03614             if (u)
03615                ASTOBJ_UNREF(u, sip_destroy_user);
03616             else
03617                ASTOBJ_UNREF(p, sip_destroy_peer);
03618             return -1; 
03619          }
03620       }
03621       if (inringing && (event == INC_CALL_RINGING)) {
03622          if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03623             (*inringing)++;
03624             ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03625          }
03626       }
03627       /* Continue */
03628       (*inuse)++;
03629       ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
03630       if (option_debug > 1 || sipdebug) {
03631          ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
03632       }
03633       break;
03634 
03635    case DEC_CALL_RINGING:
03636       if (inringing) {
03637          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03638             if (*inringing > 0)
03639                (*inringing)--;
03640             else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03641                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
03642             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03643          }
03644       }
03645       break;
03646 
03647    default:
03648       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
03649    }
03650    if (p) {
03651       ast_device_state_changed("SIP/%s", p->name);
03652       ASTOBJ_UNREF(p, sip_destroy_peer);
03653    } else /* u must be set */
03654       ASTOBJ_UNREF(u, sip_destroy_user);
03655    return 0;
03656 }

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

Update peer data in database (if used).

Definition at line 2783 of file chan_sip.c.

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

Referenced by register_verify().

02784 {
02785    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02786    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
02787        (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
02788       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->lastms);
02789    }
02790 }

static void update_provisional_keepalive ( struct sip_pvt pvt,
int  with_sdp 
) [static]

Definition at line 2504 of file chan_sip.c.

References ao2_alloc(), ao2_ref(), ast_sched_add(), PROVIS_KEEPALIVE_TIMEOUT, sip_pvt::provisional_keepalive_data, provisional_keepalive_data::pvt, remove_provisional_keepalive_sched(), sched, provisional_keepalive_data::sched_id, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().

Referenced by transmit_provisional_response().

02505 {
02506    remove_provisional_keepalive_sched(pvt);
02507 
02508    if (!pvt->provisional_keepalive_data) {
02509       if (!(pvt->provisional_keepalive_data = ao2_alloc(sizeof(*pvt->provisional_keepalive_data), NULL))) {
02510          return; /* alloc error, can not recover */
02511       }
02512       pvt->provisional_keepalive_data->sched_id = -1;
02513       pvt->provisional_keepalive_data->pvt = pvt;
02514    }
02515 
02516    /* give the scheduler a ref */
02517    ao2_ref(pvt->provisional_keepalive_data, +1);
02518 
02519    /* schedule the provisional keepalive */
02520    pvt->provisional_keepalive_data->sched_id = ast_sched_add(sched,
02521       PROVIS_KEEPALIVE_TIMEOUT,
02522       with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive,
02523       pvt->provisional_keepalive_data);
02524 
02525    /* if schedule was unsuccessful, remove the scheduler's ref */
02526    if (pvt->provisional_keepalive_data->sched_id == -1) {
02527       ao2_ref(pvt->provisional_keepalive_data, -1);
02528    }
02529 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 20459 of file chan_sip.c.

struct in_addr __ourip [static]

Definition at line 1317 of file chan_sip.c.

int allow_external_domains [static]

Accept calls to external SIP domains?

Definition at line 575 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 595 of file chan_sip.c.

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 19914 of file chan_sip.c.

Referenced by load_module(), and unload_module().

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 19916 of file chan_sip.c.

Referenced by load_module(), and unload_module().

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 20459 of file chan_sip.c.

struct sip_auth* authl = NULL [static]

Definition at line 1306 of file chan_sip.c.

Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().

int autocreatepeer [static]

Auto creation of peers at registration? Default off.

Definition at line 554 of file chan_sip.c.

struct sockaddr_in bindaddr = { 0, } [static]

The address we bind to

Definition at line 1311 of file chan_sip.c.

unsigned int chan_idx [static]

Definition at line 403 of file chan_sip.c.

struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = check_auth_buf_init , } [static]

Definition at line 9398 of file chan_sip.c.

Referenced by check_auth(), and transmit_fake_auth_response().

struct ast_custom_function checksipdomain_function [static]

Definition at line 13221 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip[] [static]

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

int compactheaders [static]

send compact sip headers

Definition at line 569 of file chan_sip.c.

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

Definition at line 236 of file chan_sip.c.

char debug_usage[] [static]

Definition at line 13105 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

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

char default_context[AST_MAX_CONTEXT] [static]

Definition at line 530 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 194 of file chan_sip.c.

char default_fromdomain[AST_MAX_EXTENSION] [static]

Definition at line 534 of file chan_sip.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 227 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Definition at line 532 of file chan_sip.c.

int default_maxcallbitrate [static]

Maximum bitrate for call

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

char default_notifymime[AST_MAX_EXTENSION] [static]

Definition at line 535 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

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

char default_subscribecontext[AST_MAX_CONTEXT] [static]

Definition at line 531 of file chan_sip.c.

char default_vmexten[AST_MAX_EXTENSION] [static]

Definition at line 537 of file chan_sip.c.

char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static]

Definition at line 19913 of file chan_sip.c.

Referenced by load_module().

char* descrip_sipaddheader [static]

Definition at line 19919 of file chan_sip.c.

Referenced by load_module().

int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 571 of file chan_sip.c.

int expiry = DEFAULT_EXPIRY [static]

Definition at line 195 of file chan_sip.c.

Referenced by complete_dpreply(), and process_clearcache().

time_t externexpire = 0 [static]

Expiration counter for re-resolving external host name in dynamic DNS

Definition at line 1314 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

char externhost[MAXHOSTNAMELEN] [static]

External host name (possibly with dynamic DNS and DHCP

Definition at line 1313 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

struct sockaddr_in externip [static]

External IP address if we are behind NAT

Definition at line 1312 of file chan_sip.c.

int externrefresh = 10 [static]

Definition at line 1315 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

int global_allowguest [static]

allow unauthenticated users/peers to connect?

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

enum transfermodes global_allowtransfer [static]

SIP Refer restriction scheme

Definition at line 579 of file chan_sip.c.

int global_alwaysauthreject [static]

Send 401 Unauthorized for all failing requests

Definition at line 551 of file chan_sip.c.

int global_autoframing [static]

Turn autoframing on or off.

Definition at line 578 of file chan_sip.c.

int global_callevents [static]

Whether we send manager events or not

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

struct ast_ha* global_contact_ha = NULL [static]

Global list of addresses dynamic peers are not allowed to use.

Definition at line 587 of file chan_sip.c.

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

int global_directrtpsetup [static]

Enable support for Direct RTP setup (no re-invites)

Definition at line 545 of file chan_sip.c.

int global_dynamic_exclude_static = 0 [static]

Definition at line 588 of file chan_sip.c.

struct ast_flags global_flags[2] = {{0}} [static]

global SIP_ flags

Definition at line 598 of file chan_sip.c.

Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), handle_response_peerpoke(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_destroy_peer(), sip_destroy_user(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_poke_noanswer(), sip_show_settings(), transmit_response_using_temp(), and update_peer().

struct ast_jb_conf global_jbconf [static]

Definition at line 234 of file chan_sip.c.

int global_limitonpeers [static]

Match call limit on peers only

Definition at line 547 of file chan_sip.c.

int global_matchexterniplocally [static]

Match externip/externhost setting against localnet setting

Definition at line 581 of file chan_sip.c.

int global_mwitime [static]

Time between MWI checks for peers

Definition at line 565 of file chan_sip.c.

int global_notifyhold [static]

Send notifications on hold

Definition at line 550 of file chan_sip.c.

int global_notifyringing [static]

Send notifications on ringing

Definition at line 549 of file chan_sip.c.

int global_prematuremediafilter [static]

Enable/disable premature frames in a call (causing 183 early media)

Definition at line 546 of file chan_sip.c.

char global_realm[MAXHOSTNAMELEN] [static]

Default realm

Definition at line 572 of file chan_sip.c.

int global_reg_timeout [static]

Definition at line 559 of file chan_sip.c.

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 560 of file chan_sip.c.

char global_regcontext[AST_MAX_CONTEXT] [static]

Context for auto-extensions

Definition at line 573 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 555 of file chan_sip.c.

int global_rtautoclear [static]

Definition at line 548 of file chan_sip.c.

int global_rtpholdtimeout [static]

Definition at line 557 of file chan_sip.c.

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 558 of file chan_sip.c.

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 556 of file chan_sip.c.

int global_shrinkcallerid [static]

enable or disable shrinking of caller id

Definition at line 561 of file chan_sip.c.

int global_t1min [static]

T1 roundtrip time minimum

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

unsigned int global_tos_audio [static]

IP type of service for audio RTP packets

Definition at line 567 of file chan_sip.c.

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 566 of file chan_sip.c.

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 568 of file chan_sip.c.

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

Definition at line 574 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 13122 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

ast_mutex_t iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Protect the SIP dialog list (of sip_pvt's).

Definition at line 601 of file chan_sip.c.

struct io_context* io [static]

The IO context

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

Referenced by ast_sip_ouraddrfor(), and unload_module().

char mandescr_show_peer[] [static]

Initial value:

 
"Description: Show one SIP peer with details on current status.\n"
"Variables: \n"
"  Peer: <name>           The peer name you want to check.\n"
"  ActionID: <id>   Optional action ID for this AMI transaction.\n"

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

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 193 of file chan_sip.c.

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

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

ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 607 of file chan_sip.c.

ast_mutex_t netlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

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

const char notify_config[] = "sip_notify.conf" [static]

Definition at line 237 of file chan_sip.c.

struct ast_config* notify_types = NULL [static]

The list of manual NOTIFY types we know how to send

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

int ourport [static]

Definition at line 1319 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]

Definition at line 1318 of file chan_sip.c.

int pedanticsipchecking [static]

Extra checking ? Default off

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

int recordhistory [static]

Record SIP history. Off by default

Definition at line 570 of file chan_sip.c.

struct c_referstatusstring referstatusstrings[] [static]

Referenced by referstatus2str().

struct ast_register_list regl [static]

The register list: Other SIP proxys we register with and place calls to.

Referenced by load_module(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().

int regobjs = 0 [static]

Registry objects

Definition at line 596 of file chan_sip.c.

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 594 of file chan_sip.c.

int ruserobjs = 0 [static]

Realtime users

Definition at line 592 of file chan_sip.c.

struct sched_context* sched [static]

The scheduling context

Definition at line 618 of file chan_sip.c.

char seen_lastms = 0 [static]

Definition at line 196 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 13078 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 13074 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 13049 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 13082 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 13069 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 13135 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 13091 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 13086 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 13101 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 13139 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 13131 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 13064 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 13059 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]

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

ast_mutex_t sip_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 609 of file chan_sip.c.

Referenced by do_monitor(), and sip_reload().

char sip_reload_usage[] [static]

Initial value:

"Usage: sip reload\n"
"       Reloads SIP configuration from sip.conf\n"

Definition at line 13127 of file chan_sip.c.

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 615 of file chan_sip.c.

enum channelreloadreason sip_reloadreason [static]

Reason for last reload/load of configuration

Definition at line 616 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 1728 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 1670 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 1696 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 1737 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 13381 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 13300 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 1310 of file chan_sip.c.

Referenced by __sip_xmit(), do_monitor(), process_via(), reg_source_db(), sipsock_read(), and unload_module().

int* sipsock_read_id [static]

ID of IO entry for sipsock FD

Definition at line 620 of file chan_sip.c.

int speerobjs = 0 [static]

Statis peers

Definition at line 593 of file chan_sip.c.

int srvlookup [static]

SRV Lookup on or off. Default is on

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

char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static]

Definition at line 19912 of file chan_sip.c.

Referenced by load_module().

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

Definition at line 19917 of file chan_sip.c.

Referenced by load_module().

struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = temp_pvt_init , } [static]

Definition at line 1263 of file chan_sip.c.

Referenced by transmit_response_using_temp().

struct ast_user_list userl [static]

The user list: Users and friends.


Generated on Sat Aug 6 00:39:52 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7