Wed Mar 4 19:58:31 2009

Asterisk developer's documentation


chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

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

Go to the source code of this file.

Data Structures

struct  ast_peer_list
 The peer list: Peers and Friends. More...
struct  ast_register_list
 The register list: Other SIP proxys we register with and place calls to. More...
struct  ast_user_list
 The user list: Users and friends. More...
struct  c_referstatusstring
struct  cfsip_methods
struct  cfsip_options
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More...
struct  cfsubscription_types
struct  domain
 Domain data structure. More...
struct  domain_list
struct  sip_auth
 sip_auth: Credentials for authentication to other SIP services More...
struct  sip_dual
 structure used in transfers More...
struct  sip_history
 sip_history: Structure for saving transactions within a SIP dialog More...
struct  sip_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  t38properties
 T.38 channel settings (at some point we need to make this alloc'ed. More...

Defines

#define ALLOWED_METHODS   "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY"
 SIP Methods we support.
#define append_history(p, event, fmt, args...)   append_history_full(p, "%-15s " fmt, event, ## args)
 Append to SIP dialog history.
#define CALLERID_UNKNOWN   "Unknown"
#define CAN_CREATE_DIALOG   1
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2
#define CAN_NOT_CREATE_DIALOG   0
#define CHECK_AUTH_BUF_INITLEN   256
#define DEC_CALL_LIMIT   0
#define DEC_CALL_RINGING   2
#define DEFAULT_ALLOW_EXT_DOM   TRUE
#define DEFAULT_ALLOWGUEST   TRUE
#define DEFAULT_AUTOCREATEPEER   FALSE
#define DEFAULT_CALLERID   "asterisk"
#define DEFAULT_COMPACTHEADERS   FALSE
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DEFAULT_EXPIRY   120
#define DEFAULT_EXPIRY   900
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_CALL_BITRATE   (384)
#define DEFAULT_MAX_EXPIRY   3600
#define DEFAULT_MAX_FORWARDS   "70"
#define DEFAULT_MAXMS   2000
#define DEFAULT_MIN_EXPIRY   60
#define DEFAULT_MOHINTERPRET   "default"
#define DEFAULT_MOHSUGGEST   ""
#define DEFAULT_MWITIME   10
#define DEFAULT_NOTIFYMIME   "application/simple-message-summary"
#define DEFAULT_NOTIFYRINGING   TRUE
#define DEFAULT_PEDANTIC   FALSE
#define DEFAULT_QUALIFY   FALSE
#define DEFAULT_REALM   "asterisk"
#define DEFAULT_REGISTRATION_TIMEOUT   20
#define DEFAULT_RETRANS   1000
#define DEFAULT_SRVLOOKUP   TRUE
#define DEFAULT_T1MIN   100
#define DEFAULT_TOS_AUDIO   0
#define DEFAULT_TOS_SIP   0
#define DEFAULT_TOS_VIDEO   0
#define DEFAULT_TRANS_TIMEOUT   -1
#define DEFAULT_USERAGENT   "Asterisk PBX"
#define DEFAULT_VMEXTEN   "asterisk"
#define EXPIRY_GUARD_LIMIT   30
#define EXPIRY_GUARD_MIN   500
#define EXPIRY_GUARD_PCT   0.20
#define EXPIRY_GUARD_SECS   15
#define FALSE   0
#define FLAG_FATAL   (1 << 1)
#define FLAG_RESPONSE   (1 << 0)
#define FORMAT   "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n"
#define FORMAT   "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n"
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
#define FORMAT   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT2   "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n"
#define FORMAT2   "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n"
#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3H   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n"
#define FORMAT3L   "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n"
#define INC_CALL_LIMIT   1
#define INC_CALL_RINGING   3
#define INITIAL_CSEQ   101
#define IPTOS_MINCOST   0x02
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MAX_AUTHTRIES   3
#define MAX_HISTORY_ENTRIES   50
#define MAX_RETRANS   6
#define NO_RTP   0
#define NOT_SUPPORTED   0
#define RTP   1
#define SDP_MAX_RTPMAP_CODECS   32
#define SDP_SAMPLE_RATE(x)   8000
#define SIP_ALREADYGONE   (1 << 0)
#define SIP_CALL_LIMIT   (1 << 28)
#define SIP_CAN_REINVITE   (1 << 20)
#define SIP_CAN_REINVITE_NAT   (2 << 20)
#define SIP_DEFER_BYE_ON_TRANSFER   (1 << 15)
#define SIP_DTMF   (3 << 16)
#define SIP_DTMF_AUTO   (3 << 16)
#define SIP_DTMF_INBAND   (1 << 16)
#define SIP_DTMF_INFO   (2 << 16)
#define SIP_DTMF_RFC2833   (0 << 16)
#define SIP_FLAGS_TO_COPY
#define SIP_FREE_BIT   (1 << 14)
#define SIP_G726_NONSTANDARD   (1 << 31)
#define SIP_GOTREFER   (1 << 7)
#define SIP_INC_COUNT   (1 << 30)
#define SIP_INSECURE_INVITE   (1 << 24)
#define SIP_INSECURE_PORT   (1 << 23)
#define SIP_MAX_HEADERS   64
#define SIP_MAX_LINES   64
#define SIP_MAX_PACKET   4096
#define SIP_NAT   (3 << 18)
#define SIP_NAT_ALWAYS   (3 << 18)
#define SIP_NAT_NEVER   (0 << 18)
#define SIP_NAT_RFC3581   (1 << 18)
#define SIP_NAT_ROUTE   (2 << 18)
#define SIP_NEEDDESTROY   (1 << 1)
#define SIP_NEEDREINVITE   (1 << 5)
#define SIP_NO_HISTORY   (1 << 27)
#define SIP_NOVIDEO   (1 << 2)
#define SIP_OPT_100REL   (1 << 1)
#define SIP_OPT_EARLY_SESSION   (1 << 3)
#define SIP_OPT_EVENTLIST   (1 << 11)
#define SIP_OPT_GRUU   (1 << 12)
#define SIP_OPT_HISTINFO   (1 << 15)
#define SIP_OPT_JOIN   (1 << 4)
#define SIP_OPT_NOREFERSUB   (1 << 14)
#define SIP_OPT_PATH   (1 << 5)
#define SIP_OPT_PRECONDITION   (1 << 7)
#define SIP_OPT_PREF   (1 << 6)
#define SIP_OPT_PRIVACY   (1 << 8)
#define SIP_OPT_REPLACES   (1 << 0)
#define SIP_OPT_RESPRIORITY   (1 << 16)
#define SIP_OPT_SDP_ANAT   (1 << 9)
#define SIP_OPT_SEC_AGREE   (1 << 10)
#define SIP_OPT_TARGET_DIALOG   (1 << 13)
#define SIP_OPT_TIMER   (1 << 2)
#define SIP_OUTGOING   (1 << 13)
#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)
#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)
#define SIP_PAGE2_BUGGY_MWI   (1 << 26)
#define SIP_PAGE2_CALL_ONHOLD   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (2 << 23)
#define SIP_PAGE2_DEBUG   (3 << 11)
#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)
#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)
#define SIP_PAGE2_DIALOG_ESTABLISHED   (1 << 29)
#define SIP_PAGE2_DYNAMIC   (1 << 13)
#define SIP_PAGE2_FLAGS_TO_COPY
#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 10)
#define SIP_PAGE2_INC_RINGING   (1 << 19)
#define SIP_PAGE2_OUTGOING_CALL   (1 << 27)
#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)
#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)
#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)
#define SIP_PAGE2_RTUPDATE   (1 << 1)
#define SIP_PAGE2_SELFDESTRUCT   (1 << 14)
#define SIP_PAGE2_STATECHANGEQUEUE   (1 << 9)
#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)
#define SIP_PAGE2_T38SUPPORT   (7 << 20)
#define SIP_PAGE2_T38SUPPORT_RTP   (2 << 20)
#define SIP_PAGE2_T38SUPPORT_TCP   (4 << 20)
#define SIP_PAGE2_T38SUPPORT_UDPTL   (1 << 20)
#define SIP_PAGE2_UDPTL_DESTINATION   (1 << 28)
#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)
#define SIP_PENDINGBYE   (1 << 6)
#define SIP_PKT_DEBUG   (1 << 0)
#define SIP_PKT_IGNORE   (1 << 2)
#define SIP_PKT_IGNORE_REQ   (1 << 4)
#define SIP_PKT_IGNORE_RESP   (1 << 3)
#define SIP_PKT_WITH_TOTAG   (1 << 1)
#define SIP_PROG_INBAND   (3 << 25)
#define SIP_PROG_INBAND_NEVER   (0 << 25)
#define SIP_PROG_INBAND_NO   (1 << 25)
#define SIP_PROG_INBAND_YES   (2 << 25)
#define SIP_PROGRESS_SENT   (1 << 4)
#define SIP_PROMISCREDIR   (1 << 8)
#define SIP_REALTIME   (1 << 11)
#define SIP_REINVITE   (7 << 20)
#define SIP_REINVITE_UPDATE   (4 << 20)
#define SIP_RINGING   (1 << 3)
#define SIP_SENDRPID   (1 << 29)
#define SIP_TRANS_TIMEOUT   32000
#define SIP_TRUSTRPID   (1 << 9)
#define SIP_USECLIENTCODE   (1 << 12)
#define SIP_USEREQPHONE   (1 << 10)
#define SIPBUFSIZE   512
#define sipdebug   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG)
#define sipdebug_config   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG)
#define sipdebug_console   ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE)
#define STANDARD_SIP_PORT   5060
 Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
#define SUPPORTED   1
#define SUPPORTED_EXTENSIONS   "replaces"
 SIP Extensions we support.
#define T38FAX_FILL_BIT_REMOVAL   (1 << 0)
#define T38FAX_RATE_12000   (1 << 12)
#define T38FAX_RATE_14400   (1 << 13)
#define T38FAX_RATE_2400   (1 << 8)
#define T38FAX_RATE_4800   (1 << 9)
#define T38FAX_RATE_7200   (1 << 10)
#define T38FAX_RATE_9600   (1 << 11)
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF   (1 << 3)
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)
#define T38FAX_TRANSCODING_JBIG   (1 << 2)
#define T38FAX_TRANSCODING_MMR   (1 << 1)
#define T38FAX_UDP_EC_FEC   (1 << 4)
#define T38FAX_UDP_EC_NONE   (0 << 4)
#define T38FAX_UDP_EC_REDUNDANCY   (2 << 4)
#define T38FAX_VERSION   (3 << 6)
#define T38FAX_VERSION_0   (0 << 6)
#define T38FAX_VERSION_1   (1 << 6)
#define TRUE   1
#define UNLINK(element, head, prev)
#define VIDEO_CODEC_MASK   0x1fc0000
#define XMIT_ERROR   -2

Enumerations

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

Functions

static const char * __get_header (const struct sip_request *req, const char *name, int *start)
static void __reg_module (void)
static int __set_address_from_contact (const char *fullcontact, struct sockaddr_in *sin)
static void __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acknowledges receipt of a packet and stops retransmission called with p locked.
static int __sip_autodestruct (const void *data)
 Kill a SIP dialog (called by scheduler).
static int __sip_destroy (struct sip_pvt *p, int lockowner)
 Execute destruction of SIP dialog structure, release memory.
static int __sip_do_register (struct sip_registry *r)
 Register with SIP proxy.
static void __sip_pretend_ack (struct sip_pvt *p)
 Pretend to ack all packets called with p locked.
static int __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod)
 Transmit packet with retransmits.
static int __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acks receipt of packet, keep it around (used for provisional responses).
static int __sip_show_channels (int fd, int argc, char *argv[], int subscriptions)
 SIP show channels CLI (main function).
static int __sip_xmit (struct sip_pvt *p, char *data, int len)
 Transmit SIP message.
static int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Base transmit response function.
static 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_digit (struct sip_request *req, char digit, unsigned int duration)
 Add DTMF INFO tone to sip message.
static int add_header (struct sip_request *req, const char *var, const char *value)
 Add header to SIP message.
static int add_header_contentLength (struct sip_request *req, int len)
 Add 'Content-Length' header to SIP message.
static int add_line (struct sip_request *req, const char *line)
 Add content (not header) to SIP message.
static void add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug)
 Add RFC 2833 DTMF offer to SDP.
static struct sip_authadd_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno)
 Add realm authentication in list.
static void add_route (struct sip_request *req, struct sip_route *route)
 Add route header into request per learned route.
static enum sip_result add_sdp (struct sip_request *resp, struct sip_pvt *p)
 Add Session Description Protocol message.
static int add_sip_domain (const char *domain, const enum domain_mode mode, const char *context)
 Add SIP domain to list of domains we are responsible for.
static int add_t38_sdp (struct sip_request *resp, struct sip_pvt *p)
 Add T.38 Session Description Protocol message.
static int add_text (struct sip_request *req, const char *text)
 Add text body to SIP message.
static int add_vidupdate (struct sip_request *req)
 add XML encoded media control with update
static void append_date (struct sip_request *req)
 Append date to SIP message.
static void append_history_full (struct sip_pvt *p, const char *fmt,...)
 Append to SIP dialog history with arg list.
static void 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)
 Build peer from configuration (file or realtime static/dynamic).
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 Build reply digest.
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 Build route list from Record-Route header.
static void build_rpid (struct sip_pvt *p)
 Build the Remote Party-ID & From using callingpres options.
static struct sip_userbuild_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
 Initiate a SIP user structure from configuration (configuration or realtime).
static void build_via (struct sip_pvt *p)
 Build a Via header for a request.
static int cb_extensionstate (char *context, char *exten, int state, void *data)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem.
static void change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
 Change hold state for a call.
static enum check_auth_result check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore)
 Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
static void check_auth_buf_init (void)
static void check_pendings (struct sip_pvt *p)
 Check pending actions on SIP call.
static int check_sip_domain (const char *domain, char *context, size_t len)
 check_sip_domain: Check if domain part of uri is local to our server
static int check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin)
 Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
static enum check_auth_result check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer)
 Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
static void check_via (struct sip_pvt *p, const struct sip_request *req)
 check Via: header for hostname, port and rport request/answer
static void cleanup_stale_contexts (char *new, char *old)
 Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
static int clear_realm_authentication (struct sip_auth *authlist)
 Clear realm authentication list (at reload).
static void clear_sip_domains (void)
 Clear our domain list (at reload).
static char * complete_sip_debug_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip debug peer' CLI.
static char * complete_sip_peer (const char *word, int state, int flags2)
 Do completion on peer name.
static char * complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip prune realtime peer' CLI.
static char * complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip prune realtime user' CLI.
static char * complete_sip_show_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show peer' CLI.
static char * complete_sip_show_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show user' CLI.
static char * complete_sip_user (const char *word, int state, int flags2)
 Do completion on user name.
static char * complete_sipch (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show channel' CLI.
static char * complete_sipnotify (const char *line, const char *word, int pos, int state)
 Support routine for 'sip notify' CLI.
static int copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy all headers from one request to another.
static int copy_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy one header field from one request to another.
static void copy_request (struct sip_request *dst, const struct sip_request *src)
 copy SIP request (mostly used to save request for responses)
static int copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy SIP VIA Headers from the request to the response.
static int create_addr (struct sip_pvt *dialog, const char *opeer)
 create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
static int create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer)
 Create address structure from peer reference. return -1 on error, 0 on success.
static void destroy_association (struct sip_peer *peer)
 Remove registration data from realtime database or AST/DB when registration expires.
static int determine_firstline_parts (struct sip_request *req)
 Parse first line of incoming SIP request.
static void * do_monitor (void *data)
 The SIP monitoring thread.
static int do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init)
 Add authentication on outbound SIP packet.
static int do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader)
 Authenticate for outbound registration.
static void do_setnat (struct sip_pvt *p, int natflags)
 Set nat mode on the various data sockets.
static int does_peer_need_mwi (struct sip_peer *peer)
 Check whether peer needs a new MWI notification check.
static const char * domain_mode_to_text (const enum domain_mode mode)
 Print domain mode to cli.
static const char * dtmfmode2str (int mode)
 Convert DTMF mode to printable string.
static int expire_register (const void *data)
 Expire registration of SIP peer.
static void extract_uri (struct sip_pvt *p, struct sip_request *req)
 Check Contact: URI of SIP message.
static const char * find_alias (const char *name, const char *_default)
 Find compressed SIP alias.
static struct sip_pvtfind_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
 Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
static const char * find_closing_quote (const char *start, const char *lim)
 Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.
static struct sip_peerfind_peer (const char *peer, struct sockaddr_in *sin, int realtime, int devstate_only)
 Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
static struct sip_authfind_realm_authentication (struct sip_auth *authlist, const char *realm)
 Find authentication for a specific realm.
static int find_sdp (struct sip_request *req)
 Determine whether a SIP message contains an SDP in its body.
static int find_sip_method (const char *msg)
 find_sip_method: Find SIP method from header
static struct cfsubscription_typesfind_subscription_type (enum subscriptiontype subtype)
 Find subscription type in array.
static struct sip_userfind_user (const char *name, int realtime)
 Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
static void free_old_route (struct sip_route *route)
 Remove route from route list.
static int func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 Dial plan function to check if domain is local.
static int func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
 Read SIP header (dialplan function).
static int function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 ${SIPCHANINFO()} Dialplan function - reads sip channel data
static int function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 ${SIPPEER()} Dialplan function - reads peer data
static char * generate_random_string (char *buf, size_t size)
 Generate 32 byte random string for callid's etc.
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 Call transfer support (old way, deprecated by the IETF)--.
static char * get_body (struct sip_request *req, char *name)
 Get a specific line from the message body.
static char * get_body_by_line (const char *line, const char *name, int nameLen)
 Reads one line of SIP message body.
static char * get_calleridname (const char *input, char *output, size_t outputsize)
 Get caller id name from SIP headers.
static int get_destination (struct sip_pvt *p, struct sip_request *oreq)
 Find out who the call is for We use the INVITE uri to find out.
static const char * get_header (const struct sip_request *req, const char *name)
 Get header from SIP request.
static char * get_in_brackets (char *tmp)
 Pick out text in brackets from character string.
static int get_msg_text (char *buf, int len, struct sip_request *req)
 Get text out of a SIP MESSAGE packet.
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq)
 Get referring dnis.
static int get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req)
 Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
static int get_rpid_num (const char *input, char *output, int maxlen)
 Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found.
static const char * get_sdp (struct sip_request *req, const char *name)
 Get a line from an SDP message body.
static const char * get_sdp_iterate (int *start, struct sip_request *req, const char *name)
 Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.
static struct sip_pvtget_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag)
 Lock interface lock and find matching pvt lock.
static const char * gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
 Get tag from packet.
static int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 Handle flag-type options common to configuration of devices - users and peers.
static int handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin)
 Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer.
static int handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
 Handle incoming SIP requests (methods).
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req)
 Handle incoming BYE request.
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req)
 Handle incoming CANCEL request.
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 Receive SIP INFO Message.
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock)
 Handle incoming INVITE request.
static int handle_request_message (struct sip_pvt *p, struct sip_request *req)
 Handle incoming MESSAGE request.
static int handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
 Handle incoming notifications.
static int handle_request_options (struct sip_pvt *p, struct sip_request *req)
 Handle incoming OPTIONS request.
static int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock)
static int handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e)
 Handle incoming REGISTER request.
static int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
 Handle incoming SUBSCRIBE request.
static void handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 Handle SIP response in dialogue.
static void handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
 Handle SIP response to INVITE dialogue.
static void handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req)
 Handle qualification responses (OPTIONS).
static void handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
static int handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno)
 Handle responses on REGISTER to services.
static const char * hangup_cause2sip (int cause)
 Convert Asterisk hangup causes to SIP codes.
static int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes.
static int init_req (struct sip_request *req, int sipmethod, const char *recip)
 Initialize SIP request.
static int init_resp (struct sip_request *resp, const char *msg)
 Initialize SIP response, based on SIP request.
static void initialize_initreq (struct sip_pvt *p, struct sip_request *req)
 Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
static void initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod)
 Initiate new SIP request to peer/user.
static const char * insecure2str (int port, int invite)
 Convert Insecure setting to printable string.
static void list_route (struct sip_route *route)
 List all routes - mostly for debugging.
static int load_module (void)
 PBX load module - initialization.
static int local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno)
 Find all call legs and bridge transferee with target called from handle_request_refer.
static int lws2sws (char *msgbuf, int len)
 Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
static void make_our_tag (char *tagbuf, size_t len)
 Make our SIP dialog tag.
static int manager_sip_show_peer (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sip_show_peers (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int method_match (enum sipmethod id, const char *name)
 returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send
static char * nat2str (int nat)
 Convert NAT setting to text string.
static void parse_copy (struct sip_request *dst, const struct sip_request *src)
 Copy SIP request, parse it.
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req)
 Parse 302 Moved temporalily response.
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 Save contact header for 200 OK on INVITE.
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
 Parse contact header and save registration (peer registration).
static int parse_request (struct sip_request *req)
 Parse a SIP message.
static unsigned int parse_sip_options (struct sip_pvt *pvt, const char *supported)
 Parse supported header in incoming packet.
static int peer_status (struct sip_peer *peer, char *status, int statuslen)
 Report Peer status in character string.
static void print_codec_to_cli (int fd, struct ast_codec_pref *pref)
 Print codec list from preference to CLI/manager.
static void print_group (int fd, ast_group_t group, int crlf)
 Print call group and pickup group.
static 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 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)
 Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
static struct sip_userrealtime_user (const char *username)
 Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).
static void receive_message (struct sip_pvt *p, struct sip_request *req)
 Receive SIP MESSAGE method messages.
static char * referstatus2str (enum referstatus rstatus)
 Convert transfer status to string.
static void reg_source_db (struct sip_peer *peer)
 Get registration details from Asterisk DB.
static void register_peer_exten (struct sip_peer *peer, int onoff)
 Automatically add peer extension to dial plan.
static enum check_auth_result register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri)
 Verify registration of user
  • Registration is done in several steps, first a REGISTER without auth to get a challenge (nonce) then a second one with auth
  • Registration requests are only matched with peers that are marked as "dynamic".

static char * regstate2str (enum sipregistrystate regstate)
 Convert registration state status to string.
static int reload (void)
 Part of Asterisk module interface.
static int reload_config (enum channelreloadreason reason)
 Re-read SIP.conf config file.
static int reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
 reply to authentication for outbound registrations
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
 Initialize a SIP request message (not the initial one in a dialog).
static int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Prepare SIP response packet.
static int restart_monitor (void)
 Start the channel monitor thread.
static int retrans_pkt (const void *data)
 Retransmit SIP message if no answer (Called from scheduler).
static int scheduler_process_request_queue (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_peer_defaults (struct sip_peer *peer)
 Set peer defaults before configuring specific configurations.
static int sip_addheader (struct ast_channel *chan, void *data)
 Add a SIP header to an outbound INVITE.
static int sip_addrcmp (char *name, struct sockaddr_in *sin)
 Support routine for find_peer.
static struct sip_pvtsip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method)
 Allocate SIP_PVT structure and set defaults.
static void sip_alreadygone (struct sip_pvt *dialog)
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
static int sip_call (struct ast_channel *ast, char *dest, int timeout)
 Initiate SIP call from PBX used from the dial() application.
static int sip_cancel_destroy (struct sip_pvt *p)
 Cancel destruction of SIP dialog.
static int sip_debug_test_addr (const struct sockaddr_in *addr)
 See if we pass debug IP filter.
static int sip_debug_test_pvt (struct sip_pvt *p)
 Test PVT for debugging output.
static void sip_destroy (struct sip_pvt *p)
 Destroy SIP call structure.
static void sip_destroy_peer (struct sip_peer *peer)
 Destroy peer object from memory.
static void sip_destroy_user (struct sip_user *user)
 Remove user object from in-memory storage.
static int sip_devicestate (void *data)
 Part of PBX channel interface.
static int sip_do_debug (int fd, int argc, char *argv[])
 Turn on SIP debugging (CLI command).
static int sip_do_debug_deprecated (int fd, int argc, char *argv[])
static int sip_do_debug_ip (int fd, int argc, char *argv[])
 Enable SIP Debugging in CLI.
static int sip_do_debug_peer (int fd, int argc, char *argv[])
 sip_do_debug_peer: Turn on SIP debugging with peer mask
static int sip_do_history (int fd, int argc, char *argv[])
 Enable SIP History logging (CLI).
static int sip_do_reload (enum channelreloadreason reason)
 Reload module.
static int sip_dtmfmode (struct ast_channel *chan, void *data)
 Set the DTMFmode for an outbound SIP call (application).
static void sip_dump_history (struct sip_pvt *dialog)
 Dump SIP history to debug log file at end of lifespan for SIP dialog.
static int sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
static int sip_get_codec (struct ast_channel *chan)
 Return SIP UA's codec (part of the RTP interface).
static enum ast_rtp_get_result sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite audio (part of RTP interface).
static struct ast_udptlsip_get_udptl_peer (struct ast_channel *chan)
static enum ast_rtp_get_result sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite video (part of RTP interface).
static int sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite)
 Handle T38 reinvite.
static int sip_hangup (struct ast_channel *ast)
 sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
static int sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
static const char * sip_nat_mode (const struct sip_pvt *p)
 Display SIP nat mode.
static struct ast_channelsip_new (struct sip_pvt *i, int state, const char *title)
 Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
static int sip_no_debug (int fd, int argc, char *argv[])
 Disable SIP Debugging in CLI.
static int sip_no_debug_deprecated (int fd, int argc, char *argv[])
static int sip_no_history (int fd, int argc, char *argv[])
 Disable SIP History logging (CLI).
static int sip_notify (int fd, int argc, char *argv[])
 Cli command to send SIP notify to peer.
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno)
 Park a call using the subsystem in res_features.c This is executed in a separate thread.
static void * sip_park_thread (void *stuff)
 Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
static void sip_peer_hold (struct sip_pvt *p, int hold)
 Change onhold state of a peer using a pvt structure.
static void sip_poke_all_peers (void)
 Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
static int sip_poke_noanswer (const void *data)
 React to lack of answer to Qualify poke.
static int sip_poke_peer (struct sip_peer *peer)
 Check availability of peer, also keep NAT open.
static int sip_poke_peer_s (const void *data)
 Poke peer (send qualify to check if peer is alive and well).
static int sip_prune_realtime (int fd, int argc, char *argv[])
 Remove temporary realtime objects from memory (CLI).
static struct ast_framesip_read (struct ast_channel *ast)
 Read SIP RTP from channel.
static struct sockaddr_in * sip_real_dst (const struct sip_pvt *p)
 The real destination address for a write.
static int sip_refer_allocate (struct sip_pvt *p)
 Allocate SIP refer structure.
static int sip_reg_timeout (const void *data)
 Registration timeout, register again.
static int sip_register (char *value, int lineno)
 Parse register=> line in sip.conf and add to registry.
static void sip_registry_destroy (struct sip_registry *reg)
 Destroy registry object Objects created with the register= statement in static configuration.
static int sip_reinvite_retry (const void *data)
 Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
static int sip_reload (int fd, int argc, char *argv[])
 Force reload of module from cli.
static struct ast_channelsip_request_call (const char *type, int format, void *data, int *cause)
 PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
static int sip_reregister (const void *data)
 Update registration with SIP Proxy.
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network.
static void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog.
static void sip_send_all_registers (void)
 Send all known registrations.
static int sip_send_mwi_to_peer (struct sip_peer *peer)
 Send message waiting indication to alert peer that they've got voicemail.
static int sip_senddigit_begin (struct ast_channel *ast, char digit)
static int sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
static int sip_sendtext (struct ast_channel *ast, const char *text)
 Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 Set the RTP peer for this call.
static int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
static int sip_show_channel (int fd, int argc, char *argv[])
 Show details of one active dialog.
static int sip_show_channels (int fd, int argc, char *argv[])
 Show active SIP channels.
static int sip_show_domains (int fd, int argc, char *argv[])
 CLI command to list local domains.
static int sip_show_history (int fd, int argc, char *argv[])
 Show history details of one dialog.
static int sip_show_inuse (int fd, int argc, char *argv[])
 CLI Command to show calls within limits set by call_limit.
static int sip_show_objects (int fd, int argc, char *argv[])
 List all allocated SIP Objects (realtime or static).
static int sip_show_peer (int fd, int argc, char *argv[])
 Show one peer in detail.
static int sip_show_peers (int fd, int argc, char *argv[])
 CLI Show Peers command.
static int sip_show_registry (int fd, int argc, char *argv[])
 Show SIP Registry (registrations with other SIP proxies.
static int sip_show_settings (int fd, int argc, char *argv[])
 List global settings for the SIP channel.
static int sip_show_subscriptions (int fd, int argc, char *argv[])
 Show active SIP subscriptions.
static int sip_show_user (int fd, int argc, char *argv[])
 Show one user in detail.
static int sip_show_users (int fd, int argc, char *argv[])
 CLI Command 'SIP Show Users'.
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect.
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call.
static int sip_uri_cmp (const char *input1, const char *input2)
static int sip_uri_headers_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp
static int sip_uri_params_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP socket.
static 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, struct sip_request *req, int reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
static int transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration)
 Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request.
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init)
 Build REFER/INVITE/OPTIONS message and transmit it.
static int transmit_message_with_text (struct sip_pvt *p, const char *text)
 Transmit text with SIP MESSAGE method.
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
 Notify user of messages waiting in voicemail.
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate)
 Notify a transferring party of the status of transfer.
static int transmit_refer (struct sip_pvt *p, const char *dest)
 Transmit SIP REFER message (initiated by the transfer() dialplan application.
static int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA.
static int transmit_reinvite_with_sdp (struct sip_pvt *p)
 Transmit reinvite with SDP.
static int transmit_reinvite_with_t38_sdp (struct sip_pvt *p)
 Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path.
static int transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit SIP request, auth added.
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits.
static int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
static int transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
 Transmit response, no retransmits, using a temporary pvt structure.
static int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Append Accept header, content length before transmitting response.
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request.
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append date and content length before transmitting response.
static int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Used for 200 OK and 183 early media.
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_sip_request (struct sip_pvt *p, struct sip_request *req)
 Transmit SIP request unreliably (only used in sip_notify subsystem).
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem.
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
static int unload_module (void)
 PBX unload module API.
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted.
static void update_peer (struct sip_peer *p, int expiry)
 Update peer data in database (if used).

Variables

static struct 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 = "f450f61f60e761b3aa089ebed76ca8a5" , .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 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 char global_realm [MAXHOSTNAMELEN]
static int global_reg_timeout
static int global_regattempts_max
static char global_regcontext [AST_MAX_CONTEXT]
static int global_relaxdtmf
static int global_rtautoclear
static int global_rtpholdtimeout
static int global_rtpkeepalive
static int global_rtptimeout
static int global_t1min
static int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600
static unsigned int global_tos_audio
static unsigned int global_tos_sip
static unsigned int global_tos_video
static char global_useragent [AST_MAX_EXTENSION]
static char history_usage []
static struct sip_pvtiflist
 sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
static 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
static char notify_usage []
static int ourport
static struct sockaddr_in outboundproxyip
static int pedanticsipchecking
static struct ast_peer_list peerl
 The peer list: Peers and Friends.
static char prune_realtime_usage []
static int recordhistory
static struct c_referstatusstring referstatusstrings []
static struct ast_register_list regl
 The register list: Other SIP proxys we register with and place calls to.
static int regobjs = 0
static int rpeerobjs = 0
static int ruserobjs = 0
static struct sched_contextsched
static char show_channel_usage []
static char show_channels_usage []
static char show_domains_usage []
static char show_history_usage []
static char show_inuse_usage []
static char show_objects_usage []
static char show_peer_usage []
static char show_peers_usage []
static char show_reg_usage []
static char show_settings_usage []
static char show_subscriptions_usage []
static char show_user_usage []
static char show_users_usage []
static struct ast_custom_function sip_header_function
static struct cfsip_methods sip_methods []
static struct cfsip_options sip_options []
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
static 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"

SIP Methods we support.

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

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

#define CALLERID_UNKNOWN   "Unknown"

Definition at line 200 of file chan_sip.c.

Referenced by initreqprep().

#define CAN_CREATE_DIALOG   1

Definition at line 369 of file chan_sip.c.

#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD   2

Definition at line 370 of file chan_sip.c.

#define CAN_NOT_CREATE_DIALOG   0

Definition at line 368 of file chan_sip.c.

#define CHECK_AUTH_BUF_INITLEN   256

Definition at line 8569 of file chan_sip.c.

Referenced by check_auth().

#define DEC_CALL_LIMIT   0

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

Referenced by handle_response_invite(), and update_call_counter().

#define DEFAULT_ALLOW_EXT_DOM   TRUE

Definition at line 508 of file chan_sip.c.

#define DEFAULT_ALLOWGUEST   TRUE

Definition at line 502 of file chan_sip.c.

#define DEFAULT_AUTOCREATEPEER   FALSE

Definition at line 512 of file chan_sip.c.

#define DEFAULT_CALLERID   "asterisk"

Definition at line 499 of file chan_sip.c.

#define DEFAULT_COMPACTHEADERS   FALSE

Definition at line 504 of file chan_sip.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 495 of file chan_sip.c.

#define DEFAULT_DEFAULT_EXPIRY   120

Definition at line 172 of file chan_sip.c.

#define DEFAULT_EXPIRY   900

Expire slowly

Definition at line 189 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

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

#define DEFAULT_MAX_CALL_BITRATE   (384)

Max bitrate for video

Definition at line 515 of file chan_sip.c.

#define DEFAULT_MAX_EXPIRY   3600

Definition at line 174 of file chan_sip.c.

#define DEFAULT_MAX_FORWARDS   "70"

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

#define DEFAULT_MIN_EXPIRY   60

Definition at line 173 of file chan_sip.c.

#define DEFAULT_MOHINTERPRET   "default"

Definition at line 496 of file chan_sip.c.

#define DEFAULT_MOHSUGGEST   ""

Definition at line 497 of file chan_sip.c.

#define DEFAULT_MWITIME   10

Definition at line 501 of file chan_sip.c.

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

Definition at line 500 of file chan_sip.c.

#define DEFAULT_NOTIFYRINGING   TRUE

Definition at line 510 of file chan_sip.c.

#define DEFAULT_PEDANTIC   FALSE

Definition at line 511 of file chan_sip.c.

#define DEFAULT_QUALIFY   FALSE

Definition at line 513 of file chan_sip.c.

#define DEFAULT_REALM   "asterisk"

Definition at line 509 of file chan_sip.c.

#define DEFAULT_REGISTRATION_TIMEOUT   20

Definition at line 175 of file chan_sip.c.

#define DEFAULT_RETRANS   1000

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

Definition at line 206 of file chan_sip.c.

#define DEFAULT_SRVLOOKUP   TRUE

Recommended setting is ON

Definition at line 503 of file chan_sip.c.

#define DEFAULT_T1MIN   100

100 MS for minimal roundtrip time

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

#define DEFAULT_TRANS_TIMEOUT   -1

Definition at line 211 of file chan_sip.c.

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

#define DEFAULT_USERAGENT   "Asterisk PBX"

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

Definition at line 517 of file chan_sip.c.

#define DEFAULT_VMEXTEN   "asterisk"

Definition at line 498 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 181 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 183 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 187 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 180 of file chan_sip.c.

Referenced by handle_response_register().

#define FALSE   0

Definition at line 154 of file chan_sip.c.

#define FLAG_FATAL   (1 << 1)

Definition at line 1037 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), and retrans_pkt().

#define FLAG_RESPONSE   (1 << 0)

Definition at line 1036 of file chan_sip.c.

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

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

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

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

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

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

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

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

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

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

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

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

Referenced by __sip_show_channels().

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

#define INC_CALL_LIMIT   1

Definition at line 614 of file chan_sip.c.

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

#define INC_CALL_RINGING   3

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

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

#define IPTOS_MINCOST   0x02

Definition at line 167 of file chan_sip.c.

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

Definition at line 197 of file chan_sip.c.

#define MAX_AUTHTRIES   3

Try authentication three times, then fail

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

#define NO_RTP   0

Definition at line 236 of file chan_sip.c.

#define NOT_SUPPORTED   0

Definition at line 409 of file chan_sip.c.

#define RTP   1

Definition at line 235 of file chan_sip.c.

#define SDP_MAX_RTPMAP_CODECS   32

Maximum number of codecs allowed in received SDP

Definition at line 218 of file chan_sip.c.

Referenced by process_sdp().

#define SDP_SAMPLE_RATE (  )     8000

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

Definition at line 6578 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 721 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 762 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 750 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 751 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 736 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 737 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 741 of file chan_sip.c.

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

#define SIP_DTMF_INBAND   (1 << 16)

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

Definition at line 739 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 740 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 738 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 767 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 735 of file chan_sip.c.

#define SIP_G726_NONSTANDARD   (1 << 31)

Use non-standard packing for G726-32 data

Definition at line 765 of file chan_sip.c.

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

#define SIP_GOTREFER   (1 << 7)

Got a refer?

Definition at line 728 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 764 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 755 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 754 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 214 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 215 of file chan_sip.c.

Referenced by add_line(), and parse_request().

#define SIP_MAX_PACKET   4096

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

Definition at line 216 of file chan_sip.c.

#define SIP_NAT   (3 << 18)

four settings, uses two bits

Definition at line 743 of file chan_sip.c.

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

#define SIP_NAT_ALWAYS   (3 << 18)

NAT Both ROUTE and RFC3581

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

Referenced by handle_common_options(), and nat2str().

#define SIP_NAT_RFC3581   (1 << 18)

NAT RFC3581

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

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

#define SIP_NEEDDESTROY   (1 << 1)

if we need to be destroyed by the monitor thread

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

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

#define SIP_OPT_100REL   (1 << 1)

Definition at line 412 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)

Definition at line 414 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)

Definition at line 422 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)

Definition at line 423 of file chan_sip.c.

#define SIP_OPT_HISTINFO   (1 << 15)

Definition at line 426 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)

Definition at line 415 of file chan_sip.c.

#define SIP_OPT_NOREFERSUB   (1 << 14)

Definition at line 425 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)

Definition at line 416 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)

Definition at line 418 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)

Definition at line 417 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)

Definition at line 419 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)

Definition at line 411 of file chan_sip.c.

Referenced by handle_request_invite().

#define SIP_OPT_RESPRIORITY   (1 << 16)

Definition at line 427 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)

Definition at line 420 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)

Definition at line 421 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)

Definition at line 424 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)

Definition at line 413 of file chan_sip.c.

#define SIP_OUTGOING   (1 << 13)

Direction of the last transaction in this dialog

Definition at line 734 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 789 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 788 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 801 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 796 of file chan_sip.c.

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

#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)

23: Active hold

Definition at line 797 of file chan_sip.c.

Referenced by change_hold_state().

#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)

23: Inactive hold

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

Referenced by add_sdp(), and change_hold_state().

#define SIP_PAGE2_DEBUG   (3 << 11)

Definition at line 782 of file chan_sip.c.

#define SIP_PAGE2_DEBUG_CONFIG   (1 << 11)

Definition at line 783 of file chan_sip.c.

#define SIP_PAGE2_DEBUG_CONSOLE   (1 << 12)

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

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

#define SIP_PAGE2_IGNOREREGEXPIRE   (1 << 10)

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

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

#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)

25: ????

Definition at line 800 of file chan_sip.c.

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

#define SIP_PAGE2_RT_FROMCONTACT   (1 << 4)

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

Referenced by expire_register().

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)

Definition at line 774 of file chan_sip.c.

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

#define SIP_PAGE2_RTSAVE_SYSNAME   (1 << 5)

Definition at line 778 of file chan_sip.c.

Referenced by realtime_update_peer(), and sip_show_settings().

#define SIP_PAGE2_RTUPDATE   (1 << 1)

Definition at line 775 of file chan_sip.c.

Referenced by sip_show_settings(), and update_peer().

#define SIP_PAGE2_SELFDESTRUCT   (1 << 14)

Automatic peers need to destruct themselves

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

Referenced by cb_extensionstate(), and handle_response().

#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)

Only issue MWI notification if subscribed to

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

Referenced by create_addr_from_peer(), and sip_alloc().

#define SIP_PAGE2_T38SUPPORT_RTP   (2 << 20)

21: T38 Fax Passthrough Support (not implemented)

Definition at line 794 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 795 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 793 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 803 of file chan_sip.c.

Referenced by handle_common_options(), and process_sdp().

#define SIP_PAGE2_VIDEOSUPPORT   (1 << 15)

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

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

#define SIP_PKT_IGNORE_REQ   (1 << 4)

Req ignore - ???

Definition at line 815 of file chan_sip.c.

Referenced by handle_request().

#define SIP_PKT_IGNORE_RESP   (1 << 3)

Resp ignore - ???

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

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 25)

Definition at line 759 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 25)

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

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 8)

Promiscuous redirection

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

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

#define SIP_REINVITE   (7 << 20)

three bits used

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

Referenced by sip_indicate().

#define SIP_SENDRPID   (1 << 29)

Remote Party-ID Support

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

Referenced by sip_call(), and sip_sipredirect().

#define SIP_TRUSTRPID   (1 << 9)

Trust RPID headers?

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

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

#define SIPBUFSIZE   512

Definition at line 161 of file chan_sip.c.

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

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

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

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

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

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

#define SUPPORTED   1

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

Definition at line 408 of file chan_sip.c.

#define SUPPORTED_EXTENSIONS   "replaces"

SIP Extensions we support.

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

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_RATE_12000   (1 << 12)

12000 bps t38FaxRate

Definition at line 837 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_14400   (1 << 13)

14400 bps t38FaxRate This is default: NO MMR and JBIG trancoding, NO fill bit removal, transferredTCF TCF, UDP FEC, Version 0 and 9600 max fax rate

Definition at line 838 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_2400   (1 << 8)

2400 bps t38FaxRate

Definition at line 833 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_4800   (1 << 9)

4800 bps t38FaxRate

Definition at line 834 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_7200   (1 << 10)

7200 bps t38FaxRate

Definition at line 835 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_9600   (1 << 11)

9600 bps t38FaxRate

Definition at line 836 of file chan_sip.c.

Referenced by process_sdp(), and t38_get_rate().

#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF   (1 << 3)

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

Definition at line 823 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF   (0 << 3)

Definition at line 822 of file chan_sip.c.

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

#define T38FAX_TRANSCODING_JBIG   (1 << 2)

Default: 0 (unset)

Definition at line 820 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_TRANSCODING_MMR   (1 << 1)

Default: 0 (unset)

Definition at line 819 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_UDP_EC_FEC   (1 << 4)

Set for t38UDPFEC

Definition at line 826 of file chan_sip.c.

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

#define T38FAX_UDP_EC_NONE   (0 << 4)

two bits, if unset NO t38UDPEC field in T38 SDP

Definition at line 825 of file chan_sip.c.

Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().

#define T38FAX_UDP_EC_REDUNDANCY   (2 << 4)

Set for t38UDPRedundancy

Definition at line 827 of file chan_sip.c.

Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().

#define T38FAX_VERSION   (3 << 6)

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

Definition at line 829 of file chan_sip.c.

Referenced by add_t38_sdp().

#define T38FAX_VERSION_0   (0 << 6)

Version 0

Definition at line 830 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define T38FAX_VERSION_1   (1 << 6)

Version 1

Definition at line 831 of file chan_sip.c.

Referenced by add_t38_sdp(), and process_sdp().

#define TRUE   1

Definition at line 158 of file chan_sip.c.

#define UNLINK ( element,
head,
prev   ) 

--- some list management macros.

Definition at line 1620 of file chan_sip.c.

Referenced by __sip_ack(), and __sip_destroy().

#define VIDEO_CODEC_MASK   0x1fc0000

Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO

Definition at line 165 of file chan_sip.c.

#define XMIT_ERROR   -2

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

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

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

00684                  {
00685    SIP_DOMAIN_AUTO,     /*!< This domain is auto-configured */
00686    SIP_DOMAIN_CONFIG,      /*!< This domain is from configuration */
00687 };

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

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

enum parse_register_result

Enumerator:
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

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

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

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

00338                    {
00339    PROXY_AUTH,
00340    WWW_AUTH,
00341 };

enum sip_result

Enumerator:
AST_SUCCESS 
AST_FAILURE 

Definition at line 247 of file chan_sip.c.

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

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

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

enum sipregistrystate

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

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

Definition at line 357 of file chan_sip.c.

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

enum subscriptiontype

Enumerator:
NONE 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 
MWI_NOTIFICATION 

Definition at line 288 of file chan_sip.c.

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

enum t38state

T38 States for a call.

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

Definition at line 848 of file chan_sip.c.

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

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

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

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

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


Function Documentation

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

Definition at line 4334 of file chan_sip.c.

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

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

static void __reg_module ( void   )  [static]

Definition at line 18939 of file chan_sip.c.

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

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

08202 {
08203    struct hostent *hp;
08204    struct ast_hostent ahp;
08205    int port;
08206    char *c, *host, *pt;
08207    char contact_buf[256];
08208    char *contact;
08209 
08210    /* Work on a copy */
08211    ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
08212    contact = contact_buf;
08213 
08214    /* Make sure it's a SIP URL */
08215    if (strncasecmp(contact, "sip:", 4)) {
08216       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
08217    } else
08218       contact += 4;
08219 
08220    /* Ditch arguments */
08221    /* XXX this code is replicated also shortly below */
08222 
08223    /* Grab host */
08224    host = strchr(contact, '@');
08225    if (!host) {   /* No username part */
08226       host = contact;
08227       c = NULL;
08228    } else {
08229       *host++ = '\0';
08230    }
08231    pt = strchr(host, ':');
08232    if (pt) {
08233       *pt++ = '\0';
08234       port = atoi(pt);
08235    } else
08236       port = STANDARD_SIP_PORT;
08237 
08238    contact = strsep(&contact, ";"); /* trim ; and beyond in username part */
08239    host = strsep(&host, ";");    /* trim ; and beyond in host/domain part */
08240 
08241    /* XXX This could block for a long time XXX */
08242    /* We should only do this if it's a name, not an IP */
08243    hp = ast_gethostbyname(host, &ahp);
08244    if (!hp)  {
08245       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
08246       return -1;
08247    }
08248    sin->sin_family = AF_INET;
08249    memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
08250    sin->sin_port = htons(port);
08251 
08252    return 0;
08253 }

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

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

Definition at line 2167 of file chan_sip.c.

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

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

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

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

Kill a SIP dialog (called by scheduler).

Definition at line 2083 of file chan_sip.c.

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

Referenced by sip_scheddestroy().

02084 {
02085    struct sip_pvt *p = (struct sip_pvt *)data;
02086 
02087    /* If this is a subscription, tell the phone that we got a timeout */
02088    if (p->subscribed) {
02089       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
02090       p->subscribed = NONE;
02091       append_history(p, "Subscribestatus", "timeout");
02092       if (option_debug > 2)
02093          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
02094       return 10000;  /* Reschedule this destruction so that we know that it's gone */
02095    }
02096 
02097    /* If there are packets still waiting for delivery, delay the destruction */
02098    /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block
02099    * of code make a sort of "safety relief valve", that allows sip channels
02100    * that were created via INVITE, then thru some sequence were CANCELED,
02101    * to die, rather than infinitely be rescheduled */
02102    if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) {
02103       if (option_debug > 2)
02104          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
02105       append_history(p, "ReliableXmit", "timeout");
02106       if (p->method == SIP_CANCEL || p->method == SIP_BYE) {
02107          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
02108       }
02109       return 10000;
02110    }
02111 
02112    /* If we're destroying a subscription, dereference peer object too */
02113    if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
02114       ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer);
02115 
02116    /* Reset schedule ID */
02117    p->autokillid = -1;
02118 
02119    if (option_debug)
02120       ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
02121    append_history(p, "AutoDestroy", "%s", p->callid);
02122    if (p->owner) {
02123       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
02124       ast_queue_hangup(p->owner);
02125    } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
02126       if (option_debug > 2)
02127          ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid);
02128       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
02129       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
02130    } else
02131       sip_destroy(p);
02132    return 0;
02133 }

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

Execute destruction of SIP dialog structure, release memory.

Definition at line 3102 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_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, 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, sip_pkt::retransid, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), ast_channel::tech_pvt, UNLINK, update_call_counter(), and sip_pvt::vrtp.

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

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

static int __sip_do_register ( struct sip_registry r  )  [static]

Register with SIP proxy.

Definition at line 7634 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

07635 {
07636    int res;
07637 
07638    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
07639    return res;
07640 }

static void __sip_pretend_ack ( struct sip_pvt p  )  [static]

Pretend to ack all packets called with p locked.

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

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

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

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

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

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

Referenced by handle_response().

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

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

SIP show channels CLI (main function).

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

11036 {
11037 #define FORMAT3L "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s %6d\n"
11038 #define FORMAT3H "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s %-6s\n"
11039 #define FORMAT2  "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-15.15s  %-7.7s  %-15.15s\n"
11040 #define FORMAT   "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-15.15s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
11041    struct sip_pvt *cur;
11042    int numchans = 0;
11043    char *referstatus = NULL;
11044 
11045    if (argc != 3)
11046       return RESULT_SHOWUSAGE;
11047    ast_mutex_lock(&iflock);
11048    cur = iflist;
11049    if (!subscriptions)
11050       ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
11051    else 
11052       ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry");
11053    for (; cur; cur = cur->next) {
11054       referstatus = "";
11055       if (cur->refer) { /* SIP transfer in progress */
11056          referstatus = referstatus2str(cur->refer->status);
11057       }
11058       if (cur->subscribed == NONE && !subscriptions) {
11059          char formatbuf[SIPBUFSIZE/2];
11060          ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 
11061             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
11062             cur->callid, 
11063             cur->ocseq, cur->icseq,
11064             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
11065             ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No",
11066             ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
11067             cur->lastmsg ,
11068             referstatus
11069          );
11070          numchans++;
11071       }
11072       if (cur->subscribed != NONE && subscriptions) {
11073          ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr),
11074             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
11075                cur->callid,
11076             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
11077             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
11078             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
11079             subscription_type2str(cur->subscribed),
11080             cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>",
11081             cur->expiry
11082 );
11083          numchans++;
11084       }
11085    }
11086    ast_mutex_unlock(&iflock);
11087    if (!subscriptions)
11088       ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : "");
11089    else
11090       ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : "");
11091    return RESULT_SUCCESS;
11092 #undef FORMAT
11093 #undef FORMAT2
11094 #undef FORMAT3
11095 }

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

Transmit SIP message.

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

01788 {
01789    int res;
01790    const struct sockaddr_in *dst = sip_real_dst(p);
01791    res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
01792 
01793    if (res == -1) {
01794       switch (errno) {
01795       case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
01796       case EHOSTUNREACH:   /* Host can't be reached */
01797       case ENETDOWN:       /* Inteface down */
01798       case ENETUNREACH: /* Network failure */
01799       case ECONNREFUSED:      /* ICMP port unreachable */ 
01800          res = XMIT_ERROR; /* Don't bother with trying to transmit again */
01801       }
01802    }
01803    if (res != len)
01804       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));
01805    return res;
01806 }

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

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

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

06170 {
06171    struct sip_request resp;
06172    int seqno = 0;
06173 
06174    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
06175       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
06176       return -1;
06177    }
06178    respprep(&resp, p, msg, req);
06179    add_header_contentLength(&resp, 0);
06180    /* If we are cancelling an incoming invite for some reason, add information
06181       about the reason why we are doing this in clear text */
06182    if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
06183       char buf[10];
06184 
06185       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
06186       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
06187       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
06188    }
06189    return send_response(p, &resp, reliable, seqno);
06190 }

static void __unreg_module ( void   )  [static]

Definition at line 18939 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 10593 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_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().

10594 {
10595    char status[30] = "";
10596    char cbuf[256];
10597    struct sip_peer *peer;
10598    char codec_buf[512];
10599    struct ast_codec_pref *pref;
10600    struct ast_variable *v;
10601    struct sip_auth *auth;
10602    int x = 0, codec = 0, load_realtime;
10603    int realtimepeers;
10604 
10605    realtimepeers = ast_check_realtime("sippeers");
10606 
10607    if (argc < 4)
10608       return RESULT_SHOWUSAGE;
10609 
10610    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10611    peer = find_peer(argv[3], NULL, load_realtime, 0);
10612    if (s) {    /* Manager */
10613       if (peer) {
10614          const char *id = astman_get_header(m,"ActionID");
10615 
10616          astman_append(s, "Response: Success\r\n");
10617          if (!ast_strlen_zero(id))
10618             astman_append(s, "ActionID: %s\r\n",id);
10619       } else {
10620          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]);
10621          astman_send_error(s, m, cbuf);
10622          return 0;
10623       }
10624    }
10625    if (peer && type==0 ) { /* Normal listing */
10626       ast_cli(fd,"\n\n");
10627       ast_cli(fd, "  * Name       : %s\n", peer->name);
10628       if (realtimepeers) { /* Realtime is enabled */
10629          ast_cli(fd, "  Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No");
10630       }
10631       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
10632       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
10633       for (auth = peer->auth; auth; auth = auth->next) {
10634          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
10635          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
10636       }
10637       ast_cli(fd, "  Context      : %s\n", peer->context);
10638       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
10639       ast_cli(fd, "  Language     : %s\n", peer->language);
10640       if (!ast_strlen_zero(peer->accountcode))
10641          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
10642       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
10643       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
10644       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
10645       if (!ast_strlen_zero(peer->fromuser))
10646          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
10647       if (!ast_strlen_zero(peer->fromdomain))
10648          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
10649       ast_cli(fd, "  Callgroup    : ");
10650       print_group(fd, peer->callgroup, 0);
10651       ast_cli(fd, "  Pickupgroup  : ");
10652       print_group(fd, peer->pickupgroup, 0);
10653       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
10654       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
10655       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
10656       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
10657       ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No"));
10658       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
10659       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
10660       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
10661       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)));
10662       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10663       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
10664       ast_cli(fd, "  T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No");
10665 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10666       ast_cli(fd, "  T38 pt RTP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No");
10667       ast_cli(fd, "  T38 pt TCP   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No");
10668 #endif
10669       ast_cli(fd, "  CanReinvite  : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No");
10670       ast_cli(fd, "  PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No");
10671       ast_cli(fd, "  User=Phone   : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No");
10672       ast_cli(fd, "  Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No");
10673       ast_cli(fd, "  Trust RPID   : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No");
10674       ast_cli(fd, "  Send RPID    : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No");
10675       ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10676       ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10677 
10678       /* - is enumerated */
10679       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10680       ast_cli(fd, "  LastMsg      : %d\n", peer->lastmsg);
10681       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
10682       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));
10683       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
10684       if (!ast_strlen_zero(global_regcontext))
10685          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
10686       ast_cli(fd, "  Def. Username: %s\n", peer->username);
10687       ast_cli(fd, "  SIP Options  : ");
10688       if (peer->sipoptions) {
10689          int lastoption = -1;
10690          for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
10691             if (sip_options[x].id != lastoption) {
10692                if (peer->sipoptions & sip_options[x].id)
10693                   ast_cli(fd, "%s ", sip_options[x].text);
10694                lastoption = x;
10695             }
10696          }
10697       } else
10698          ast_cli(fd, "(none)");
10699 
10700       ast_cli(fd, "\n");
10701       ast_cli(fd, "  Codecs       : ");
10702       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10703       ast_cli(fd, "%s\n", codec_buf);
10704       ast_cli(fd, "  Codec Order  : (");
10705       print_codec_to_cli(fd, &peer->prefs);
10706       ast_cli(fd, ")\n");
10707 
10708       ast_cli(fd, "  Auto-Framing:  %s \n", peer->autoframing ? "Yes" : "No");
10709       ast_cli(fd, "  Status       : ");
10710       peer_status(peer, status, sizeof(status));
10711       ast_cli(fd, "%s\n",status);
10712       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
10713       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
10714       if (peer->chanvars) {
10715          ast_cli(fd, "  Variables    :\n");
10716          for (v = peer->chanvars ; v ; v = v->next)
10717             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10718       }
10719       ast_cli(fd,"\n");
10720       ASTOBJ_UNREF(peer,sip_destroy_peer);
10721    } else  if (peer && type == 1) { /* manager listing */
10722       char buf[256];
10723       astman_append(s, "Channeltype: SIP\r\n");
10724       astman_append(s, "ObjectName: %s\r\n", peer->name);
10725       astman_append(s, "ChanObjectType: peer\r\n");
10726       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
10727       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
10728       astman_append(s, "Context: %s\r\n", peer->context);
10729       astman_append(s, "Language: %s\r\n", peer->language);
10730       if (!ast_strlen_zero(peer->accountcode))
10731          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
10732       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
10733       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
10734       if (!ast_strlen_zero(peer->fromuser))
10735          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
10736       if (!ast_strlen_zero(peer->fromdomain))
10737          astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
10738       astman_append(s, "Callgroup: ");
10739       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup));
10740       astman_append(s, "Pickupgroup: ");
10741       astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup));
10742       astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
10743       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
10744       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
10745       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
10746       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
10747       astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N"));
10748       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
10749       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
10750       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)));
10751       astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
10752       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
10753       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
10754       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
10755       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
10756       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
10757 
10758       /* - is enumerated */
10759       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
10760       astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg);
10761       astman_append(s, "ToHost: %s\r\n", peer->tohost);
10762       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));
10763       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));
10764       astman_append(s, "Default-Username: %s\r\n", peer->username);
10765       if (!ast_strlen_zero(global_regcontext))
10766          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
10767       astman_append(s, "Codecs: ");
10768       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
10769       astman_append(s, "%s\r\n", codec_buf);
10770       astman_append(s, "CodecOrder: ");
10771       pref = &peer->prefs;
10772       for(x = 0; x < 32 ; x++) {
10773          codec = ast_codec_pref_index(pref,x);
10774          if (!codec)
10775             break;
10776          astman_append(s, "%s", ast_getformatname(codec));
10777          if (x < 31 && ast_codec_pref_index(pref,x+1))
10778             astman_append(s, ",");
10779       }
10780 
10781       astman_append(s, "\r\n");
10782       astman_append(s, "Status: ");
10783       peer_status(peer, status, sizeof(status));
10784       astman_append(s, "%s\r\n", status);
10785       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
10786       astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact);
10787       if (peer->chanvars) {
10788          for (v = peer->chanvars ; v ; v = v->next) {
10789             astman_append(s, "ChanVariable:\n");
10790             astman_append(s, " %s,%s\r\n", v->name, v->value);
10791          }
10792       }
10793 
10794       ASTOBJ_UNREF(peer,sip_destroy_peer);
10795 
10796    } else {
10797       ast_cli(fd,"Peer %s not found.\n", argv[3]);
10798       ast_cli(fd,"\n");
10799    }
10800 
10801    return RESULT_SUCCESS;
10802 }

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

10144 {
10145    regex_t regexbuf;
10146    int havepattern = FALSE;
10147 
10148 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n"
10149 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n"
10150 
10151    char name[256];
10152    int total_peers = 0;
10153    int peers_mon_online = 0;
10154    int peers_mon_offline = 0;
10155    int peers_unmon_offline = 0;
10156    int peers_unmon_online = 0;
10157    const char *id;
10158    char idtext[256] = "";
10159    int realtimepeers;
10160 
10161    realtimepeers = ast_check_realtime("sippeers");
10162 
10163    if (s) { /* Manager - get ActionID */
10164       id = astman_get_header(m,"ActionID");
10165       if (!ast_strlen_zero(id))
10166          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
10167    }
10168 
10169    switch (argc) {
10170    case 5:
10171       if (!strcasecmp(argv[3], "like")) {
10172          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
10173             return RESULT_SHOWUSAGE;
10174          havepattern = TRUE;
10175       } else
10176          return RESULT_SHOWUSAGE;
10177    case 3:
10178       break;
10179    default:
10180       return RESULT_SHOWUSAGE;
10181    }
10182 
10183    if (!s) /* Normal list */
10184       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
10185    
10186    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
10187       char status[20] = "";
10188       char srch[2000];
10189       char pstatus;
10190       
10191       ASTOBJ_RDLOCK(iterator);
10192 
10193       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10194          ASTOBJ_UNLOCK(iterator);
10195          continue;
10196       }
10197 
10198       if (!ast_strlen_zero(iterator->username) && !s)
10199          snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
10200       else
10201          ast_copy_string(name, iterator->name, sizeof(name));
10202       
10203       pstatus = peer_status(iterator, status, sizeof(status));
10204       if (pstatus == 1)
10205          peers_mon_online++;
10206       else if (pstatus == 0)
10207          peers_mon_offline++;
10208       else {
10209          if (iterator->addr.sin_port == 0)
10210             peers_unmon_offline++;
10211          else
10212             peers_unmon_online++;
10213       }
10214 
10215       snprintf(srch, sizeof(srch), FORMAT, name,
10216          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
10217          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
10218          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
10219          iterator->ha ? " A " : "   ",    /* permit/deny */
10220          ntohs(iterator->addr.sin_port), status,
10221          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
10222 
10223       if (!s)  {/* Normal CLI list */
10224          ast_cli(fd, FORMAT, name, 
10225          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
10226          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
10227          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : "   ",   /* NAT=yes? */
10228          iterator->ha ? " A " : "   ",       /* permit/deny */
10229          
10230          ntohs(iterator->addr.sin_port), status,
10231          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : "");
10232       } else { /* Manager format */
10233          /* The names here need to be the same as other channels */
10234          astman_append(s, 
10235          "Event: PeerEntry\r\n%s"
10236          "Channeltype: SIP\r\n"
10237          "ObjectName: %s\r\n"
10238          "ChanObjectType: peer\r\n" /* "peer" or "user" */
10239          "IPaddress: %s\r\n"
10240          "IPport: %d\r\n"
10241          "Dynamic: %s\r\n"
10242          "Natsupport: %s\r\n"
10243          "VideoSupport: %s\r\n"
10244          "ACL: %s\r\n"
10245          "Status: %s\r\n"
10246          "RealtimeDevice: %s\r\n\r\n", 
10247          idtext,
10248          iterator->name, 
10249          iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-",
10250          ntohs(iterator->addr.sin_port), 
10251          ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no",   /* Dynamic or not? */
10252          ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
10253          ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
10254          iterator->ha ? "yes" : "no",       /* permit/deny */
10255          status,
10256          realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no");
10257       }
10258 
10259       ASTOBJ_UNLOCK(iterator);
10260 
10261       total_peers++;
10262    } while(0) );
10263    
10264    if (!s)
10265       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
10266               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
10267 
10268    if (havepattern)
10269       regfree(&regexbuf);
10270 
10271    if (total)
10272       *total = total_peers;
10273    
10274 
10275    return RESULT_SUCCESS;
10276 #undef FORMAT
10277 #undef FORMAT2
10278 }

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

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

15261 {
15262    struct ast_rtp_quality qos;
15263    struct sip_pvt *p = chan->tech_pvt;
15264    char *all = "", *parse = ast_strdupa(preparse);
15265    AST_DECLARE_APP_ARGS(args,
15266       AST_APP_ARG(param);
15267       AST_APP_ARG(type);
15268       AST_APP_ARG(field);
15269    );
15270    AST_STANDARD_APP_ARGS(args, parse);
15271 
15272    /* Sanity check */
15273    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
15274       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
15275       return 0;
15276    }
15277 
15278    if (strcasecmp(args.param, "rtpqos"))
15279       return 0;
15280 
15281    /* Default arguments of audio,all */
15282    if (ast_strlen_zero(args.type))
15283       args.type = "audio";
15284    if (ast_strlen_zero(args.field))
15285       args.field = "all";
15286 
15287    memset(buf, 0, buflen);
15288    memset(&qos, 0, sizeof(qos));
15289 
15290    if (strcasecmp(args.type, "AUDIO") == 0) {
15291       all = ast_rtp_get_quality(p->rtp, &qos);
15292    } else if (strcasecmp(args.type, "VIDEO") == 0) {
15293       all = ast_rtp_get_quality(p->vrtp, &qos);
15294    }
15295 
15296    if (strcasecmp(args.field, "local_ssrc") == 0)
15297       snprintf(buf, buflen, "%u", qos.local_ssrc);
15298    else if (strcasecmp(args.field, "local_lostpackets") == 0)
15299       snprintf(buf, buflen, "%u", qos.local_lostpackets);
15300    else if (strcasecmp(args.field, "local_jitter") == 0)
15301       snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0);
15302    else if (strcasecmp(args.field, "local_count") == 0)
15303       snprintf(buf, buflen, "%u", qos.local_count);
15304    else if (strcasecmp(args.field, "remote_ssrc") == 0)
15305       snprintf(buf, buflen, "%u", qos.remote_ssrc);
15306    else if (strcasecmp(args.field, "remote_lostpackets") == 0)
15307       snprintf(buf, buflen, "%u", qos.remote_lostpackets);
15308    else if (strcasecmp(args.field, "remote_jitter") == 0)
15309       snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0);
15310    else if (strcasecmp(args.field, "remote_count") == 0)
15311       snprintf(buf, buflen, "%u", qos.remote_count);
15312    else if (strcasecmp(args.field, "rtt") == 0)
15313       snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0);
15314    else if (strcasecmp(args.field, "all") == 0)
15315       ast_copy_string(buf, all, buflen);
15316    else {
15317       ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
15318       return -1;
15319    }
15320    return 0;
15321 }

static void add_blank ( struct sip_request req  )  [static]

add a blank line if no body

Definition at line 2273 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

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

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

06377 {
06378    int rtp_code;
06379    struct ast_format_list fmt;
06380 
06381 
06382    if (debug)
06383       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
06384    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
06385       return;
06386 
06387    if (p->rtp) {
06388       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
06389       fmt = ast_codec_pref_getsize(pref, codec);
06390    } 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 */
06391       return;
06392    ast_build_string(m_buf, m_size, " %d", rtp_code);
06393    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06394           ast_rtp_lookup_mime_subtype(1, codec,
06395                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
06396           sample_rate);
06397    if (codec == AST_FORMAT_G729A) {
06398       /* Indicate that we don't support VAD (G.729 annex B) */
06399       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
06400    } else if (codec == AST_FORMAT_G723_1) {
06401       /* Indicate that we don't support VAD (G.723.1 annex A) */
06402       ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code);
06403    } else if (codec == AST_FORMAT_ILBC) {
06404       /* Add information about us using only 20/30 ms packetization */
06405       ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
06406    }
06407 
06408    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
06409       *min_packet_size = fmt.cur_ms;
06410 
06411    /* Our first codec packetization processed cannot be less than zero */
06412    if ((*min_packet_size) == 0  && fmt.cur_ms)
06413       *min_packet_size = fmt.cur_ms;
06414 }

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

Add DTMF INFO tone to sip message.

Definition at line 6342 of file chan_sip.c.

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

Referenced by transmit_info_with_digit().

06343 {
06344    char tmp[256];
06345 
06346    snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
06347    add_header(req, "Content-Type", "application/dtmf-relay");
06348    add_header_contentLength(req, strlen(tmp));
06349    add_line(req, tmp);
06350    return 0;
06351 }

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

Add header to SIP message.

Definition at line 5733 of file chan_sip.c.

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

05734 {
05735    int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */
05736 
05737    if (req->headers == SIP_MAX_HEADERS) {
05738       ast_log(LOG_WARNING, "Out of SIP header space\n");
05739       return -1;
05740    }
05741 
05742    if (req->lines) {
05743       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
05744       return -1;
05745    }
05746 
05747    if (maxlen <= 0) {
05748       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
05749       return -1;
05750    }
05751 
05752    req->header[req->headers] = req->data + req->len;
05753 
05754    if (compactheaders)
05755       var = find_alias(var, var);
05756 
05757    snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
05758    req->len += strlen(req->header[req->headers]);
05759    req->headers++;
05760 
05761    return 0;   
05762 }

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

Add 'Content-Length' header to SIP message.

Definition at line 5765 of file chan_sip.c.

References add_header().

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

05766 {
05767    char clen[10];
05768 
05769    snprintf(clen, sizeof(clen), "%d", len);
05770    return add_header(req, "Content-Length", clen);
05771 }

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

Add content (not header) to SIP message.

Definition at line 5774 of file chan_sip.c.

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

05775 {
05776    if (req->lines == SIP_MAX_LINES)  {
05777       ast_log(LOG_WARNING, "Out of SIP line space\n");
05778       return -1;
05779    }
05780    if (!req->lines) {
05781       /* Add extra empty return */
05782       snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
05783       req->len += strlen(req->data + req->len);
05784    }
05785    if (req->len >= sizeof(req->data) - 4) {
05786       ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
05787       return -1;
05788    }
05789    req->line[req->lines] = req->data + req->len;
05790    snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
05791    req->len += strlen(req->line[req->lines]);
05792    req->lines++;
05793    return 0;   
05794 }

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

06556 {
06557    int rtp_code;
06558 
06559    if (debug)
06560       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
06561    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
06562       return;
06563 
06564    ast_build_string(m_buf, m_size, " %d", rtp_code);
06565    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
06566           ast_rtp_lookup_mime_subtype(0, format, 0),
06567           sample_rate);
06568    if (format == AST_RTP_DTMF)
06569       /* Indicate we support DTMF and FLASH... */
06570       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
06571 }

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

Add realm authentication in list.

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

16994 {
16995    char authcopy[256];
16996    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
16997    char *stringp;
16998    struct sip_auth *a, *b, *auth;
16999 
17000    if (ast_strlen_zero(configuration))
17001       return authlist;
17002 
17003    if (option_debug)
17004       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
17005 
17006    ast_copy_string(authcopy, configuration, sizeof(authcopy));
17007    stringp = authcopy;
17008 
17009    username = stringp;
17010    realm = strrchr(stringp, '@');
17011    if (realm)
17012       *realm++ = '\0';
17013    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
17014       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
17015       return authlist;
17016    }
17017    stringp = username;
17018    username = strsep(&stringp, ":");
17019    if (username) {
17020       secret = strsep(&stringp, ":");
17021       if (!secret) {
17022          stringp = username;
17023          md5secret = strsep(&stringp,"#");
17024       }
17025    }
17026    if (!(auth = ast_calloc(1, sizeof(*auth))))
17027       return authlist;
17028 
17029    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
17030    ast_copy_string(auth->username, username, sizeof(auth->username));
17031    if (secret)
17032       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
17033    if (md5secret)
17034       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
17035 
17036    /* find the end of the list */
17037    for (b = NULL, a = authlist; a ; b = a, a = a->next)
17038       ;
17039    if (b)
17040       b->next = auth;   /* Add structure add end of list */
17041    else
17042       authlist = auth;
17043 
17044    if (option_verbose > 2)
17045       ast_verbose("Added authentication for realm %s\n", realm);
17046 
17047    return authlist;
17048 
17049 }

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

Add route header into request per learned route.

Definition at line 5895 of file chan_sip.c.

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

Referenced by reqprep().

05896 {
05897    char r[SIPBUFSIZE*2], *p;
05898    int n, rem = sizeof(r);
05899 
05900    if (!route)
05901       return;
05902 
05903    p = r;
05904    for (;route ; route = route->next) {
05905       n = strlen(route->hop);
05906       if (rem < n+3) /* we need room for ",<route>" */
05907          break;
05908       if (p != r) {  /* add a separator after fist route */
05909          *p++ = ',';
05910          --rem;
05911       }
05912       *p++ = '<';
05913       ast_copy_string(p, route->hop, rem); /* cannot fail */
05914       p += n;
05915       *p++ = '>';
05916       rem -= (n+2);
05917    }
05918    *p = '\0';
05919    add_header(req, "Route", r);
05920 }

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

Add Session Description Protocol message.

Definition at line 6581 of file chan_sip.c.

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

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

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

16930 {
16931    struct domain *d;
16932 
16933    if (ast_strlen_zero(domain)) {
16934       ast_log(LOG_WARNING, "Zero length domain.\n");
16935       return 1;
16936    }
16937 
16938    if (!(d = ast_calloc(1, sizeof(*d))))
16939       return 0;
16940 
16941    ast_copy_string(d->domain, domain, sizeof(d->domain));
16942 
16943    if (!ast_strlen_zero(context))
16944       ast_copy_string(d->context, context, sizeof(d->context));
16945 
16946    d->mode = mode;
16947 
16948    AST_LIST_LOCK(&domain_list);
16949    AST_LIST_INSERT_TAIL(&domain_list, d, list);
16950    AST_LIST_UNLOCK(&domain_list);
16951 
16952    if (sipdebug)  
16953       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
16954 
16955    return 1;
16956 }

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

Add T.38 Session Description Protocol message.

Definition at line 6453 of file chan_sip.c.

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

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

06454 {
06455    int len = 0;
06456    int x = 0;
06457    struct sockaddr_in udptlsin;
06458    char v[256] = "";
06459    char s[256] = "";
06460    char o[256] = "";
06461    char c[256] = "";
06462    char t[256] = "";
06463    char m_modem[256];
06464    char a_modem[1024];
06465    char *m_modem_next = m_modem;
06466    size_t m_modem_left = sizeof(m_modem);
06467    char *a_modem_next = a_modem;
06468    size_t a_modem_left = sizeof(a_modem);
06469    struct sockaddr_in udptldest = { 0, };
06470    int debug;
06471    
06472    debug = sip_debug_test_pvt(p);
06473    len = 0;
06474    if (!p->udptl) {
06475       ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n");
06476       return -1;
06477    }
06478    
06479    if (!p->sessionid) {
06480       p->sessionid = getpid();
06481       p->sessionversion = p->sessionid;
06482    } else
06483       p->sessionversion++;
06484    
06485    /* Our T.38 end is */
06486    ast_udptl_get_us(p->udptl, &udptlsin);
06487    
06488    /* Determine T.38 UDPTL destination */
06489    if (p->udptlredirip.sin_addr.s_addr) {
06490       udptldest.sin_port = p->udptlredirip.sin_port;
06491       udptldest.sin_addr = p->udptlredirip.sin_addr;
06492    } else {
06493       udptldest.sin_addr = p->ourip;
06494       udptldest.sin_port = udptlsin.sin_port;
06495    }
06496    
06497    if (debug) 
06498       ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
06499    
06500    /* We break with the "recommendation" and send our IP, in order that our
06501       peer doesn't have to ast_gethostbyname() us */
06502    
06503    if (debug) {
06504       ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
06505          p->t38.capability,
06506          p->t38.peercapability,
06507          p->t38.jointcapability);
06508    }
06509    snprintf(v, sizeof(v), "v=0\r\n");
06510    snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr));
06511    snprintf(s, sizeof(s), "s=session\r\n");
06512    snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
06513    snprintf(t, sizeof(t), "t=0 0\r\n");
06514    ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
06515    
06516    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
06517       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
06518    if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
06519       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
06520    if ((x = t38_get_rate(p->t38.jointcapability)))
06521       ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
06522    if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL)
06523       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n");
06524    if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR)
06525       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n");
06526    if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG)
06527       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n");
06528    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
06529    x = ast_udptl_get_local_max_datagram(p->udptl);
06530    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
06531    ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
06532    if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
06533       ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
06534    len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem);
06535    add_header(resp, "Content-Type", "application/sdp");
06536    add_header_contentLength(resp, len);
06537    add_line(resp, v);
06538    add_line(resp, o);
06539    add_line(resp, s);
06540    add_line(resp, c);
06541    add_line(resp, t);
06542    add_line(resp, m_modem);
06543    add_line(resp, a_modem);
06544    
06545    /* Update lastrtprx when we send our SDP */
06546    p->lastrtprx = p->lastrtptx = time(NULL);
06547    
06548    return 0;
06549 }

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

Add text body to SIP message.

Definition at line 6331 of file chan_sip.c.

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

Referenced by transmit_message_with_text().

06332 {
06333    /* XXX Convert \n's to \r\n's XXX */
06334    add_header(req, "Content-Type", "text/plain");
06335    add_header_contentLength(req, strlen(text));
06336    add_line(req, text);
06337    return 0;
06338 }

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

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

Referenced by transmit_info_with_vidupdate().

06356 {
06357    const char *xml_is_a_huge_waste_of_space =
06358       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
06359       " <media_control>\r\n"
06360       "  <vc_primitive>\r\n"
06361       "   <to_encoder>\r\n"
06362       "    <picture_fast_update>\r\n"
06363       "    </picture_fast_update>\r\n"
06364       "   </to_encoder>\r\n"
06365       "  </vc_primitive>\r\n"
06366       " </media_control>\r\n";
06367    add_header(req, "Content-Type", "application/media_control+xml");
06368    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
06369    add_line(req, xml_is_a_huge_waste_of_space);
06370    return 0;
06371 }

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

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

06279 {
06280    char tmpdat[256];
06281    struct tm tm;
06282    time_t t = time(NULL);
06283 
06284    gmtime_r(&t, &tm);
06285    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
06286    add_header(req, "Date", tmpdat);
06287 }

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

Append to SIP dialog history with arg list.

Definition at line 1893 of file chan_sip.c.

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

01894 {
01895    va_list ap;
01896 
01897    if (!p)
01898       return;
01899 
01900    if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 
01901       && !recordhistory && !dumphistory) {
01902       return;
01903    }
01904 
01905    va_start(ap, fmt);
01906    append_history_va(p, fmt, ap);
01907    va_end(ap);
01908 
01909    return;
01910 }

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

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

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

13515 {
13516    if (chan && chan->_state == AST_STATE_UP) {
13517       if (ast_test_flag(chan, AST_FLAG_MOH))
13518          ast_moh_stop(chan);
13519       else if (chan->generatordata)
13520          ast_deactivate_generator(chan);
13521    }
13522 }

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

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

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

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

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

13527 {
13528    int res = 0;
13529    struct ast_channel *peera = NULL,   
13530       *peerb = NULL,
13531       *peerc = NULL,
13532       *peerd = NULL;
13533 
13534 
13535    /* We will try to connect the transferee with the target and hangup
13536       all channels to the transferer */   
13537    if (option_debug > 3) {
13538       ast_log(LOG_DEBUG, "Sip transfer:--------------------\n");
13539       if (transferer->chan1)
13540          ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
13541       else
13542          ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n");
13543       if (target->chan1)
13544          ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
13545       else
13546          ast_log(LOG_DEBUG, "-- No target first channel ---\n");
13547       if (transferer->chan2)
13548          ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
13549       else
13550          ast_log(LOG_DEBUG, "-- No bridged call to transferee\n");
13551       if (target->chan2)
13552          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)");
13553       else
13554          ast_log(LOG_DEBUG, "-- No target second channel ---\n");
13555       ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n");
13556    }
13557    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
13558       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
13559       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
13560       peerc = transferer->chan2; /* Asterisk to Transferee */
13561       peerd = target->chan2;     /* Asterisk to Target */
13562       if (option_debug > 2)
13563          ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n");
13564    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
13565       peera = target->chan1;     /* Transferer to PBX -> target channel */
13566       peerb = transferer->chan1; /* Transferer to IVR*/
13567       peerc = target->chan2;     /* Asterisk to Target */
13568       peerd = transferer->chan2; /* Nothing */
13569       if (option_debug > 2)
13570          ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n");
13571    }
13572 
13573    if (peera && peerb && peerc && (peerb != peerc)) {
13574       ast_quiet_chan(peera);     /* Stop generators */
13575       ast_quiet_chan(peerb);  
13576       ast_quiet_chan(peerc);
13577       if (peerd)
13578          ast_quiet_chan(peerd);
13579 
13580       if (option_debug > 3)
13581          ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
13582       if (ast_channel_masquerade(peerb, peerc)) {
13583          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
13584          res = -1;
13585       } else
13586          ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n");
13587       return res;
13588    } else {
13589       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
13590       if (transferer->chan1)
13591          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
13592       if (target->chan1)
13593          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
13594       return -2;
13595    }
13596    return 0;
13597 }

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

Scheduled congestion on a call.

Definition at line 2963 of file chan_sip.c.

References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_control(), sip_pvt::initid, sip_pvt::lock, LOG_NOTICE, ast_channel::name, and sip_pvt::owner.

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

static void build_callid_pvt ( struct sip_pvt pvt  )  [static]

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

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

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

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

04512 {
04513    char buf[33];
04514 
04515    const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
04516 
04517    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
04518 }

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

Definition at line 7004 of file chan_sip.c.

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

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

07005 {
07006    /* Construct Contact: header */
07007    if (ourport != STANDARD_SIP_PORT)
07008       ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip), ourport);
07009    else
07010       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip));
07011 }

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

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

Definition at line 17260 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_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::lastmsgssent, ast_variable::lineno, LOG_DEBUG, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, sip_peer::name, ast_variable::next, sip_peer::objflags, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.

17261 {
17262    struct sip_peer *peer = NULL;
17263    struct ast_ha *oldha = NULL;
17264    int obproxyfound=0;
17265    int found=0;
17266    int firstpass=1;
17267    int format=0;     /* Ama flags */
17268    time_t regseconds = 0;
17269    char *varname = NULL, *varval = NULL;
17270    struct ast_variable *tmpvar = NULL;
17271    struct ast_flags peerflags[2] = {{(0)}};
17272    struct ast_flags mask[2] = {{(0)}};
17273    char fullcontact[sizeof(peer->fullcontact)] = "";
17274 
17275    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
17276       /* Note we do NOT use find_peer here, to avoid realtime recursion */
17277       /* We also use a case-sensitive comparison (unlike find_peer) so
17278          that case changes made to the peer name will be properly handled
17279          during reload
17280       */
17281       peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
17282 
17283    if (peer) {
17284       /* Already in the list, remove it and it will be added back (or FREE'd)  */
17285       found = 1;
17286       if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
17287          firstpass = 0;
17288    } else {
17289       if (!(peer = ast_calloc(1, sizeof(*peer))))
17290          return NULL;
17291 
17292       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))
17293          rpeerobjs++;
17294       else
17295          speerobjs++;
17296       ASTOBJ_INIT(peer);
17297    }
17298    /* Note that our peer HAS had its reference count incrased */
17299    if (firstpass) {
17300       peer->lastmsgssent = -1;
17301       oldha = peer->ha;
17302       peer->ha = NULL;
17303       set_peer_defaults(peer);   /* Set peer defaults */
17304    }
17305    if (!found && name)
17306          ast_copy_string(peer->name, name, sizeof(peer->name));
17307 
17308    /* If we have channel variables, remove them (reload) */
17309    if (peer->chanvars) {
17310       ast_variables_destroy(peer->chanvars);
17311       peer->chanvars = NULL;
17312       /* XXX should unregister ? */
17313    }
17314 
17315    /* If we have realm authentication information, remove them (reload) */
17316    clear_realm_authentication(peer->auth);
17317    peer->auth = NULL;
17318 
17319    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
17320       if (handle_common_options(&peerflags[0], &mask[0], v))
17321          continue;
17322       if (realtime && !strcasecmp(v->name, "regseconds")) {
17323          ast_get_time_t(v->value, &regseconds, 0, NULL);
17324       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
17325          inet_aton(v->value, &(peer->addr.sin_addr));
17326       } else if (realtime && !strcasecmp(v->name, "name"))
17327          ast_copy_string(peer->name, v->value, sizeof(peer->name));
17328       else if (realtime && !strcasecmp(v->name, "fullcontact")) {
17329          /* Reconstruct field, because realtime separates our value at the ';' */
17330          if (!ast_strlen_zero(fullcontact)) {
17331             strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1);
17332             strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1);
17333          } else {
17334             ast_copy_string(fullcontact, v->value, sizeof(fullcontact));
17335             ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT);
17336          }
17337       } else if (!strcasecmp(v->name, "secret")) 
17338          ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
17339       else if (!strcasecmp(v->name, "md5secret")) 
17340          ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
17341       else if (!strcasecmp(v->name, "auth"))
17342          peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
17343       else if (!strcasecmp(v->name, "callerid")) {
17344          ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
17345       } else if (!strcasecmp(v->name, "fullname")) {
17346          ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
17347       } else if (!strcasecmp(v->name, "cid_number")) {
17348          ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
17349       } else if (!strcasecmp(v->name, "context")) {
17350          ast_copy_string(peer->context, v->value, sizeof(peer->context));
17351       } else if (!strcasecmp(v->name, "subscribecontext")) {
17352          ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
17353       } else if (!strcasecmp(v->name, "fromdomain")) {
17354          ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
17355       } else if (!strcasecmp(v->name, "usereqphone")) {
17356          ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
17357       } else if (!strcasecmp(v->name, "fromuser")) {
17358          ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
17359       } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
17360          if (!strcasecmp(v->value, "dynamic")) {
17361             if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
17362                ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
17363             } else {
17364                /* They'll register with us */
17365                if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
17366                   /* Initialize stuff if this is a new peer, or if it used to be
17367                    * non-dynamic before the reload. */
17368                   memset(&peer->addr.sin_addr, 0, 4);
17369                   if (peer->addr.sin_port) {
17370                      /* If we've already got a port, make it the default rather than absolute */
17371                      peer->defaddr.sin_port = peer->addr.sin_port;
17372                      peer->addr.sin_port = 0;
17373                   }
17374                }
17375                ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
17376             }
17377          } else {
17378             /* Non-dynamic.  Make sure we become that way if we're not */
17379             if (!AST_SCHED_DEL(sched, peer->expire)) {
17380                struct sip_peer *peer_ptr = peer;
17381                ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
17382             }
17383             ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
17384             if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
17385                if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) {
17386                   ASTOBJ_UNREF(peer, sip_destroy_peer);
17387                   return NULL;
17388                }
17389             }
17390             if (!strcasecmp(v->name, "outboundproxy"))
17391                obproxyfound=1;
17392             else {
17393                ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost));
17394                if (!peer->addr.sin_port)
17395                   peer->addr.sin_port = htons(STANDARD_SIP_PORT);
17396             }
17397             if (global_dynamic_exclude_static) {
17398                global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha);
17399             }
17400          }
17401       } else if (!strcasecmp(v->name, "defaultip")) {
17402          if (ast_get_ip(&peer->defaddr, v->value)) {
17403             ASTOBJ_UNREF(peer, sip_destroy_peer);
17404             return NULL;
17405          }
17406       } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
17407          peer->ha = ast_append_ha(v->name, v->value, peer->ha);
17408       } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
17409          peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha);
17410       } else if (!strcasecmp(v->name, "port")) {
17411          if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC))
17412             peer->defaddr.sin_port = htons(atoi(v->value));
17413          else
17414             peer->addr.sin_port = htons(atoi(v->value));
17415       } else if (!strcasecmp(v->name, "callingpres")) {
17416          peer->callingpres = ast_parse_caller_presentation(v->value);
17417          if (peer->callingpres == -1)
17418             peer->callingpres = atoi(v->value);
17419       } else if (!strcasecmp(v->name, "username")) {
17420          ast_copy_string(peer->username, v->value, sizeof(peer->username));
17421       } else if (!strcasecmp(v->name, "language")) {
17422          ast_copy_string(peer->language, v->value, sizeof(peer->language));
17423       } else if (!strcasecmp(v->name, "regexten")) {
17424          ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
17425       } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) {
17426          peer->call_limit = atoi(v->value);
17427          if (peer->call_limit < 0)
17428             peer->call_limit = 0;
17429       } else if (!strcasecmp(v->name, "amaflags")) {
17430          format = ast_cdr_amaflags2int(v->value);
17431          if (format < 0) {
17432             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
17433          } else {
17434             peer->amaflags = format;
17435          }
17436       } else if (!strcasecmp(v->name, "accountcode")) {
17437          ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
17438       } else if (!strcasecmp(v->name, "mohinterpret")
17439          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
17440          ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
17441       } else if (!strcasecmp(v->name, "mohsuggest")) {
17442          ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
17443       } else if (!strcasecmp(v->name, "mailbox")) {
17444          ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
17445       } else if (!strcasecmp(v->name, "hasvoicemail")) {
17446          /* People expect that if 'hasvoicemail' is set, that the mailbox will
17447           * be also set, even if not explicitly specified. */
17448          if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
17449             ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox));
17450          }
17451       } else if (!strcasecmp(v->name, "subscribemwi")) {
17452          ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
17453       } else if (!strcasecmp(v->name, "vmexten")) {
17454          ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
17455       } else if (!strcasecmp(v->name, "callgroup")) {
17456          peer->callgroup = ast_get_group(v->value);
17457       } else if (!strcasecmp(v->name, "allowtransfer")) {
17458          peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
17459       } else if (!strcasecmp(v->name, "pickupgroup")) {
17460          peer->pickupgroup = ast_get_group(v->value);
17461       } else if (!strcasecmp(v->name, "allow")) {
17462          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
17463       } else if (!strcasecmp(v->name, "disallow")) {
17464          ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
17465       } else if (!strcasecmp(v->name, "autoframing")) {
17466          peer->autoframing = ast_true(v->value);
17467       } else if (!strcasecmp(v->name, "rtptimeout")) {
17468          if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
17469             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17470             peer->rtptimeout = global_rtptimeout;
17471          }
17472       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
17473          if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
17474             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
17475             peer->rtpholdtimeout = global_rtpholdtimeout;
17476          }
17477       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
17478          if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
17479             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
17480             peer->rtpkeepalive = global_rtpkeepalive;
17481          }
17482       } else if (!strcasecmp(v->name, "setvar")) {
17483          /* Set peer channel variable */
17484          varname = ast_strdupa(v->value);
17485          if ((varval = strchr(varname, '='))) {
17486             *varval++ = '\0';
17487             if ((tmpvar = ast_variable_new(varname, varval))) {
17488                tmpvar->next = peer->chanvars;
17489                peer->chanvars = tmpvar;
17490             }
17491          }
17492       } else if (!strcasecmp(v->name, "qualify")) {
17493          if (!strcasecmp(v->value, "no")) {
17494             peer->maxms = 0;
17495          } else if (!strcasecmp(v->value, "yes")) {
17496             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
17497          } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
17498             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);
17499             peer->maxms = 0;
17500          }
17501          if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {
17502             /* This would otherwise cause a network storm, where the
17503              * qualify response refreshes the peer from the database,
17504              * which in turn causes another qualify to be sent, ad
17505              * infinitum. */
17506             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);
17507             peer->maxms = 0;
17508          }
17509       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
17510          peer->maxcallbitrate = atoi(v->value);
17511          if (peer->maxcallbitrate < 0)
17512             peer->maxcallbitrate = default_maxcallbitrate;
17513       }
17514    }
17515    if (!ast_strlen_zero(fullcontact)) {
17516       ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact));
17517       /* We have a hostname in the fullcontact, but if we don't have an
17518        * address listed on the entry (or if it's 'dynamic'), then we need to
17519        * parse the entry to obtain the IP address, so a dynamic host can be
17520        * contacted immediately after reload (as opposed to waiting for it to
17521        * register once again). */
17522       __set_address_from_contact(fullcontact, &peer->addr);
17523    }
17524 
17525    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
17526       time_t nowtime = time(NULL);
17527 
17528       if ((nowtime - regseconds) > 0) {
17529          destroy_association(peer);
17530          memset(&peer->addr, 0, sizeof(peer->addr));
17531          if (option_debug)
17532             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
17533       }
17534    }
17535    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
17536    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
17537    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
17538       global_allowsubscribe = TRUE; /* No global ban any more */
17539    if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME))
17540       reg_source_db(peer);
17541    ASTOBJ_UNMARK(peer);
17542    ast_free_ha(oldha);
17543    return peer;
17544 }

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

11795 {
11796    char a1[256];
11797    char a2[256];
11798    char a1_hash[256];
11799    char a2_hash[256];
11800    char resp[256];
11801    char resp_hash[256];
11802    char uri[256];
11803    char opaque[256] = "";
11804    char cnonce[80];
11805    const char *username;
11806    const char *secret;
11807    const char *md5secret;
11808    struct sip_auth *auth = NULL; /* Realm authentication */
11809 
11810    if (!ast_strlen_zero(p->domain))
11811       ast_copy_string(uri, p->domain, sizeof(uri));
11812    else if (!ast_strlen_zero(p->uri))
11813       ast_copy_string(uri, p->uri, sizeof(uri));
11814    else
11815       snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr));
11816 
11817    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
11818 
11819    /* Check if we have separate auth credentials */
11820    if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */
11821       auth = find_realm_authentication(authl, p->realm); /* If not, global list */
11822 
11823    if (auth) {
11824       ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
11825       username = auth->username;
11826       secret = auth->secret;
11827       md5secret = auth->md5secret;
11828       if (sipdebug)
11829          ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid);
11830    } else {
11831       /* No authentication, use peer or register= config */
11832       username = p->authname;
11833       secret =  p->peersecret;
11834       md5secret = p->peermd5secret;
11835    }
11836    if (ast_strlen_zero(username))   /* We have no authentication */
11837       return -1;
11838 
11839    /* Calculate SIP digest response */
11840    snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret);
11841    snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri);
11842    if (!ast_strlen_zero(md5secret))
11843       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
11844    else
11845       ast_md5_hash(a1_hash,a1);
11846    ast_md5_hash(a2_hash,a2);
11847 
11848    p->noncecount++;
11849    if (!ast_strlen_zero(p->qop))
11850       snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
11851    else
11852       snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash);
11853    ast_md5_hash(resp_hash, resp);
11854 
11855    /* only include the opaque string if it's set */
11856    if (!ast_strlen_zero(p->opaque)) {
11857      snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
11858    }
11859 
11860    /* XXX We hard code our qop to "auth" for now.  XXX */
11861    if (!ast_strlen_zero(p->qop))
11862       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);
11863    else
11864       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);
11865 
11866    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
11867 
11868    return 0;
11869 }

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 8463 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(), and handle_response_invite().

08464 {
08465    struct sip_route *thishop, *head, *tail;
08466    int start = 0;
08467    int len;
08468    const char *rr, *contact, *c;
08469 
08470    /* Once a persistant route is set, don't fool with it */
08471    if (p->route && p->route_persistant) {
08472       if (option_debug)
08473          ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop);
08474       return;
08475    }
08476 
08477    if (p->route) {
08478       free_old_route(p->route);
08479       p->route = NULL;
08480    }
08481 
08482    /* We only want to create the route set the first time this is called */
08483    p->route_persistant = 1;
08484    
08485    /* Build a tailq, then assign it to p->route when done.
08486     * If backwards, we add entries from the head so they end up
08487     * in reverse order. However, we do need to maintain a correct
08488     * tail pointer because the contact is always at the end.
08489     */
08490    head = NULL;
08491    tail = head;
08492    /* 1st we pass through all the hops in any Record-Route headers */
08493    for (;;) {
08494       /* Each Record-Route header */
08495       rr = __get_header(req, "Record-Route", &start);
08496       if (*rr == '\0')
08497          break;
08498       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
08499          ++rr;
08500          len = strcspn(rr, ">") + 1;
08501          /* Make a struct route */
08502          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08503             /* ast_calloc is not needed because all fields are initialized in this block */
08504             ast_copy_string(thishop->hop, rr, len);
08505             if (option_debug > 1)
08506                ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop);
08507             /* Link in */
08508             if (backwards) {
08509                /* Link in at head so they end up in reverse order */
08510                thishop->next = head;
08511                head = thishop;
08512                /* If this was the first then it'll be the tail */
08513                if (!tail)
08514                   tail = thishop;
08515             } else {
08516                thishop->next = NULL;
08517                /* Link in at the end */
08518                if (tail)
08519                   tail->next = thishop;
08520                else
08521                   head = thishop;
08522                tail = thishop;
08523             }
08524          }
08525       }
08526    }
08527 
08528    /* Only append the contact if we are dealing with a strict router */
08529    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
08530       /* 2nd append the Contact: if there is one */
08531       /* Can be multiple Contact headers, comma separated values - we just take the first */
08532       contact = get_header(req, "Contact");
08533       if (!ast_strlen_zero(contact)) {
08534          if (option_debug > 1)
08535             ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
08536          /* Look for <: delimited address */
08537          c = strchr(contact, '<');
08538          if (c) {
08539             /* Take to > */
08540             ++c;
08541             len = strcspn(c, ">") + 1;
08542          } else {
08543             /* No <> - just take the lot */
08544             c = contact;
08545             len = strlen(contact) + 1;
08546          }
08547          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
08548             /* ast_calloc is not needed because all fields are initialized in this block */
08549             ast_copy_string(thishop->hop, c, len);
08550             thishop->next = NULL;
08551             /* Goes at the end */
08552             if (tail)
08553                tail->next = thishop;
08554             else
08555                head = thishop;
08556          }
08557       }
08558    }
08559 
08560    /* Store as new route */
08561    p->route = head;
08562 
08563    /* For debugging dump what we ended up with */
08564    if (sip_debug_test_pvt(p))
08565       list_route(p->route);
08566 }

static void build_rpid ( struct sip_pvt p  )  [static]

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

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

07015 {
07016    int send_pres_tags = TRUE;
07017    const char *privacy=NULL;
07018    const char *screen=NULL;
07019    char buf[256];
07020    const char *clid = default_callerid;
07021    const char *clin = NULL;
07022    const char *fromdomain;
07023 
07024    if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
07025       return;
07026 
07027    if (p->owner && p->owner->cid.cid_num)
07028       clid = p->owner->cid.cid_num;
07029    if (p->owner && p->owner->cid.cid_name)
07030       clin = p->owner->cid.cid_name;
07031    if (ast_strlen_zero(clin))
07032       clin = clid;
07033 
07034    switch (p->callingpres) {
07035    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
07036       privacy = "off";
07037       screen = "no";
07038       break;
07039    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
07040       privacy = "off";
07041       screen = "yes";
07042       break;
07043    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
07044       privacy = "off";
07045       screen = "no";
07046       break;
07047    case AST_PRES_ALLOWED_NETWORK_NUMBER:
07048       privacy = "off";
07049       screen = "yes";
07050       break;
07051    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
07052       privacy = "full";
07053       screen = "no";
07054       break;
07055    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
07056       privacy = "full";
07057       screen = "yes";
07058       break;
07059    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
07060       privacy = "full";
07061       screen = "no";
07062       break;
07063    case AST_PRES_PROHIB_NETWORK_NUMBER:
07064       privacy = "full";
07065       screen = "yes";
07066       break;
07067    case AST_PRES_NUMBER_NOT_AVAILABLE:
07068       send_pres_tags = FALSE;
07069       break;
07070    default:
07071       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
07072       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
07073          privacy = "full";
07074       else
07075          privacy = "off";
07076       screen = "no";
07077       break;
07078    }
07079    
07080    fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
07081 
07082    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
07083    if (send_pres_tags)
07084       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
07085    ast_string_field_set(p, rpid, buf);
07086 
07087    ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
07088                 S_OR(p->fromuser, clid),
07089                 fromdomain, p->tag);
07090 }

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

17081 {
17082    struct sip_user *user;
17083    int format;
17084    struct ast_ha *oldha = NULL;
17085    char *varname = NULL, *varval = NULL;
17086    struct ast_variable *tmpvar = NULL;
17087    struct ast_flags userflags[2] = {{(0)}};
17088    struct ast_flags mask[2] = {{(0)}};
17089 
17090 
17091    if (!(user = ast_calloc(1, sizeof(*user))))
17092       return NULL;
17093       
17094    suserobjs++;
17095    ASTOBJ_INIT(user);
17096    ast_copy_string(user->name, name, sizeof(user->name));
17097    oldha = user->ha;
17098    user->ha = NULL;
17099    ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
17100    ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
17101    user->capability = global_capability;
17102    user->allowtransfer = global_allowtransfer;
17103    user->maxcallbitrate = default_maxcallbitrate;
17104    user->autoframing = global_autoframing;
17105    user->prefs = default_prefs;
17106    /* set default context */
17107    strcpy(user->context, default_context);
17108    strcpy(user->language, default_language);
17109    strcpy(user->mohinterpret, default_mohinterpret);
17110    strcpy(user->mohsuggest, default_mohsuggest);
17111    /* First we walk through the v parameters list and then the alt parameters list */
17112    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
17113       if (handle_common_options(&userflags[0], &mask[0], v))
17114          continue;
17115 
17116       if (!strcasecmp(v->name, "context")) {
17117          ast_copy_string(user->context, v->value, sizeof(user->context));
17118       } else if (!strcasecmp(v->name, "subscribecontext")) {
17119          ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext));
17120       } else if (!strcasecmp(v->name, "setvar")) {
17121          varname = ast_strdupa(v->value);
17122          if ((varval = strchr(varname,'='))) {
17123             *varval++ = '\0';
17124             if ((tmpvar = ast_variable_new(varname, varval))) {
17125                tmpvar->next = user->chanvars;
17126                user->chanvars = tmpvar;
17127             }
17128          }
17129       } else if (!strcasecmp(v->name, "permit") ||
17130                !strcasecmp(v->name, "deny")) {
17131          user->ha = ast_append_ha(v->name, v->value, user->ha);
17132       } else if (!strcasecmp(v->name, "allowtransfer")) {
17133          user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
17134       } else if (!strcasecmp(v->name, "secret")) {
17135          ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
17136       } else if (!strcasecmp(v->name, "md5secret")) {
17137          ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret));
17138       } else if (!strcasecmp(v->name, "callerid")) {
17139          ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
17140       } else if (!strcasecmp(v->name, "fullname")) {
17141          ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name));
17142       } else if (!strcasecmp(v->name, "cid_number")) {
17143          ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num));
17144       } else if (!strcasecmp(v->name, "callgroup")) {
17145          user->callgroup = ast_get_group(v->value);
17146       } else if (!strcasecmp(v->name, "pickupgroup")) {
17147          user->pickupgroup = ast_get_group(v->value);
17148       } else if (!strcasecmp(v->name, "language")) {
17149          ast_copy_string(user->language, v->value, sizeof(user->language));
17150       } else if (!strcasecmp(v->name, "mohinterpret") 
17151          || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
17152          ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
17153       } else if (!strcasecmp(v->name, "mohsuggest")) {
17154          ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
17155       } else if (!strcasecmp(v->name, "accountcode")) {
17156          ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
17157       } else if (!strcasecmp(v->name, "call-limit")) {
17158          user->call_limit = atoi(v->value);
17159          if (user->call_limit < 0)
17160             user->call_limit = 0;
17161       } else if (!strcasecmp(v->name, "amaflags")) {
17162          format = ast_cdr_amaflags2int(v->value);
17163          if (format < 0) {
17164             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
17165          } else {
17166             user->amaflags = format;
17167          }
17168       } else if (!strcasecmp(v->name, "allow")) {
17169          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
17170       } else if (!strcasecmp(v->name, "disallow")) {
17171          ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
17172       } else if (!strcasecmp(v->name, "autoframing")) {
17173          user->autoframing = ast_true(v->value);
17174       } else if (!strcasecmp(v->name, "callingpres")) {
17175          user->callingpres = ast_parse_caller_presentation(v->value);
17176          if (user->callingpres == -1)
17177             user->callingpres = atoi(v->value);
17178       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
17179          user->maxcallbitrate = atoi(v->value);
17180          if (user->maxcallbitrate < 0)
17181             user->maxcallbitrate = default_maxcallbitrate;
17182       }
17183       /* We can't just report unknown options here because this may be a
17184        * type=friend entry.  All user options are valid for a peer, but not
17185        * the other way around.  */
17186    }
17187    ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags);
17188    ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags);
17189    if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
17190       global_allowsubscribe = TRUE; /* No global ban any more */
17191    ast_free_ha(oldha);
17192    return user;
17193 }

static void build_via ( struct sip_pvt p  )  [static]

Build a Via header for a request.

Definition at line 1810 of file chan_sip.c.

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

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

01811 {
01812    /* Work around buggy UNIDEN UIP200 firmware */
01813    const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
01814 
01815    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01816    ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
01817                 ast_inet_ntoa(p->ourip), ourport, (int) p->branch, rport);
01818 }

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

Callback for the devicestate notification (SUBSCRIBE) support subsystem.

Note:
If you add an "hint" priority to the extension in the dial plan, you will get notifications on device state changes

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

08772 {
08773    struct sip_pvt *p = data;
08774 
08775    ast_mutex_lock(&p->lock);
08776 
08777    switch(state) {
08778    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
08779    case AST_EXTENSION_REMOVED:   /* Extension is gone */
08780       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
08781          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
08782       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
08783       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);
08784       p->stateid = -1;
08785       p->subscribed = NONE;
08786       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
08787       break;
08788    default: /* Tell user */
08789       p->laststate = state;
08790       break;
08791    }
08792    if (p->subscribed != NONE) {  /* Only send state NOTIFY if we know the format */
08793       if (!p->pendinginvite) {
08794          transmit_state_notify(p, state, 1, FALSE);
08795       } else {
08796          /* We already have a NOTIFY sent that is not answered. Queue the state up.
08797             if many state changes happen meanwhile, we will only send a notification of the last one */
08798          ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
08799       }
08800    }
08801    if (option_verbose > 1)
08802       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,
08803             ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
08804 
08805    
08806    ast_mutex_unlock(&p->lock);
08807 
08808    return 0;
08809 }

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

05085 {
05086    if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
05087       sip_peer_hold(dialog, holdstate);
05088    if (global_callevents)
05089       manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold",
05090                "Channel: %s\r\n"
05091                "Uniqueid: %s\r\n",
05092                dialog->owner->name, 
05093                dialog->owner->uniqueid);
05094    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data);
05095    if (!holdstate) {    /* Put off remote hold */
05096       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
05097       return;
05098    }
05099    /* No address for RTP, we're on hold */
05100 
05101    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
05102       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
05103    else if (sendonly == 2) /* Inactive stream */
05104       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
05105    else
05106       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
05107    return;
05108 }

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 8576 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_random(), ast_skip_blanks(), ast_string_field_build, 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, sip_methods, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, ast_dynamic_str::str, text, transmit_response_with_auth(), and TRUE.

Referenced by check_user_full(), and register_verify().

08579 {
08580    const char *response = "407 Proxy Authentication Required";
08581    const char *reqheader = "Proxy-Authorization";
08582    const char *respheader = "Proxy-Authenticate";
08583    const char *authtoken;
08584    char a1_hash[256];
08585    char resp_hash[256]="";
08586    char *c;
08587    int  wrongnonce = FALSE;
08588    int  good_response;
08589    const char *usednonce = p->randdata;
08590    struct ast_dynamic_str *buf;
08591    int res;
08592 
08593    /* table of recognised keywords, and their value in the digest */
08594    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
08595    struct x {
08596       const char *key;
08597       const char *s;
08598    } *i, keys[] = {
08599       [K_RESP] = { "response=", "" },
08600       [K_URI] = { "uri=", "" },
08601       [K_USER] = { "username=", "" },
08602       [K_NONCE] = { "nonce=", "" },
08603       [K_LAST] = { NULL, NULL}
08604    };
08605 
08606    /* Always OK if no secret */
08607    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
08608       return AUTH_SUCCESSFUL;
08609    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
08610       /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
08611          of headers -- GO SIP!  Whoo hoo!  Two things that do the same thing but are used in
08612          different circumstances! What a surprise. */
08613       response = "401 Unauthorized";
08614       reqheader = "Authorization";
08615       respheader = "WWW-Authenticate";
08616    }
08617    authtoken =  get_header(req, reqheader);  
08618    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
08619       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
08620          information */
08621       if (!reliable) {
08622          /* Resend message if this was NOT a reliable delivery.   Otherwise the
08623             retransmission should get it */
08624          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08625          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
08626          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08627       }
08628       return AUTH_CHALLENGE_SENT;
08629    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
08630       /* We have no auth, so issue challenge and request authentication */
08631       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08632       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
08633       /* Schedule auto destroy in 32 seconds */
08634       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08635       return AUTH_CHALLENGE_SENT;
08636    } 
08637 
08638    /* --- We have auth, so check it */
08639 
08640    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
08641          an example in the spec of just what it is you're doing a hash on. */
08642 
08643    if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN)))
08644       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
08645 
08646    /* Make a copy of the response and parse it */
08647    res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken);
08648 
08649    if (res == AST_DYNSTR_BUILD_FAILED)
08650       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
08651 
08652    c = buf->str;
08653 
08654    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
08655       for (i = keys; i->key != NULL; i++) {
08656          const char *separator = ",";  /* default */
08657 
08658          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
08659             continue;
08660          /* Found. Skip keyword, take text in quotes or up to the separator. */
08661          c += strlen(i->key);
08662          if (*c == '"') { /* in quotes. Skip first and look for last */
08663             c++;
08664             separator = "\"";
08665          }
08666          i->s = c;
08667          strsep(&c, separator);
08668          break;
08669       }
08670       if (i->key == NULL) /* not found, jump after space or comma */
08671          strsep(&c, " ,");
08672    }
08673 
08674    /* Verify that digest username matches  the username we auth as */
08675    if (strcmp(username, keys[K_USER].s)) {
08676       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
08677          username, keys[K_USER].s);
08678       /* Oops, we're trying something here */
08679       return AUTH_USERNAME_MISMATCH;
08680    }
08681 
08682    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
08683    if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
08684       wrongnonce = TRUE;
08685       usednonce = keys[K_NONCE].s;
08686    }
08687 
08688    if (!ast_strlen_zero(md5secret))
08689       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
08690    else {
08691       char a1[256];
08692       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
08693       ast_md5_hash(a1_hash, a1);
08694    }
08695 
08696    /* compute the expected response to compare with what we received */
08697    {
08698       char a2[256];
08699       char a2_hash[256];
08700       char resp[256];
08701 
08702       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
08703             S_OR(keys[K_URI].s, uri));
08704       ast_md5_hash(a2_hash, a2);
08705       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
08706       ast_md5_hash(resp_hash, resp);
08707    }
08708 
08709    good_response = keys[K_RESP].s &&
08710          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
08711    if (wrongnonce) {
08712       if (good_response) {
08713          if (sipdebug)
08714             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
08715          /* We got working auth token, based on stale nonce . */
08716          ast_string_field_build(p, randdata, "%08lx", ast_random());
08717          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
08718       } else {
08719          /* Everything was wrong, so give the device one more try with a new challenge */
08720          if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
08721             if (sipdebug)
08722                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
08723             ast_string_field_build(p, randdata, "%08lx", ast_random());
08724          } else {
08725             if (sipdebug)
08726                ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
08727          }
08728          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
08729       }
08730 
08731       /* Schedule auto destroy in 32 seconds */
08732       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
08733       return AUTH_CHALLENGE_SENT;
08734    } 
08735    if (good_response) {
08736       append_history(p, "AuthOK", "Auth challenge succesful for %s", username);
08737       return AUTH_SUCCESSFUL;
08738    }
08739 
08740    /* Ok, we have a bad username/secret pair */
08741    /* Tell the UAS not to re-send this authentication data, because
08742       it will continue to fail
08743    */
08744 
08745    return AUTH_SECRET_FAILED;
08746 }

static void check_auth_buf_init ( void   )  [static]

Definition at line 8568 of file chan_sip.c.

08579 {

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

Definition at line 12268 of file chan_sip.c.

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

Referenced by handle_request(), and handle_response_invite().

12269 {
12270    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
12271       /* if we can't BYE, then this is really a pending CANCEL */
12272       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
12273          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
12274          /* Actually don't destroy us yet, wait for the 487 on our original 
12275             INVITE, but do set an autodestruct just in case we never get it. */
12276       else {
12277          /* We have a pending outbound invite, don't send someting
12278             new in-transaction */
12279          if (p->pendinginvite)
12280             return;
12281 
12282          /* Perhaps there is an SD change INVITE outstanding */
12283          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
12284       }
12285       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
12286       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12287    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
12288       /* if we can't REINVITE, hold it for later */
12289       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
12290          if (option_debug)
12291             ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
12292       } else {
12293          if (option_debug)
12294             ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
12295          /* Didn't get to reinvite yet, so do it now */
12296          transmit_reinvite_with_sdp(p);
12297          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
12298       }
12299    }
12300 }

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

16960 {
16961    struct domain *d;
16962    int result = 0;
16963 
16964    AST_LIST_LOCK(&domain_list);
16965    AST_LIST_TRAVERSE(&domain_list, d, list) {
16966       if (strcasecmp(d->domain, domain))
16967          continue;
16968 
16969       if (len && !ast_strlen_zero(d->context))
16970          ast_copy_string(context, d->context, len);
16971       
16972       result = 1;
16973       break;
16974    }
16975    AST_LIST_UNLOCK(&domain_list);
16976 
16977    return result;
16978 }

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

References check_user_full().

Referenced by handle_request_invite().

09890 {
09891    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
09892 }

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

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

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 9433 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_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.

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

09434 {
09435    char via[512];
09436    char *c, *pt;
09437    struct hostent *hp;
09438    struct ast_hostent ahp;
09439 
09440    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
09441 
09442    /* Work on the leftmost value of the topmost Via header */
09443    c = strchr(via, ',');
09444    if (c)
09445       *c = '\0';
09446 
09447    /* Check for rport */
09448    c = strstr(via, ";rport");
09449    if (c && (c[6] != '=')) /* rport query, not answer */
09450       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
09451 
09452    c = strchr(via, ';');
09453    if (c) 
09454       *c = '\0';
09455 
09456    c = strchr(via, ' ');
09457    if (c) {
09458       *c = '\0';
09459       c = ast_skip_blanks(c+1);
09460       if (strcasecmp(via, "SIP/2.0/UDP")) {
09461          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
09462          return;
09463       }
09464       pt = strchr(c, ':');
09465       if (pt)
09466          *pt++ = '\0';  /* remember port pointer */
09467       hp = ast_gethostbyname(c, &ahp);
09468       if (!hp) {
09469          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
09470          return;
09471       }
09472       memset(&p->sa, 0, sizeof(p->sa));
09473       p->sa.sin_family = AF_INET;
09474       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
09475       p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT);
09476 
09477       if (sip_debug_test_pvt(p)) {
09478          const struct sockaddr_in *dst = sip_real_dst(p);
09479          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
09480       }
09481    }
09482 }

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

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

10334 {
10335    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
10336 
10337    while ((oldcontext = strsep(&old, "&"))) {
10338       stalecontext = '\0';
10339       ast_copy_string(newlist, new, sizeof(newlist));
10340       stringp = newlist;
10341       while ((newcontext = strsep(&stringp, "&"))) {
10342          if (strcmp(newcontext, oldcontext) == 0) {
10343             /* This is not the context you're looking for */
10344             stalecontext = '\0';
10345             break;
10346          } else if (strcmp(newcontext, oldcontext)) {
10347             stalecontext = oldcontext;
10348          }
10349          
10350       }
10351       if (stalecontext)
10352          ast_context_destroy(ast_context_find(stalecontext), "SIP");
10353    }
10354 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 17052 of file chan_sip.c.

References free, and sip_auth::next.

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

17053 {
17054    struct sip_auth *a = authlist;
17055    struct sip_auth *b;
17056 
17057    while (a) {
17058       b = a;
17059       a = a->next;
17060       free(b);
17061    }
17062 
17063    return 1;
17064 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

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

16982 {
16983    struct domain *d;
16984 
16985    AST_LIST_LOCK(&domain_list);
16986    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
16987       free(d);
16988    AST_LIST_UNLOCK(&domain_list);
16989 }

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

References complete_sip_peer().

11148 {
11149    if (pos == 3)
11150       return complete_sip_peer(word, state, 0);
11151 
11152    return NULL;
11153 }

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

Do completion on peer name.

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

11122 {
11123    char *result = NULL;
11124    int wordlen = strlen(word);
11125    int which = 0;
11126 
11127    ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
11128       /* locking of the object is not required because only the name and flags are being compared */
11129       if (!strncasecmp(word, iterator->name, wordlen) &&
11130             (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
11131             ++which > state)
11132          result = ast_strdup(iterator->name);
11133    } while(0) );
11134    return result;
11135 }

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

References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.

11216 {
11217    if (pos == 4)
11218       return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11219    return NULL;
11220 }

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

References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.

11224 {
11225    if (pos == 4)
11226       return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS);
11227 
11228    return NULL;
11229 }

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

References complete_sip_peer().

11139 {
11140    if (pos == 3)
11141       return complete_sip_peer(word, state, 0);
11142 
11143    return NULL;
11144 }

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

References complete_sip_user().

11177 {
11178    if (pos == 3)
11179       return complete_sip_user(word, state, 0);
11180 
11181    return NULL;
11182 }

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

Do completion on user name.

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

11157 {
11158    char *result = NULL;
11159    int wordlen = strlen(word);
11160    int which = 0;
11161 
11162    ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do {
11163       /* locking of the object is not required because only the name and flags are being compared */
11164       if (!strncasecmp(word, iterator->name, wordlen)) {
11165          if (flags2 && !ast_test_flag(&iterator->flags[1], flags2))
11166             continue;
11167          if (++which > state) {
11168             result = ast_strdup(iterator->name);
11169          }
11170       }
11171    } while(0) );
11172    return result;
11173 }

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

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

11099 {
11100    int which=0;
11101    struct sip_pvt *cur;
11102    char *c = NULL;
11103    int wordlen = strlen(word);
11104 
11105    if (pos != 3) {
11106       return NULL;
11107    }
11108 
11109    ast_mutex_lock(&iflock);
11110    for (cur = iflist; cur; cur = cur->next) {
11111       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
11112          c = ast_strdup(cur->callid);
11113          break;
11114       }
11115    }
11116    ast_mutex_unlock(&iflock);
11117    return c;
11118 }

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

Support routine for 'sip notify' CLI.

Definition at line 11185 of file chan_sip.c.

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

11186 {
11187    char *c = NULL;
11188 
11189    if (pos == 2) {
11190       int which = 0;
11191       char *cat = NULL;
11192       int wordlen = strlen(word);
11193 
11194       /* do completion for notify type */
11195 
11196       if (!notify_types)
11197          return NULL;
11198       
11199       while ( (cat = ast_category_browse(notify_types, cat)) ) {
11200          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
11201             c = ast_strdup(cat);
11202             break;
11203          }
11204       }
11205       return c;
11206    }
11207 
11208    if (pos > 2)
11209       return complete_sip_peer(word, state, 0);
11210 
11211    return NULL;
11212 }

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

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

Referenced by respprep().

05809 {
05810    int start = 0;
05811    int copied = 0;
05812    for (;;) {
05813       const char *tmp = __get_header(orig, field, &start);
05814 
05815       if (ast_strlen_zero(tmp))
05816          break;
05817       /* Add what we're responding to */
05818       add_header(req, field, tmp);
05819       copied++;
05820    }
05821    return copied ? 0 : -1;
05822 }

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

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

Referenced by reqprep(), and respprep().

05798 {
05799    const char *tmp = get_header(orig, field);
05800 
05801    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
05802       return add_header(req, field, tmp);
05803    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
05804    return -1;
05805 }

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

06858 {
06859    long offset;
06860    int x;
06861    offset = ((void *)dst) - ((void *)src);
06862    /* First copy stuff */
06863    memcpy(dst, src, sizeof(*dst));
06864    /* Now fix pointer arithmetic */
06865    for (x=0; x < src->headers; x++)
06866       dst->header[x] += offset;
06867    for (x=0; x < src->lines; x++)
06868       dst->line[x] += offset;
06869    dst->rlPart1 += offset;
06870    dst->rlPart2 += offset;
06871 }

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

05831 {
05832    int copied = 0;
05833    int start = 0;
05834 
05835    for (;;) {
05836       char new[512];
05837       const char *oh = __get_header(orig, field, &start);
05838 
05839       if (ast_strlen_zero(oh))
05840          break;
05841 
05842       if (!copied) { /* Only check for empty rport in topmost via header */
05843          char leftmost[512], *others, *rport;
05844 
05845          /* Only work on leftmost value */
05846          ast_copy_string(leftmost, oh, sizeof(leftmost));
05847          others = strchr(leftmost, ',');
05848          if (others)
05849              *others++ = '\0';
05850 
05851          /* Find ;rport;  (empty request) */
05852          rport = strstr(leftmost, ";rport");
05853          if (rport && *(rport+6) == '=') 
05854             rport = NULL;     /* We already have a parameter to rport */
05855 
05856          /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting)  */
05857          if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
05858             /* We need to add received port - rport */
05859             char *end;
05860 
05861             rport = strstr(leftmost, ";rport");
05862 
05863             if (rport) {
05864                end = strchr(rport + 1, ';');
05865                if (end)
05866                   memmove(rport, end, strlen(end) + 1);
05867                else
05868                   *rport = '\0';
05869             }
05870 
05871             /* Add rport to first VIA header if requested */
05872             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
05873                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05874                ntohs(p->recv.sin_port),
05875                others ? "," : "", others ? others : "");
05876          } else {
05877             /* We should *always* add a received to the topmost via */
05878             snprintf(new, sizeof(new), "%s;received=%s%s%s",
05879                leftmost, ast_inet_ntoa(p->recv.sin_addr),
05880                others ? "," : "", others ? others : "");
05881          }
05882          oh = new;   /* the header to copy */
05883       }  /* else add the following via headers untouched */
05884       add_header(req, field, oh);
05885       copied++;
05886    }
05887    if (!copied) {
05888       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
05889       return -1;
05890    }
05891    return 0;
05892 }

static int create_addr ( struct sip_pvt dialog,
const char *  opeer 
) [static]

create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success

Definition at line 2909 of file chan_sip.c.

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

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

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

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

static void destroy_association ( struct sip_peer peer  )  [static]

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

Definition at line 8050 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, and SIP_PAGE2_RT_FROMCONTACT.

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

08051 {
08052    if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
08053       if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT))
08054          ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL);
08055       else 
08056          ast_db_del("SIP/Registry", peer->name);
08057    }
08058 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

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

06902 {
06903    char *e = ast_skip_blanks(req->header[0]);   /* there shouldn't be any */
06904 
06905    if (!*e)
06906       return -1;
06907    req->rlPart1 = e; /* method or protocol */
06908    e = ast_skip_nonblanks(e);
06909    if (*e)
06910       *e++ = '\0';
06911    /* Get URI or status code */
06912    e = ast_skip_blanks(e);
06913    if ( !*e )
06914       return -1;
06915    ast_trim_blanks(e);
06916 
06917    if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
06918       if (strlen(e) < 3)   /* status code is 3 digits */
06919          return -1;
06920       req->rlPart2 = e;
06921    } else { /* We have a request */
06922       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
06923          ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
06924          e++;
06925          if (!*e)
06926             return -1; 
06927       }
06928       req->rlPart2 = e; /* URI */
06929       e = ast_skip_nonblanks(e);
06930       if (*e)
06931          *e++ = '\0';
06932       e = ast_skip_blanks(e);
06933       if (strcasecmp(e, "SIP/2.0") ) {
06934          ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
06935          return -1;
06936       }
06937    }
06938    return 1;
06939 }

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

References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), DEADLOCK_AVOIDANCE, FALSE, sip_pvt::flags, iflist, iflock, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sip_reload_lock, sipsock, sipsock_read(), t, T38_ENABLED, and VERBOSE_PREFIX_1.

16260 {
16261    int res;
16262    struct sip_pvt *sip;
16263    struct sip_peer *peer = NULL;
16264    time_t t;
16265    int fastrestart = FALSE;
16266    int lastpeernum = -1;
16267    int curpeernum;
16268    int reloading;
16269 
16270    /* Add an I/O event to our SIP UDP socket */
16271    if (sipsock > -1) 
16272       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
16273    
16274    /* From here on out, we die whenever asked */
16275    for(;;) {
16276       /* Check for a reload request */
16277       ast_mutex_lock(&sip_reload_lock);
16278       reloading = sip_reloading;
16279       sip_reloading = FALSE;
16280       ast_mutex_unlock(&sip_reload_lock);
16281       if (reloading) {
16282          if (option_verbose > 0)
16283             ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
16284          sip_do_reload(sip_reloadreason);
16285 
16286          /* Change the I/O fd of our UDP socket */
16287          if (sipsock > -1) {
16288             if (sipsock_read_id)
16289                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
16290             else
16291                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
16292          } else if (sipsock_read_id) {
16293             ast_io_remove(io, sipsock_read_id);
16294             sipsock_read_id = NULL;
16295          }
16296       }
16297 restartsearch:    
16298       /* Check for interfaces needing to be killed */
16299       ast_mutex_lock(&iflock);
16300       t = time(NULL);
16301       /* don't scan the interface list if it hasn't been a reasonable period
16302          of time since the last time we did it (when MWI is being sent, we can
16303          get back to this point every millisecond or less)
16304       */
16305       for (sip = iflist; !fastrestart && sip; sip = sip->next) {
16306          /*! \note If we can't get a lock on an interface, skip it and come
16307           * back later. Note that there is the possibility of a deadlock with
16308           * sip_hangup otherwise, because sip_hangup is called with the channel
16309           * locked first, and the iface lock is attempted second.
16310           */
16311          if (ast_mutex_trylock(&sip->lock))
16312             continue;
16313 
16314          /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
16315          if (sip->rtp && sip->owner &&
16316              (sip->owner->_state == AST_STATE_UP) &&
16317              !sip->redirip.sin_addr.s_addr &&
16318              sip->t38.state != T38_ENABLED) {
16319             if (sip->lastrtptx &&
16320                 ast_rtp_get_rtpkeepalive(sip->rtp) &&
16321                 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
16322                /* Need to send an empty RTP packet */
16323                sip->lastrtptx = time(NULL);
16324                ast_rtp_sendcng(sip->rtp, 0);
16325             }
16326             if (sip->lastrtprx &&
16327                (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
16328                 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
16329                /* Might be a timeout now -- see if we're on hold */
16330                struct sockaddr_in sin;
16331                ast_rtp_get_peer(sip->rtp, &sin);
16332                if (sin.sin_addr.s_addr || 
16333                    (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
16334                     (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
16335                   /* Needs a hangup */
16336                   if (ast_rtp_get_rtptimeout(sip->rtp)) {
16337                      while (sip->owner && ast_channel_trylock(sip->owner)) {
16338                         DEADLOCK_AVOIDANCE(&sip->lock);
16339                      }
16340                      if (sip->owner) {
16341                         ast_log(LOG_NOTICE,
16342                            "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
16343                            sip->owner->name,
16344                            (long) (t - sip->lastrtprx));
16345                         /* Issue a softhangup */
16346                         ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
16347                         ast_channel_unlock(sip->owner);
16348                         /* forget the timeouts for this call, since a hangup
16349                            has already been requested and we don't want to
16350                            repeatedly request hangups
16351                         */
16352                         ast_rtp_set_rtptimeout(sip->rtp, 0);
16353                         ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
16354                         if (sip->vrtp) {
16355                            ast_rtp_set_rtptimeout(sip->vrtp, 0);
16356                            ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
16357                         }
16358                      }
16359                   }
16360                }
16361             }
16362          }
16363          /* If we have sessions that needs to be destroyed, do it now */
16364          if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
16365              !sip->owner) {
16366             ast_mutex_unlock(&sip->lock);
16367             __sip_destroy(sip, 1);
16368             ast_mutex_unlock(&iflock);
16369             usleep(1);
16370             goto restartsearch;
16371          }
16372          ast_mutex_unlock(&sip->lock);
16373       }
16374       ast_mutex_unlock(&iflock);
16375 
16376       /* XXX TODO The scheduler usage in this module does not have sufficient 
16377        * synchronization being done between running the scheduler and places 
16378        * scheduling tasks.  As it is written, any scheduled item may not run 
16379        * any sooner than about  1 second, regardless of whether a sooner time 
16380        * was asked for. */
16381 
16382       pthread_testcancel();
16383       /* Wait for sched or io */
16384       res = ast_sched_wait(sched);
16385       if ((res < 0) || (res > 1000))
16386          res = 1000;
16387       /* If we might need to send more mailboxes, don't wait long at all.*/
16388       if (fastrestart)
16389          res = 1;
16390       res = ast_io_wait(io, res);
16391       if (option_debug && res > 20)
16392          ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
16393       ast_mutex_lock(&monlock);
16394       res = ast_sched_runq(sched);
16395       if (option_debug && res >= 20)
16396          ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
16397 
16398       /* Send MWI notifications to peers - static and cached realtime peers */
16399       t = time(NULL);
16400       fastrestart = FALSE;
16401       curpeernum = 0;
16402       peer = NULL;
16403       /* Find next peer that needs mwi */
16404       ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
16405          if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
16406             fastrestart = TRUE;
16407             lastpeernum = curpeernum;
16408             peer = ASTOBJ_REF(iterator);
16409          };
16410          curpeernum++;
16411       } while (0)
16412       );
16413       /* Send MWI to the peer */
16414       if (peer) {
16415          ASTOBJ_WRLOCK(peer);
16416          sip_send_mwi_to_peer(peer);
16417          ASTOBJ_UNLOCK(peer);
16418          ASTOBJ_UNREF(peer,sip_destroy_peer);
16419       } else {
16420          /* Reset where we come from */
16421          lastpeernum = -1;
16422       }
16423       ast_mutex_unlock(&monlock);
16424    }
16425    /* Never reached */
16426    return NULL;
16427    
16428 }

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

11696 {
11697    char digest[1024];
11698 
11699    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
11700       return -2;
11701 
11702    p->authtries++;
11703    if (option_debug > 1)
11704       ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
11705    memset(digest, 0, sizeof(digest));
11706    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
11707       /* No way to authenticate */
11708       return -1;
11709    }
11710    /* Now we have a reply digest */
11711    p->options->auth = digest;
11712    p->options->authheader = respheader;
11713    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
11714 }

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

11675 {
11676    char digest[1024];
11677    p->authtries++;
11678    memset(digest,0,sizeof(digest));
11679    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
11680       /* There's nothing to use for authentication */
11681       /* No digest challenge in request */
11682       if (sip_debug_test_pvt(p) && p->registry)
11683          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
11684          /* No old challenge */
11685       return -1;
11686    }
11687    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
11688       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
11689    if (sip_debug_test_pvt(p) && p->registry)
11690       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
11691    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
11692 }

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

Set nat mode on the various data sockets.

Definition at line 2776 of file chan_sip.c.

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

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

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

static int does_peer_need_mwi ( struct sip_peer peer  )  [static]

Check whether peer needs a new MWI notification check.

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

16239 {
16240    time_t t = time(NULL);
16241 
16242    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
16243        !peer->mwipvt) { /* We don't have a subscription */
16244       peer->lastmsgcheck = t; /* Reset timer */
16245       return FALSE;
16246    }
16247 
16248    if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime)
16249       return TRUE;
16250 
16251    return FALSE;
16252 }

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

Print domain mode to cli.

Definition at line 10522 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

10523 {
10524    switch (mode) {
10525    case SIP_DOMAIN_AUTO:
10526       return "[Automatic]";
10527    case SIP_DOMAIN_CONFIG:
10528       return "[Configured]";
10529    }
10530 
10531    return "";
10532 }

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

Convert DTMF mode to printable string.

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

10303 {
10304    switch (mode) {
10305    case SIP_DTMF_RFC2833:
10306       return "rfc2833";
10307    case SIP_DTMF_INFO:
10308       return "info";
10309    case SIP_DTMF_INBAND:
10310       return "inband";
10311    case SIP_DTMF_AUTO:
10312       return "auto";
10313    }
10314    return "<error>";
10315 }

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

Expire registration of SIP peer.

Definition at line 8061 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, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.

Referenced by parse_register_contact(), and reg_source_db().

08062 {
08063    struct sip_peer *peer = (struct sip_peer *)data;
08064    
08065    if (!peer)     /* Hmmm. We have no peer. Weird. */
08066       return 0;
08067 
08068    memset(&peer->addr, 0, sizeof(peer->addr));
08069 
08070    destroy_association(peer); /* remove registration data from storage */
08071    
08072    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08073    register_peer_exten(peer, FALSE);   /* Remove regexten */
08074    peer->expire = -1;
08075    ast_device_state_changed("SIP/%s", peer->name);
08076 
08077    /* Do we need to release this peer from memory? 
08078       Only for realtime peers and autocreated peers
08079    */
08080    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
08081        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
08082       struct sip_peer *peer_ptr = peer_ptr;
08083       peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);
08084       if (peer_ptr) {
08085          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08086       }
08087    }
08088 
08089    ASTOBJ_UNREF(peer, sip_destroy_peer);
08090 
08091    return 0;
08092 }

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

Check Contact: URI of SIP message.

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

06992 {
06993    char stripped[SIPBUFSIZE];
06994    char *c;
06995 
06996    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
06997    c = get_in_brackets(stripped);
06998    c = strsep(&c, ";"); /* trim ; and beyond */
06999    if (!ast_strlen_zero(c))
07000       ast_string_field_set(p, uri, c);
07001 }

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

References aliases.

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

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

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

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

References s.

Referenced by get_in_brackets().

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

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

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

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

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

Find authentication for a specific realm.

Definition at line 17067 of file chan_sip.c.

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

Referenced by build_reply_digest().

17068 {
17069    struct sip_auth *a;
17070 
17071    for (a = authlist; a; a = a->next) {
17072       if (!strcasecmp(a->realm, realm))
17073          break;
17074    }
17075 
17076    return a;
17077 }

static int find_sdp ( struct sip_request req  )  [static]

Determine whether a SIP message contains an SDP in its body.

Parameters:
req the SIP request to process
Returns:
1 if SDP found, 0 if not found
Also updates req->sdp_start and req->sdp_end to indicate where the SDP lives in the message body.

Definition at line 4992 of file chan_sip.c.

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

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

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

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

find_sip_method: Find SIP method from header

Definition at line 1695 of file chan_sip.c.

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

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

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

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

Find subscription type in array.

Definition at line 11010 of file chan_sip.c.

References subscription_types, and type.

Referenced by transmit_state_notify().

11011 {
11012    int i;
11013 
11014    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
11015       if (subscription_types[i].type == subtype) {
11016          return &subscription_types[i];
11017       }
11018    }
11019    return &subscription_types[0];
11020 }

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

References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.

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

static void free_old_route ( struct sip_route route  )  [static]

Remove route from route list.

Definition at line 8440 of file chan_sip.c.

References free, and sip_route::next.

Referenced by __sip_destroy(), and build_route().

08441 {
08442    struct sip_route *next;
08443 
08444    while (route) {
08445       next = route->next;
08446       free(route);
08447       route = next;
08448    }
08449 }

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

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

12031 {
12032    if (ast_strlen_zero(data)) {
12033       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
12034       return -1;
12035    }
12036    if (check_sip_domain(data, NULL, 0))
12037       ast_copy_string(buf, data, len);
12038    else
12039       buf[0] = '\0';
12040    return 0;
12041 }

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

11967 {
11968    struct sip_pvt *p;
11969    const char *content = NULL;
11970    AST_DECLARE_APP_ARGS(args,
11971       AST_APP_ARG(header);
11972       AST_APP_ARG(number);
11973    );
11974    int i, number, start = 0;
11975 
11976    if (ast_strlen_zero(data)) {
11977       ast_log(LOG_WARNING, "This function requires a header name.\n");
11978       return -1;
11979    }
11980 
11981    ast_channel_lock(chan);
11982    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
11983       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
11984       ast_channel_unlock(chan);
11985       return -1;
11986    }
11987 
11988    AST_STANDARD_APP_ARGS(args, data);
11989    if (!args.number) {
11990       number = 1;
11991    } else {
11992       sscanf(args.number, "%d", &number);
11993       if (number < 1)
11994          number = 1;
11995    }
11996 
11997    p = chan->tech_pvt;
11998 
11999    /* If there is no private structure, this channel is no longer alive */
12000    if (!p) {
12001       ast_channel_unlock(chan);
12002       return -1;
12003    }
12004 
12005    for (i = 0; i < number; i++)
12006       content = __get_header(&p->initreq, args.header, &start);
12007 
12008    if (ast_strlen_zero(content)) {
12009       ast_channel_unlock(chan);
12010       return -1;
12011    }
12012 
12013    ast_copy_string(buf, content, len);
12014    ast_channel_unlock(chan);
12015 
12016    return 0;
12017 }

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

12150 {
12151    struct sip_pvt *p;
12152 
12153    *buf = 0;
12154    
12155    if (!data) {
12156       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
12157       return -1;
12158    }
12159 
12160    ast_channel_lock(chan);
12161    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
12162       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
12163       ast_channel_unlock(chan);
12164       return -1;
12165    }
12166 
12167    p = chan->tech_pvt;
12168 
12169    /* If there is no private structure, this channel is no longer alive */
12170    if (!p) {
12171       ast_channel_unlock(chan);
12172       return -1;
12173    }
12174 
12175    if (!strcasecmp(data, "peerip")) {
12176       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
12177    } else  if (!strcasecmp(data, "recvip")) {
12178       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
12179    } else  if (!strcasecmp(data, "from")) {
12180       ast_copy_string(buf, p->from, len);
12181    } else  if (!strcasecmp(data, "uri")) {
12182       ast_copy_string(buf, p->uri, len);
12183    } else  if (!strcasecmp(data, "useragent")) {
12184       ast_copy_string(buf, p->useragent, len);
12185    } else  if (!strcasecmp(data, "peername")) {
12186       ast_copy_string(buf, p->peername, len);
12187    } else if (!strcasecmp(data, "t38passthrough")) {
12188       if (p->t38.state == T38_DISABLED)
12189          ast_copy_string(buf, "0", sizeof("0"));
12190       else    /* T38 is offered or enabled in this call */
12191          ast_copy_string(buf, "1", sizeof("1"));
12192    } else {
12193       ast_channel_unlock(chan);
12194       return -1;
12195    }
12196    ast_channel_unlock(chan);
12197 
12198    return 0;
12199 }

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

12056 {
12057    struct sip_peer *peer;
12058    char *colname;
12059 
12060    if ((colname = strchr(data, ':')))  /*! \todo Will be deprecated after 1.4 */
12061       *colname++ = '\0';
12062    else if ((colname = strchr(data, '|')))
12063       *colname++ = '\0';
12064    else
12065       colname = "ip";
12066 
12067    if (!(peer = find_peer(data, NULL, 1, 0)))
12068       return -1;
12069 
12070    if (!strcasecmp(colname, "ip")) {
12071       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
12072    } else  if (!strcasecmp(colname, "status")) {
12073       peer_status(peer, buf, len);
12074    } else  if (!strcasecmp(colname, "language")) {
12075       ast_copy_string(buf, peer->language, len);
12076    } else  if (!strcasecmp(colname, "regexten")) {
12077       ast_copy_string(buf, peer->regexten, len);
12078    } else  if (!strcasecmp(colname, "limit")) {
12079       snprintf(buf, len, "%d", peer->call_limit);
12080    } else  if (!strcasecmp(colname, "curcalls")) {
12081       snprintf(buf, len, "%d", peer->inUse);
12082    } else  if (!strcasecmp(colname, "accountcode")) {
12083       ast_copy_string(buf, peer->accountcode, len);
12084    } else  if (!strcasecmp(colname, "useragent")) {
12085       ast_copy_string(buf, peer->useragent, len);
12086    } else  if (!strcasecmp(colname, "mailbox")) {
12087       ast_copy_string(buf, peer->mailbox, len);
12088    } else  if (!strcasecmp(colname, "context")) {
12089       ast_copy_string(buf, peer->context, len);
12090    } else  if (!strcasecmp(colname, "expire")) {
12091       snprintf(buf, len, "%d", peer->expire);
12092    } else  if (!strcasecmp(colname, "dynamic")) {
12093       ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
12094    } else  if (!strcasecmp(colname, "callerid_name")) {
12095       ast_copy_string(buf, peer->cid_name, len);
12096    } else  if (!strcasecmp(colname, "callerid_num")) {
12097       ast_copy_string(buf, peer->cid_num, len);
12098    } else  if (!strcasecmp(colname, "codecs")) {
12099       ast_getformatname_multiple(buf, len -1, peer->capability);
12100    } else  if (!strncasecmp(colname, "codec[", 6)) {
12101       char *codecnum;
12102       int index = 0, codec = 0;
12103       
12104       codecnum = colname + 6; /* move past the '[' */
12105       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
12106       index = atoi(codecnum);
12107       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
12108          ast_copy_string(buf, ast_getformatname(codec), len);
12109       } else {
12110          buf[0] = '\0';
12111       }
12112    } else {
12113       buf[0] = '\0';
12114    }
12115 
12116    ASTOBJ_UNREF(peer, sip_destroy_peer);
12117 
12118    return 0;
12119 }

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

Generate 32 byte random string for callid's etc.

Definition at line 4487 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

04488 {
04489    long val[4];
04490    int x;
04491 
04492    for (x=0; x<4; x++)
04493       val[x] = ast_random();
04494    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
04495 
04496    return buf;
04497 }

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

09374 {
09375    char tmp[256] = "", *c, *a;
09376    struct sip_request *req = oreq ? oreq : &p->initreq;
09377    struct sip_refer *referdata = NULL;
09378    const char *transfer_context = NULL;
09379    
09380    if (!p->refer && !sip_refer_allocate(p))
09381       return -1;
09382 
09383    referdata = p->refer;
09384 
09385    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
09386    c = get_in_brackets(tmp);
09387 
09388    if (pedanticsipchecking)
09389       ast_uri_decode(c);
09390    
09391    if (strncasecmp(c, "sip:", 4)) {
09392       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
09393       return -1;
09394    }
09395    c += 4;
09396    if ((a = strchr(c, ';')))  /* Remove arguments */
09397       *a = '\0';
09398    
09399    if ((a = strchr(c, '@'))) {   /* Separate Domain */
09400       *a++ = '\0';
09401       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
09402    }
09403    
09404    if (sip_debug_test_pvt(p))
09405       ast_verbose("Looking for %s in %s\n", c, p->context);
09406 
09407    if (p->owner)  /* Mimic behaviour in res_features.c */
09408       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
09409 
09410    /* By default, use the context in the channel sending the REFER */
09411    if (ast_strlen_zero(transfer_context)) {
09412       transfer_context = S_OR(p->owner->macrocontext,
09413                S_OR(p->context, default_context));
09414    }
09415    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
09416       /* This is a blind transfer */
09417       if (option_debug)
09418          ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
09419       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
09420       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
09421       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
09422       referdata->refer_call = NULL;
09423       /* Set new context */
09424       ast_string_field_set(p, context, transfer_context);
09425       return 0;
09426    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
09427       return 1;
09428    }
09429 
09430    return -1;
09431 }

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

Get a specific line from the message body.

Definition at line 4281 of file chan_sip.c.

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

Referenced by handle_request_info().

04282 {
04283    int x;
04284    int len = strlen(name);
04285    char *r;
04286 
04287    for (x = 0; x < req->lines; x++) {
04288       r = get_body_by_line(req->line[x], name, len);
04289       if (r[0] != '\0')
04290          return r;
04291    }
04292 
04293    return "";
04294 }

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

References ast_skip_blanks().

Referenced by get_body(), and get_sdp_iterate().

04248 {
04249    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
04250       return ast_skip_blanks(line + nameLen + 1);
04251 
04252    return "";
04253 }

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

Get caller id name from SIP headers.

Definition at line 9485 of file chan_sip.c.

References ast_copy_string(), and ast_skip_blanks().

Referenced by check_user_full().

09486 {
09487    const char *end = strchr(input,'<');   /* first_bracket */
09488    const char *tmp = strchr(input,'"');   /* first quote */
09489    int bytes = 0;
09490    int maxbytes = outputsize - 1;
09491 
09492    if (!end || end == input)  /* we require a part in brackets */
09493       return NULL;
09494 
09495    end--; /* move just before "<" */
09496 
09497    if (tmp && tmp <= end) {
09498       /* The quote (tmp) precedes the bracket (end+1).
09499        * Find the matching quote and return the content.
09500        */
09501       end = strchr(tmp+1, '"');
09502       if (!end)
09503          return NULL;
09504       bytes = (int) (end - tmp);
09505       /* protect the output buffer */
09506       if (bytes > maxbytes)
09507          bytes = maxbytes;
09508       ast_copy_string(output, tmp + 1, bytes);
09509    } else {
09510       /* No quoted string, or it is inside brackets. */
09511       /* clear the empty characters in the begining*/
09512       input = ast_skip_blanks(input);
09513       /* clear the empty characters in the end */
09514       while(*end && *end < 33 && end > input)
09515          end--;
09516       if (end >= input) {
09517          bytes = (int) (end - input) + 2;
09518          /* protect the output buffer */
09519          if (bytes > maxbytes)
09520             bytes = maxbytes;
09521          ast_copy_string(output, input, bytes);
09522       } else
09523          return NULL;
09524    }
09525    return output;
09526 }

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 9020 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, sip_pvt::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().

09021 {
09022    char tmp[256] = "", *uri, *a;
09023    char tmpf[256] = "", *from;
09024    struct sip_request *req;
09025    char *colon;
09026    char *decoded_uri;
09027    
09028    req = oreq;
09029    if (!req)
09030       req = &p->initreq;
09031 
09032    /* Find the request URI */
09033    if (req->rlPart2)
09034       ast_copy_string(tmp, req->rlPart2, sizeof(tmp));
09035    
09036    if (pedanticsipchecking)
09037       ast_uri_decode(tmp);
09038 
09039    uri = get_in_brackets(tmp);
09040 
09041    if (strncasecmp(uri, "sip:", 4)) {
09042       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
09043       return -1;
09044    }
09045    uri += 4;
09046 
09047    /* Now find the From: caller ID and name */
09048    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
09049    if (!ast_strlen_zero(tmpf)) {
09050       if (pedanticsipchecking)
09051          ast_uri_decode(tmpf);
09052       from = get_in_brackets(tmpf);
09053    } else {
09054       from = NULL;
09055    }
09056    
09057    if (!ast_strlen_zero(from)) {
09058       if (strncasecmp(from, "sip:", 4)) {
09059          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
09060          return -1;
09061       }
09062       from += 4;
09063       if ((a = strchr(from, '@')))
09064          *a++ = '\0';
09065       else
09066          a = from;   /* just a domain */
09067       from = strsep(&from, ";"); /* Remove userinfo options */
09068       a = strsep(&a, ";");    /* Remove URI options */
09069       ast_string_field_set(p, fromdomain, a);
09070    }
09071 
09072    /* Skip any options and find the domain */
09073 
09074    /* Get the target domain */
09075    if ((a = strchr(uri, '@'))) {
09076       *a++ = '\0';
09077    } else { /* No username part */
09078       a = uri;
09079       uri = "s";  /* Set extension to "s" */
09080    }
09081    colon = strchr(a, ':'); /* Remove :port */
09082    if (colon)
09083       *colon = '\0';
09084 
09085    uri = strsep(&uri, ";");   /* Remove userinfo options */
09086    a = strsep(&a, ";");    /* Remove URI options */
09087 
09088    ast_string_field_set(p, domain, a);
09089 
09090    if (!AST_LIST_EMPTY(&domain_list)) {
09091       char domain_context[AST_MAX_EXTENSION];
09092 
09093       domain_context[0] = '\0';
09094       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
09095          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
09096             if (option_debug)
09097                ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
09098             return -2;
09099          }
09100       }
09101       /* If we have a context defined, overwrite the original context */
09102       if (!ast_strlen_zero(domain_context))
09103          ast_string_field_set(p, context, domain_context);
09104    }
09105 
09106    /* If the request coming in is a subscription and subscribecontext has been specified use it */
09107    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext))
09108       ast_string_field_set(p, context, p->subscribecontext);
09109 
09110    if (sip_debug_test_pvt(p))
09111       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
09112 
09113    /* If this is a subscription we actually just need to see if a hint exists for the extension */
09114    if (req->method == SIP_SUBSCRIBE) {
09115       char hint[AST_MAX_EXTENSION];
09116       return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1);
09117    } else {
09118       decoded_uri = ast_strdupa(uri);
09119       ast_uri_decode(decoded_uri);
09120       /* Check the dialplan for the username part of the request URI,
09121          the domain will be stored in the SIPDOMAIN variable
09122          Since extensions.conf can have unescaped characters, try matching a decoded
09123          uri in addition to the non-decoded uri
09124          Return 0 if we have a matching extension */
09125       if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) ||
09126           !strcmp(decoded_uri, ast_pickup_ext())) {
09127          if (!oreq)
09128             ast_string_field_set(p, exten, decoded_uri);
09129          return 0;
09130       } 
09131    }
09132 
09133    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
09134    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
09135        ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) ||
09136        !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) {
09137       return 1;
09138    }
09139    
09140    return -1;
09141 }

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

Get header from SIP request.

Definition at line 4370 of file chan_sip.c.

References __get_header().

04371 {
04372    int start = 0;
04373    return __get_header(req, name, &start);
04374 }

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

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

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

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

Referenced by handle_request_notify(), and receive_message().

09896 {
09897    int x;
09898    int y;
09899 
09900    buf[0] = '\0';
09901    y = len - strlen(buf) - 5;
09902    if (y < 0)
09903       y = 0;
09904    for (x=0;x<req->lines;x++) {
09905       strncat(buf, req->line[x], y); /* safe */
09906       y -= strlen(req->line[x]) + 1;
09907       if (y < 0)
09908          y = 0;
09909       if (y != 0)
09910          strcat(buf, "\n"); /* safe */
09911    }
09912    return 0;
09913 }

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

Get referring dnis.

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

08992 {
08993    char tmp[256], *c, *a;
08994    struct sip_request *req;
08995    
08996    req = oreq;
08997    if (!req)
08998       req = &p->initreq;
08999    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
09000    if (ast_strlen_zero(tmp))
09001       return 0;
09002    c = get_in_brackets(tmp);
09003    if (strncasecmp(c, "sip:", 4)) {
09004       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
09005       return -1;
09006    }
09007    c += 4;
09008    a = c;
09009    strsep(&a, "@;"); /* trim anything after @ or ; */
09010    if (sip_debug_test_pvt(p))
09011       ast_verbose("RDNIS is %s\n", c);
09012    ast_string_field_set(p, rdnis, c);
09013 
09014    return 0;
09015 }

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 9207 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::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, and sip_debug_test_pvt().

Referenced by handle_request_refer().

09208 {
09209 
09210    const char *p_referred_by = NULL;
09211    char *h_refer_to = NULL; 
09212    char *h_referred_by = NULL;
09213    char *refer_to;
09214    const char *p_refer_to;
09215    char *referred_by_uri = NULL;
09216    char *ptr;
09217    struct sip_request *req = NULL;
09218    const char *transfer_context = NULL;
09219    struct sip_refer *referdata;
09220 
09221 
09222    req = outgoing_req;
09223    referdata = transferer->refer;
09224 
09225    if (!req)
09226       req = &transferer->initreq;
09227 
09228    p_refer_to = get_header(req, "Refer-To");
09229    if (ast_strlen_zero(p_refer_to)) {
09230       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
09231       return -2;  /* Syntax error */
09232    }
09233    h_refer_to = ast_strdupa(p_refer_to);
09234    refer_to = get_in_brackets(h_refer_to);
09235    if (pedanticsipchecking)
09236       ast_uri_decode(refer_to);
09237 
09238    if (strncasecmp(refer_to, "sip:", 4)) {
09239       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
09240       return -3;
09241    }
09242    refer_to += 4;       /* Skip sip: */
09243 
09244    /* Get referred by header if it exists */
09245    p_referred_by = get_header(req, "Referred-By");
09246    if (!ast_strlen_zero(p_referred_by)) {
09247       char *lessthan;
09248       h_referred_by = ast_strdupa(p_referred_by);
09249       if (pedanticsipchecking)
09250          ast_uri_decode(h_referred_by);
09251 
09252       /* Store referrer's caller ID name */
09253       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
09254       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
09255          *(lessthan - 1) = '\0'; /* Space */
09256       }
09257 
09258       referred_by_uri = get_in_brackets(h_referred_by);
09259       if(strncasecmp(referred_by_uri, "sip:", 4)) {
09260          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
09261          referred_by_uri = (char *) NULL;
09262       } else {
09263          referred_by_uri += 4;      /* Skip sip: */
09264       }
09265    }
09266 
09267    /* Check for arguments in the refer_to header */
09268    if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */
09269       *ptr++ = '\0';
09270       if (!strncasecmp(ptr, "REPLACES=", 9)) {
09271          char *to = NULL, *from = NULL;
09272 
09273          /* This is an attended transfer */
09274          referdata->attendedtransfer = 1;
09275          ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
09276          ast_uri_decode(referdata->replaces_callid);
09277          if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
09278             *ptr++ = '\0';
09279          }
09280 
09281          if (ptr) {
09282             /* Find the different tags before we destroy the string */
09283             to = strcasestr(ptr, "to-tag=");
09284             from = strcasestr(ptr, "from-tag=");
09285          }
09286 
09287          /* Grab the to header */
09288          if (to) {
09289             ptr = to + 7;
09290             if ((to = strchr(ptr, '&')))
09291                *to = '\0';
09292             if ((to = strchr(ptr, ';')))
09293                *to = '\0';
09294             ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
09295          }
09296 
09297          if (from) {
09298             ptr = from + 9;
09299             if ((to = strchr(ptr, '&')))
09300                *to = '\0';
09301             if ((to = strchr(ptr, ';')))
09302                *to = '\0';
09303             ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
09304          }
09305 
09306          if (option_debug > 1) {
09307             if (!pedanticsipchecking)
09308                ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
09309             else
09310                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>" );
09311          }
09312       }
09313    }
09314    
09315    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
09316       char *urioption = NULL, *domain;
09317       *ptr++ = '\0';
09318 
09319       if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */
09320          *urioption++ = '\0';
09321       
09322       domain = ptr;
09323       if ((ptr = strchr(domain, ':'))) /* Remove :port */
09324          *ptr = '\0';
09325       
09326       /* Save the domain for the dial plan */
09327       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
09328       if (urioption)
09329          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
09330    }
09331 
09332    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
09333       *ptr = '\0';
09334    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
09335    
09336    if (referred_by_uri) {
09337       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
09338          *ptr = '\0';
09339       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
09340    } else {
09341       referdata->referred_by[0] = '\0';
09342    }
09343 
09344    /* Determine transfer context */
09345    if (transferer->owner)  /* Mimic behaviour in res_features.c */
09346       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
09347 
09348    /* By default, use the context in the channel sending the REFER */
09349    if (ast_strlen_zero(transfer_context)) {
09350       transfer_context = S_OR(transferer->owner->macrocontext,
09351                S_OR(transferer->context, default_context));
09352    }
09353 
09354    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
09355    
09356    /* Either an existing extension or the parking extension */
09357    if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
09358       if (sip_debug_test_pvt(transferer)) {
09359          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
09360       }
09361       /* We are ready to transfer to the extension */
09362       return 0;
09363    } 
09364    if (sip_debug_test_pvt(transferer))
09365       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
09366 
09367    /* Failure, we can't find this extension */
09368    return -1;
09369 }

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

References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

09533 {
09534    char *start;
09535    char *end;
09536 
09537    start = strchr(input,':');
09538    if (!start) {
09539       output[0] = '\0';
09540       return 0;
09541    }
09542    start++;
09543 
09544    /* we found "number" */
09545    ast_copy_string(output,start,maxlen);
09546    output[maxlen-1] = '\0';
09547 
09548    end = strchr(output,'@');
09549    if (end)
09550       *end = '\0';
09551    else
09552       output[0] = '\0';
09553    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
09554       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
09555 
09556    return 0;
09557 }

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

Get a line from an SDP message body.

Definition at line 4273 of file chan_sip.c.

References get_sdp_iterate().

04274 {
04275    int dummy = 0;
04276 
04277    return get_sdp_iterate(&dummy, req, name);
04278 }

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

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

04260 {
04261    int len = strlen(name);
04262 
04263    while (*start < req->sdp_end) {
04264       const char *r = get_body_by_line(req->line[(*start)++], name, len);
04265       if (r[0] != '\0')
04266          return r;
04267    }
04268 
04269    return "";
04270 }

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

09146 {
09147    struct sip_pvt *sip_pvt_ptr;
09148 
09149    ast_mutex_lock(&iflock);
09150 
09151    if (option_debug > 3 && totag)
09152       ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
09153 
09154    /* Search interfaces and find the match */
09155    for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) {
09156       if (!strcmp(sip_pvt_ptr->callid, callid)) {
09157          int match = 1;
09158 
09159          /* Go ahead and lock it (and its owner) before returning */
09160          ast_mutex_lock(&sip_pvt_ptr->lock);
09161 
09162          /* Check if tags match. If not, this is not the call we want
09163             (With a forking SIP proxy, several call legs share the
09164             call id, but have different tags)
09165          */
09166          if (pedanticsipchecking) {
09167             const char *pvt_fromtag, *pvt_totag;
09168 
09169             if (ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL)) {
09170                /* Outgoing call tags : from is "our", to is "their" */
09171                pvt_fromtag = sip_pvt_ptr->tag ;
09172                pvt_totag = sip_pvt_ptr->theirtag ;
09173             } else {
09174                /* Incoming call tags : from is "their", to is "our" */
09175                pvt_fromtag = sip_pvt_ptr->theirtag ;
09176                pvt_totag = sip_pvt_ptr->tag ;
09177             }
09178             if (ast_strlen_zero(fromtag) || strcmp(fromtag, pvt_fromtag) || (!ast_strlen_zero(totag) && strcmp(totag, pvt_totag)))
09179                match = 0;
09180          }
09181 
09182          if (!match) {
09183             ast_mutex_unlock(&sip_pvt_ptr->lock);
09184             continue;
09185          }
09186 
09187          if (option_debug > 3 && totag)             
09188             ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n",
09189                ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING",
09190                sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
09191 
09192          /* deadlock avoidance... */
09193          while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
09194             DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock);
09195          }
09196          break;
09197       }
09198    }
09199    ast_mutex_unlock(&iflock);
09200    if (option_debug > 3 && !sip_pvt_ptr)
09201       ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag);
09202    return sip_pvt_ptr;
09203 }

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

References ast_copy_string(), and get_header().

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

13605 {
13606    const char *thetag;
13607 
13608    if (!tagbuf)
13609       return NULL;
13610    tagbuf[0] = '\0';    /* reset the buffer */
13611    thetag = get_header(req, header);
13612    thetag = strcasestr(thetag, ";tag=");
13613    if (thetag) {
13614       thetag += 5;
13615       ast_copy_string(tagbuf, thetag, tagbufsize);
13616       return strsep(&tagbuf, ";");
13617    }
13618    return NULL;
13619 }

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

16817 {
16818    int res = 1;
16819 
16820    if (!strcasecmp(v->name, "trustrpid")) {
16821       ast_set_flag(&mask[0], SIP_TRUSTRPID);
16822       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
16823    } else if (!strcasecmp(v->name, "sendrpid")) {
16824       ast_set_flag(&mask[0], SIP_SENDRPID);
16825       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
16826    } else if (!strcasecmp(v->name, "g726nonstandard")) {
16827       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
16828       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
16829    } else if (!strcasecmp(v->name, "useclientcode")) {
16830       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
16831       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
16832    } else if (!strcasecmp(v->name, "dtmfmode")) {
16833       ast_set_flag(&mask[0], SIP_DTMF);
16834       ast_clear_flag(&flags[0], SIP_DTMF);
16835       if (!strcasecmp(v->value, "inband"))
16836          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
16837       else if (!strcasecmp(v->value, "rfc2833"))
16838          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16839       else if (!strcasecmp(v->value, "info"))
16840          ast_set_flag(&flags[0], SIP_DTMF_INFO);
16841       else if (!strcasecmp(v->value, "auto"))
16842          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
16843       else {
16844          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
16845          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
16846       }
16847    } else if (!strcasecmp(v->name, "nat")) {
16848       ast_set_flag(&mask[0], SIP_NAT);
16849       ast_clear_flag(&flags[0], SIP_NAT);
16850       if (!strcasecmp(v->value, "never"))
16851          ast_set_flag(&flags[0], SIP_NAT_NEVER);
16852       else if (!strcasecmp(v->value, "route"))
16853          ast_set_flag(&flags[0], SIP_NAT_ROUTE);
16854       else if (ast_true(v->value))
16855          ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
16856       else
16857          ast_set_flag(&flags[0], SIP_NAT_RFC3581);
16858    } else if (!strcasecmp(v->name, "canreinvite")) {
16859       ast_set_flag(&mask[0], SIP_REINVITE);
16860       ast_clear_flag(&flags[0], SIP_REINVITE);
16861       if(ast_true(v->value)) {
16862          ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
16863       } else if (!ast_false(v->value)) {
16864          char buf[64];
16865          char *word, *next = buf;
16866 
16867          ast_copy_string(buf, v->value, sizeof(buf));
16868          while ((word = strsep(&next, ","))) {
16869             if(!strcasecmp(word, "update")) {
16870                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
16871             } else if(!strcasecmp(word, "nonat")) {
16872                ast_set_flag(&flags[0], SIP_CAN_REINVITE);
16873                ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
16874             } else {
16875                ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
16876             }
16877          }
16878       }
16879    } else if (!strcasecmp(v->name, "insecure")) {
16880       ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16881       ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16882       set_insecure_flags(flags, v->value, v->lineno);
16883    } else if (!strcasecmp(v->name, "progressinband")) {
16884       ast_set_flag(&mask[0], SIP_PROG_INBAND);
16885       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
16886       if (ast_true(v->value))
16887          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
16888       else if (strcasecmp(v->value, "never"))
16889          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
16890    } else if (!strcasecmp(v->name, "promiscredir")) {
16891       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
16892       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
16893    } else if (!strcasecmp(v->name, "videosupport")) {
16894       ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
16895       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
16896    } else if (!strcasecmp(v->name, "allowoverlap")) {
16897       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
16898       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
16899    } else if (!strcasecmp(v->name, "allowsubscribe")) {
16900       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
16901       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
16902    } else if (!strcasecmp(v->name, "t38pt_udptl")) {
16903       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
16904       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
16905 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
16906    } else if (!strcasecmp(v->name, "t38pt_rtp")) {
16907       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
16908       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
16909    } else if (!strcasecmp(v->name, "t38pt_tcp")) {
16910       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
16911       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
16912 #endif
16913    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
16914       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
16915       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
16916    } else if (!strcasecmp(v->name, "buggymwi")) {
16917       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
16918       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
16919    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
16920       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
16921       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
16922    } else
16923       res = 0;
16924 
16925    return res;
16926 }

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

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

Definition at line 13789 of file chan_sip.c.

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

Referenced by handle_request_invite().

13790 {
13791    struct ast_frame *f;
13792    int earlyreplace = 0;
13793    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
13794    struct ast_channel *c = p->owner;   /* Our incoming call */
13795    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
13796    struct ast_channel *targetcall;     /* The bridge to the take-over target */
13797 
13798    /* Check if we're in ring state */
13799    if (replacecall->_state == AST_STATE_RING)
13800       earlyreplace = 1;
13801 
13802    /* Check if we have a bridge */
13803    if (!(targetcall = ast_bridged_channel(replacecall))) {
13804       /* We have no bridge */
13805       if (!earlyreplace) {
13806          if (option_debug > 1)
13807             ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
13808          oneleggedreplace = 1;
13809       }
13810    } 
13811    if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING)
13812          ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n");
13813 
13814    if (option_debug > 3) {
13815       if (targetcall) 
13816          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); 
13817       else
13818          ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 
13819    }
13820 
13821    if (ignore) {
13822       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
13823       /* We should answer something here. If we are here, the
13824          call we are replacing exists, so an accepted 
13825          can't harm */
13826       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13827       /* Do something more clever here */
13828       ast_channel_unlock(c);
13829       ast_mutex_unlock(&p->refer->refer_call->lock);
13830       return 1;
13831    } 
13832    if (!c) {
13833       /* What to do if no channel ??? */
13834       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
13835       transmit_response_reliable(p, "503 Service Unavailable", req);
13836       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
13837       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13838       ast_mutex_unlock(&p->refer->refer_call->lock);
13839       return 1;
13840    }
13841    append_history(p, "Xfer", "INVITE/Replace received");
13842    /* We have three channels to play with
13843       channel c: New incoming call
13844       targetcall: Call from PBX to target
13845       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
13846       replacecall: The owner of the previous
13847       We need to masq C into refer_call to connect to 
13848       targetcall;
13849       If we are talking to internal audio stream, target call is null.
13850    */
13851 
13852    /* Fake call progress */
13853    transmit_response(p, "100 Trying", req);
13854    ast_setstate(c, AST_STATE_RING);
13855 
13856    /* Masquerade the new call into the referred call to connect to target call 
13857       Targetcall is not touched by the masq */
13858 
13859    /* Answer the incoming call and set channel to UP state */
13860    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE);
13861       
13862    ast_setstate(c, AST_STATE_UP);
13863    
13864    /* Stop music on hold and other generators */
13865    ast_quiet_chan(replacecall);
13866    ast_quiet_chan(targetcall);
13867    if (option_debug > 3)
13868       ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
13869    /* Unlock clone, but not original (replacecall) */
13870    if (!oneleggedreplace)
13871       ast_channel_unlock(c);
13872 
13873    /* Unlock PVT */
13874    ast_mutex_unlock(&p->refer->refer_call->lock);
13875 
13876    /* Make sure that the masq does not free our PVT for the old call */
13877    if (! earlyreplace && ! oneleggedreplace )
13878       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
13879       
13880    /* Prepare the masquerade - if this does not happen, we will be gone */
13881    if(ast_channel_masquerade(replacecall, c))
13882       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
13883    else if (option_debug > 3)
13884       ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
13885 
13886    /* The masquerade will happen as soon as someone reads a frame from the channel */
13887 
13888    /* C should now be in place of replacecall */
13889    /* ast_read needs to lock channel */
13890    ast_channel_unlock(c);
13891    
13892    if (earlyreplace || oneleggedreplace ) {
13893       /* Force the masq to happen */
13894       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13895          ast_frfree(f);
13896          f = NULL;
13897          if (option_debug > 3)
13898             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from RING channel!\n");
13899       } else {
13900          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from RING channel \n");
13901       }
13902       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13903       if (!oneleggedreplace)
13904          ast_channel_unlock(replacecall);
13905    } else { /* Bridged call, UP channel */
13906       if ((f = ast_read(replacecall))) {  /* Force the masq to happen */
13907          /* Masq ok */
13908          ast_frfree(f);
13909          f = NULL;
13910          if (option_debug > 2)
13911             ast_log(LOG_DEBUG, "Invite/Replace:  Could successfully read frame from channel! Masq done.\n");
13912       } else {
13913          ast_log(LOG_WARNING, "Invite/Replace:  Could not read frame from channel. Transfer failed\n");
13914       }
13915       ast_channel_unlock(replacecall);
13916    }
13917    ast_mutex_unlock(&p->refer->refer_call->lock);
13918 
13919    ast_setstate(c, AST_STATE_DOWN);
13920    if (option_debug > 3) {
13921       struct ast_channel *test;
13922       ast_log(LOG_DEBUG, "After transfer:----------------------------\n");
13923       ast_log(LOG_DEBUG, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
13924       if (replacecall)
13925          ast_log(LOG_DEBUG, " -- replacecall:        %s State %s\n", replacecall->name, ast_state2str(replacecall->_state));
13926       if (p->owner) {
13927          ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state));
13928          test = ast_bridged_channel(p->owner);
13929          if (test)
13930             ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state));
13931          else
13932             ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n");
13933       } else 
13934          ast_log(LOG_DEBUG, " -- No channel yet \n");
13935       ast_log(LOG_DEBUG, "End After transfer:----------------------------\n");
13936    }
13937 
13938    ast_channel_unlock(p->owner); /* Unlock new owner */
13939    if (!oneleggedreplace)
13940       ast_mutex_unlock(&p->lock);   /* Unlock SIP structure */
13941 
13942    /* The call should be down with no ast_channel, so hang it up */
13943    c->tech_pvt = NULL;
13944    ast_hangup(c);
13945    return 0;
13946 }

static int handle_request ( struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int *  recount,
int *  nounlock 
) [static]

Handle incoming SIP requests (methods).

Note:
This is where all incoming requests go first

Definition at line 15763 of file chan_sip.c.

References __sip_ack(), append_history, 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, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), TRUE, and sip_pvt::useragent.

15764 {
15765    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
15766       relatively static */
15767    const char *cmd;
15768    const char *cseq;
15769    const char *useragent;
15770    int seqno;
15771    int len;
15772    int ignore = FALSE;
15773    int respid;
15774    int res = 0;
15775    int debug = sip_debug_test_pvt(p);
15776    char *e;
15777    int error = 0;
15778 
15779    /* Get Method and Cseq */
15780    cseq = get_header(req, "Cseq");
15781    cmd = req->header[0];
15782 
15783    /* Must have Cseq */
15784    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
15785       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
15786       error = 1;
15787    }
15788    if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) {
15789       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
15790       error = 1;
15791    }
15792    if (error) {
15793       if (!p->initreq.headers)   /* New call */
15794          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */
15795       return -1;
15796    }
15797    /* Get the command XXX */
15798 
15799    cmd = req->rlPart1;
15800    e = req->rlPart2;
15801 
15802    /* Save useragent of the client */
15803    useragent = get_header(req, "User-Agent");
15804    if (!ast_strlen_zero(useragent))
15805       ast_string_field_set(p, useragent, useragent);
15806 
15807    /* Find out SIP method for incoming request */
15808    if (req->method == SIP_RESPONSE) {  /* Response to our request */
15809       /* Response to our request -- Do some sanity checks */   
15810       if (!p->initreq.headers) {
15811          if (option_debug)
15812             ast_log(LOG_DEBUG, "That's odd...  Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
15813          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
15814          return 0;
15815       } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) {
15816          if (option_debug)
15817             ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
15818          return -1;
15819       } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) {
15820          /* ignore means "don't do anything with it" but still have to 
15821             respond appropriately  */
15822          ignore = TRUE;
15823          ast_set_flag(req, SIP_PKT_IGNORE);
15824          ast_set_flag(req, SIP_PKT_IGNORE_RESP);
15825          append_history(p, "Ignore", "Ignoring this retransmit\n");
15826       } else if (e) {
15827          e = ast_skip_blanks(e);
15828          if (sscanf(e, "%d %n", &respid, &len) != 1) {
15829             ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
15830          } else {
15831             if (respid <= 0) {
15832                ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
15833                return 0;
15834             }
15835             /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */
15836             if ((respid == 200) || ((respid >= 300) && (respid <= 399)))
15837                extract_uri(p, req);
15838             handle_response(p, respid, e + len, req, ignore, seqno);
15839          }
15840       }
15841       return 0;
15842    }
15843 
15844    /* New SIP request coming in 
15845       (could be new request in existing SIP dialog as well...) 
15846     */         
15847    
15848    p->method = req->method;   /* Find out which SIP method they are using */
15849    if (option_debug > 3)
15850       ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
15851 
15852    if (p->icseq && (p->icseq > seqno) ) {
15853       if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
15854          if (option_debug > 2)
15855             ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n");
15856       }  else {
15857          if (option_debug)
15858             ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
15859          if (req->method != SIP_ACK)
15860             transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
15861          return -1;
15862       }
15863    } else if (p->icseq &&
15864          p->icseq == seqno &&
15865          req->method != SIP_ACK &&
15866          (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) {
15867       /* ignore means "don't do anything with it" but still have to 
15868          respond appropriately.  We do this if we receive a repeat of
15869          the last sequence number  */
15870       ignore = 2;
15871       ast_set_flag(req, SIP_PKT_IGNORE);
15872       ast_set_flag(req, SIP_PKT_IGNORE_REQ);
15873       if (option_debug > 2)
15874          ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
15875    }
15876       
15877    if (seqno >= p->icseq)
15878       /* Next should follow monotonically (but not necessarily 
15879          incrementally -- thanks again to the genius authors of SIP --
15880          increasing */
15881       p->icseq = seqno;
15882 
15883    /* Find their tag if we haven't got it */
15884    if (ast_strlen_zero(p->theirtag)) {
15885       char tag[128];
15886 
15887       gettag(req, "From", tag, sizeof(tag));
15888       ast_string_field_set(p, theirtag, tag);
15889    }
15890    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
15891 
15892    if (pedanticsipchecking) {
15893       /* If this is a request packet without a from tag, it's not
15894          correct according to RFC 3261  */
15895       /* Check if this a new request in a new dialog with a totag already attached to it,
15896          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
15897       if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) {
15898          /* If this is a first request and it got a to-tag, it is not for us */
15899          if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) {
15900             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
15901             /* Will cease to exist after ACK */
15902          } else if (req->method != SIP_ACK) {
15903             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
15904             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15905          }
15906          return res;
15907       }
15908    }
15909 
15910    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
15911       transmit_response(p, "400 Bad request", req);
15912       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15913       return -1;
15914    }
15915 
15916    /* Handle various incoming SIP methods in requests */
15917    switch (p->method) {
15918    case SIP_OPTIONS:
15919       res = handle_request_options(p, req);
15920       break;
15921    case SIP_INVITE:
15922       res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock);
15923       break;
15924    case SIP_REFER:
15925       res = handle_request_refer(p, req, debug, ignore, seqno, nounlock);
15926       break;
15927    case SIP_CANCEL:
15928       res = handle_request_cancel(p, req);
15929       break;
15930    case SIP_BYE:
15931       res = handle_request_bye(p, req);
15932       break;
15933    case SIP_MESSAGE:
15934       res = handle_request_message(p, req);
15935       break;
15936    case SIP_SUBSCRIBE:
15937       res = handle_request_subscribe(p, req, sin, seqno, e);
15938       break;
15939    case SIP_REGISTER:
15940       res = handle_request_register(p, req, sin, e);
15941       break;
15942    case SIP_INFO:
15943       if (ast_test_flag(req, SIP_PKT_DEBUG))
15944          ast_verbose("Receiving INFO!\n");
15945       if (!ignore) 
15946          handle_request_info(p, req);
15947       else  /* if ignoring, transmit response */
15948          transmit_response(p, "200 OK", req);
15949       break;
15950    case SIP_NOTIFY:
15951       res = handle_request_notify(p, req, sin, seqno, e);
15952       break;
15953    case SIP_ACK:
15954       /* Make sure we don't ignore this */
15955       if (seqno == p->pendinginvite) {
15956          p->invitestate = INV_TERMINATED;
15957          p->pendinginvite = 0;
15958          __sip_ack(p, seqno, FLAG_RESPONSE, 0);
15959          if (find_sdp(req)) {
15960             if (process_sdp(p, req))
15961                return -1;
15962          } 
15963          check_pendings(p);
15964       }
15965       /* Got an ACK that we did not match. Ignore silently */
15966       if (!p->lastinvite && ast_strlen_zero(p->randdata))
15967          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15968       break;
15969    default:
15970       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
15971       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
15972          cmd, ast_inet_ntoa(p->sa.sin_addr));
15973       /* If this is some new method, and we don't have a call, destroy it now */
15974       if (!p->initreq.headers)
15975          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
15976       break;
15977    }
15978    return res;
15979 }

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

Handle incoming BYE request.

Definition at line 15324 of file chan_sip.c.

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

Referenced by handle_request().

15325 {
15326    struct ast_channel *c=NULL;
15327    int res;
15328    struct ast_channel *bridged_to;
15329    
15330    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
15331    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 
15332       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
15333 
15334    __sip_pretend_ack(p);
15335 
15336    p->invitestate = INV_TERMINATED;
15337 
15338    copy_request(&p->initreq, req);
15339    check_via(p, req);
15340    sip_alreadygone(p);
15341 
15342    /* Get RTCP quality before end of call */
15343    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) {
15344       char *audioqos, *videoqos;
15345       if (p->rtp) {
15346          audioqos = ast_rtp_get_quality(p->rtp, NULL);
15347          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
15348             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
15349          if (p->owner)
15350             pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos);
15351       }
15352       if (p->vrtp) {
15353          videoqos = ast_rtp_get_quality(p->vrtp, NULL);
15354          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
15355             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
15356          if (p->owner)
15357             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
15358       }
15359    }
15360 
15361    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
15362 
15363    if (!ast_strlen_zero(get_header(req, "Also"))) {
15364       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
15365          ast_inet_ntoa(p->recv.sin_addr));
15366       if (ast_strlen_zero(p->context))
15367          ast_string_field_set(p, context, default_context);
15368       res = get_also_info(p, req);
15369       if (!res) {
15370          c = p->owner;
15371          if (c) {
15372             bridged_to = ast_bridged_channel(c);
15373             if (bridged_to) {
15374                /* Don't actually hangup here... */
15375                ast_queue_control(c, AST_CONTROL_UNHOLD);
15376                ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
15377             } else
15378                ast_queue_hangup(p->owner);
15379          }
15380       } else {
15381          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
15382          if (p->owner)
15383             ast_queue_hangup(p->owner);
15384       }
15385    } else if (p->owner) {
15386       ast_queue_hangup(p->owner);
15387       if (option_debug > 2)
15388          ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n");
15389    } else {
15390       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15391       if (option_debug > 2)
15392          ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n");
15393    }
15394    ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
15395    transmit_response(p, "200 OK", req);
15396 
15397    return 1;
15398 }

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

Handle incoming CANCEL request.

Definition at line 15218 of file chan_sip.c.

References __sip_pretend_ack(), ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_dual::req, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().

Referenced by handle_request().

15219 {
15220       
15221    check_via(p, req);
15222    sip_alreadygone(p);
15223 
15224    /* At this point, we could have cancelled the invite at the same time
15225       as the other side sends a CANCEL. Our final reply with error code
15226       might not have been received by the other side before the CANCEL
15227       was sent, so let's just give up retransmissions and waiting for
15228       ACK on our error code. The call is hanging up any way. */
15229    if (p->invitestate == INV_TERMINATED)
15230       __sip_pretend_ack(p);
15231    else
15232       p->invitestate = INV_CANCELLED;
15233    
15234    if (p->owner && p->owner->_state == AST_STATE_UP) {
15235       /* This call is up, cancel is ignored, we need a bye */
15236       transmit_response(p, "200 OK", req);
15237       if (option_debug)
15238          ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n");
15239       return 0;
15240    }
15241 
15242    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 
15243       update_call_counter(p, DEC_CALL_LIMIT);
15244 
15245    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
15246    if (p->owner)
15247       ast_queue_hangup(p->owner);
15248    else
15249       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15250    if (p->initreq.len > 0) {
15251       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
15252       transmit_response(p, "200 OK", req);
15253       return 1;
15254    } else {
15255       transmit_response(p, "481 Call Leg Does Not Exist", req);
15256       return 0;
15257    }
15258 }

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

11371 {
11372    char buf[1024];
11373    unsigned int event;
11374    const char *c = get_header(req, "Content-Type");
11375 
11376    /* Need to check the media/type */
11377    if (!strcasecmp(c, "application/dtmf-relay") ||
11378          !strcasecmp(c, "application/DTMF") ||
11379        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
11380       unsigned int duration = 0;
11381 
11382       /* Try getting the "signal=" part */
11383       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
11384          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
11385          transmit_response(p, "200 OK", req); /* Should return error */
11386          return;
11387       } else {
11388          ast_copy_string(buf, c, sizeof(buf));
11389       }
11390 
11391       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
11392          duration = atoi(c);
11393       if (!duration)
11394          duration = 100; /* 100 ms */
11395 
11396       if (!p->owner) {  /* not a PBX call */
11397          transmit_response(p, "481 Call leg/transaction does not exist", req);
11398          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11399          return;
11400       }
11401 
11402       if (ast_strlen_zero(buf)) {
11403          transmit_response(p, "200 OK", req);
11404          return;
11405       }
11406 
11407       if (buf[0] == '*')
11408          event = 10;
11409       else if (buf[0] == '#')
11410          event = 11;
11411       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
11412          event = 12 + buf[0] - 'A';
11413       else
11414          event = atoi(buf);
11415       if (event == 16) {
11416          /* send a FLASH event */
11417          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
11418          ast_queue_frame(p->owner, &f);
11419          if (sipdebug)
11420             ast_verbose("* DTMF-relay event received: FLASH\n");
11421       } else {
11422          /* send a DTMF event */
11423          struct ast_frame f = { AST_FRAME_DTMF, };
11424          if (event < 10) {
11425             f.subclass = '0' + event;
11426          } else if (event < 11) {
11427             f.subclass = '*';
11428          } else if (event < 12) {
11429             f.subclass = '#';
11430          } else if (event < 16) {
11431             f.subclass = 'A' + (event - 12);
11432          }
11433          f.len = duration;
11434          ast_queue_frame(p->owner, &f);
11435          if (sipdebug)
11436             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
11437       }
11438       transmit_response(p, "200 OK", req);
11439       return;
11440    } else if (!strcasecmp(c, "application/media_control+xml")) {
11441       /* Eh, we'll just assume it's a fast picture update for now */
11442       if (p->owner)
11443          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
11444       transmit_response(p, "200 OK", req);
11445       return;
11446    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
11447       /* Client code (from SNOM phone) */
11448       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
11449          if (p->owner && p->owner->cdr)
11450             ast_cdr_setuserfield(p->owner, c);
11451          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
11452             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
11453          transmit_response(p, "200 OK", req);
11454       } else {
11455          transmit_response(p, "403 Unauthorized", req);
11456       }
11457       return;
11458    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
11459       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
11460       transmit_response(p, "200 OK", req);
11461       return;
11462    }
11463 
11464    /* Other type of INFO message, not really understood by Asterisk */
11465    /* if (get_msg_text(buf, sizeof(buf), req)) { */
11466 
11467    /* Nothing in the header is interesting, now check if content-length is 0 */ 
11468    if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 
11469       transmit_response(p, "200 OK", req); 
11470       return; 
11471    } /* else ... there issomething in the message body, do something with it if you need to */ 
11472 
11473    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
11474    transmit_response(p, "415 Unsupported media type", req);
11475    return;
11476 }

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

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_BUSY, 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_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(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), ast_channel::name, option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_request::rlPart2, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_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_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, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.

Referenced by handle_request().

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

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

Handle incoming MESSAGE request.

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

15402 {
15403    if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
15404       if (ast_test_flag(req, SIP_PKT_DEBUG))
15405          ast_verbose("Receiving message!\n");
15406       receive_message(p, req);
15407    } else
15408       transmit_response(p, "202 Accepted", req);
15409    return 1;
15410 }

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

13623 {
13624    /* This is mostly a skeleton for future improvements */
13625    /* Mostly created to return proper answers on notifications on outbound REFER's */
13626    int res = 0;
13627    const char *event = get_header(req, "Event");
13628    char *eventid = NULL;
13629    char *sep;
13630 
13631    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
13632       *sep++ = '\0';
13633       eventid = sep;
13634    }
13635    
13636    if (option_debug > 1 && sipdebug)
13637       ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event);
13638 
13639    if (strcmp(event, "refer")) {
13640       /* We don't understand this event. */
13641       /* Here's room to implement incoming voicemail notifications :-) */
13642       transmit_response(p, "489 Bad event", req);
13643       res = -1;
13644    } else {
13645       /* Save nesting depth for now, since there might be other events we will
13646          support in the future */
13647 
13648       /* Handle REFER notifications */
13649 
13650       char buf[1024];
13651       char *cmd, *code;
13652       int respcode;
13653       int success = TRUE;
13654 
13655       /* EventID for each transfer... EventID is basically the REFER cseq 
13656 
13657        We are getting notifications on a call that we transfered
13658        We should hangup when we are getting a 200 OK in a sipfrag
13659        Check if we have an owner of this event */
13660       
13661       /* Check the content type */
13662       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
13663          /* We need a sipfrag */
13664          transmit_response(p, "400 Bad request", req);
13665          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13666          return -1;
13667       }
13668 
13669       /* Get the text of the attachment */
13670       if (get_msg_text(buf, sizeof(buf), req)) {
13671          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
13672          transmit_response(p, "400 Bad request", req);
13673          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13674          return -1;
13675       }
13676 
13677       /*
13678       From the RFC...
13679       A minimal, but complete, implementation can respond with a single
13680          NOTIFY containing either the body:
13681                SIP/2.0 100 Trying
13682       
13683          if the subscription is pending, the body:
13684                SIP/2.0 200 OK
13685          if the reference was successful, the body:
13686                SIP/2.0 503 Service Unavailable
13687          if the reference failed, or the body:
13688                SIP/2.0 603 Declined
13689 
13690          if the REFER request was accepted before approval to follow the
13691          reference could be obtained and that approval was subsequently denied
13692          (see Section 2.4.7).
13693       
13694       If there are several REFERs in the same dialog, we need to
13695       match the ID of the event header...
13696       */
13697       if (option_debug > 2)
13698          ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
13699       cmd = ast_skip_blanks(buf);
13700       code = cmd;
13701       /* We are at SIP/2.0 */
13702       while(*code && (*code > 32)) {   /* Search white space */
13703          code++;
13704       }
13705       *code++ = '\0';
13706       code = ast_skip_blanks(code);
13707       sep = code;
13708       sep++;
13709       while(*sep && (*sep > 32)) {  /* Search white space */
13710          sep++;
13711       }
13712       *sep++ = '\0';       /* Response string */
13713       respcode = atoi(code);
13714       switch (respcode) {
13715       case 100:   /* Trying: */
13716       case 101:   /* dialog establishment */
13717          /* Don't do anything yet */
13718          break;
13719       case 183:   /* Ringing: */
13720          /* Don't do anything yet */
13721          break;
13722       case 200:   /* OK: The new call is up, hangup this call */
13723          /* Hangup the call that we are replacing */
13724          break;
13725       case 301: /* Moved permenantly */
13726       case 302: /* Moved temporarily */
13727          /* Do we get the header in the packet in this case? */
13728          success = FALSE;
13729          break;
13730       case 503:   /* Service Unavailable: The new call failed */
13731             /* Cancel transfer, continue the call */
13732          success = FALSE;
13733          break;
13734       case 603:   /* Declined: Not accepted */
13735             /* Cancel transfer, continue the current call */
13736          success = FALSE;
13737          break;
13738       }
13739       if (!success) {
13740          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
13741       }
13742       
13743       /* Confirm that we received this packet */
13744       transmit_response(p, "200 OK", req);
13745    };
13746 
13747    if (!p->lastinvite)
13748       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13749 
13750    return res;
13751 }

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

Handle incoming OPTIONS request.

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

13755 {
13756    int res;
13757 
13758 
13759    /* XXX Should we authenticate OPTIONS? XXX */
13760 
13761    if (p->lastinvite) {
13762       /* if this is a request in an active dialog, just confirm that the dialog exists. */
13763       transmit_response_with_allow(p, "200 OK", req, 0);
13764       return 0;
13765    }
13766 
13767    res = get_destination(p, req);
13768    build_contact(p);
13769 
13770    if (ast_strlen_zero(p->context))
13771       ast_string_field_set(p, context, default_context);
13772 
13773    if (ast_shutting_down())
13774       transmit_response_with_allow(p, "503 Unavailable", req, 0);
13775    else if (res < 0)
13776       transmit_response_with_allow(p, "404 Not Found", req, 0);
13777    else 
13778       transmit_response_with_allow(p, "200 OK", req, 0);
13779 
13780    /* Destroy if this OPTIONS was the opening request, but not if
13781       it's in the middle of a normal call flow. */
13782    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13783 
13784    return res;
13785 }

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

References sip_pvt::allowtransfer, append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, AST_LIST_EMPTY, ast_log(), ast_parking_ext(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_refer::attendedtransfer, sip_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().

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

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

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

Referenced by handle_request().

15711 {
15712    enum check_auth_result res;
15713 
15714    /* Use this as the basis */
15715    if (ast_test_flag(req, SIP_PKT_DEBUG))
15716       ast_verbose("Using latest REGISTER request as basis request\n");
15717    copy_request(&p->initreq, req);
15718    check_via(p, req);
15719    if ((res = register_verify(p, sin, req, e)) < 0) {
15720       const char *reason;
15721 
15722       switch (res) {
15723       case AUTH_SECRET_FAILED:
15724          reason = "Wrong password";
15725          break;
15726       case AUTH_USERNAME_MISMATCH:
15727          reason = "Username/auth name mismatch";
15728          break;
15729       case AUTH_NOT_FOUND:
15730          reason = "No matching peer found";
15731          break;
15732       case AUTH_UNKNOWN_DOMAIN:
15733          reason = "Not a local domain";
15734          break;
15735       case AUTH_PEER_NOT_DYNAMIC:
15736          reason = "Peer is not supposed to register";
15737          break;
15738       case AUTH_ACL_FAILED:
15739          reason = "Device does not match ACL";
15740          break;
15741       default:
15742          reason = "Unknown failure";
15743          break;
15744       }
15745       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
15746          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
15747          reason);
15748       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
15749    } else
15750       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
15751 
15752    if (res < 1) {
15753       /* Destroy the session, but keep us around for just a bit in case they don't
15754          get our 200 OK */
15755       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15756    }
15757    return res;
15758 }

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

References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), sip_pvt::callid, cb_extensionstate(), 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, iflist, iflock, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::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(), sip_pvt::useragent, sip_pvt::username, and XPIDF_XML.

Referenced by handle_request().

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

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

Handle SIP response in dialogue.

Definition at line 12902 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_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, cb_extensionstate(), 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, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_STATECHANGEQUEUE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, sip_pvt::theirtag, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.

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

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

Handle SIP response to INVITE dialogue.

Bug:
Is there any way we can go back to the audio call on both sides here?

Definition at line 12317 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_ERROR, 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_PENDINGBYE, SIP_PKT_IGNORE, sip_reinvite_retry(), sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::theirtag, 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().

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

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

Handle qualification responses (OPTIONS).

Definition at line 12835 of file chan_sip.c.

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

Referenced by handle_response().

12836 {
12837    struct sip_peer *peer = p->relatedpeer;
12838    int statechanged, is_reachable, was_reachable;
12839    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
12840 
12841    /*
12842     * Compute the response time to a ping (goes in peer->lastms.)
12843     * -1 means did not respond, 0 means unknown,
12844     * 1..maxms is a valid response, >maxms means late response.
12845     */
12846    if (pingtime < 1) /* zero = unknown, so round up to 1 */
12847       pingtime = 1;
12848 
12849    /* Now determine new state and whether it has changed.
12850     * Use some helper variables to simplify the writing
12851     * of the expressions.
12852     */
12853    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
12854    is_reachable = pingtime <= peer->maxms;
12855    statechanged = peer->lastms == 0 /* yes, unknown before */
12856       || was_reachable != is_reachable;
12857 
12858    peer->lastms = pingtime;
12859    peer->call = NULL;
12860    if (statechanged) {
12861       const char *s = is_reachable ? "Reachable" : "Lagged";
12862 
12863       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
12864          peer->name, s, pingtime, peer->maxms);
12865       ast_device_state_changed("SIP/%s", peer->name);
12866       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12867          "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
12868          peer->name, s, pingtime);
12869    }
12870 
12871    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
12872       struct sip_peer *peer_ptr = peer;
12873       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
12874    }
12875 
12876    ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12877 
12878    /* Try again eventually */
12879    peer->pokeexpire = ast_sched_add(sched,
12880       is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
12881       sip_poke_peer_s, ASTOBJ_REF(peer));
12882 
12883    if (peer->pokeexpire == -1) {
12884       ASTOBJ_UNREF(peer, sip_destroy_peer);
12885    }
12886 }

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

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

12647 {
12648    char *auth = "Proxy-Authenticate";
12649    char *auth2 = "Proxy-Authorization";
12650 
12651    /* If no refer structure exists, then do nothing */
12652    if (!p->refer)
12653       return;
12654 
12655    switch (resp) {
12656    case 202:   /* Transfer accepted */
12657       /* We need  to do something here */
12658       /* The transferee is now sending INVITE to target */
12659       p->refer->status = REFER_ACCEPTED;
12660       /* Now wait for next message */
12661       if (option_debug > 2)
12662          ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n");
12663       /* We should hang along, waiting for NOTIFY's here */
12664       break;
12665 
12666    case 401:   /* Not www-authorized on SIP method */
12667    case 407:   /* Proxy auth */
12668       if (ast_strlen_zero(p->authname)) {
12669          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
12670             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
12671          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12672       }
12673       if (resp == 401) {
12674          auth = "WWW-Authenticate";
12675          auth2 = "Authorization";
12676       }
12677       if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) {
12678          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
12679          p->refer->status = REFER_NOAUTH;
12680          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12681       }
12682       break;
12683    case 481: /* Call leg does not exist */
12684 
12685       /* A transfer with Replaces did not work */
12686       /* OEJ: We should Set flag, cancel the REFER, go back
12687       to original call - but right now we can't */
12688       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
12689       if (p->owner)
12690          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
12691       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12692       break;
12693 
12694    case 500:   /* Server error */
12695    case 501:   /* Method not implemented */
12696       /* Return to the current call onhold */
12697       /* Status flag needed to be reset */
12698       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
12699       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12700       p->refer->status = REFER_FAILED;
12701       break;
12702    case 603:   /* Transfer declined */
12703       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
12704       p->refer->status = REFER_FAILED;
12705       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
12706       break;
12707    }
12708 }

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

Handle responses on REGISTER to services.

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

12712 {
12713    int expires, expires_ms;
12714    struct sip_registry *r;
12715    r=p->registry;
12716 
12717    switch (resp) {
12718    case 401:   /* Unauthorized */
12719       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) {
12720          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
12721          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12722          }
12723       break;
12724    case 403:   /* Forbidden */
12725       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
12726       if (global_regattempts_max)
12727          p->registry->regattempts = global_regattempts_max+1;
12728       AST_SCHED_DEL(sched, r->timeout);
12729       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12730       break;
12731    case 404:   /* Not found */
12732       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname);
12733       if (global_regattempts_max)
12734          p->registry->regattempts = global_regattempts_max+1;
12735       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12736       r->call = NULL;
12737       AST_SCHED_DEL(sched, r->timeout);
12738       break;
12739    case 407:   /* Proxy auth */
12740       if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) {
12741          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
12742          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12743       }
12744       break;
12745    case 408:   /* Request timeout */
12746       /* Got a timeout response, so reset the counter of failed responses */
12747       r->regattempts = 0;
12748       break;
12749    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
12750       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname);
12751       if (global_regattempts_max)
12752          p->registry->regattempts = global_regattempts_max+1;
12753       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12754       r->call = NULL;
12755       AST_SCHED_DEL(sched, r->timeout);
12756       break;
12757    case 200:   /* 200 OK */
12758       if (!r) {
12759          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));
12760          ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
12761          return 0;
12762       }
12763 
12764       r->regstate = REG_STATE_REGISTERED;
12765       r->regtime = time(NULL);      /* Reset time of last succesful registration */
12766       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
12767       r->regattempts = 0;
12768       if (option_debug)
12769          ast_log(LOG_DEBUG, "Registration successful\n");
12770       if (r->timeout > -1) {
12771          if (option_debug)
12772             ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
12773       }
12774       AST_SCHED_DEL(sched, r->timeout);
12775       r->call = NULL;
12776       p->registry = NULL;
12777       /* Let this one hang around until we have all the responses */
12778       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12779       /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */
12780 
12781       /* set us up for re-registering */
12782       /* figure out how long we got registered for */
12783       AST_SCHED_DEL(sched, r->expire);
12784       /* according to section 6.13 of RFC, contact headers override
12785          expires headers, so check those first */
12786       expires = 0;
12787 
12788       /* XXX todo: try to save the extra call */
12789       if (!ast_strlen_zero(get_header(req, "Contact"))) {
12790          const char *contact = NULL;
12791          const char *tmptmp = NULL;
12792          int start = 0;
12793          for(;;) {
12794             contact = __get_header(req, "Contact", &start);
12795             /* this loop ensures we get a contact header about our register request */
12796             if(!ast_strlen_zero(contact)) {
12797                if( (tmptmp=strstr(contact, p->our_contact))) {
12798                   contact=tmptmp;
12799                   break;
12800                }
12801             } else
12802                break;
12803          }
12804          tmptmp = strcasestr(contact, "expires=");
12805          if (tmptmp) {
12806             if (sscanf(tmptmp + 8, "%d;", &expires) != 1)
12807                expires = 0;
12808          }
12809 
12810       }
12811       if (!expires) 
12812          expires=atoi(get_header(req, "expires"));
12813       if (!expires)
12814          expires=default_expiry;
12815 
12816       expires_ms = expires * 1000;
12817       if (expires <= EXPIRY_GUARD_LIMIT)
12818          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN);
12819       else
12820          expires_ms -= EXPIRY_GUARD_SECS * 1000;
12821       if (sipdebug)
12822          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
12823 
12824       r->refresh= (int) expires_ms / 1000;
12825 
12826       /* Schedule re-registration before we expire */
12827       AST_SCHED_DEL(sched, r->expire);
12828       r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 
12829       ASTOBJ_UNREF(r, sip_registry_destroy);
12830    }
12831    return 1;
12832 }

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

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

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 3367 of file chan_sip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.

Referenced by handle_response().

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

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

Initialize SIP request.

Definition at line 6000 of file chan_sip.c.

References sip_methods, and cfsip_methods::text.

06001 {
06002    /* Initialize a request */
06003    memset(req, 0, sizeof(*req));
06004         req->method = sipmethod;
06005    req->header[0] = req->data;
06006    snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
06007    req->len = strlen(req->header[0]);
06008    req->headers++;
06009    return 0;
06010 }

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

Initialize SIP response, based on SIP request.

Definition at line 5987 of file chan_sip.c.

References SIP_RESPONSE.

05988 {
05989    /* Initialize a response */
05990    memset(resp, 0, sizeof(*resp));
05991    resp->method = SIP_RESPONSE;
05992    resp->header[0] = resp->data;
05993    snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg);
05994    resp->len = strlen(resp->header[0]);
05995    resp->headers++;
05996    return 0;
05997 }

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

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

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

Initiate new SIP request to peer/user.

Definition at line 7093 of file chan_sip.c.

References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::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, 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::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().

07094 {
07095    char invite_buf[256] = "";
07096    char *invite = invite_buf;
07097    size_t invite_max = sizeof(invite_buf);
07098    char from[256];
07099    char to[256];
07100    char tmp[SIPBUFSIZE/2];
07101    char tmp2[SIPBUFSIZE/2];
07102    const char *l = NULL, *n = NULL;
07103    const char *urioptions = "";
07104 
07105    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
07106       const char *s = p->username;  /* being a string field, cannot be NULL */
07107 
07108       /* Test p->username against allowed characters in AST_DIGIT_ANY
07109          If it matches the allowed characters list, then sipuser = ";user=phone"
07110          If not, then sipuser = ""
07111       */
07112       /* + is allowed in first position in a tel: uri */
07113       if (*s == '+')
07114          s++;
07115       for (; *s; s++) {
07116          if (!strchr(AST_DIGIT_ANYNUM, *s) )
07117             break;
07118       }
07119       /* If we have only digits, add ;user=phone to the uri */
07120       if (!*s)
07121          urioptions = ";user=phone";
07122    }
07123 
07124 
07125    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
07126 
07127    if (p->owner) {
07128       l = p->owner->cid.cid_num;
07129       n = p->owner->cid.cid_name;
07130    }
07131    /* if we are not sending RPID and user wants his callerid restricted */
07132    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
07133        ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
07134       l = CALLERID_UNKNOWN;
07135       n = l;
07136    }
07137    if (ast_strlen_zero(l))
07138       l = default_callerid;
07139    if (ast_strlen_zero(n))
07140       n = l;
07141    /* Allow user to be overridden */
07142    if (!ast_strlen_zero(p->fromuser))
07143       l = p->fromuser;
07144    else /* Save for any further attempts */
07145       ast_string_field_set(p, fromuser, l);
07146 
07147    /* Allow user to be overridden */
07148    if (!ast_strlen_zero(p->fromname))
07149       n = p->fromname;
07150    else /* Save for any further attempts */
07151       ast_string_field_set(p, fromname, n);
07152 
07153    if (pedanticsipchecking) {
07154       ast_uri_encode(n, tmp, sizeof(tmp), 0);
07155       n = tmp;
07156       ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
07157       l = tmp2;
07158    }
07159 
07160    if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
07161       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), ourport, p->tag);
07162    else
07163       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
07164 
07165    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
07166    if (!ast_strlen_zero(p->fullcontact)) {
07167       /* If we have full contact, trust it */
07168       ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
07169    } else {
07170       /* Otherwise, use the username while waiting for registration */
07171       ast_build_string(&invite, &invite_max, "sip:");
07172       if (!ast_strlen_zero(p->username)) {
07173          n = p->username;
07174          if (pedanticsipchecking) {
07175             ast_uri_encode(n, tmp, sizeof(tmp), 0);
07176             n = tmp;
07177          }
07178          ast_build_string(&invite, &invite_max, "%s@", n);
07179       }
07180       ast_build_string(&invite, &invite_max, "%s", p->tohost);
07181       if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
07182          ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
07183       ast_build_string(&invite, &invite_max, "%s", urioptions);
07184    }
07185 
07186    /* If custom URI options have been provided, append them */
07187    if (p->options && !ast_strlen_zero(p->options->uri_options))
07188       ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
07189    
07190    ast_string_field_set(p, uri, invite_buf);
07191 
07192    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
07193       /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
07194       snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag);
07195    } else if (p->options && p->options->vxml_url) {
07196       /* If there is a VXML URL append it to the SIP URL */
07197       snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
07198    } else 
07199       snprintf(to, sizeof(to), "<%s>", p->uri);
07200    
07201    init_req(req, sipmethod, p->uri);
07202    snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
07203 
07204    add_header(req, "Via", p->via);
07205    /* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
07206     * OTOH, then we won't have anything in p->route anyway */
07207    /* Build Remote Party-ID and From */
07208    if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
07209       build_rpid(p);
07210       add_header(req, "From", p->rpid_from);
07211    } else 
07212       add_header(req, "From", from);
07213    add_header(req, "To", to);
07214    ast_string_field_set(p, exten, l);
07215    build_contact(p);
07216    add_header(req, "Contact", p->our_contact);
07217    add_header(req, "Call-ID", p->callid);
07218    add_header(req, "CSeq", tmp);
07219    if (!ast_strlen_zero(global_useragent))
07220       add_header(req, "User-Agent", global_useragent);
07221    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07222    if (!ast_strlen_zero(p->rpid))
07223       add_header(req, "Remote-Party-ID", p->rpid);
07224 }

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

Convert Insecure setting to printable string.

Definition at line 10318 of file chan_sip.c.

Referenced by _sip_show_peer().

10319 {
10320    if (port && invite)
10321       return "port,invite";
10322    else if (port)
10323       return "port";
10324    else if (invite)
10325       return "invite";
10326    else
10327       return "no";
10328 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 8452 of file chan_sip.c.

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

Referenced by build_route().

08453 {
08454    if (!route)
08455       ast_verbose("list_route: no route\n");
08456    else {
08457       for (;route; route = route->next)
08458          ast_verbose("list_route: hop: <%s>\n", route->hop);
08459    }
08460 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 18787 of file chan_sip.c.

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

18788 {
18789    ASTOBJ_CONTAINER_INIT(&userl);   /* User object list */
18790    ASTOBJ_CONTAINER_INIT(&peerl);   /* Peer object list */
18791    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list */
18792 
18793    if (!(sched = sched_context_create())) {
18794       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
18795       return AST_MODULE_LOAD_FAILURE;
18796    }
18797 
18798    if (!(io = io_context_create())) {
18799       ast_log(LOG_ERROR, "Unable to create I/O context\n");
18800       sched_context_destroy(sched);
18801       return AST_MODULE_LOAD_FAILURE;
18802    }
18803 
18804    sip_reloadreason = CHANNEL_MODULE_LOAD;
18805 
18806    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
18807       return AST_MODULE_LOAD_DECLINE;
18808 
18809    /* Make sure we can register our sip channel type */
18810    if (ast_channel_register(&sip_tech)) {
18811       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
18812       io_context_destroy(io);
18813       sched_context_destroy(sched);
18814       return AST_MODULE_LOAD_FAILURE;
18815    }
18816 
18817    /* Register all CLI functions for SIP */
18818    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
18819 
18820    /* Tell the RTP subdriver that we're here */
18821    ast_rtp_proto_register(&sip_rtp);
18822 
18823    /* Tell the UDPTL subdriver that we're here */
18824    ast_udptl_proto_register(&sip_udptl);
18825 
18826    /* Register dialplan applications */
18827    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
18828    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
18829 
18830    /* Register dialplan functions */
18831    ast_custom_function_register(&sip_header_function);
18832    ast_custom_function_register(&sippeer_function);
18833    ast_custom_function_register(&sipchaninfo_function);
18834    ast_custom_function_register(&checksipdomain_function);
18835 
18836    /* Register manager commands */
18837    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers,
18838          "List SIP peers (text format)", mandescr_show_peers);
18839    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer,
18840          "Show SIP peer (text format)", mandescr_show_peer);
18841 
18842    sip_poke_all_peers();   
18843    sip_send_all_registers();
18844    
18845    /* And start the monitor for the first time */
18846    restart_monitor();
18847 
18848    return AST_MODULE_LOAD_SUCCESS;
18849 }

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

References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, attempt_transfer(), sip_dual::chan1, sip_dual::chan2, sip_pvt::flags, get_sip_pvt_byid_locked(), sip_refer::localtransfer, sip_pvt::lock, LOG_DEBUG, 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(), transmit_response(), and TRUE.

Referenced by handle_request_refer().

14784 {
14785    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
14786                /* Chan 2: Call from Asterisk to target */
14787    int res = 0;
14788    struct sip_pvt *targetcall_pvt;
14789 
14790    /* Check if the call ID of the replaces header does exist locally */
14791    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
14792       transferer->refer->replaces_callid_fromtag))) {
14793       if (transferer->refer->localtransfer) {
14794          /* We did not find the refered call. Sorry, can't accept then */
14795          transmit_response(transferer, "202 Accepted", req);
14796          /* Let's fake a response from someone else in order
14797             to follow the standard */
14798          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
14799          append_history(transferer, "Xfer", "Refer failed");
14800          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);  
14801          transferer->refer->status = REFER_FAILED;
14802          return -1;
14803       }
14804       /* Fall through for remote transfers that we did not find locally */
14805       if (option_debug > 2)
14806          ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
14807       return 0;
14808    }
14809 
14810    /* Ok, we can accept this transfer */
14811    transmit_response(transferer, "202 Accepted", req);
14812    append_history(transferer, "Xfer", "Refer accepted");
14813    if (!targetcall_pvt->owner) { /* No active channel */
14814       if (option_debug > 3)
14815          ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n");
14816       /* Cancel transfer */
14817       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
14818       append_history(transferer, "Xfer", "Refer failed");
14819       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
14820       transferer->refer->status = REFER_FAILED;
14821       ast_mutex_unlock(&targetcall_pvt->lock);
14822       ast_channel_unlock(current->chan1);
14823       return -1;
14824    }
14825 
14826    /* We have a channel, find the bridge */
14827    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
14828    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
14829 
14830    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
14831       /* Wrong state of new channel */
14832       if (option_debug > 3) {
14833          if (target.chan2) 
14834             ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
14835          else if (target.chan1->_state != AST_STATE_RING)
14836             ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n");
14837          else
14838             ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n");
14839       }
14840    }
14841 
14842    /* Transfer */
14843    if (option_debug > 3 && sipdebug) {
14844       if (current->chan2)  /* We have two bridges */
14845          ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
14846       else        /* One bridge, propably transfer of IVR/voicemail etc */
14847          ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
14848    }
14849 
14850    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
14851 
14852    /* Perform the transfer */
14853    res = attempt_transfer(current, &target);
14854    ast_mutex_unlock(&targetcall_pvt->lock);
14855    if (res) {
14856       /* Failed transfer */
14857       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
14858       append_history(transferer, "Xfer", "Refer failed");
14859       transferer->refer->status = REFER_FAILED;
14860       if (targetcall_pvt->owner)
14861          ast_channel_unlock(targetcall_pvt->owner);
14862       /* Right now, we have to hangup, sorry. Bridge is destroyed */
14863       if (res != -2)
14864          ast_hangup(transferer->owner);
14865       else
14866          ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
14867    } else {
14868       /* Transfer succeeded! */
14869 
14870       /* Tell transferer that we're done. */
14871       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
14872       append_history(transferer, "Xfer", "Refer succeeded");
14873       transferer->refer->status = REFER_200OK;
14874       if (targetcall_pvt->owner) {
14875          if (option_debug)
14876             ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
14877          ast_channel_unlock(targetcall_pvt->owner);
14878       }
14879    }
14880    return 1;
14881 }

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

References t.

Referenced by sipsock_read().

04857 {
04858    int h = 0, t = 0; 
04859    int lws = 0; 
04860 
04861    for (; h < len;) { 
04862       /* Eliminate all CRs */ 
04863       if (msgbuf[h] == '\r') { 
04864          h++; 
04865          continue; 
04866       } 
04867       /* Check for end-of-line */ 
04868       if (msgbuf[h] == '\n') { 
04869          /* Check for end-of-message */ 
04870          if (h + 1 == len) 
04871             break; 
04872          /* Check for a continuation line */ 
04873          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
04874             /* Merge continuation line */ 
04875             h++; 
04876             continue; 
04877          } 
04878          /* Propagate LF and start new line */ 
04879          msgbuf[t++] = msgbuf[h++]; 
04880          lws = 0;
04881          continue; 
04882       } 
04883       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
04884          if (lws) { 
04885             h++; 
04886             continue; 
04887          } 
04888          msgbuf[t++] = msgbuf[h++]; 
04889          lws = 1; 
04890          continue; 
04891       } 
04892       msgbuf[t++] = msgbuf[h++]; 
04893       if (lws) 
04894          lws = 0; 
04895    } 
04896    msgbuf[t] = '\0'; 
04897    return t; 
04898 }

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

Make our SIP dialog tag.

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

04522 {
04523    snprintf(tagbuf, len, "as%08lx", ast_random());
04524 }

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

Show SIP peers in the manager API.

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

10564 {
10565    const char *a[4];
10566    const char *peer;
10567    int ret;
10568 
10569    peer = astman_get_header(m,"Peer");
10570    if (ast_strlen_zero(peer)) {
10571       astman_send_error(s, m, "Peer: <name> missing.");
10572       return 0;
10573    }
10574    a[0] = "sip";
10575    a[1] = "show";
10576    a[2] = "peer";
10577    a[3] = peer;
10578 
10579    ret = _sip_show_peer(1, -1, s, m, 4, a);
10580    astman_append(s, "\r\n\r\n" );
10581    return ret;
10582 }

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

Show SIP peers in the manager API.

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

10115 {
10116    const char *id = astman_get_header(m,"ActionID");
10117    const char *a[] = {"sip", "show", "peers"};
10118    char idtext[256] = "";
10119    int total = 0;
10120 
10121    if (!ast_strlen_zero(id))
10122       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
10123 
10124    astman_send_ack(s, m, "Peer status list will follow");
10125    /* List the peers in separate manager events */
10126    _sip_show_peers(-1, &total, s, m, 3, a);
10127    /* Send final confirmation */
10128    astman_append(s,
10129    "Event: PeerlistComplete\r\n"
10130    "ListItems: %d\r\n"
10131    "%s"
10132    "\r\n", total, idtext);
10133    return 0;
10134 }

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

References sip_request::len, sip_methods, and text.

Referenced by __sip_semi_ack(), and find_sip_method().

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

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

Convert NAT setting to text string.

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

10018 {
10019    switch(nat) {
10020    case SIP_NAT_NEVER:
10021       return "No";
10022    case SIP_NAT_ROUTE:
10023       return "Route";
10024    case SIP_NAT_ALWAYS:
10025       return "Always";
10026    case SIP_NAT_RFC3581:
10027       return "RFC3581";
10028    default:
10029       return "Unknown";
10030    }
10031 }

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

Copy SIP request, parse it.

Definition at line 2264 of file chan_sip.c.

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

Referenced by send_request(), and send_response().

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

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

Parse 302 Moved temporalily response.

Definition at line 12218 of file chan_sip.c.

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

Referenced by handle_response().

12219 {
12220    char tmp[SIPBUFSIZE];
12221    char *s, *e, *uri, *t;
12222    char *domain;
12223 
12224    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
12225    if ((t = strchr(tmp, ',')))
12226       *t = '\0';
12227    s = get_in_brackets(tmp);
12228    uri = ast_strdupa(s);
12229    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
12230       if (!strncasecmp(s, "sip:", 4))
12231          s += 4;
12232       e = strchr(s, ';');
12233       if (e)
12234          *e = '\0';
12235       if (option_debug)
12236          ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
12237       if (p->owner)
12238          ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
12239    } else {
12240       e = strchr(tmp, '@');
12241       if (e) {
12242          *e++ = '\0';
12243          domain = e;
12244       } else {
12245          /* No username part */
12246          domain = tmp;
12247       }
12248       e = strchr(s, ';');  /* Strip of parameters in the username part */
12249       if (e)
12250          *e = '\0';
12251       e = strchr(domain, ';');   /* Strip of parameters in the domain part */
12252       if (e)
12253          *e = '\0';
12254    
12255       if (!strncasecmp(s, "sip:", 4))
12256          s += 4;
12257       if (option_debug > 1)
12258          ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
12259       if (p->owner) {
12260          pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri);
12261          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
12262          ast_string_field_set(p->owner, call_forward, s);
12263       }
12264    }
12265 }

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

08182 {
08183    char contact[SIPBUFSIZE]; 
08184    char *c;
08185 
08186    /* Look for brackets */
08187    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
08188    c = get_in_brackets(contact);
08189 
08190    /* Save full contact to call pvt for later bye or re-invite */
08191    ast_string_field_set(pvt, fullcontact, c);
08192 
08193    /* Save URI for later ACKs, BYE or RE-invites */
08194    ast_string_field_set(pvt, okcontacturi, c);
08195 
08196    /* We should return false for URI:s we can't handle,
08197       like sips:, tel:, mailto:,ldap: etc */
08198    return TRUE;      
08199 }

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

References 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_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::contactha, destroy_association(), 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(), sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, sip_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().

08271 {
08272    char contact[SIPBUFSIZE]; 
08273    char data[SIPBUFSIZE];
08274    const char *expires = get_header(req, "Expires");
08275    int expiry = atoi(expires);
08276    char *curi, *n, *pt;
08277    int port;
08278    const char *useragent;
08279    struct hostent *hp;
08280    struct ast_hostent ahp;
08281    struct sockaddr_in oldsin, testsin;
08282 
08283    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
08284 
08285    if (ast_strlen_zero(expires)) {  /* No expires header */
08286       expires = strcasestr(contact, ";expires=");
08287       if (expires) {
08288          /* XXX bug here, we overwrite the string */
08289          expires = strsep((char **) &expires, ";"); /* trim ; and beyond */
08290          if (sscanf(expires + 9, "%d", &expiry) != 1)
08291             expiry = default_expiry;
08292       } else {
08293          /* Nothing has been specified */
08294          expiry = default_expiry;
08295       }
08296    }
08297 
08298    /* Look for brackets */
08299    curi = contact;
08300    if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
08301       strsep(&curi, ";");  /* This is Header options, not URI options */
08302    curi = get_in_brackets(contact);
08303 
08304    /* if they did not specify Contact: or Expires:, they are querying
08305       what we currently have stored as their contact address, so return
08306       it
08307    */
08308    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
08309       /* If we have an active registration, tell them when the registration is going to expire */
08310       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact))
08311          pvt->expiry = ast_sched_when(sched, peer->expire);
08312       return PARSE_REGISTER_QUERY;
08313    } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */
08314       /* This means remove all registrations and return OK */
08315       memset(&peer->addr, 0, sizeof(peer->addr));
08316       if (!AST_SCHED_DEL(sched, peer->expire)) {
08317          struct sip_peer *peer_ptr = peer;
08318          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08319       }
08320 
08321       destroy_association(peer);
08322       
08323       register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */
08324       peer->fullcontact[0] = '\0';
08325       peer->useragent[0] = '\0';
08326       peer->sipoptions = 0;
08327       peer->lastms = 0;
08328       pvt->expiry = 0;
08329 
08330       if (option_verbose > 2)
08331          ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name);
08332 
08333       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
08334       return PARSE_REGISTER_UPDATE;
08335    }
08336 
08337    /* Store whatever we got as a contact from the client */
08338    ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact));
08339 
08340    /* For the 200 OK, we should use the received contact */
08341    ast_string_field_build(pvt, our_contact, "<%s>", curi);
08342 
08343    /* Make sure it's a SIP URL */
08344    if (strncasecmp(curi, "sip:", 4)) {
08345       ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
08346    } else
08347       curi += 4;
08348    /* Ditch q */
08349    curi = strsep(&curi, ";");
08350    /* Grab host */
08351    n = strchr(curi, '@');
08352    if (!n) {
08353       n = curi;
08354       curi = NULL;
08355    } else
08356       *n++ = '\0';
08357    pt = strchr(n, ':');
08358    if (pt) {
08359       *pt++ = '\0';
08360       port = atoi(pt);
08361    } else
08362       port = STANDARD_SIP_PORT;
08363    oldsin = peer->addr;
08364 
08365    /* Check that they're allowed to register at this IP */
08366    /* XXX This could block for a long time XXX */
08367    hp = ast_gethostbyname(n, &ahp);
08368    if (!hp)  {
08369       ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
08370       *peer->fullcontact = '\0';
08371       ast_string_field_set(pvt, our_contact, "");
08372       return PARSE_REGISTER_FAILED;
08373    }
08374    memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr));
08375    if (  ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW ||
08376          ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) {
08377       ast_log(LOG_WARNING, "Host '%s' disallowed by rule\n", n);
08378       *peer->fullcontact = '\0';
08379       ast_string_field_set(pvt, our_contact, "");
08380       return PARSE_REGISTER_FAILED;
08381    }
08382 
08383    if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
08384       peer->addr.sin_family = AF_INET;
08385       memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
08386       peer->addr.sin_port = htons(port);
08387    } else {
08388       /* Don't trust the contact field.  Just use what they came to us
08389          with */
08390       peer->addr = pvt->recv;
08391    }
08392 
08393    /* Save SIP options profile */
08394    peer->sipoptions = pvt->sipoptions;
08395 
08396    if (curi && ast_strlen_zero(peer->username))
08397       ast_copy_string(peer->username, curi, sizeof(peer->username));
08398 
08399    if (!AST_SCHED_DEL(sched, peer->expire)) {
08400       struct sip_peer *peer_ptr = peer;
08401       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08402    }
08403    if (expiry > max_expiry)
08404       expiry = max_expiry;
08405    if (expiry < min_expiry)
08406       expiry = min_expiry;
08407    if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
08408       peer->expire = -1;
08409    } else {
08410       peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
08411       if (peer->expire == -1) {
08412          struct sip_peer *peer_ptr = peer;
08413          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08414       }
08415    }
08416    pvt->expiry = expiry;
08417    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);
08418    if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
08419       ast_db_put("SIP/Registry", peer->name, data);
08420    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08421 
08422    /* Is this a new IP address for us? */
08423    if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) {
08424       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));
08425    }
08426    sip_poke_peer(peer);
08427    register_peer_exten(peer, 1);
08428    
08429    /* Save User agent */
08430    useragent = get_header(req, "User-Agent");
08431    if (strcasecmp(useragent, peer->useragent)) {   /* XXX copy if they are different ? */
08432       ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent));
08433       if (option_verbose > 3)
08434          ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);  
08435    }
08436    return PARSE_REGISTER_UPDATE;
08437 }

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

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

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

Parse supported header in incoming packet.

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

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

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

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

10037 {
10038    int res = 0;
10039    if (peer->maxms) {
10040       if (peer->lastms < 0) {
10041          ast_copy_string(status, "UNREACHABLE", statuslen);
10042       } else if (peer->lastms > peer->maxms) {
10043          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
10044          res = 1;
10045       } else if (peer->lastms) {
10046          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
10047          res = 1;
10048       } else {
10049          ast_copy_string(status, "UNKNOWN", statuslen);
10050       }
10051    } else { 
10052       ast_copy_string(status, "Unmonitored", statuslen);
10053       /* Checking if port is 0 */
10054       res = -1;
10055    }
10056    return res;
10057 }

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

10505 {
10506    int x, codec;
10507 
10508    for(x = 0; x < 32 ; x++) {
10509       codec = ast_codec_pref_index(pref, x);
10510       if (!codec)
10511          break;
10512       ast_cli(fd, "%s", ast_getformatname(codec));
10513       ast_cli(fd, ":%d", pref->framing[x]);
10514       if (x < 31 && ast_codec_pref_index(pref, x + 1))
10515          ast_cli(fd, ",");
10516    }
10517    if (!x)
10518       ast_cli(fd, "none");
10519 }

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

Print call group and pickup group.

Definition at line 10295 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

10296 {
10297    char buf[256];
10298    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
10299 }

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

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

15982 {
15983    struct sip_request *req;
15984 
15985    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
15986       if (handle_request(p, req, &p->recv, recount, nounlock) == -1) {
15987          /* Request failed */
15988          if (option_debug) {
15989             ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
15990          }
15991       }
15992       ast_free(req);
15993    }
15994 }

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

Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().

< RTP Audio port number

< RTP Video port number

< media socket address

< Video socket address

< RTP Audio host IP

< RTP video host IP

Definition at line 5115 of file chan_sip.c.

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

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

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

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

16047 {
16048    struct sip_request *newreq;
16049 
16050    if (!(newreq = ast_calloc(1, sizeof(*newreq)))) {
16051       return -1;
16052    }
16053 
16054    copy_request(newreq, req);
16055    AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next);
16056    if (p->request_queue_sched_id == -1) {
16057       p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p);
16058    }
16059 
16060    return 0;
16061 }

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

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

static void realtime_update_peer ( const char *  peername,
struct sockaddr_in *  sin,
const char *  username,
const char *  fullcontact,
int  expirey 
) [static]

Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.

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

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

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

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

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

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

09920 {
09921    char buf[1024];
09922    struct ast_frame f;
09923    const char *content_type = get_header(req, "Content-Type");
09924 
09925    if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
09926       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
09927       if (!p->owner)
09928          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09929       return;
09930    }
09931 
09932    if (get_msg_text(buf, sizeof(buf), req)) {
09933       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
09934       transmit_response(p, "202 Accepted", req);
09935       if (!p->owner)
09936          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09937       return;
09938    }
09939 
09940    if (p->owner) {
09941       if (sip_debug_test_pvt(p))
09942          ast_verbose("Message received: '%s'\n", buf);
09943       memset(&f, 0, sizeof(f));
09944       f.frametype = AST_FRAME_TEXT;
09945       f.subclass = 0;
09946       f.offset = 0;
09947       f.data = buf;
09948       f.datalen = strlen(buf);
09949       ast_queue_frame(p->owner, &f);
09950       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
09951    } else { /* Message outside of a call, we do not support that */
09952       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);
09953       transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */
09954       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
09955    }
09956    return;
09957 }

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

Convert transfer status to string.

Definition at line 1644 of file chan_sip.c.

References referstatusstrings, and text.

Referenced by __sip_show_channels().

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

static void reg_source_db ( struct sip_peer peer  )  [static]

Get registration details from Asterisk DB.

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

08110 {
08111    char data[256];
08112    struct in_addr in;
08113    int expiry;
08114    int port;
08115    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
08116 
08117    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 
08118       return;
08119    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
08120       return;
08121 
08122    scan = data;
08123    addr = strsep(&scan, ":");
08124    port_str = strsep(&scan, ":");
08125    expiry_str = strsep(&scan, ":");
08126    username = strsep(&scan, ":");
08127    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
08128 
08129    if (!inet_aton(addr, &in))
08130       return;
08131 
08132    if (port_str)
08133       port = atoi(port_str);
08134    else
08135       return;
08136 
08137    if (expiry_str)
08138       expiry = atoi(expiry_str);
08139    else
08140       return;
08141 
08142    if (username)
08143       ast_copy_string(peer->username, username, sizeof(peer->username));
08144    if (contact)
08145       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
08146 
08147    if (option_debug > 1)
08148       ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
08149              peer->name, peer->username, ast_inet_ntoa(in), port, expiry);
08150 
08151    memset(&peer->addr, 0, sizeof(peer->addr));
08152    peer->addr.sin_family = AF_INET;
08153    peer->addr.sin_addr = in;
08154    peer->addr.sin_port = htons(port);
08155    if (sipsock < 0) {
08156       /* SIP isn't up yet, so schedule a poke only, pretty soon */
08157       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
08158          struct sip_peer *peer_ptr = peer;
08159          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08160       }
08161       peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer));
08162       if (peer->pokeexpire == -1) {
08163          struct sip_peer *peer_ptr = peer;
08164          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08165       }
08166    } else
08167       sip_poke_peer(peer);
08168    if (!AST_SCHED_DEL(sched, peer->expire)) {
08169       struct sip_peer *peer_ptr = peer;
08170       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08171    }
08172    peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer));
08173    if (peer->expire == -1) {
08174       struct sip_peer *peer_ptr = peer;
08175       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
08176    }
08177    register_peer_exten(peer, TRUE);
08178 }

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

Automatically add peer extension to dial plan.

Definition at line 2450 of file chan_sip.c.

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

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

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 8825 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_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, manager_event(), sip_peer::md5secret, sip_peer::name, name, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.

08827 {
08828    enum check_auth_result res = AUTH_NOT_FOUND;
08829    struct sip_peer *peer;
08830    char tmp[256];
08831    char *name, *c;
08832    char *t;
08833    char *domain;
08834 
08835    /* Terminate URI */
08836    t = uri;
08837    while(*t && (*t > 32) && (*t != ';'))
08838       t++;
08839    *t = '\0';
08840    
08841    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
08842    if (pedanticsipchecking)
08843       ast_uri_decode(tmp);
08844 
08845    c = get_in_brackets(tmp);
08846    c = strsep(&c, ";"); /* Ditch ;user=phone */
08847 
08848    if (!strncasecmp(c, "sip:", 4)) {
08849       name = c + 4;
08850    } else {
08851       name = c;
08852       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
08853    }
08854 
08855    /* Strip off the domain name */
08856    if ((c = strchr(name, '@'))) {
08857       *c++ = '\0';
08858       domain = c;
08859       if ((c = strchr(domain, ':')))   /* Remove :port */
08860          *c = '\0';
08861       if (!AST_LIST_EMPTY(&domain_list)) {
08862          if (!check_sip_domain(domain, NULL, 0)) {
08863             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
08864             return AUTH_UNKNOWN_DOMAIN;
08865          }
08866       }
08867    }
08868 
08869    ast_string_field_set(p, exten, name);
08870    build_contact(p);
08871    peer = find_peer(name, NULL, 1, 0);
08872    if (!(peer && ast_apply_ha(peer->ha, sin))) {
08873       /* Peer fails ACL check */
08874       if (peer) {
08875          ASTOBJ_UNREF(peer, sip_destroy_peer);
08876          res = AUTH_ACL_FAILED;
08877       } else
08878          res = AUTH_NOT_FOUND;
08879    }
08880    if (peer) {
08881       /* Set Frame packetization */
08882       if (p->rtp) {
08883          ast_rtp_codec_setpref(p->rtp, &peer->prefs);
08884          p->autoframing = peer->autoframing;
08885       }
08886       if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) {
08887          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
08888          res = AUTH_PEER_NOT_DYNAMIC;
08889       } else {
08890          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
08891          transmit_response(p, "100 Trying", req);
08892          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) {
08893             if (sip_cancel_destroy(p))
08894                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
08895 
08896             /* We have a succesful registration attemp with proper authentication,
08897                now, update the peer */
08898             switch (parse_register_contact(p, peer, req)) {
08899             case PARSE_REGISTER_FAILED:
08900                ast_log(LOG_WARNING, "Failed to parse contact info\n");
08901                transmit_response_with_date(p, "400 Bad Request", req);
08902                peer->lastmsgssent = -1;
08903                res = 0;
08904                break;
08905             case PARSE_REGISTER_QUERY:
08906                transmit_response_with_date(p, "200 OK", req);
08907                peer->lastmsgssent = -1;
08908                res = 0;
08909                break;
08910             case PARSE_REGISTER_UPDATE:
08911                update_peer(peer, p->expiry);
08912                /* Say OK and ask subsystem to retransmit msg counter */
08913                transmit_response_with_date(p, "200 OK", req);
08914                if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
08915                   peer->lastmsgssent = -1;
08916                res = 0;
08917                break;
08918             }
08919          } 
08920       }
08921    }
08922    if (!peer && autocreatepeer) {
08923       /* Create peer if we have autocreate mode enabled */
08924       peer = temp_peer(name);
08925       if (peer) {
08926          ASTOBJ_CONTAINER_LINK(&peerl, peer);
08927          if (sip_cancel_destroy(p))
08928             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
08929          switch (parse_register_contact(p, peer, req)) {
08930          case PARSE_REGISTER_FAILED:
08931             ast_log(LOG_WARNING, "Failed to parse contact info\n");
08932             transmit_response_with_date(p, "400 Bad Request", req);
08933             peer->lastmsgssent = -1;
08934             res = 0;
08935             break;
08936          case PARSE_REGISTER_QUERY:
08937             transmit_response_with_date(p, "200 OK", req);
08938             peer->lastmsgssent = -1;
08939             res = 0;
08940             break;
08941          case PARSE_REGISTER_UPDATE:
08942             /* Say OK and ask subsystem to retransmit msg counter */
08943             transmit_response_with_date(p, "200 OK", req);
08944             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
08945             peer->lastmsgssent = -1;
08946             res = 0;
08947             break;
08948          }
08949       }
08950    }
08951    if (!res) {
08952       ast_device_state_changed("SIP/%s", peer->name);
08953    }
08954    if (res < 0) {
08955       switch (res) {
08956       case AUTH_SECRET_FAILED:
08957          /* Wrong password in authentication. Go away, don't try again until you fixed it */
08958          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
08959          break;
08960       case AUTH_USERNAME_MISMATCH:
08961          /* Username and digest username does not match. 
08962             Asterisk uses the From: username for authentication. We need the
08963             users to use the same authentication user name until we support
08964             proper authentication by digest auth name */
08965          transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
08966          break;
08967       case AUTH_NOT_FOUND:
08968       case AUTH_PEER_NOT_DYNAMIC:
08969       case AUTH_ACL_FAILED:
08970          if (global_alwaysauthreject) {
08971             transmit_fake_auth_response(p, &p->initreq, 1);
08972          } else {
08973             /* URI not found */
08974             if (res == AUTH_PEER_NOT_DYNAMIC)
08975                transmit_response(p, "403 Forbidden", &p->initreq);
08976             else
08977                transmit_response(p, "404 Not found", &p->initreq);
08978          }
08979          break;
08980       default:
08981          break;
08982       }
08983    }
08984    if (peer)
08985       ASTOBJ_UNREF(peer, sip_destroy_peer);
08986 
08987    return res;
08988 }

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

Convert registration state status to string.

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

07587 {
07588    switch(regstate) {
07589    case REG_STATE_FAILED:
07590       return "Failed";
07591    case REG_STATE_UNREGISTERED:
07592       return "Unregistered";
07593    case REG_STATE_REGSENT:
07594       return "Request Sent";
07595    case REG_STATE_AUTHSENT:
07596       return "Auth. Sent";
07597    case REG_STATE_REGISTERED:
07598       return "Registered";
07599    case REG_STATE_REJECTED:
07600       return "Rejected";
07601    case REG_STATE_TIMEOUT:
07602       return "Timeout";
07603    case REG_STATE_NOAUTH:
07604       return "No Authentication";
07605    default:
07606       return "Unknown";
07607    }
07608 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 18673 of file chan_sip.c.

References sip_reload().

18674 {
18675    return sip_reload(0, 0, NULL);
18676 }

static int reload_config ( enum channelreloadreason  reason  )  [static]

Re-read SIP.conf config file.

Note:
This function reloads all config data, except for active peers (with registrations). They will only change configuration data at restart, not at reload. SIP debug and recordhistory state will not change

< Default DTMF setting: RFC2833

< NAT support if requested by device with rport

< Allow re-invites

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

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

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

11721 {
11722    char tmp[512];
11723    char *c;
11724    char oldnonce[256];
11725 
11726    /* table of recognised keywords, and places where they should be copied */
11727    const struct x {
11728       const char *key;
11729       int field_index;
11730    } *i, keys[] = {
11731       { "realm=", ast_string_field_index(p, realm) },
11732       { "nonce=", ast_string_field_index(p, nonce) },
11733       { "opaque=", ast_string_field_index(p, opaque) },
11734       { "qop=", ast_string_field_index(p, qop) },
11735       { "domain=", ast_string_field_index(p, domain) },
11736       { NULL, 0 },
11737    };
11738 
11739    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
11740    if (ast_strlen_zero(tmp)) 
11741       return -1;
11742    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
11743       ast_log(LOG_WARNING, "missing Digest.\n");
11744       return -1;
11745    }
11746    c = tmp + strlen("Digest ");
11747    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
11748    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
11749       for (i = keys; i->key != NULL; i++) {
11750          char *src, *separator;
11751          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
11752             continue;
11753          /* Found. Skip keyword, take text in quotes or up to the separator. */
11754          c += strlen(i->key);
11755          if (*c == '"') {
11756             src = ++c;
11757             separator = "\"";
11758          } else {
11759             src = c;
11760             separator = ",";
11761          }
11762          strsep(&c, separator); /* clear separator and move ptr */
11763          ast_string_field_index_set(p, i->field_index, src);
11764          break;
11765       }
11766       if (i->key == NULL) /* not found, try ',' */
11767          strsep(&c, ",");
11768    }
11769    /* Reset nonce count */
11770    if (strcmp(p->nonce, oldnonce)) 
11771       p->noncecount = 0;
11772 
11773    /* Save auth data for following registrations */
11774    if (p->registry) {
11775       struct sip_registry *r = p->registry;
11776 
11777       if (strcmp(r->nonce, p->nonce)) {
11778          ast_string_field_set(r, realm, p->realm);
11779          ast_string_field_set(r, nonce, p->nonce);
11780          ast_string_field_set(r, domain, p->domain);
11781          ast_string_field_set(r, opaque, p->opaque);
11782          ast_string_field_set(r, qop, p->qop);
11783          r->noncecount = 0;
11784       }
11785    }
11786    return build_reply_digest(p, sipmethod, digest, digest_len); 
11787 }

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 6062 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_MESSAGE, sip_methods, SIP_OUTGOING, sipdebug, sip_pvt::tag, text, cfsip_methods::text, sip_pvt::theirtag, TRUE, sip_pvt::uri, and sip_pvt::via.

06063 {
06064    struct sip_request *orig = &p->initreq;
06065    char stripped[80];
06066    char tmp[80];
06067    char newto[256];
06068    const char *c;
06069    const char *ot, *of;
06070    int is_strict = FALSE;     /*!< Strict routing flag */
06071 
06072    memset(req, 0, sizeof(struct sip_request));
06073    
06074    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
06075    
06076    if (!seqno) {
06077       p->ocseq++;
06078       seqno = p->ocseq;
06079    }
06080    
06081    if (sipmethod == SIP_CANCEL) {
06082       p->branch = p->invite_branch;
06083       build_via(p);
06084    } else if (newbranch) {
06085       p->branch ^= ast_random();
06086       build_via(p);
06087    }
06088 
06089    /* Check for strict or loose router */
06090    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
06091       is_strict = TRUE;
06092       if (sipdebug)
06093          ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
06094    }
06095 
06096    if (sipmethod == SIP_CANCEL)
06097       c = p->initreq.rlPart2; /* Use original URI */
06098    else if (sipmethod == SIP_ACK) {
06099       /* Use URI from Contact: in 200 OK (if INVITE) 
06100       (we only have the contacturi on INVITEs) */
06101       if (!ast_strlen_zero(p->okcontacturi))
06102          c = is_strict ? p->route->hop : p->okcontacturi;
06103       else
06104          c = p->initreq.rlPart2;
06105    } else if (!ast_strlen_zero(p->okcontacturi)) 
06106       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
06107    else if (!ast_strlen_zero(p->uri)) 
06108       c = p->uri;
06109    else {
06110       char *n;
06111       /* We have no URI, use To: or From:  header as URI (depending on direction) */
06112       ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
06113             sizeof(stripped));
06114       n = get_in_brackets(stripped);
06115       c = strsep(&n, ";"); /* trim ; and beyond */
06116    }  
06117    init_req(req, sipmethod, c);
06118 
06119    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
06120 
06121    add_header(req, "Via", p->via);
06122    if (p->route) {
06123       set_destination(p, p->route->hop);
06124       add_route(req, is_strict ? p->route->next : p->route);
06125    }
06126 
06127    ot = get_header(orig, "To");
06128    of = get_header(orig, "From");
06129 
06130    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
06131       as our original request, including tag (or presumably lack thereof) */
06132    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
06133       /* Add the proper tag if we don't have it already.  If they have specified
06134          their tag, use it.  Otherwise, use our own tag */
06135       if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
06136          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
06137       else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
06138          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
06139       else
06140          snprintf(newto, sizeof(newto), "%s", ot);
06141       ot = newto;
06142    }
06143 
06144    if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06145       add_header(req, "From", of);
06146       add_header(req, "To", ot);
06147    } else {
06148       add_header(req, "From", ot);
06149       add_header(req, "To", of);
06150    }
06151    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
06152    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
06153       add_header(req, "Contact", p->our_contact);
06154 
06155    copy_header(req, orig, "Call-ID");
06156    add_header(req, "CSeq", tmp);
06157 
06158    if (!ast_strlen_zero(global_useragent))
06159       add_header(req, "User-Agent", global_useragent);
06160    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
06161 
06162    if (!ast_strlen_zero(p->rpid))
06163       add_header(req, "Remote-Party-ID", p->rpid);
06164 
06165    return 0;
06166 }

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

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

06015 {
06016    char newto[256];
06017    const char *ot;
06018 
06019    init_resp(resp, msg);
06020    copy_via_headers(p, resp, req, "Via");
06021    if (msg[0] == '1' || msg[0] == '2')
06022       copy_all_header(resp, req, "Record-Route");
06023    copy_header(resp, req, "From");
06024    ot = get_header(req, "To");
06025    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
06026       /* Add the proper tag if we don't have it already.  If they have specified
06027          their tag, use it.  Otherwise, use our own tag */
06028       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
06029          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
06030       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
06031          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
06032       else
06033          ast_copy_string(newto, ot, sizeof(newto));
06034       ot = newto;
06035    }
06036    add_header(resp, "To", ot);
06037    copy_header(resp, req, "Call-ID");
06038    copy_header(resp, req, "CSeq");
06039    if (!ast_strlen_zero(global_useragent))
06040       add_header(resp, "User-Agent", global_useragent);
06041    add_header(resp, "Allow", ALLOWED_METHODS);
06042    add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
06043    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
06044       /* For registration responses, we also need expiry and
06045          contact info */
06046       char tmp[256];
06047 
06048       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
06049       add_header(resp, "Expires", tmp);
06050       if (p->expiry) {  /* Only add contact if we have an expiry time */
06051          char contact[SIPBUFSIZE];
06052          snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
06053          add_header(resp, "Contact", contact);  /* Not when we unregister */
06054       }
06055    } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) {
06056       add_header(resp, "Contact", p->our_contact);
06057    }
06058    return 0;
06059 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

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

16432 {
16433    /* If we're supposed to be stopped -- stay stopped */
16434    if (monitor_thread == AST_PTHREADT_STOP)
16435       return 0;
16436    ast_mutex_lock(&monlock);
16437    if (monitor_thread == pthread_self()) {
16438       ast_mutex_unlock(&monlock);
16439       ast_log(LOG_WARNING, "Cannot kill myself\n");
16440       return -1;
16441    }
16442    if (monitor_thread != AST_PTHREADT_NULL) {
16443       /* Wake up the thread */
16444       pthread_kill(monitor_thread, SIGURG);
16445    } else {
16446       /* Start a new monitor */
16447       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
16448          ast_mutex_unlock(&monlock);
16449          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
16450          return -1;
16451       }
16452    }
16453    ast_mutex_unlock(&monlock);
16454    return 0;
16455 }

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

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

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

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

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

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

15997 {
15998    struct sip_pvt *p = (struct sip_pvt *) data;
15999    int recount = 0;
16000    int nounlock = 0;
16001    int lockretry;
16002 
16003    for (lockretry = 10; lockretry > 0; lockretry--) {
16004       ast_mutex_lock(&p->lock);
16005 
16006       /* lock the owner if it has one -- we may need it */
16007       /* because this is deadlock-prone, we need to try and unlock if failed */
16008       if (!p->owner || !ast_channel_trylock(p->owner)) {
16009          break;   /* locking succeeded */
16010       }
16011 
16012       if (lockretry != 1) {
16013          ast_mutex_unlock(&p->lock);
16014          /* Sleep for a very short amount of time */
16015          usleep(1);
16016       }
16017    }
16018 
16019    if (!lockretry) {
16020       int retry = !AST_LIST_EMPTY(&p->request_queue);
16021 
16022       /* we couldn't get the owner lock, which is needed to process
16023          the queued requests, so return a non-zero value, which will
16024          cause the scheduler to run this request again later if there
16025          still requests to be processed
16026       */
16027       ast_mutex_unlock(&p->lock);
16028       return retry;
16029    };
16030 
16031    process_request_queue(p, &recount, &nounlock);
16032    p->request_queue_sched_id = -1;
16033 
16034    if (p->owner && !nounlock) {
16035       ast_channel_unlock(p->owner);
16036    }
16037    ast_mutex_unlock(&p->lock);
16038 
16039    if (recount) {
16040       ast_update_use_count();
16041    }
16042 
16043    return 0;
16044 }

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

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

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

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

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

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

static int set_address_from_contact ( struct sip_pvt pvt  )  [static]

Change the other partys IP address based on given contact.

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

08257 {
08258    if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
08259       /* NAT: Don't trust the contact field.  Just use what they came to us
08260          with. */
08261       pvt->sa = pvt->recv;
08262       return 0;
08263    }
08264 
08265    return __set_address_from_contact(pvt->fullcontact, &pvt->sa);
08266 }

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

Set destination from SIP URI.

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

05924 {
05925    char *h, *maddr, hostname[256];
05926    int port, hn;
05927    struct hostent *hp;
05928    struct ast_hostent ahp;
05929    int debug=sip_debug_test_pvt(p);
05930 
05931    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
05932    /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
05933 
05934    if (debug)
05935       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
05936 
05937    /* Find and parse hostname */
05938    h = strchr(uri, '@');
05939    if (h)
05940       ++h;
05941    else {
05942       h = uri;
05943       if (strncasecmp(h, "sip:", 4) == 0)
05944          h += 4;
05945       else if (strncasecmp(h, "sips:", 5) == 0)
05946          h += 5;
05947    }
05948    hn = strcspn(h, ":;>") + 1;
05949    if (hn > sizeof(hostname)) 
05950       hn = sizeof(hostname);
05951    ast_copy_string(hostname, h, hn);
05952    /* XXX bug here if string has been trimmed to sizeof(hostname) */
05953    h += hn - 1;
05954 
05955    /* Is "port" present? if not default to STANDARD_SIP_PORT */
05956    if (*h == ':') {
05957       /* Parse port */
05958       ++h;
05959       port = strtol(h, &h, 10);
05960    }
05961    else
05962       port = STANDARD_SIP_PORT;
05963 
05964    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
05965    maddr = strstr(h, "maddr=");
05966    if (maddr) {
05967       maddr += 6;
05968       hn = strspn(maddr, "0123456789.") + 1;
05969       if (hn > sizeof(hostname))
05970          hn = sizeof(hostname);
05971       ast_copy_string(hostname, maddr, hn);
05972    }
05973    
05974    hp = ast_gethostbyname(hostname, &ahp);
05975    if (hp == NULL)  {
05976       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
05977       return;
05978    }
05979    p->sa.sin_family = AF_INET;
05980    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
05981    p->sa.sin_port = htons(port);
05982    if (debug)
05983       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
05984 }

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

16766 {
16767    static int dep_insecure_very = 0;
16768    static int dep_insecure_yes = 0;
16769 
16770    if (ast_strlen_zero(value))
16771       return;
16772 
16773    if (!strcasecmp(value, "very")) {
16774       ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE);
16775       if(!dep_insecure_very) {
16776          if(lineno != -1)
16777             ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno);
16778          else
16779             ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n");
16780          dep_insecure_very = 1;
16781       }
16782    }
16783    else if (ast_true(value)) {
16784       ast_set_flag(flags, SIP_INSECURE_PORT);
16785       if(!dep_insecure_yes) {
16786          if(lineno != -1)
16787             ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno);
16788          else
16789             ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value);
16790          dep_insecure_yes = 1;
16791       }
16792    }
16793    else if (!ast_false(value)) {
16794       char buf[64];
16795       char *word, *next;
16796       ast_copy_string(buf, value, sizeof(buf));
16797       next = buf;
16798       while ((word = strsep(&next, ","))) {
16799          if (!strcasecmp(word, "port"))
16800             ast_set_flag(flags, SIP_INSECURE_PORT);
16801          else if (!strcasecmp(word, "invite"))
16802             ast_set_flag(flags, SIP_INSECURE_INVITE);
16803          else
16804             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
16805       }
16806    }
16807 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

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

17197 {
17198    if (peer->expire == 0) {
17199       /* Don't reset expire or port time during reload 
17200          if we have an active registration 
17201       */
17202       peer->expire = -1;
17203       peer->pokeexpire = -1;
17204       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
17205    }
17206    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
17207    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
17208    strcpy(peer->context, default_context);
17209    strcpy(peer->subscribecontext, default_subscribecontext);
17210    strcpy(peer->language, default_language);
17211    strcpy(peer->mohinterpret, default_mohinterpret);
17212    strcpy(peer->mohsuggest, default_mohsuggest);
17213    peer->addr.sin_family = AF_INET;
17214    peer->defaddr.sin_family = AF_INET;
17215    peer->capability = global_capability;
17216    peer->maxcallbitrate = default_maxcallbitrate;
17217    peer->rtptimeout = global_rtptimeout;
17218    peer->rtpholdtimeout = global_rtpholdtimeout;
17219    peer->rtpkeepalive = global_rtpkeepalive;
17220    peer->allowtransfer = global_allowtransfer;
17221    peer->autoframing = global_autoframing;
17222    strcpy(peer->vmexten, default_vmexten);
17223    peer->secret[0] = '\0';
17224    peer->md5secret[0] = '\0';
17225    peer->cid_num[0] = '\0';
17226    peer->cid_name[0] = '\0';
17227    peer->fromdomain[0] = '\0';
17228    peer->fromuser[0] = '\0';
17229    peer->regexten[0] = '\0';
17230    peer->mailbox[0] = '\0';
17231    peer->callgroup = 0;
17232    peer->pickupgroup = 0;
17233    peer->maxms = default_qualify;
17234    peer->prefs = default_prefs;
17235 }

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

Add a SIP header to an outbound INVITE.

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

18487 {
18488    int no = 0;
18489    int ok = FALSE;
18490    char varbuf[30];
18491    char *inbuf = (char *) data;
18492    
18493    if (ast_strlen_zero(inbuf)) {
18494       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
18495       return 0;
18496    }
18497    ast_channel_lock(chan);
18498 
18499    /* Check for headers */
18500    while (!ok && no <= 50) {
18501       no++;
18502       snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no);
18503 
18504       /* Compare without the leading underscores */
18505       if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) )
18506          ok = TRUE;
18507    }
18508    if (ok) {
18509       pbx_builtin_setvar_helper (chan, varbuf, inbuf);
18510       if (sipdebug)
18511          ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf);
18512    } else {
18513       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
18514    }
18515    ast_channel_unlock(chan);
18516    return 0;
18517 }

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

Support routine for find_peer.

Definition at line 2676 of file chan_sip.c.

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

Referenced by find_peer().

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

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 4527 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_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), errno, free, 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().

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

static void sip_alreadygone ( struct sip_pvt dialog  )  [static]

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

01672 {
01673    if (option_debug > 2)
01674       ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
01675    ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
01676 }

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

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

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

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 2985 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, t38properties::state, sip_pvt::t38, T38_LOCAL_DIRECT, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.

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

static int sip_cancel_destroy ( struct sip_pvt p  )  [static]

Cancel destruction of SIP dialog.

Definition at line 2153 of file chan_sip.c.

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

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

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

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

See if we pass debug IP filter.

Definition at line 1753 of file chan_sip.c.

References sipdebug.

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

01754 {
01755    if (!sipdebug)
01756       return 0;
01757    if (debugaddr.sin_addr.s_addr) {
01758       if (((ntohs(debugaddr.sin_port) != 0)
01759          && (debugaddr.sin_port != addr->sin_port))
01760          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
01761          return 0;
01762    }
01763    return 1;
01764 }

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

Test PVT for debugging output.

Definition at line 1779 of file chan_sip.c.

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

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

01780 {
01781    if (!sipdebug)
01782       return 0;
01783    return sip_debug_test_addr(sip_real_dst(p));
01784 }

static void sip_destroy ( struct sip_pvt p  )  [static]

Destroy SIP call structure.

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

03358 {
03359    ast_mutex_lock(&iflock);
03360    if (option_debug > 2)
03361       ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid);
03362    __sip_destroy(p, 1);
03363    ast_mutex_unlock(&iflock);
03364 }

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

Destroy peer object from memory.

Definition at line 2486 of file chan_sip.c.

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

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

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

static void sip_destroy_user ( struct sip_user user  )  [static]

Remove user object from in-memory storage.

Definition at line 2704 of file chan_sip.c.

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

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

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

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

16601 {
16602    char *host;
16603    char *tmp;
16604 
16605    struct hostent *hp;
16606    struct ast_hostent ahp;
16607    struct sip_peer *p;
16608 
16609    int res = AST_DEVICE_INVALID;
16610 
16611    /* make sure data is not null. Maybe unnecessary, but better be safe */
16612    host = ast_strdupa(data ? data : "");
16613    if ((tmp = strchr(host, '@')))
16614       host = tmp + 1;
16615 
16616    if (option_debug > 2) 
16617       ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
16618 
16619    /* If find_peer asks for a realtime peer, then this breaks rtautoclear.  This
16620     * is because when a peer tries to autoexpire, the last thing it does is to
16621     * queue up an event telling the system that the devicestate has changed
16622     * (presumably to unavailable).  If we ask for a realtime peer here, this would
16623     * load it BACK into memory, thus defeating the point of trying to trying to
16624     * clear dead hosts out of memory.
16625     */
16626    if ((p = find_peer(host, NULL, 0, 1))) {
16627       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
16628          /* we have an address for the peer */
16629       
16630          /* Check status in this order
16631             - Hold
16632             - Ringing
16633             - Busy (enforced only by call limit)
16634             - Inuse (we have a call)
16635             - Unreachable (qualify)
16636             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
16637             for registered devices */
16638 
16639          if (p->onHold)
16640             /* First check for hold or ring states */
16641             res = AST_DEVICE_ONHOLD;
16642          else if (p->inRinging) {
16643             if (p->inRinging == p->inUse)
16644                res = AST_DEVICE_RINGING;
16645             else
16646                res = AST_DEVICE_RINGINUSE;
16647          } else if (p->call_limit && (p->inUse == p->call_limit))
16648             /* check call limit */
16649             res = AST_DEVICE_BUSY;
16650          else if (p->call_limit && p->inUse)
16651             /* Not busy, but we do have a call */
16652             res = AST_DEVICE_INUSE;
16653          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 
16654             /* We don't have a call. Are we reachable at all? Requires qualify= */
16655             res = AST_DEVICE_UNAVAILABLE;
16656          else  /* Default reply if we're registered and have no other data */
16657             res = AST_DEVICE_NOT_INUSE;
16658       } else {
16659          /* there is no address, it's unavailable */
16660          res = AST_DEVICE_UNAVAILABLE;
16661       }
16662       ASTOBJ_UNREF(p,sip_destroy_peer);
16663    } else {
16664       char *port = strchr(host, ':');
16665       if (port)
16666          *port = '\0';
16667       hp = ast_gethostbyname(host, &ahp);
16668       if (hp)
16669          res = AST_DEVICE_UNKNOWN;
16670    }
16671 
16672    return res;
16673 }

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

Turn on SIP debugging (CLI command).

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

11534 {
11535    int oldsipdebug = sipdebug_console;
11536    if (argc != 3) {
11537       if (argc != 5) 
11538          return RESULT_SHOWUSAGE;
11539       else if (strcmp(argv[3], "ip") == 0)
11540          return sip_do_debug_ip(fd, argc, argv);
11541       else if (strcmp(argv[3], "peer") == 0)
11542          return sip_do_debug_peer(fd, argc, argv);
11543       else
11544          return RESULT_SHOWUSAGE;
11545    }
11546    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11547    memset(&debugaddr, 0, sizeof(debugaddr));
11548    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11549    return RESULT_SUCCESS;
11550 }

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

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

11553 {
11554    int oldsipdebug = sipdebug_console;
11555    char *newargv[6] = { "sip", "set", "debug", NULL };
11556    if (argc != 2) {
11557       if (argc != 4) 
11558          return RESULT_SHOWUSAGE;
11559       else if (strcmp(argv[2], "ip") == 0) {
11560          newargv[3] = argv[2];
11561          newargv[4] = argv[3];
11562          return sip_do_debug_ip(fd, argc + 1, newargv);
11563       } else if (strcmp(argv[2], "peer") == 0) {
11564          newargv[3] = argv[2];
11565          newargv[4] = argv[3];
11566          return sip_do_debug_peer(fd, argc + 1, newargv);
11567       } else
11568          return RESULT_SHOWUSAGE;
11569    }
11570    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11571    memset(&debugaddr, 0, sizeof(debugaddr));
11572    ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
11573    return RESULT_SUCCESS;
11574 }

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

Enable SIP Debugging in CLI.

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

11480 {
11481    struct hostent *hp;
11482    struct ast_hostent ahp;
11483    int port = 0;
11484    char *p, *arg;
11485 
11486    /* sip set debug ip <ip> */
11487    if (argc != 5)
11488       return RESULT_SHOWUSAGE;
11489    p = arg = argv[4];
11490    strsep(&p, ":");
11491    if (p)
11492       port = atoi(p);
11493    hp = ast_gethostbyname(arg, &ahp);
11494    if (hp == NULL)
11495       return RESULT_SHOWUSAGE;
11496 
11497    debugaddr.sin_family = AF_INET;
11498    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
11499    debugaddr.sin_port = htons(port);
11500    if (port == 0)
11501       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
11502    else
11503       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
11504 
11505    ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11506 
11507    return RESULT_SUCCESS;
11508 }

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

11512 {
11513    struct sip_peer *peer;
11514    if (argc != 5)
11515       return RESULT_SHOWUSAGE;
11516    peer = find_peer(argv[4], NULL, 1, 0);
11517    if (peer) {
11518       if (peer->addr.sin_addr.s_addr) {
11519          debugaddr.sin_family = AF_INET;
11520          debugaddr.sin_addr = peer->addr.sin_addr;
11521          debugaddr.sin_port = peer->addr.sin_port;
11522          ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
11523          ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11524       } else
11525          ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]);
11526       ASTOBJ_UNREF(peer,sip_destroy_peer);
11527    } else
11528       ast_cli(fd, "No such peer '%s'\n", argv[4]);
11529    return RESULT_SUCCESS;
11530 }

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

Enable SIP History logging (CLI).

Definition at line 11652 of file chan_sip.c.

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

11653 {
11654    if (argc != 2) {
11655       return RESULT_SHOWUSAGE;
11656    }
11657    recordhistory = TRUE;
11658    ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n");
11659    return RESULT_SUCCESS;
11660 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

Definition at line 18632 of file chan_sip.c.

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

Referenced by do_monitor().

18633 {
18634    reload_config(reason);
18635 
18636    /* Prune peers who still are supposed to be deleted */
18637    ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
18638    if (option_debug > 3)
18639       ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
18640 
18641    /* Send qualify (OPTIONS) to all peers */
18642    sip_poke_all_peers();
18643 
18644    /* Register with all services */
18645    sip_send_all_registers();
18646 
18647    if (option_debug > 3)
18648       ast_log(LOG_DEBUG, "--------------- SIP reload done\n");
18649 
18650    return 0;
18651 }

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

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

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

18432 {
18433    struct sip_pvt *p;
18434    char *mode;
18435    if (data)
18436       mode = (char *)data;
18437    else {
18438       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
18439       return 0;
18440    }
18441    ast_channel_lock(chan);
18442    if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
18443       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
18444       ast_channel_unlock(chan);
18445       return 0;
18446    }
18447    p = chan->tech_pvt;
18448    if (!p) {
18449       ast_channel_unlock(chan);
18450       return 0;
18451    }
18452    ast_mutex_lock(&p->lock);
18453    if (!strcasecmp(mode,"info")) {
18454       ast_clear_flag(&p->flags[0], SIP_DTMF);
18455       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
18456       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
18457    } else if (!strcasecmp(mode,"rfc2833")) {
18458       ast_clear_flag(&p->flags[0], SIP_DTMF);
18459       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
18460       p->jointnoncodeccapability |= AST_RTP_DTMF;
18461    } else if (!strcasecmp(mode,"inband")) { 
18462       ast_clear_flag(&p->flags[0], SIP_DTMF);
18463       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
18464       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
18465    } else
18466       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
18467    if (p->rtp)
18468       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
18469    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
18470       if (!p->vad) {
18471          p->vad = ast_dsp_new();
18472          ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT);
18473       }
18474    } else {
18475       if (p->vad) {
18476          ast_dsp_free(p->vad);
18477          p->vad = NULL;
18478       }
18479    }
18480    ast_mutex_unlock(&p->lock);
18481    ast_channel_unlock(chan);
18482    return 0;
18483 }

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

11338 {
11339    int x = 0;
11340    struct sip_history *hist;
11341    static int errmsg = 0;
11342 
11343    if (!dialog)
11344       return;
11345 
11346    if (!option_debug && !sipdebug) {
11347       if (!errmsg) {
11348          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
11349          errmsg = 1;
11350       }
11351       return;
11352    }
11353 
11354    ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
11355    if (dialog->subscribed)
11356       ast_log(LOG_DEBUG, "  * Subscription\n");
11357    else
11358       ast_log(LOG_DEBUG, "  * SIP Call\n");
11359    if (dialog->history)
11360       AST_LIST_TRAVERSE(dialog->history, hist, list)
11361          ast_log(LOG_DEBUG, "  %-3.3d. %s\n", ++x, hist->event);
11362    if (!x)
11363       ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid);
11364    ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
11365 }

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

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

static int sip_get_codec ( struct ast_channel chan  )  [static]

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

Definition at line 18576 of file chan_sip.c.

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

18577 {
18578    struct sip_pvt *p = chan->tech_pvt;
18579    return p->jointcapability ? p->jointcapability : p->capability;   
18580 }

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

18285 {
18286    struct sip_pvt *p = NULL;
18287    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
18288 
18289    if (!(p = chan->tech_pvt))
18290       return AST_RTP_GET_FAILED;
18291 
18292    ast_mutex_lock(&p->lock);
18293    if (!(p->rtp)) {
18294       ast_mutex_unlock(&p->lock);
18295       return AST_RTP_GET_FAILED;
18296    }
18297 
18298    *rtp = p->rtp;
18299 
18300    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
18301       res = AST_RTP_TRY_PARTIAL;
18302    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
18303       res = AST_RTP_TRY_NATIVE;
18304    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
18305       res = AST_RTP_GET_FAILED;
18306 
18307    ast_mutex_unlock(&p->lock);
18308 
18309    return res;
18310 }

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

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

18150 {
18151    struct sip_pvt *p;
18152    struct ast_udptl *udptl = NULL;
18153    
18154    p = chan->tech_pvt;
18155    if (!p)
18156       return NULL;
18157    
18158    ast_mutex_lock(&p->lock);
18159    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
18160       udptl = p->udptl;
18161    ast_mutex_unlock(&p->lock);
18162    return udptl;
18163 }

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

18314 {
18315    struct sip_pvt *p = NULL;
18316    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
18317    
18318    if (!(p = chan->tech_pvt))
18319       return AST_RTP_GET_FAILED;
18320 
18321    ast_mutex_lock(&p->lock);
18322    if (!(p->vrtp)) {
18323       ast_mutex_unlock(&p->lock);
18324       return AST_RTP_GET_FAILED;
18325    }
18326 
18327    *rtp = p->vrtp;
18328 
18329    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
18330       res = AST_RTP_TRY_NATIVE;
18331 
18332    ast_mutex_unlock(&p->lock);
18333 
18334    return res;
18335 }

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 18201 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, 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_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.

Referenced by handle_request_invite(), and handle_response_invite().

18202 {
18203    struct sip_pvt *p;
18204    int flag = 0;
18205    
18206    p = chan->tech_pvt;
18207    if (!p || !pvt->udptl)
18208       return -1;
18209    
18210    /* Setup everything on the other side like offered/responded from first side */
18211    ast_mutex_lock(&p->lock);
18212 
18213    /*! \todo check if this is not set earlier when setting up the PVT. If not
18214       maybe it should move there. */
18215    p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability;
18216 
18217    ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
18218    ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl));
18219    ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl));
18220    
18221    if (reinvite) {      /* If we are handling sending re-invite to the other side of the bridge */
18222       /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects,
18223          not really T38 re-invites which are different. In this
18224          case it's used properly, to see if we can reinvite over
18225          NAT 
18226       */
18227       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
18228          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
18229          flag =1;
18230       } else {
18231          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
18232       }
18233       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
18234          if (!p->pendinginvite) {
18235             if (option_debug > 2) {
18236                if (flag)
18237                   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));
18238                else
18239                   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));
18240             }
18241             transmit_reinvite_with_t38_sdp(p);
18242          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18243             if (option_debug > 2) {
18244                if (flag)
18245                   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));
18246                else
18247                   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));
18248             }
18249             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
18250          }
18251       }
18252       /* Reset lastrtprx timer */
18253       p->lastrtprx = p->lastrtptx = time(NULL);
18254       ast_mutex_unlock(&p->lock);
18255       return 0;
18256    } else { /* If we are handling sending 200 OK to the other side of the bridge */
18257       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) {
18258          ast_udptl_get_peer(pvt->udptl, &p->udptlredirip);
18259          flag = 1;
18260       } else {
18261          memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
18262       }
18263       if (option_debug > 2) {
18264          if (flag)
18265             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));
18266          else
18267             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));
18268       }
18269       pvt->t38.state = T38_ENABLED;
18270       p->t38.state = T38_ENABLED;
18271       if (option_debug > 1) {
18272          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>");
18273          ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
18274       }
18275       transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
18276       p->lastrtprx = p->lastrtptx = time(NULL);
18277       ast_mutex_unlock(&p->lock);
18278       return 0;
18279    }
18280 }

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

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

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

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

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

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

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

Display SIP nat mode.

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

01774 {
01775    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
01776 }

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 4039 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_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_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, sip_pvt::jointcapability, language, sip_pvt::language, sip_pvt::lock, LOG_DEBUG, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::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_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_PEER_DIRECT, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::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().

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

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

Disable SIP Debugging in CLI.

Definition at line 11633 of file chan_sip.c.

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

11634 {
11635    if (argc != 4)
11636       return RESULT_SHOWUSAGE;
11637    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11638    ast_cli(fd, "SIP Debugging Disabled\n");
11639    return RESULT_SUCCESS;
11640 }

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

Definition at line 11642 of file chan_sip.c.

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

11643 {
11644    if (argc != 3)
11645       return RESULT_SHOWUSAGE;
11646    ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE);
11647    ast_cli(fd, "SIP Debugging Disabled\n");
11648    return RESULT_SUCCESS;
11649 }

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

Disable SIP History logging (CLI).

Definition at line 11663 of file chan_sip.c.

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

11664 {
11665    if (argc != 3) {
11666       return RESULT_SHOWUSAGE;
11667    }
11668    recordhistory = FALSE;
11669    ast_cli(fd, "SIP History Recording Disabled\n");
11670    return RESULT_SUCCESS;
11671 }

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

Cli command to send SIP notify to peer.

Definition at line 11577 of file chan_sip.c.

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

11578 {
11579    struct ast_variable *varlist;
11580    int i;
11581 
11582    if (argc < 4)
11583       return RESULT_SHOWUSAGE;
11584 
11585    if (!notify_types) {
11586       ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
11587       return RESULT_FAILURE;
11588    }
11589 
11590    varlist = ast_variable_browse(notify_types, argv[2]);
11591 
11592    if (!varlist) {
11593       ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
11594       return RESULT_FAILURE;
11595    }
11596 
11597    for (i = 3; i < argc; i++) {
11598       struct sip_pvt *p;
11599       struct sip_request req;
11600       struct ast_variable *var;
11601 
11602       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
11603          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
11604          return RESULT_FAILURE;
11605       }
11606 
11607       if (create_addr(p, argv[i])) {
11608          /* Maybe they're not registered, etc. */
11609          sip_destroy(p);
11610          ast_cli(fd, "Could not create address for '%s'\n", argv[i]);
11611          continue;
11612       }
11613 
11614       initreqprep(&req, p, SIP_NOTIFY);
11615 
11616       for (var = varlist; var; var = var->next)
11617          add_header(&req, var->name, ast_unescape_semicolon(var->value));
11618 
11619       /* Recalculate our side, and recalculate Call ID */
11620       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
11621          p->ourip = __ourip;
11622       build_via(p);
11623       build_callid_pvt(p);
11624       ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
11625       transmit_sip_request(p, &req);
11626       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11627    }
11628 
11629    return RESULT_SUCCESS;
11630 }

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 13413 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_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, 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().

13414 {
13415    struct sip_dual *d;
13416    struct ast_channel *transferee, *transferer;
13417       /* Chan2m: The transferer, chan1m: The transferee */
13418    pthread_t th;
13419 
13420    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
13421    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
13422    if ((!transferer) || (!transferee)) {
13423       if (transferee) {
13424          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13425          ast_hangup(transferee);
13426       }
13427       if (transferer) {
13428          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13429          ast_hangup(transferer);
13430       }
13431       return -1;
13432    }
13433 
13434    /* Make formats okay */
13435    transferee->readformat = chan1->readformat;
13436    transferee->writeformat = chan1->writeformat;
13437 
13438    /* Prepare for taking over the channel */
13439    ast_channel_masquerade(transferee, chan1);
13440 
13441    /* Setup the extensions and such */
13442    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
13443    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
13444    transferee->priority = chan1->priority;
13445       
13446    /* We make a clone of the peer channel too, so we can play
13447       back the announcement */
13448 
13449    /* Make formats okay */
13450    transferer->readformat = chan2->readformat;
13451    transferer->writeformat = chan2->writeformat;
13452 
13453    /* Prepare for taking over the channel.  Go ahead and grab this channel
13454     * lock here to avoid a deadlock with callbacks into the channel driver
13455     * that hold the channel lock and want the pvt lock.  */
13456    while (ast_channel_trylock(chan2)) {
13457       struct sip_pvt *pvt = chan2->tech_pvt;
13458       DEADLOCK_AVOIDANCE(&pvt->lock);
13459    }
13460    ast_channel_masquerade(transferer, chan2);
13461    ast_channel_unlock(chan2);
13462 
13463    /* Setup the extensions and such */
13464    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
13465    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
13466    transferer->priority = chan2->priority;
13467 
13468    ast_channel_lock(transferer);
13469    if (ast_do_masquerade(transferer)) {
13470       ast_log(LOG_WARNING, "Masquerade failed :(\n");
13471       ast_channel_unlock(transferer);
13472       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
13473       ast_hangup(transferer);
13474       return -1;
13475    }
13476    ast_channel_unlock(transferer);
13477    if (!transferer || !transferee) {
13478       if (!transferer) { 
13479          if (option_debug)
13480             ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n");
13481       }
13482       if (!transferee) {
13483          if (option_debug)
13484             ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n");
13485       }
13486       return -1;
13487    }
13488    if ((d = ast_calloc(1, sizeof(*d)))) {
13489       pthread_attr_t attr;
13490 
13491       pthread_attr_init(&attr);
13492       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
13493 
13494       /* Save original request for followup */
13495       copy_request(&d->req, req);
13496       d->chan1 = transferee;  /* Transferee */
13497       d->chan2 = transferer;  /* Transferer */
13498       d->seqno = seqno;
13499       if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) {
13500          /* Could not start thread */
13501          free(d); /* We don't need it anymore. If thread is created, d will be free'd
13502                   by sip_park_thread() */
13503          pthread_attr_destroy(&attr);
13504          return 0;
13505       }
13506       pthread_attr_destroy(&attr);
13507    } 
13508    return -1;
13509 }

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

References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, free, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, 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().

13347 {
13348    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
13349    struct sip_dual *d;
13350    struct sip_request req;
13351    int ext;
13352    int res;
13353 
13354    d = stuff;
13355    transferee = d->chan1;
13356    transferer = d->chan2;
13357    copy_request(&req, &d->req);
13358 
13359    if (!transferee || !transferer) {
13360       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
13361       return NULL;
13362    }
13363    if (option_debug > 3) 
13364       ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
13365 
13366    ast_channel_lock(transferee);
13367    if (ast_do_masquerade(transferee)) {
13368       ast_log(LOG_WARNING, "Masquerade failed.\n");
13369       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
13370       ast_channel_unlock(transferee);
13371       return NULL;
13372    } 
13373    ast_channel_unlock(transferee);
13374 
13375    res = ast_park_call(transferee, transferer, 0, &ext);
13376    
13377 
13378 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
13379    if (!res) {
13380       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
13381    } else {
13382       /* Then tell the transferer what happened */
13383       sprintf(buf, "Call parked on extension '%d'", ext);
13384       transmit_message_with_text(transferer->tech_pvt, buf);
13385    }
13386 #endif
13387 
13388    /* Any way back to the current call??? */
13389    /* Transmit response to the REFER request */
13390    transmit_response(transferer->tech_pvt, "202 Accepted", &req);
13391    if (!res)   {
13392       /* Transfer succeeded */
13393       append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext);
13394       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
13395       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
13396       ast_hangup(transferer); /* This will cause a BYE */
13397       if (option_debug)
13398          ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
13399    } else {
13400       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
13401       append_history(transferer->tech_pvt, "SIPpark","Parking failed\n");
13402       if (option_debug)
13403          ast_log(LOG_DEBUG, "SIP Call parked failed \n");
13404       /* Do not hangup call */
13405    }
13406    free(d);
13407    return NULL;
13408 }

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

08750 {
08751    struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0);
08752 
08753    if (!peer)
08754       return;
08755 
08756    /* If they put someone on hold, increment the value... otherwise decrement it */
08757    if (hold)
08758       peer->onHold++;
08759    else
08760       peer->onHold--;
08761 
08762    /* Request device state update */
08763    ast_device_state_changed("SIP/%s", peer->name);
08764 
08765    return;
08766 }

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

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

Referenced by load_module(), and sip_do_reload().

18587 {
18588    int ms = 0;
18589    
18590    if (!speerobjs)   /* No peers, just give up */
18591       return;
18592 
18593    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
18594       ASTOBJ_WRLOCK(iterator);
18595       if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) {
18596          struct sip_peer *peer_ptr = iterator;
18597          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
18598       }
18599       ms += 100;
18600       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator));
18601       if (iterator->pokeexpire == -1) {
18602          struct sip_peer *peer_ptr = iterator;
18603          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
18604       }
18605       ASTOBJ_UNLOCK(iterator);
18606    } while (0)
18607    );
18608 }

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

React to lack of answer to Qualify poke.

Definition at line 16458 of file chan_sip.c.

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

Referenced by sip_poke_peer().

16459 {
16460    struct sip_peer *peer = (struct sip_peer *)data;
16461    
16462    peer->pokeexpire = -1;
16463    if (peer->lastms > -1) {
16464       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
16465       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
16466    }
16467    if (peer->call)
16468       sip_destroy(peer->call);
16469    peer->call = NULL;
16470    peer->lastms = -1;
16471    ast_device_state_changed("SIP/%s", peer->name);
16472 
16473    /* This function gets called one place outside of the scheduler ... */
16474    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16475       struct sip_peer *peer_ptr = peer;
16476       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16477    }
16478 
16479    /* There is no need to ASTOBJ_REF() here.  Just let the scheduled callback
16480     * inherit the reference that the current callback already has. */
16481    peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
16482    if (peer->pokeexpire == -1) {
16483       ASTOBJ_UNREF(peer, sip_destroy_peer);
16484    }
16485 
16486    return 0;
16487 }

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 16492 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 parse_register_contact(), reg_source_db(), and sip_poke_peer_s().

16493 {
16494    struct sip_pvt *p;
16495    int xmitres = 0;
16496 
16497    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
16498       /* IF we have no IP, or this isn't to be monitored, return
16499         imeediately after clearing things out */
16500       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16501          struct sip_peer *peer_ptr = peer;
16502          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16503       }
16504       peer->lastms = 0;
16505       peer->call = NULL;
16506       return 0;
16507    }
16508    if (peer->call) {
16509       if (sipdebug)
16510          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
16511       sip_destroy(peer->call);
16512    }
16513    if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
16514       return -1;
16515    
16516    p->sa = peer->addr;
16517    p->recv = peer->addr;
16518    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
16519    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
16520 
16521    /* Send OPTIONs to peer's fullcontact */
16522    if (!ast_strlen_zero(peer->fullcontact))
16523       ast_string_field_set(p, fullcontact, peer->fullcontact);
16524 
16525    if (!ast_strlen_zero(peer->tohost))
16526       ast_string_field_set(p, tohost, peer->tohost);
16527    else
16528       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
16529 
16530    /* Recalculate our side, and recalculate Call ID */
16531    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16532       p->ourip = __ourip;
16533    build_via(p);
16534    build_callid_pvt(p);
16535 
16536    if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16537       struct sip_peer *peer_ptr = peer;
16538       ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16539    }
16540 
16541    p->relatedpeer = ASTOBJ_REF(peer);
16542    ast_set_flag(&p->flags[0], SIP_OUTGOING);
16543 #ifdef VOCAL_DATA_HACK
16544    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
16545    xmitres = transmit_invite(p, SIP_INVITE, 0, 2);
16546 #else
16547    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2);
16548 #endif
16549    gettimeofday(&peer->ps, NULL);
16550    if (xmitres == XMIT_ERROR) {
16551       sip_poke_noanswer(ASTOBJ_REF(peer));   /* Immediately unreachable, network problems */
16552    } else {
16553       if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
16554          struct sip_peer *peer_ptr = peer;
16555          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16556       }
16557       peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer));
16558       if (peer->pokeexpire == -1) {
16559          struct sip_peer *peer_ptr = peer;
16560          ASTOBJ_UNREF(peer_ptr, sip_destroy_peer);
16561       }
16562    }
16563 
16564    return 0;
16565 }

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

References ASTOBJ_UNREF, sip_peer::pokeexpire, sip_destroy_peer(), and sip_poke_peer().

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

08096 {
08097    struct sip_peer *peer = (struct sip_peer *) data;
08098 
08099    peer->pokeexpire = -1;
08100 
08101    sip_poke_peer(peer);
08102 
08103    ASTOBJ_UNREF(peer, sip_destroy_peer);
08104 
08105    return 0;
08106 }

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

Remove temporary realtime objects from memory (CLI).

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

10358 {
10359    struct sip_peer *peer;
10360    struct sip_user *user;
10361    int pruneuser = FALSE;
10362    int prunepeer = FALSE;
10363    int multi = FALSE;
10364    char *name = NULL;
10365    regex_t regexbuf;
10366 
10367    switch (argc) {
10368    case 4:
10369       if (!strcasecmp(argv[3], "user"))
10370          return RESULT_SHOWUSAGE;
10371       if (!strcasecmp(argv[3], "peer"))
10372          return RESULT_SHOWUSAGE;
10373       if (!strcasecmp(argv[3], "like"))
10374          return RESULT_SHOWUSAGE;
10375       if (!strcasecmp(argv[3], "all")) {
10376          multi = TRUE;
10377          pruneuser = prunepeer = TRUE;
10378       } else {
10379          pruneuser = prunepeer = TRUE;
10380          name = argv[3];
10381       }
10382       break;
10383    case 5:
10384       if (!strcasecmp(argv[4], "like"))
10385          return RESULT_SHOWUSAGE;
10386       if (!strcasecmp(argv[3], "all"))
10387          return RESULT_SHOWUSAGE;
10388       if (!strcasecmp(argv[3], "like")) {
10389          multi = TRUE;
10390          name = argv[4];
10391          pruneuser = prunepeer = TRUE;
10392       } else if (!strcasecmp(argv[3], "user")) {
10393          pruneuser = TRUE;
10394          if (!strcasecmp(argv[4], "all"))
10395             multi = TRUE;
10396          else
10397             name = argv[4];
10398       } else if (!strcasecmp(argv[3], "peer")) {
10399          prunepeer = TRUE;
10400          if (!strcasecmp(argv[4], "all"))
10401             multi = TRUE;
10402          else
10403             name = argv[4];
10404       } else
10405          return RESULT_SHOWUSAGE;
10406       break;
10407    case 6:
10408       if (strcasecmp(argv[4], "like"))
10409          return RESULT_SHOWUSAGE;
10410       if (!strcasecmp(argv[3], "user")) {
10411          pruneuser = TRUE;
10412          name = argv[5];
10413       } else if (!strcasecmp(argv[3], "peer")) {
10414          prunepeer = TRUE;
10415          name = argv[5];
10416       } else
10417          return RESULT_SHOWUSAGE;
10418       break;
10419    default:
10420       return RESULT_SHOWUSAGE;
10421    }
10422 
10423    if (multi && name) {
10424       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
10425          return RESULT_SHOWUSAGE;
10426    }
10427 
10428    if (multi) {
10429       if (prunepeer) {
10430          int pruned = 0;
10431 
10432          ASTOBJ_CONTAINER_WRLOCK(&peerl);
10433          ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
10434             ASTOBJ_RDLOCK(iterator);
10435             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10436                ASTOBJ_UNLOCK(iterator);
10437                continue;
10438             };
10439             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10440                ASTOBJ_MARK(iterator);
10441                pruned++;
10442             }
10443             ASTOBJ_UNLOCK(iterator);
10444          } while (0) );
10445          if (pruned) {
10446             ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
10447             ast_cli(fd, "%d peers pruned.\n", pruned);
10448          } else
10449             ast_cli(fd, "No peers found to prune.\n");
10450          ASTOBJ_CONTAINER_UNLOCK(&peerl);
10451       }
10452       if (pruneuser) {
10453          int pruned = 0;
10454 
10455          ASTOBJ_CONTAINER_WRLOCK(&userl);
10456          ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
10457             ASTOBJ_RDLOCK(iterator);
10458             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10459                ASTOBJ_UNLOCK(iterator);
10460                continue;
10461             };
10462             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10463                ASTOBJ_MARK(iterator);
10464                pruned++;
10465             }
10466             ASTOBJ_UNLOCK(iterator);
10467          } while (0) );
10468          if (pruned) {
10469             ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
10470             ast_cli(fd, "%d users pruned.\n", pruned);
10471          } else
10472             ast_cli(fd, "No users found to prune.\n");
10473          ASTOBJ_CONTAINER_UNLOCK(&userl);
10474       }
10475    } else {
10476       if (prunepeer) {
10477          if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
10478             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10479                ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
10480                ASTOBJ_CONTAINER_LINK(&peerl, peer);
10481             } else
10482                ast_cli(fd, "Peer '%s' pruned.\n", name);
10483             ASTOBJ_UNREF(peer, sip_destroy_peer);
10484          } else
10485             ast_cli(fd, "Peer '%s' not found.\n", name);
10486       }
10487       if (pruneuser) {
10488          if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
10489             if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
10490                ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
10491                ASTOBJ_CONTAINER_LINK(&userl, user);
10492             } else
10493                ast_cli(fd, "User '%s' pruned.\n", name);
10494             ASTOBJ_UNREF(user, sip_destroy_user);
10495          } else
10496             ast_cli(fd, "User '%s' not found.\n", name);
10497       }
10498    }
10499 
10500    return RESULT_SUCCESS;
10501 }

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

Read SIP RTP from channel.

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

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

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

The real destination address for a write.

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

01768 {
01769    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
01770 }

static int sip_refer_allocate ( struct sip_pvt p  )  [static]

Allocate SIP refer structure.

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

07901 {
07902    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
07903    return p->refer ? 1 : 0;
07904 }

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

Registration timeout, register again.

Definition at line 7643 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(), 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(), and sip_registry::username.

Referenced by transmit_register().

07644 {
07645 
07646    /* if we are here, our registration timed out, so we'll just do it over */
07647    struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
07648    struct sip_pvt *p;
07649    int res;
07650 
07651    /* if we couldn't get a reference to the registry object, punt */
07652    if (!r)
07653       return 0;
07654 
07655    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
07656    if (r->call) {
07657       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
07658          in the single SIP manager thread. */
07659       p = r->call;
07660       ast_mutex_lock(&p->lock);
07661       if (p->registry)
07662          ASTOBJ_UNREF(p->registry, sip_registry_destroy);
07663       r->call = NULL;
07664       ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
07665       /* Pretend to ACK anything just in case */
07666       __sip_pretend_ack(p);
07667       ast_mutex_unlock(&p->lock);
07668    }
07669    /* If we have a limit, stop registration and give up */
07670    if (global_regattempts_max && (r->regattempts > global_regattempts_max)) {
07671       /* Ok, enough is enough. Don't try any more */
07672       /* We could add an external notification here... 
07673          steal it from app_voicemail :-) */
07674       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
07675       r->regstate = REG_STATE_FAILED;
07676    } else {
07677       r->regstate = REG_STATE_UNREGISTERED;
07678       r->timeout = -1;
07679       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
07680    }
07681    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));
07682    ASTOBJ_UNREF(r, sip_registry_destroy);
07683    return 0;
07684 }

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

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

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

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

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

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

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

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

Referenced by handle_response_invite().

12307 {
12308    struct sip_pvt *p = (struct sip_pvt *) data;
12309 
12310    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
12311    p->waitid = -1;
12312    return 0;
12313 }

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

Force reload of module from cli.

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

18655 {
18656    ast_mutex_lock(&sip_reload_lock);
18657    if (sip_reloading) 
18658       ast_verbose("Previous SIP reload not yet done\n");
18659    else {
18660       sip_reloading = TRUE;
18661       if (fd)
18662          sip_reloadreason = CHANNEL_CLI_RELOAD;
18663       else
18664          sip_reloadreason = CHANNEL_MODULE_RELOAD;
18665    }
18666    ast_mutex_unlock(&sip_reload_lock);
18667    restart_monitor();
18668 
18669    return 0;
18670 }

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

References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, 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.

16678 {
16679    int oldformat;
16680    struct sip_pvt *p;
16681    struct ast_channel *tmpc = NULL;
16682    char *ext, *host;
16683    char tmp[256];
16684    char *dest = data;
16685 
16686    oldformat = format;
16687    if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) {
16688       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));
16689       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
16690       return NULL;
16691    }
16692    if (option_debug)
16693       ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
16694 
16695    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) {
16696       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data);
16697       *cause = AST_CAUSE_SWITCH_CONGESTION;
16698       return NULL;
16699    }
16700 
16701    ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL);
16702 
16703    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
16704       sip_destroy(p);
16705       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
16706       *cause = AST_CAUSE_SWITCH_CONGESTION;
16707       return NULL;
16708    }
16709 
16710    ast_copy_string(tmp, dest, sizeof(tmp));
16711    host = strchr(tmp, '@');
16712    if (host) {
16713       *host++ = '\0';
16714       ext = tmp;
16715    } else {
16716       ext = strchr(tmp, '/');
16717       if (ext) 
16718          *ext++ = '\0';
16719       host = tmp;
16720    }
16721 
16722    if (create_addr(p, host)) {
16723       *cause = AST_CAUSE_UNREGISTERED;
16724       if (option_debug > 2)
16725          ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n");
16726       sip_destroy(p);
16727       return NULL;
16728    }
16729    if (ast_strlen_zero(p->peername) && ext)
16730       ast_string_field_set(p, peername, ext);
16731    /* Recalculate our side, and recalculate Call ID */
16732    if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16733       p->ourip = __ourip;
16734    build_via(p);
16735    build_callid_pvt(p);
16736    
16737    /* We have an extension to call, don't use the full contact here */
16738    /* This to enable dialing registered peers with extension dialling,
16739       like SIP/peername/extension   
16740       SIP/peername will still use the full contact */
16741    if (ext) {
16742       ast_string_field_set(p, username, ext);
16743       ast_string_field_free(p, fullcontact);
16744    }
16745 #if 0
16746    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
16747 #endif
16748    p->prefcodec = oldformat;           /* Format for this call */
16749    ast_mutex_lock(&p->lock);
16750    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
16751    ast_mutex_unlock(&p->lock);
16752    if (!tmpc)
16753       sip_destroy(p);
16754    ast_update_use_count();
16755    restart_monitor();
16756    return tmpc;
16757 }

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

Update registration with SIP Proxy.

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

07612 {
07613    /* if we are here, we know that we need to reregister. */
07614    struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
07615 
07616    /* if we couldn't get a reference to the registry object, punt */
07617    if (!r)
07618       return 0;
07619 
07620    if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY))
07621       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
07622    /* Since registry's are only added/removed by the the monitor thread, this
07623       may be overkill to reference/dereference at all here */
07624    if (sipdebug)
07625       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
07626 
07627    r->expire = -1;
07628    __sip_do_register(r);
07629    ASTOBJ_UNREF(r, sip_registry_destroy);
07630    return 0;
07631 }

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

References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::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().

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

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

Schedule destruction of SIP dialog.

Definition at line 2136 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(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().

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

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

Definition at line 18611 of file chan_sip.c.

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

Referenced by load_module(), and sip_do_reload().

18612 {
18613    int ms;
18614    int regspacing;
18615    if (!regobjs)
18616       return;
18617    regspacing = default_expiry * 1000/regobjs;
18618    if (regspacing > 100)
18619       regspacing = 100;
18620    ms = regspacing;
18621    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
18622       ASTOBJ_WRLOCK(iterator);
18623       AST_SCHED_DEL(sched, iterator->expire);
18624       ms += regspacing;
18625       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
18626       ASTOBJ_UNLOCK(iterator);
18627    } while (0)
18628    );
18629 }

static int sip_send_mwi_to_peer ( struct sip_peer peer  )  [static]

Send message waiting indication to alert peer that they've got voicemail.

Definition at line 16188 of file chan_sip.c.

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

Referenced by handle_request_subscribe().

16189 {
16190    /* Called with peerl lock, but releases it */
16191    struct sip_pvt *p;
16192    int newmsgs, oldmsgs;
16193 
16194    /* Do we have an IP address? If not, skip this peer */
16195    if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
16196       return 0;
16197 
16198    /* Check for messages */
16199    ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs);
16200    
16201    peer->lastmsgcheck = time(NULL);
16202    
16203    /* Return now if it's the same thing we told them last time */
16204    if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) {
16205       return 0;
16206    }
16207    
16208    
16209    peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs));
16210 
16211    if (peer->mwipvt) {
16212       /* Base message on subscription */
16213       p = peer->mwipvt;
16214    } else {
16215       /* Build temporary dialog for this message */
16216       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 
16217          return -1;
16218       if (create_addr_from_peer(p, peer)) {
16219          /* Maybe they're not registered, etc. */
16220          sip_destroy(p);
16221          return 0;
16222       }
16223       /* Recalculate our side, and recalculate Call ID */
16224       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
16225          p->ourip = __ourip;
16226       build_via(p);
16227       build_callid_pvt(p);
16228       /* Destroy this session after 32 secs */
16229       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16230    }
16231    /* Send MWI */
16232    ast_set_flag(&p->flags[0], SIP_OUTGOING);
16233    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
16234    return 0;
16235 }

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

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

03871 {
03872    struct sip_pvt *p = ast->tech_pvt;
03873    int res = 0;
03874 
03875    ast_mutex_lock(&p->lock);
03876    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03877    case SIP_DTMF_INBAND:
03878       res = -1; /* Tell Asterisk to generate inband indications */
03879       break;
03880    case SIP_DTMF_RFC2833:
03881       if (p->rtp)
03882          ast_rtp_senddigit_begin(p->rtp, digit);
03883       break;
03884    default:
03885       break;
03886    }
03887    ast_mutex_unlock(&p->lock);
03888 
03889    return res;
03890 }

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

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

03895 {
03896    struct sip_pvt *p = ast->tech_pvt;
03897    int res = 0;
03898 
03899    ast_mutex_lock(&p->lock);
03900    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
03901    case SIP_DTMF_INFO:
03902       transmit_info_with_digit(p, digit, duration);
03903       break;
03904    case SIP_DTMF_RFC2833:
03905       if (p->rtp)
03906          ast_rtp_senddigit_end(p->rtp, digit);
03907       break;
03908    case SIP_DTMF_INBAND:
03909       res = -1; /* Tell Asterisk to stop inband indications */
03910       break;
03911    }
03912    ast_mutex_unlock(&p->lock);
03913 
03914    return res;
03915 }

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

References ast_strlen_zero(), ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().

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

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

References ast_channel::_state, append_history, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::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().

18339 {
18340    struct sip_pvt *p;
18341    int changed = 0;
18342 
18343    p = chan->tech_pvt;
18344    if (!p) 
18345       return -1;
18346 
18347    /* Disable early RTP bridge  */
18348    if (chan->_state != AST_STATE_UP && !global_directrtpsetup)    /* We are in early state */
18349       return 0;
18350 
18351    ast_mutex_lock(&p->lock);
18352    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
18353       /* If we're destroyed, don't bother */
18354       ast_mutex_unlock(&p->lock);
18355       return 0;
18356    }
18357 
18358    /* if this peer cannot handle reinvites of the media stream to devices
18359       that are known to be behind a NAT, then stop the process now
18360    */
18361    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
18362       ast_mutex_unlock(&p->lock);
18363       return 0;
18364    }
18365 
18366    if (rtp) {
18367       changed |= ast_rtp_get_peer(rtp, &p->redirip);
18368    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
18369       memset(&p->redirip, 0, sizeof(p->redirip));
18370       changed = 1;
18371    }
18372    if (vrtp) {
18373       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
18374    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
18375       memset(&p->vredirip, 0, sizeof(p->vredirip));
18376       changed = 1;
18377    }
18378    if (codecs) {
18379       if ((p->redircodecs != codecs)) {
18380          p->redircodecs = codecs;
18381          changed = 1;
18382       }
18383       if ((p->capability & codecs) != p->capability) {
18384          p->jointcapability &= codecs;
18385          p->capability &= codecs;
18386          changed = 1;
18387       }
18388    }
18389    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
18390       if (chan->_state != AST_STATE_UP) { /* We are in early state */
18391          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
18392             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
18393          if (option_debug)
18394             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));
18395       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
18396          if (option_debug > 2) {
18397             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));
18398          }
18399          transmit_reinvite_with_sdp(p);
18400       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18401          if (option_debug > 2) {
18402             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));
18403          }
18404          /* We have a pending Invite. Send re-invite when we're done with the invite */
18405          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
18406       }
18407    }
18408    /* Reset lastrtprx timer */
18409    p->lastrtprx = p->lastrtptx = time(NULL);
18410    ast_mutex_unlock(&p->lock);
18411    return 0;
18412 }

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

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

18166 {
18167    struct sip_pvt *p;
18168    
18169    p = chan->tech_pvt;
18170    if (!p)
18171       return -1;
18172    ast_mutex_lock(&p->lock);
18173    if (udptl)
18174       ast_udptl_get_peer(udptl, &p->udptlredirip);
18175    else
18176       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
18177    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
18178       if (!p->pendinginvite) {
18179          if (option_debug > 2) {
18180             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);
18181          }
18182          transmit_reinvite_with_t38_sdp(p);
18183       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18184          if (option_debug > 2) {
18185             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);
18186          }
18187          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
18188       }
18189    }
18190    /* Reset lastrtprx timer */
18191    p->lastrtprx = p->lastrtptx = time(NULL);
18192    ast_mutex_unlock(&p->lock);
18193    return 0;
18194 }

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

Show details of one active dialog.

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

11233 {
11234    struct sip_pvt *cur;
11235    size_t len;
11236    int found = 0;
11237 
11238    if (argc != 4)
11239       return RESULT_SHOWUSAGE;
11240    len = strlen(argv[3]);
11241    ast_mutex_lock(&iflock);
11242    for (cur = iflist; cur; cur = cur->next) {
11243       if (!strncasecmp(cur->callid, argv[3], len)) {
11244          char formatbuf[SIPBUFSIZE/2];
11245          ast_cli(fd,"\n");
11246          if (cur->subscribed != NONE)
11247             ast_cli(fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
11248          else
11249             ast_cli(fd, "  * SIP Call\n");
11250          ast_cli(fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
11251          ast_cli(fd, "  Call-ID:                %s\n", cur->callid);
11252          ast_cli(fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
11253          ast_cli(fd, "  Our Codec Capability:   %d\n", cur->capability);
11254          ast_cli(fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
11255          ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
11256          ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
11257          ast_cli(fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
11258          ast_cli(fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
11259          ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
11260          ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
11261          ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
11262          ast_cli(fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
11263          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)" );
11264          ast_cli(fd, "  Our Tag:                %s\n", cur->tag);
11265          ast_cli(fd, "  Their Tag:              %s\n", cur->theirtag);
11266          ast_cli(fd, "  SIP User agent:         %s\n", cur->useragent);
11267          if (!ast_strlen_zero(cur->username))
11268             ast_cli(fd, "  Username:               %s\n", cur->username);
11269          if (!ast_strlen_zero(cur->peername))
11270             ast_cli(fd, "  Peername:               %s\n", cur->peername);
11271          if (!ast_strlen_zero(cur->uri))
11272             ast_cli(fd, "  Original uri:           %s\n", cur->uri);
11273          if (!ast_strlen_zero(cur->cid_num))
11274             ast_cli(fd, "  Caller-ID:              %s\n", cur->cid_num);
11275          ast_cli(fd, "  Need Destroy:           %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY));
11276          ast_cli(fd, "  Last Message:           %s\n", cur->lastmsg);
11277          ast_cli(fd, "  Promiscuous Redir:      %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
11278          ast_cli(fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
11279          ast_cli(fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
11280          ast_cli(fd, "  SIP Options:            ");
11281          if (cur->sipoptions) {
11282             int x;
11283             for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
11284                if (cur->sipoptions & sip_options[x].id)
11285                   ast_cli(fd, "%s ", sip_options[x].text);
11286             }
11287          } else
11288             ast_cli(fd, "(none)\n");
11289          ast_cli(fd, "\n\n");
11290          found++;
11291       }
11292    }
11293    ast_mutex_unlock(&iflock);
11294    if (!found) 
11295       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
11296    return RESULT_SUCCESS;
11297 }

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

Show active SIP channels.

Definition at line 11023 of file chan_sip.c.

References __sip_show_channels().

11024 {
11025         return __sip_show_channels(fd, argc, argv, 0);
11026 }

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

CLI command to list local domains.

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

10536 {
10537    struct domain *d;
10538 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
10539 
10540    if (AST_LIST_EMPTY(&domain_list)) {
10541       ast_cli(fd, "SIP Domain support not enabled.\n\n");
10542       return RESULT_SUCCESS;
10543    } else {
10544       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
10545       AST_LIST_LOCK(&domain_list);
10546       AST_LIST_TRAVERSE(&domain_list, d, list)
10547          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
10548             domain_mode_to_text(d->mode));
10549       AST_LIST_UNLOCK(&domain_list);
10550       ast_cli(fd, "\n");
10551       return RESULT_SUCCESS;
10552    }
10553 }

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

Show history details of one dialog.

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

11301 {
11302    struct sip_pvt *cur;
11303    size_t len;
11304    int found = 0;
11305 
11306    if (argc != 4)
11307       return RESULT_SHOWUSAGE;
11308    if (!recordhistory)
11309       ast_cli(fd, "\n***Note: History recording is currently DISABLED.  Use 'sip history' to ENABLE.\n");
11310    len = strlen(argv[3]);
11311    ast_mutex_lock(&iflock);
11312    for (cur = iflist; cur; cur = cur->next) {
11313       if (!strncasecmp(cur->callid, argv[3], len)) {
11314          struct sip_history *hist;
11315          int x = 0;
11316 
11317          ast_cli(fd,"\n");
11318          if (cur->subscribed != NONE)
11319             ast_cli(fd, "  * Subscription\n");
11320          else
11321             ast_cli(fd, "  * SIP Call\n");
11322          if (cur->history)
11323             AST_LIST_TRAVERSE(cur->history, hist, list)
11324                ast_cli(fd, "%d. %s\n", ++x, hist->event);
11325          if (x == 0)
11326             ast_cli(fd, "Call '%s' has no history\n", cur->callid);
11327          found++;
11328       }
11329    }
11330    ast_mutex_unlock(&iflock);
11331    if (!found) 
11332       ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]);
11333    return RESULT_SUCCESS;
11334 }

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

09961 {
09962 #define FORMAT  "%-25.25s %-15.15s %-15.15s \n"
09963 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
09964    char ilimits[40];
09965    char iused[40];
09966    int showall = FALSE;
09967 
09968    if (argc < 3) 
09969       return RESULT_SHOWUSAGE;
09970 
09971    if (argc == 4 && !strcmp(argv[3],"all")) 
09972          showall = TRUE;
09973    
09974    ast_cli(fd, FORMAT, "* User name", "In use", "Limit");
09975    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
09976       ASTOBJ_RDLOCK(iterator);
09977       if (iterator->call_limit)
09978          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09979       else 
09980          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09981       snprintf(iused, sizeof(iused), "%d", iterator->inUse);
09982       if (showall || iterator->call_limit)
09983          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09984       ASTOBJ_UNLOCK(iterator);
09985    } while (0) );
09986 
09987    ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit");
09988 
09989    ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
09990       ASTOBJ_RDLOCK(iterator);
09991       if (iterator->call_limit)
09992          snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
09993       else 
09994          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
09995       snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging);
09996       if (showall || iterator->call_limit)
09997          ast_cli(fd, FORMAT2, iterator->name, iused, ilimits);
09998       ASTOBJ_UNLOCK(iterator);
09999    } while (0) );
10000 
10001    return RESULT_SUCCESS;
10002 #undef FORMAT
10003 #undef FORMAT2
10004 }

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

List all allocated SIP Objects (realtime or static).

Definition at line 10281 of file chan_sip.c.

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

10282 {
10283    char tmp[256];
10284    if (argc != 3)
10285       return RESULT_SHOWUSAGE;
10286    ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
10287    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl);
10288    ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
10289    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl);
10290    ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs);
10291    ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &regl);
10292    return RESULT_SUCCESS;
10293 }

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

Show one peer in detail.

Definition at line 10587 of file chan_sip.c.

References _sip_show_peer().

10588 {
10589    return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv);
10590 }

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

CLI Show Peers command.

Definition at line 10137 of file chan_sip.c.

References _sip_show_peers().

10138 {
10139    return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv);
10140 }

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

Show SIP Registry (registrations with other SIP proxies.

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

10861 {
10862 #define FORMAT2 "%-30.30s  %-12.12s  %8.8s %-20.20s %-25.25s\n"
10863 #define FORMAT  "%-30.30s  %-12.12s  %8d %-20.20s %-25.25s\n"
10864    char host[80];
10865    char tmpdat[256];
10866    struct tm tm;
10867 
10868 
10869    if (argc != 3)
10870       return RESULT_SHOWUSAGE;
10871    ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
10872    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
10873       ASTOBJ_RDLOCK(iterator);
10874       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
10875       if (iterator->regtime) {
10876          ast_localtime(&iterator->regtime, &tm, NULL);
10877          strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
10878       } else {
10879          tmpdat[0] = 0;
10880       }
10881       ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
10882       ASTOBJ_UNLOCK(iterator);
10883    } while(0));
10884    return RESULT_SUCCESS;
10885 #undef FORMAT
10886 #undef FORMAT2
10887 }

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

List global settings for the SIP channel.

Definition at line 10890 of file chan_sip.c.

References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, SIPBUFSIZE, and transfermode2str().

10891 {
10892    int realtimepeers;
10893    int realtimeusers;
10894    char codec_buf[SIPBUFSIZE];
10895 
10896    realtimepeers = ast_check_realtime("sippeers");
10897    realtimeusers = ast_check_realtime("sipusers");
10898 
10899    if (argc != 3)
10900       return RESULT_SHOWUSAGE;
10901    ast_cli(fd, "\n\nGlobal Settings:\n");
10902    ast_cli(fd, "----------------\n");
10903    ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
10904    ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
10905    ast_cli(fd, "  Videosupport:           %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
10906    ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
10907    ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
10908    ast_cli(fd, "  Allow subscriptions:    %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
10909    ast_cli(fd, "  Allow overlap dialing:  %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
10910    ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
10911    ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
10912    ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
10913    ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
10914    ast_cli(fd, "  Our auth realm          %s\n", global_realm);
10915    ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
10916    ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
10917    ast_cli(fd, "  Call limit peers only:  %s\n", global_limitonpeers ? "Yes" : "No");
10918    ast_cli(fd, "  Direct RTP setup:       %s\n", global_directrtpsetup ? "Yes" : "No");
10919    ast_cli(fd, "  User Agent:             %s\n", global_useragent);
10920    ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
10921    ast_cli(fd, "  Reg. context:           %s\n", S_OR(global_regcontext, "(not set)"));
10922    ast_cli(fd, "  Caller ID:              %s\n", default_callerid);
10923    ast_cli(fd, "  From: Domain:           %s\n", default_fromdomain);
10924    ast_cli(fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
10925    ast_cli(fd, "  Call Events:            %s\n", global_callevents ? "On" : "Off");
10926    ast_cli(fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
10927    ast_cli(fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
10928    ast_cli(fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
10929    ast_cli(fd, "  T38 fax pt UDPTL:       %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No");
10930 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
10931    ast_cli(fd, "  T38 fax pt RTP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No");
10932    ast_cli(fd, "  T38 fax pt TCP:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No");
10933 #endif
10934    ast_cli(fd, "  RFC2833 Compensation:   %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No");
10935    if (!realtimepeers && !realtimeusers)
10936       ast_cli(fd, "  SIP realtime:           Disabled\n" );
10937    else
10938       ast_cli(fd, "  SIP realtime:           Enabled\n" );
10939 
10940    ast_cli(fd, "\nGlobal Signalling Settings:\n");
10941    ast_cli(fd, "---------------------------\n");
10942    ast_cli(fd, "  Codecs:                 ");
10943    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
10944    ast_cli(fd, "%s\n", codec_buf);
10945    ast_cli(fd, "  Codec Order:            ");
10946    print_codec_to_cli(fd, &default_prefs);
10947    ast_cli(fd, "\n");
10948    ast_cli(fd, "  T1 minimum:             %d\n", global_t1min);
10949    ast_cli(fd, "  Relax DTMF:             %s\n", global_relaxdtmf ? "Yes" : "No");
10950    ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
10951    ast_cli(fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
10952    ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
10953    ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
10954    ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
10955    ast_cli(fd, "  DNS SRV lookup:         %s\n", srvlookup ? "Yes" : "No");
10956    ast_cli(fd, "  Pedantic SIP support:   %s\n", pedanticsipchecking ? "Yes" : "No");
10957    ast_cli(fd, "  Reg. min duration       %d secs\n", min_expiry);
10958    ast_cli(fd, "  Reg. max duration:      %d secs\n", max_expiry);
10959    ast_cli(fd, "  Reg. default duration:  %d secs\n", default_expiry);
10960    ast_cli(fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
10961    ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
10962    ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
10963    ast_cli(fd, "  Notify hold state:      %s\n", global_notifyhold ? "Yes" : "No");
10964    ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
10965    ast_cli(fd, "  Max Call Bitrate:       %d kbps\r\n", default_maxcallbitrate);
10966    ast_cli(fd, "  Auto-Framing:           %s \r\n", global_autoframing ? "Yes" : "No");
10967    ast_cli(fd, "\nDefault Settings:\n");
10968    ast_cli(fd, "-----------------\n");
10969    ast_cli(fd, "  Context:                %s\n", default_context);
10970    ast_cli(fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
10971    ast_cli(fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
10972    ast_cli(fd, "  Qualify:                %d\n", default_qualify);
10973    ast_cli(fd, "  Use ClientCode:         %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
10974    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" );
10975    ast_cli(fd, "  Language:               %s\n", S_OR(default_language, "(Defaults to English)"));
10976    ast_cli(fd, "  MOH Interpret:          %s\n", default_mohinterpret);
10977    ast_cli(fd, "  MOH Suggest:            %s\n", default_mohsuggest);
10978    ast_cli(fd, "  Voice Mail Extension:   %s\n", default_vmexten);
10979 
10980    
10981    if (realtimepeers || realtimeusers) {
10982       ast_cli(fd, "\nRealtime SIP Settings:\n");
10983       ast_cli(fd, "----------------------\n");
10984       ast_cli(fd, "  Realtime Peers:         %s\n", realtimepeers ? "Yes" : "No");
10985       ast_cli(fd, "  Realtime Users:         %s\n", realtimeusers ? "Yes" : "No");
10986       ast_cli(fd, "  Cache Friends:          %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No");
10987       ast_cli(fd, "  Update:                 %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No");
10988       ast_cli(fd, "  Ignore Reg. Expire:     %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No");
10989       ast_cli(fd, "  Save sys. name:         %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No");
10990       ast_cli(fd, "  Auto Clear:             %d\n", global_rtautoclear);
10991    }
10992    ast_cli(fd, "\n----\n");
10993    return RESULT_SUCCESS;
10994 }

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

Show active SIP subscriptions.

Definition at line 11029 of file chan_sip.c.

References __sip_show_channels().

11030 {
11031         return __sip_show_channels(fd, argc, argv, 1);
11032 }

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

Show one user in detail.

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

10806 {
10807    char cbuf[256];
10808    struct sip_user *user;
10809    struct ast_variable *v;
10810    int load_realtime;
10811 
10812    if (argc < 4)
10813       return RESULT_SHOWUSAGE;
10814 
10815    /* Load from realtime storage? */
10816    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
10817 
10818    user = find_user(argv[3], load_realtime);
10819    if (user) {
10820       ast_cli(fd,"\n\n");
10821       ast_cli(fd, "  * Name       : %s\n", user->name);
10822       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
10823       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
10824       ast_cli(fd, "  Context      : %s\n", user->context);
10825       ast_cli(fd, "  Language     : %s\n", user->language);
10826       if (!ast_strlen_zero(user->accountcode))
10827          ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
10828       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
10829       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
10830       ast_cli(fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
10831       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
10832       ast_cli(fd, "  Call limit   : %d\n", user->call_limit);
10833       ast_cli(fd, "  Callgroup    : ");
10834       print_group(fd, user->callgroup, 0);
10835       ast_cli(fd, "  Pickupgroup  : ");
10836       print_group(fd, user->pickupgroup, 0);
10837       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
10838       ast_cli(fd, "  ACL          : %s\n", (user->ha?"Yes":"No"));
10839       ast_cli(fd, "  Codec Order  : (");
10840       print_codec_to_cli(fd, &user->prefs);
10841       ast_cli(fd, ")\n");
10842 
10843       ast_cli(fd, "  Auto-Framing:  %s \n", user->autoframing ? "Yes" : "No");
10844       if (user->chanvars) {
10845          ast_cli(fd, "  Variables    :\n");
10846          for (v = user->chanvars ; v ; v = v->next)
10847             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
10848       }
10849       ast_cli(fd,"\n");
10850       ASTOBJ_UNREF(user,sip_destroy_user);
10851    } else {
10852       ast_cli(fd,"User %s not found.\n", argv[3]);
10853       ast_cli(fd,"\n");
10854    }
10855 
10856    return RESULT_SUCCESS;
10857 }

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

CLI Command 'SIP Show Users'.

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

10061 {
10062    regex_t regexbuf;
10063    int havepattern = FALSE;
10064 
10065 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
10066 
10067    switch (argc) {
10068    case 5:
10069       if (!strcasecmp(argv[3], "like")) {
10070          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
10071             return RESULT_SHOWUSAGE;
10072          havepattern = TRUE;
10073       } else
10074          return RESULT_SHOWUSAGE;
10075    case 3:
10076       break;
10077    default:
10078       return RESULT_SHOWUSAGE;
10079    }
10080 
10081    ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
10082    ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
10083       ASTOBJ_RDLOCK(iterator);
10084 
10085       if (havepattern && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
10086          ASTOBJ_UNLOCK(iterator);
10087          continue;
10088       }
10089 
10090       ast_cli(fd, FORMAT, iterator->name, 
10091          iterator->secret, 
10092          iterator->accountcode,
10093          iterator->context,
10094          iterator->ha ? "Yes" : "No",
10095          nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
10096       ASTOBJ_UNLOCK(iterator);
10097    } while (0)
10098    );
10099 
10100    if (havepattern)
10101       regfree(&regexbuf);
10102 
10103    return RESULT_SUCCESS;
10104 #undef FORMAT
10105 }

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

18526 {
18527    char *cdest;
18528    char *extension, *host, *port;
18529    char tmp[80];
18530    
18531    cdest = ast_strdupa(dest);
18532    
18533    extension = strsep(&cdest, "@");
18534    host = strsep(&cdest, ":");
18535    port = strsep(&cdest, ":");
18536    if (ast_strlen_zero(extension)) {
18537       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
18538       return 0;
18539    }
18540 
18541    /* we'll issue the redirect message here */
18542    if (!host) {
18543       char *localtmp;
18544       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
18545       if (ast_strlen_zero(tmp)) {
18546          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
18547          return 0;
18548       }
18549       if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) {
18550          char lhost[80], lport[80];
18551          memset(lhost, 0, sizeof(lhost));
18552          memset(lport, 0, sizeof(lport));
18553          localtmp++;
18554          /* This is okey because lhost and lport are as big as tmp */
18555          sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport);
18556          if (ast_strlen_zero(lhost)) {
18557             ast_log(LOG_ERROR, "Can't find the host address\n");
18558             return 0;
18559          }
18560          host = ast_strdupa(lhost);
18561          if (!ast_strlen_zero(lport)) {
18562             port = ast_strdupa(lport);
18563          }
18564       }
18565    }
18566 
18567    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
18568    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
18569 
18570    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
18571    sip_alreadygone(p);
18572    return 0;
18573 }

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

Transfer SIP call.

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

03919 {
03920    struct sip_pvt *p = ast->tech_pvt;
03921    int res;
03922 
03923    if (dest == NULL) /* functions below do not take a NULL */
03924       dest = "";
03925    ast_mutex_lock(&p->lock);
03926    if (ast->_state == AST_STATE_RING)
03927       res = sip_sipredirect(p, dest);
03928    else
03929       res = transmit_refer(p, dest);
03930    ast_mutex_unlock(&p->lock);
03931    return res;
03932 }

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

Definition at line 14125 of file chan_sip.c.

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

Referenced by handle_request_invite().

14126 {
14127    char *uri1 = ast_strdupa(input1);
14128    char *uri2 = ast_strdupa(input2);
14129    char *host1;
14130    char *host2;
14131    char *params1;
14132    char *params2;
14133    char *headers1;
14134    char *headers2;
14135 
14136    /* Strip off "sip:" from the URI. We know this is present
14137     * because it was checked back in parse_request()
14138     */
14139    strsep(&uri1, ":");
14140    strsep(&uri2, ":");
14141 
14142    if ((host1 = strchr(uri1, '@'))) {
14143       *host1++ = '\0';
14144    }
14145    if ((host2 = strchr(uri2, '@'))) {
14146       *host2++ = '\0';
14147    }
14148 
14149    /* Check for mismatched username and passwords. This is the
14150     * only case-sensitive comparison of a SIP URI
14151     */
14152    if ((host1 && !host2) ||
14153          (host2 && !host1) ||
14154          (host1 && host2 && strcmp(uri1, uri2))) {
14155       return 1;
14156    }
14157 
14158    if (!host1)
14159       host1 = uri1;
14160    if (!host2)
14161       host2 = uri2;
14162 
14163    /* Strip off the parameters and headers so we can compare
14164     * host and port
14165     */
14166 
14167    if ((params1 = strchr(host1, ';'))) {
14168       *params1++ = '\0';
14169    }
14170    if ((params2 = strchr(host2, ';'))) {
14171       *params2++ = '\0';
14172    }
14173 
14174    /* Headers come after parameters, but there may be headers without
14175     * parameters, thus the S_OR
14176     */
14177    if ((headers1 = strchr(S_OR(params1, host1), '?'))) {
14178       *headers1++ = '\0';
14179    }
14180    if ((headers2 = strchr(S_OR(params2, host2), '?'))) {
14181       *headers2++ = '\0';
14182    }
14183 
14184    /* Now the host/port are properly isolated. We can get by with a string comparison
14185     * because the SIP URI checking rules have some interesting exceptions that make
14186     * this possible. I will note 2 in particular
14187     * 1. hostnames which resolve to the same IP address as well as a hostname and its
14188     *    IP address are not considered a match with SIP URI's.
14189     * 2. If one URI specifies a port and the other does not, then the URIs do not match.
14190     *    This includes if one URI explicitly contains port 5060 and the other implies it
14191     *    by not having a port specified.
14192     */
14193 
14194    if (strcasecmp(host1, host2)) {
14195       return 1;
14196    }
14197 
14198    /* Headers have easier rules to follow, so do those first */
14199    if (sip_uri_headers_cmp(headers1, headers2)) {
14200       return 1;
14201    }
14202 
14203    /* And now the parameters. Ugh */
14204    return sip_uri_params_cmp(params1, params2);
14205 }

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

References ast_strdupa, and ast_strlen_zero().

Referenced by sip_uri_cmp().

14092 {
14093    char *headers1 = ast_strdupa(input1);
14094    char *headers2 = ast_strdupa(input2);
14095    int zerolength1 = ast_strlen_zero(headers1);
14096    int zerolength2 = ast_strlen_zero(headers2);
14097    int different = 0;
14098    char *header1;
14099 
14100    if ((zerolength1 && !zerolength2) ||
14101          (zerolength2 && !zerolength1))
14102       return 1;
14103 
14104    if (zerolength1 && zerolength2)
14105       return 0;
14106 
14107    /* At this point, we can definitively state that both inputs are
14108     * not zero-length. First, one more optimization. If the length
14109     * of the headers is not equal, then we definitely have no match
14110     */
14111    if (strlen(headers1) != strlen(headers2)) {
14112       return 1;
14113    }
14114 
14115    for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) {
14116       if (!strcasestr(headers2, header1)) {
14117          different = 1;
14118          break;
14119       }
14120    }
14121 
14122    return different;
14123 }

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

helper routine for sip_uri_cmp

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

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

Definition at line 13964 of file chan_sip.c.

References ast_strdupa, and ast_strlen_zero().

Referenced by sip_uri_cmp().

13965 {
13966    char *params1 = ast_strdupa(input1);
13967    char *params2 = ast_strdupa(input2);
13968    char *pos1;
13969    char *pos2;
13970    int maddrmatch = 0;
13971    int ttlmatch = 0;
13972    int usermatch = 0;
13973    int methodmatch = 0;
13974 
13975    /*Quick optimization. If both params are zero-length, then
13976     * they match
13977     */
13978    if (ast_strlen_zero(params1) && ast_strlen_zero(params2)) {
13979       return 0;
13980    }
13981 
13982    pos1 = params1;
13983    while (!ast_strlen_zero(pos1)) {
13984       char *name1 = pos1;
13985       char *value1 = strchr(pos1, '=');
13986       char *semicolon1 = strchr(pos1, ';');
13987       int matched = 0;
13988       if (semicolon1) {
13989          *semicolon1++ = '\0';
13990       }
13991       if (!value1) {
13992          goto fail;
13993       }
13994       *value1++ = '\0';
13995       /* Checkpoint reached. We have the name and value parsed for param1 
13996        * We have to duplicate params2 each time through the second loop
13997        * or else we can't search and replace the semicolons with \0 each
13998        * time
13999        */
14000       pos2 = ast_strdupa(params2);
14001       while (!ast_strlen_zero(pos2)) {
14002          char *name2 = pos2;
14003          char *value2 = strchr(pos2, '=');
14004          char *semicolon2 = strchr(pos2, ';');
14005          if (semicolon2) {
14006             *semicolon2++ = '\0';
14007          }
14008          if (!value2) {
14009             goto fail;
14010          }
14011          *value2++ = '\0';
14012          if (!strcasecmp(name1, name2)) {
14013             if (strcasecmp(value1, value2)) {
14014                goto fail;
14015             } else {
14016                matched = 1;
14017                break;
14018             }
14019          }
14020          pos2 = semicolon2;
14021       }
14022       /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */
14023       if (!strcasecmp(name1, "maddr")) {
14024          if (matched) {
14025             maddrmatch = 1;
14026          } else {
14027             goto fail;
14028          }
14029       } else if (!strcasecmp(name1, "ttl")) {
14030          if (matched) {
14031             ttlmatch = 1;
14032          } else {
14033             goto fail;
14034          }
14035       } else if (!strcasecmp(name1, "user")) {
14036          if (matched) {
14037             usermatch = 1;
14038          } else {
14039             goto fail;
14040          }
14041       } else if (!strcasecmp(name1, "method")) {
14042          if (matched) {
14043             methodmatch = 1;
14044          } else {
14045             goto fail;
14046          }
14047       }
14048       pos1 = semicolon1;
14049    }
14050 
14051    /* We've made it out of that horrible O(m*n) construct and there are no
14052     * failures yet. We're not done yet, though, because params2 could have
14053     * an maddr, ttl, user, or method header and params1 did not.
14054     */
14055    pos2 = params2;
14056    while (!ast_strlen_zero(pos2)) {
14057       char *name2 = pos2;
14058       char *value2 = strchr(pos2, '=');
14059       char *semicolon2 = strchr(pos2, ';');
14060       if (semicolon2) {
14061          *semicolon2++ = '\0';
14062       }
14063       if (!value2) {
14064          goto fail;
14065       }
14066       *value2++ = '\0';
14067       if ((!strcasecmp(name2, "maddr") && !maddrmatch) ||
14068             (!strcasecmp(name2, "ttl") && !ttlmatch) ||
14069             (!strcasecmp(name2, "user") && !usermatch) ||
14070             (!strcasecmp(name2, "method") && !methodmatch)) {
14071          goto fail;
14072       }
14073    }
14074    return 0;
14075 
14076 fail:
14077    return 1;
14078 }

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

Send frame to media channel (rtp).

Definition at line 3743 of file chan_sip.c.

References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtptx, sip_pvt::lock, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.

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

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

16069 {
16070    struct sip_request req;
16071    struct sockaddr_in sin = { 0, };
16072    struct sip_pvt *p;
16073    int res;
16074    socklen_t len = sizeof(sin);
16075    int nounlock = 0;
16076    int recount = 0;
16077    int lockretry;
16078 
16079    memset(&req, 0, sizeof(req));
16080    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
16081    if (res < 0) {
16082 #if !defined(__FreeBSD__)
16083       if (errno == EAGAIN)
16084          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
16085       else 
16086 #endif
16087       if (errno != ECONNREFUSED)
16088          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
16089       return 1;
16090    }
16091    if (option_debug && res == sizeof(req.data) - 1)
16092       ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n");
16093 
16094    req.data[res] = '\0';
16095    req.len = res;
16096    if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */
16097       ast_set_flag(&req, SIP_PKT_DEBUG);
16098    if (pedanticsipchecking)
16099       req.len = lws2sws(req.data, req.len);  /* Fix multiline headers */
16100    if (ast_test_flag(&req, SIP_PKT_DEBUG))
16101       ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data);
16102 
16103    if(parse_request(&req) == -1) /* Bad packet, can't parse */
16104       return 1;
16105 
16106    req.method = find_sip_method(req.rlPart1);
16107 
16108    if (ast_test_flag(&req, SIP_PKT_DEBUG))
16109       ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : "");
16110 
16111    if (req.headers < 2) /* Must have at least two headers */
16112       return 1;
16113 
16114    /* Process request, with netlock held, and with usual deadlock avoidance */
16115    for (lockretry = 10; lockretry > 0; lockretry--) {
16116       ast_mutex_lock(&netlock);
16117 
16118       /* Find the active SIP dialog or create a new one */
16119       p = find_call(&req, &sin, req.method); /* returns p locked */
16120       if (p == NULL) {
16121          if (option_debug)
16122             ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len);
16123          ast_mutex_unlock(&netlock);
16124          return 1;
16125       }
16126       /* Go ahead and lock the owner if it has one -- we may need it */
16127       /* because this is deadlock-prone, we need to try and unlock if failed */
16128       if (!p->owner || !ast_channel_trylock(p->owner))
16129          break;   /* locking succeeded */
16130       if (lockretry != 1) {
16131          ast_mutex_unlock(&p->lock);
16132          ast_mutex_unlock(&netlock);
16133          /* Sleep for a very short amount of time */
16134          usleep(1);
16135       }
16136    }
16137    p->recv = sin;
16138 
16139    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */
16140       append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2);
16141 
16142    if (!lockretry) {
16143       if (!queue_request(p, &req)) {
16144          /* the request has been queued for later handling */
16145          ast_mutex_unlock(&p->lock);
16146          ast_mutex_unlock(&netlock);
16147          return 1;
16148       }
16149 
16150       /* This is unsafe, since p->owner is not locked. */
16151       if (p->owner)
16152          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 ??? - "));
16153       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
16154       if (req.method != SIP_ACK)
16155          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
16156       /* XXX We could add retry-after to make sure they come back */
16157       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
16158       ast_mutex_unlock(&p->lock);
16159       ast_mutex_unlock(&netlock);
16160       return 1;
16161    }
16162 
16163    /* if there are queued requests on this sip_pvt, process them first, so that everything is
16164       handled in order
16165    */
16166    if (!AST_LIST_EMPTY(&p->request_queue)) {
16167       AST_SCHED_DEL(sched, p->request_queue_sched_id);
16168       process_request_queue(p, &recount, &nounlock);
16169    }
16170 
16171    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
16172       /* Request failed */
16173       if (option_debug)
16174          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
16175    }
16176       
16177    if (p->owner && !nounlock)
16178       ast_channel_unlock(p->owner);
16179    ast_mutex_unlock(&p->lock);
16180    ast_mutex_unlock(&netlock);
16181    if (recount)
16182       ast_update_use_count();
16183 
16184    return 1;
16185 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

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

12890 {
12891    /* Immediately stop RTP, VRTP and UDPTL as applicable */
12892    if (p->rtp)
12893       ast_rtp_stop(p->rtp);
12894    if (p->vrtp)
12895       ast_rtp_stop(p->vrtp);
12896    if (p->udptl)
12897       ast_udptl_stop(p->udptl);
12898 }

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

Show subscription type in string format.

Definition at line 10997 of file chan_sip.c.

References subscription_types, and type.

Referenced by sip_show_channel().

10998 {
10999    int i;
11000 
11001    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
11002       if (subscription_types[i].type == subtype) {
11003          return subscription_types[i].text;
11004       }
11005    }
11006    return subscription_types[0].text;
11007 }

static int t38_get_rate ( int  t38cap  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

Definition at line 6417 of file chan_sip.c.

References ast_log(), LOG_DEBUG, option_debug, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, and T38FAX_RATE_9600.

Referenced by add_t38_sdp().

06418 {
06419    int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
06420    
06421    if (maxrate & T38FAX_RATE_14400) {
06422       if (option_debug > 1)
06423          ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n");
06424       return 14400;
06425    } else if (maxrate & T38FAX_RATE_12000) {
06426       if (option_debug > 1)
06427          ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n");
06428       return 12000;
06429    } else if (maxrate & T38FAX_RATE_9600) {
06430       if (option_debug > 1)
06431          ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n");
06432       return 9600;
06433    } else if (maxrate & T38FAX_RATE_7200) {
06434       if (option_debug > 1)
06435          ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n");
06436       return 7200;
06437    } else if (maxrate & T38FAX_RATE_4800) {
06438       if (option_debug > 1)
06439          ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n");
06440       return 4800;
06441    } else if (maxrate & T38FAX_RATE_2400) {
06442       if (option_debug > 1)
06443          ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n");
06444       return 2400;
06445    } else {
06446       if (option_debug > 1)
06447          ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n");
06448       return 0;
06449    }
06450 }

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

Create temporary peer (used in autocreatepeer mode).

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

17239 {
17240    struct sip_peer *peer;
17241 
17242    if (!(peer = ast_calloc(1, sizeof(*peer))))
17243       return NULL;
17244 
17245    apeerobjs++;
17246    ASTOBJ_INIT(peer);
17247    set_peer_defaults(peer);
17248 
17249    ast_copy_string(peer->name, name, sizeof(peer->name));
17250 
17251    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
17252    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
17253    peer->prefs = default_prefs;
17254    reg_source_db(peer);
17255 
17256    return peer;
17257 }

static void temp_pvt_cleanup ( void *   )  [static]

Definition at line 6192 of file chan_sip.c.

References ast_string_field_free_memory, and free.

06193 {
06194    struct sip_pvt *p = data;
06195 
06196    ast_string_field_free_memory(p);
06197 
06198    free(data);
06199 }

static void temp_pvt_init ( void   )  [static]

A per-thread temporary pvt structure.

Definition at line 1205 of file chan_sip.c.

01220 { 0, };  /*!< The address we bind to */

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

Convert transfer mode to text string.

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

10008 {
10009    if (mode == TRANSFER_OPENFORALL)
10010       return "open";
10011    else if (mode == TRANSFER_CLOSED)
10012       return "closed";
10013    return "strict";
10014 }

static void transmit_fake_auth_response ( struct sip_pvt p,
struct sip_request req,
int  reliable 
) [static]

Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.

Definition at line 8814 of file chan_sip.c.

References ast_random(), ast_string_field_build, sip_pvt::randdata, and transmit_response_with_auth().

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

08815 {
08816    ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
08817    transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
08818 }

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

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

Referenced by sip_senddigit_end().

07982 {
07983    struct sip_request req;
07984 
07985    reqprep(&req, p, SIP_INFO, 0, 1);
07986    add_digit(&req, digit, duration);
07987    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07988 }

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 7991 of file chan_sip.c.

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

Referenced by sip_indicate().

07992 {
07993    struct sip_request req;
07994 
07995    reqprep(&req, p, SIP_INFO, 0, 1);
07996    add_vidupdate(&req);
07997    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07998 }

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

References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_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, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.

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

07228 {
07229    struct sip_request req;
07230    
07231    req.method = sipmethod;
07232    if (init) {    /* Seems like init always is 2 */
07233       /* Bump branch even on initial requests */
07234       p->branch ^= ast_random();
07235       p->invite_branch = p->branch;
07236       build_via(p);
07237       if (init > 1)
07238          initreqprep(&req, p, sipmethod);
07239       else
07240          reqprep(&req, p, sipmethod, 0, 1);
07241    } else
07242       reqprep(&req, p, sipmethod, 0, 1);
07243       
07244    if (p->options && p->options->auth)
07245       add_header(&req, p->options->authheader, p->options->auth);
07246    append_date(&req);
07247    if (sipmethod == SIP_REFER) { /* Call transfer */
07248       if (p->refer) {
07249          char buf[SIPBUFSIZE];
07250          if (!ast_strlen_zero(p->refer->refer_to))
07251             add_header(&req, "Refer-To", p->refer->refer_to);
07252          if (!ast_strlen_zero(p->refer->referred_by)) {
07253             snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
07254             add_header(&req, "Referred-By", buf);
07255          }
07256       }
07257    }
07258    /* This new INVITE is part of an attended transfer. Make sure that the
07259    other end knows and replace the current call with this new call */
07260    if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) {
07261       add_header(&req, "Replaces", p->options->replaces);
07262       add_header(&req, "Require", "replaces");
07263    }
07264 
07265    add_header(&req, "Allow", ALLOWED_METHODS);
07266    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07267    if (p->options && p->options->addsipheaders && p->owner) {
07268       struct ast_channel *chan = p->owner; /* The owner channel */
07269       struct varshead *headp;
07270    
07271       ast_channel_lock(chan);
07272 
07273       headp = &chan->varshead;
07274 
07275       if (!headp)
07276          ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
07277       else {
07278          const struct ast_var_t *current;
07279          AST_LIST_TRAVERSE(headp, current, entries) {  
07280             /* SIPADDHEADER: Add SIP header to outgoing call */
07281             if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
07282                char *content, *end;
07283                const char *header = ast_var_value(current);
07284                char *headdup = ast_strdupa(header);
07285 
07286                /* Strip of the starting " (if it's there) */
07287                if (*headdup == '"')
07288                   headdup++;
07289                if ((content = strchr(headdup, ':'))) {
07290                   *content++ = '\0';
07291                   content = ast_skip_blanks(content); /* Skip white space */
07292                   /* Strip the ending " (if it's there) */
07293                   end = content + strlen(content) -1; 
07294                   if (*end == '"')
07295                      *end = '\0';
07296                
07297                   add_header(&req, headdup, content);
07298                   if (sipdebug)
07299                      ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
07300                }
07301             }
07302          }
07303       }
07304 
07305       ast_channel_unlock(chan);
07306    }
07307    if (sdp) {
07308       if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) {
07309          ast_udptl_offered_from_local(p->udptl, 1);
07310          if (option_debug)
07311             ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
07312          add_t38_sdp(&req, p);
07313       } else if (p->rtp) 
07314          add_sdp(&req, p);
07315    } else {
07316       add_header_contentLength(&req, 0);
07317    }
07318 
07319    if (!p->initreq.headers || init > 2)
07320       initialize_initreq(p, &req);
07321    p->lastinvite = p->ocseq;
07322    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
07323 }

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

Transmit text with SIP MESSAGE method.

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

07891 {
07892    struct sip_request req;
07893 
07894    reqprep(&req, p, SIP_MESSAGE, 0, 1);
07895    add_text(&req, text);
07896    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07897 }

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

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

Referenced by sip_send_mwi_to_peer().

07515 {
07516    struct sip_request req;
07517    char tmp[500];
07518    char *t = tmp;
07519    size_t maxbytes = sizeof(tmp);
07520 
07521    initreqprep(&req, p, SIP_NOTIFY);
07522    add_header(&req, "Event", "message-summary");
07523    add_header(&req, "Content-Type", default_notifymime);
07524 
07525    ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
07526    ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
07527       S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
07528    /* Cisco has a bug in the SIP stack where it can't accept the
07529       (0/0) notification. This can temporarily be disabled in
07530       sip.conf with the "buggymwi" option */
07531    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)"));
07532 
07533    if (p->subscribed) {
07534       if (p->expiry)
07535          add_header(&req, "Subscription-State", "active");
07536       else  /* Expired */
07537          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07538    }
07539 
07540    if (t > tmp + sizeof(tmp))
07541       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07542 
07543    add_header_contentLength(&req, strlen(tmp));
07544    add_line(&req, tmp);
07545 
07546    if (!p->initreq.headers) 
07547       initialize_initreq(p, &req);
07548    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07549 }

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

References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::lastnoninvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.

Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().

07561 {
07562    struct sip_request req;
07563    char tmp[SIPBUFSIZE/2];
07564 
07565    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07566    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
07567    add_header(&req, "Event", tmp);
07568    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
07569    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
07570    add_header(&req, "Allow", ALLOWED_METHODS);
07571    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07572 
07573    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
07574    add_header_contentLength(&req, strlen(tmp));
07575    add_line(&req, tmp);
07576 
07577    if (!p->initreq.headers)
07578       initialize_initreq(p, &req);
07579 
07580    p->lastnoninvite = p->ocseq;
07581 
07582    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07583 }

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

07912 {
07913    struct sip_request req = { 
07914       .headers = 0,  
07915    };
07916    char from[256];
07917    const char *of;
07918    char *c;
07919    char referto[256];
07920    char *ttag, *ftag;
07921    char *theirtag = ast_strdupa(p->theirtag);
07922 
07923    if (option_debug || sipdebug)
07924       ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
07925 
07926    /* Are we transfering an inbound or outbound call ? */
07927    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
07928       of = get_header(&p->initreq, "To");
07929       ttag = theirtag;
07930       ftag = p->tag;
07931    } else {
07932       of = get_header(&p->initreq, "From");
07933       ftag = theirtag;
07934       ttag = p->tag;
07935    }
07936 
07937    ast_copy_string(from, of, sizeof(from));
07938    of = get_in_brackets(from);
07939    ast_string_field_set(p, from, of);
07940    if (strncasecmp(of, "sip:", 4))
07941       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
07942    else
07943       of += 4;
07944    /* Get just the username part */
07945    if ((c = strchr(dest, '@')))
07946       c = NULL;
07947    else if ((c = strchr(of, '@')))
07948       *c++ = '\0';
07949    if (c) 
07950       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
07951    else
07952       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
07953 
07954    /* save in case we get 407 challenge */
07955    sip_refer_allocate(p);
07956    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
07957    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
07958    p->refer->status = REFER_SENT;   /* Set refer status */
07959 
07960    reqprep(&req, p, SIP_REFER, 0, 1);
07961 
07962    add_header(&req, "Refer-To", referto);
07963    add_header(&req, "Allow", ALLOWED_METHODS);
07964    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
07965    if (!ast_strlen_zero(p->our_contact))
07966       add_header(&req, "Referred-By", p->our_contact);
07967 
07968    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07969    /* We should propably wait for a NOTIFY here until we ack the transfer */
07970    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
07971 
07972    /*! \todo In theory, we should hang around and wait for a reply, before
07973    returning to the dial plan here. Don't know really how that would
07974    affect the transfer() app or the pbx, but, well, to make this
07975    useful we should have a STATUS code on transfer().
07976    */
07977 }

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

References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, 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, 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_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, username, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.

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

07688 {
07689    struct sip_request req;
07690    char from[256];
07691    char to[256];
07692    char tmp[80];
07693    char addr[80];
07694    struct sip_pvt *p;
07695    char *fromdomain;
07696 
07697    /* exit if we are already in process with this registrar ?*/
07698    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
07699       if (r) {
07700          ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
07701       }
07702       return 0;
07703    }
07704 
07705    if (r->call) { /* We have a registration */
07706       if (!auth) {
07707          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
07708          return 0;
07709       } else {
07710          p = r->call;
07711          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
07712          ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */
07713       }
07714    } else {
07715       /* Build callid for registration if we haven't registered before */
07716       if (!r->callid_valid) {
07717          build_callid_registry(r, __ourip, default_fromdomain);
07718          r->callid_valid = TRUE;
07719       }
07720       /* Allocate SIP packet for registration */
07721       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
07722          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
07723          return 0;
07724       }
07725       if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
07726          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
07727       /* Find address to hostname */
07728       if (create_addr(p, r->hostname)) {
07729          /* we have what we hope is a temporary network error,
07730           * probably DNS.  We need to reschedule a registration try */
07731          sip_destroy(p);
07732 
07733          if (r->timeout > -1)
07734             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
07735          else
07736             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);
07737 
07738          AST_SCHED_DEL(sched, r->timeout);
07739          r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07740          r->regattempts++;
07741          return 0;
07742       }
07743       /* Copy back Call-ID in case create_addr changed it */
07744       ast_string_field_set(r, callid, p->callid);
07745       if (r->portno) {
07746          p->sa.sin_port = htons(r->portno);
07747          p->recv.sin_port = htons(r->portno);
07748       } else   /* Set registry port to the port set from the peer definition/srv or default */
07749          r->portno = ntohs(p->sa.sin_port);
07750       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
07751       r->call=p;        /* Save pointer to SIP packet */
07752       p->registry = ASTOBJ_REF(r);  /* Add pointer to registry in packet */
07753       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
07754          ast_string_field_set(p, peersecret, r->secret);
07755       if (!ast_strlen_zero(r->md5secret))
07756          ast_string_field_set(p, peermd5secret, r->md5secret);
07757       /* User name in this realm  
07758       - if authuser is set, use that, otherwise use username */
07759       if (!ast_strlen_zero(r->authuser)) {   
07760          ast_string_field_set(p, peername, r->authuser);
07761          ast_string_field_set(p, authname, r->authuser);
07762       } else if (!ast_strlen_zero(r->username)) {
07763          ast_string_field_set(p, peername, r->username);
07764          ast_string_field_set(p, authname, r->username);
07765          ast_string_field_set(p, fromuser, r->username);
07766       }
07767       if (!ast_strlen_zero(r->username))
07768          ast_string_field_set(p, username, r->username);
07769       /* Save extension in packet */
07770       ast_string_field_set(p, exten, r->contact);
07771 
07772       /*
07773         check which address we should use in our contact header 
07774         based on whether the remote host is on the external or
07775         internal network so we can register through nat
07776        */
07777       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
07778          p->ourip = bindaddr.sin_addr;
07779       build_contact(p);
07780    }
07781 
07782    /* set up a timeout */
07783    if (auth == NULL)  {
07784       if (r->timeout > -1)
07785          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
07786       AST_SCHED_DEL(sched, r->timeout);
07787       r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
07788       if (option_debug)
07789          ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
07790    }
07791 
07792    if ((fromdomain = strchr(r->username, '@'))) {
07793       /* the domain name is just behind '@' */
07794       fromdomain++ ;
07795       /* We have a domain in the username for registration */
07796       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
07797       if (!ast_strlen_zero(p->theirtag))
07798          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
07799       else
07800          snprintf(to, sizeof(to), "<sip:%s>", r->username);
07801 
07802       /* If the registration username contains '@', then the domain should be used as
07803          the equivalent of "fromdomain" for the registration */
07804       if (ast_strlen_zero(p->fromdomain)) {
07805          ast_string_field_set(p, fromdomain, fromdomain);
07806       }
07807    } else {
07808       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
07809       if (!ast_strlen_zero(p->theirtag))
07810          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
07811       else
07812          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
07813    }
07814    
07815    /* Fromdomain is what we are registering to, regardless of actual
07816       host name from SRV */
07817    if (!ast_strlen_zero(p->fromdomain)) {
07818       if (r->portno && r->portno != STANDARD_SIP_PORT)
07819          snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
07820       else
07821          snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
07822    } else {
07823       if (r->portno && r->portno != STANDARD_SIP_PORT)
07824          snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
07825       else
07826          snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
07827    }
07828    ast_string_field_set(p, uri, addr);
07829 
07830    p->branch ^= ast_random();
07831 
07832    init_req(&req, sipmethod, addr);
07833 
07834    /* Add to CSEQ */
07835    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
07836    p->ocseq = r->ocseq;
07837 
07838    build_via(p);
07839    add_header(&req, "Via", p->via);
07840    add_header(&req, "From", from);
07841    add_header(&req, "To", to);
07842    add_header(&req, "Call-ID", p->callid);
07843    add_header(&req, "CSeq", tmp);
07844    if (!ast_strlen_zero(global_useragent))
07845       add_header(&req, "User-Agent", global_useragent);
07846    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
07847 
07848    
07849    if (auth)   /* Add auth header */
07850       add_header(&req, authheader, auth);
07851    else if (!ast_strlen_zero(r->nonce)) {
07852       char digest[1024];
07853 
07854       /* We have auth data to reuse, build a digest header! */
07855       if (sipdebug)
07856          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
07857       ast_string_field_set(p, realm, r->realm);
07858       ast_string_field_set(p, nonce, r->nonce);
07859       ast_string_field_set(p, domain, r->domain);
07860       ast_string_field_set(p, opaque, r->opaque);
07861       ast_string_field_set(p, qop, r->qop);
07862       r->noncecount++;
07863       p->noncecount = r->noncecount;
07864 
07865       memset(digest,0,sizeof(digest));
07866       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
07867          add_header(&req, "Authorization", digest);
07868       else
07869          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
07870    
07871    }
07872 
07873    snprintf(tmp, sizeof(tmp), "%d", default_expiry);
07874    add_header(&req, "Expires", tmp);
07875    add_header(&req, "Contact", p->our_contact);
07876    add_header(&req, "Event", "registration");
07877    add_header_contentLength(&req, 0);
07878 
07879    initialize_initreq(p, &req);
07880    if (sip_debug_test_pvt(p))
07881       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
07882    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
07883    r->regattempts++; /* Another attempt */
07884    if (option_debug > 3)
07885       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
07886    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
07887 }

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

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

Referenced by check_pendings(), and sip_set_rtp_peer().

06948 {
06949    struct sip_request req;
06950 
06951    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06952    
06953    add_header(&req, "Allow", ALLOWED_METHODS);
06954    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06955    if (sipdebug)
06956       add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
06957    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
06958       append_history(p, "ReInv", "Re-invite sent");
06959    add_sdp(&req, p);
06960    /* Use this as the basis */
06961    initialize_initreq(p, &req);
06962    p->lastinvite = p->ocseq;
06963    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06964    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06965 }

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

References add_header(), add_t38_sdp(), ALLOWED_METHODS, ast_set_flag, ast_test_flag, ast_udptl_offered_from_local(), sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, sip_pvt::udptl, and XMIT_CRITICAL.

Referenced by sip_handle_t38_reinvite(), sip_read(), and sip_set_udptl_peer().

06972 {
06973    struct sip_request req;
06974 
06975    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
06976    
06977    add_header(&req, "Allow", ALLOWED_METHODS);
06978    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
06979    if (sipdebug)
06980       add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)");
06981    ast_udptl_offered_from_local(p->udptl, 1);
06982    add_t38_sdp(&req, p);
06983    /* Use this as the basis */
06984    initialize_initreq(p, &req);
06985    ast_set_flag(&p->flags[0], SIP_OUTGOING);    /* Change direction of this dialog */
06986    p->lastinvite = p->ocseq;
06987    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
06988 }

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

References add_header_contentLength(), INV_CONFIRMED, sip_pvt::invitestate, sip_pvt::ocseq, reqprep(), send_request(), and SIP_ACK.

Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().

08004 {
08005    struct sip_request resp;
08006 
08007    if (sipmethod == SIP_ACK)
08008       p->invitestate = INV_CONFIRMED;
08009 
08010    reqprep(&resp, p, sipmethod, seqno, newbranch);
08011    add_header_contentLength(&resp, 0);
08012    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
08013 }

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

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

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

08017 {
08018    struct sip_request resp;
08019 
08020    reqprep(&resp, p, sipmethod, seqno, newbranch);
08021    if (!ast_strlen_zero(p->realm)) {
08022       char digest[1024];
08023 
08024       memset(digest, 0, sizeof(digest));
08025       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
08026          if (p->options && p->options->auth_type == PROXY_AUTH)
08027             add_header(&resp, "Proxy-Authorization", digest);
08028          else if (p->options && p->options->auth_type == WWW_AUTH)
08029             add_header(&resp, "Authorization", digest);
08030          else  /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */
08031             add_header(&resp, "Proxy-Authorization", digest);
08032       } else
08033          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
08034    }
08035    /* If we are hanging up and know a cause for that, send it in clear text to make
08036       debugging easier. */
08037    if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) {
08038       char buf[10];
08039 
08040       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
08041       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
08042       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
08043    }
08044 
08045    add_header_contentLength(&resp, 0);
08046    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
08047 }

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

Transmit response, no retransmits.

Definition at line 6253 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

06254 {
06255    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06256 }

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

References __transmit_response(), and XMIT_CRITICAL.

Referenced by handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), sip_indicate(), and sip_sipredirect().

06273 {
06274    return __transmit_response(p, msg, req, XMIT_CRITICAL);
06275 }

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

06203 {
06204    struct sip_pvt *p = NULL;
06205 
06206    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
06207       ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
06208       return -1;
06209    }
06210 
06211    /* if the structure was just allocated, initialize it */
06212    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
06213       ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
06214       if (ast_string_field_init(p, 512))
06215          return -1;
06216    }
06217 
06218    /* Initialize the bare minimum */
06219    p->method = intended_method;
06220 
06221    if (sin) {
06222       p->sa = *sin;
06223       if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
06224          p->ourip = __ourip;
06225    } else
06226       p->ourip = __ourip;
06227 
06228    p->branch = ast_random();
06229    make_our_tag(p->tag, sizeof(p->tag));
06230    p->ocseq = INITIAL_CSEQ;
06231 
06232    if (useglobal_nat && sin) {
06233       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
06234       p->recv = *sin;
06235       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
06236    }
06237    check_via(p, req);
06238 
06239    ast_string_field_set(p, fromdomain, default_fromdomain);
06240    build_via(p);
06241    ast_string_field_set(p, callid, callid);
06242 
06243    /* Use this temporary pvt structure to send the message */
06244    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
06245 
06246    /* Free the string fields, but not the pool space */
06247    ast_string_field_reset_all(p);
06248 
06249    return 0;
06250 }

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

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

Referenced by handle_request(), and handle_request_options().

06301 {
06302    struct sip_request resp;
06303    respprep(&resp, p, msg, req);
06304    add_header(&resp, "Accept", "application/sdp");
06305    add_header_contentLength(&resp, 0);
06306    return send_response(p, &resp, reliable, 0);
06307 }

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

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

06311 {
06312    struct sip_request resp;
06313    char tmp[512];
06314    int seqno = 0;
06315 
06316    if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) {
06317       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
06318       return -1;
06319    }
06320    /* Stale means that they sent us correct authentication, but 
06321       based it on an old challenge (nonce) */
06322    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
06323    respprep(&resp, p, msg, req);
06324    add_header(&resp, header, tmp);
06325    add_header_contentLength(&resp, 0);
06326    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
06327    return send_response(p, &resp, reliable, seqno);
06328 }

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

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

Referenced by register_verify().

06291 {
06292    struct sip_request resp;
06293    respprep(&resp, p, msg, req);
06294    append_date(&resp);
06295    add_header_contentLength(&resp, 0);
06296    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
06297 }

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 6876 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, and try_suggested_sip_codec().

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

06877 {
06878    struct sip_request resp;
06879    int seqno;
06880    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06881       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06882       return -1;
06883    }
06884    respprep(&resp, p, msg, req);
06885    if (p->rtp) {
06886       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06887          if (option_debug)
06888             ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n");
06889          ast_rtp_codec_setpref(p->rtp, &p->prefs);
06890       }
06891       try_suggested_sip_codec(p);   
06892       add_sdp(&resp, p);
06893    } else 
06894       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
06895    if (reliable && !p->pendinginvite)
06896       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06897    return send_response(p, &resp, reliable, seqno);
06898 }

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

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

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

06837 {
06838    struct sip_request resp;
06839    int seqno;
06840    
06841    if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
06842       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
06843       return -1;
06844    }
06845    respprep(&resp, p, msg, req);
06846    if (p->udptl) {
06847       ast_udptl_offered_from_local(p->udptl, 0);
06848       add_t38_sdp(&resp, p);
06849    } else 
06850       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
06851    if (retrans && !p->pendinginvite)
06852       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
06853    return send_response(p, &resp, retrans, seqno);
06854 }

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

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

Referenced by handle_request_invite().

06260 {
06261    struct sip_request resp;
06262    respprep(&resp, p, msg, req);
06263    append_date(&resp);
06264    add_header(&resp, "Unsupported", unsupported);
06265    add_header_contentLength(&resp, 0);
06266    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
06267 }

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

07553 {
07554    if (!p->initreq.headers)   /* Initialize first request before sending */
07555       initialize_initreq(p, req);
07556    return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
07557 }

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

References add_header(), add_header_contentLength(), add_line(), 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(), cb_extensionstate(), and handle_request_subscribe().

07327 {
07328    char tmp[4000], from[256], to[256];
07329    char *t = tmp, *c, *mfrom, *mto;
07330    size_t maxbytes = sizeof(tmp);
07331    struct sip_request req;
07332    char hint[AST_MAX_EXTENSION];
07333    char *statestring = "terminated";
07334    const struct cfsubscription_types *subscriptiontype;
07335    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
07336    char *pidfstate = "--";
07337    char *pidfnote= "Ready";
07338 
07339    memset(from, 0, sizeof(from));
07340    memset(to, 0, sizeof(to));
07341    memset(tmp, 0, sizeof(tmp));
07342 
07343    switch (state) {
07344    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
07345       statestring = (global_notifyringing) ? "early" : "confirmed";
07346       local_state = NOTIFY_INUSE;
07347       pidfstate = "busy";
07348       pidfnote = "Ringing";
07349       break;
07350    case AST_EXTENSION_RINGING:
07351       statestring = "early";
07352       local_state = NOTIFY_INUSE;
07353       pidfstate = "busy";
07354       pidfnote = "Ringing";
07355       break;
07356    case AST_EXTENSION_INUSE:
07357       statestring = "confirmed";
07358       local_state = NOTIFY_INUSE;
07359       pidfstate = "busy";
07360       pidfnote = "On the phone";
07361       break;
07362    case AST_EXTENSION_BUSY:
07363       statestring = "confirmed";
07364       local_state = NOTIFY_CLOSED;
07365       pidfstate = "busy";
07366       pidfnote = "On the phone";
07367       break;
07368    case AST_EXTENSION_UNAVAILABLE:
07369       statestring = "terminated";
07370       local_state = NOTIFY_CLOSED;
07371       pidfstate = "away";
07372       pidfnote = "Unavailable";
07373       break;
07374    case AST_EXTENSION_ONHOLD:
07375       statestring = "confirmed";
07376       local_state = NOTIFY_CLOSED;
07377       pidfstate = "busy";
07378       pidfnote = "On Hold";
07379       break;
07380    case AST_EXTENSION_NOT_INUSE:
07381    default:
07382       /* Default setting */
07383       break;
07384    }
07385 
07386    subscriptiontype = find_subscription_type(p->subscribed);
07387    
07388    /* Check which device/devices we are watching  and if they are registered */
07389    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
07390       char *hint2 = hint, *individual_hint = NULL;
07391       int hint_count = 0, unavailable_count = 0;
07392 
07393       while ((individual_hint = strsep(&hint2, "&"))) {
07394          hint_count++;
07395 
07396          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
07397             unavailable_count++;
07398       }
07399 
07400       /* If none of the hinted devices are registered, we will
07401        * override notification and show no availability.
07402        */
07403       if (hint_count > 0 && hint_count == unavailable_count) {
07404          local_state = NOTIFY_CLOSED;
07405          pidfstate = "away";
07406          pidfnote = "Not online";
07407       }
07408    }
07409 
07410    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
07411    c = get_in_brackets(from);
07412    if (strncasecmp(c, "sip:", 4)) {
07413       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07414       return -1;
07415    }
07416    mfrom = strsep(&c, ";");   /* trim ; and beyond */
07417 
07418    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
07419    c = get_in_brackets(to);
07420    if (strncasecmp(c, "sip:", 4)) {
07421       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
07422       return -1;
07423    }
07424    mto = strsep(&c, ";");  /* trim ; and beyond */
07425 
07426    reqprep(&req, p, SIP_NOTIFY, 0, 1);
07427 
07428    
07429    add_header(&req, "Event", subscriptiontype->event);
07430    add_header(&req, "Content-Type", subscriptiontype->mediatype);
07431    switch(state) {
07432    case AST_EXTENSION_DEACTIVATED:
07433       if (timeout)
07434          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07435       else {
07436          add_header(&req, "Subscription-State", "terminated;reason=probation");
07437          add_header(&req, "Retry-After", "60");
07438       }
07439       break;
07440    case AST_EXTENSION_REMOVED:
07441       add_header(&req, "Subscription-State", "terminated;reason=noresource");
07442       break;
07443    default:
07444       if (p->expiry)
07445          add_header(&req, "Subscription-State", "active");
07446       else  /* Expired */
07447          add_header(&req, "Subscription-State", "terminated;reason=timeout");
07448    }
07449    switch (p->subscribed) {
07450    case XPIDF_XML:
07451    case CPIM_PIDF_XML:
07452       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07453       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
07454       ast_build_string(&t, &maxbytes, "<presence>\n");
07455       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
07456       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
07457       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
07458       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
07459       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
07460       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
07461       break;
07462    case PIDF_XML: /* Eyebeam supports this format */
07463       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
07464       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);
07465       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
07466       if (pidfstate[0] != '-')
07467          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
07468       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
07469       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
07470       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
07471       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
07472       if (pidfstate[0] == 'b') /* Busy? Still open ... */
07473          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
07474       else
07475          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
07476       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
07477       break;
07478    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
07479       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
07480       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);
07481       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
07482          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
07483       else
07484          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
07485       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
07486       if (state == AST_EXTENSION_ONHOLD) {
07487          ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
07488                                          "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n"
07489                                          "</target>\n</local>\n", mto);
07490       }
07491       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
07492       break;
07493    case NONE:
07494    default:
07495       break;
07496    }
07497 
07498    if (t > tmp + sizeof(tmp))
07499       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
07500 
07501    add_header_contentLength(&req, strlen(tmp));
07502    add_line(&req, tmp);
07503    p->pendinginvite = p->ocseq;  /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
07504 
07505    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
07506 }

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

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

03692 {
03693    int fmt;
03694    const char *codec;
03695 
03696    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
03697    if (!codec) 
03698       return;
03699 
03700    fmt = ast_getformatbyname(codec);
03701    if (fmt) {
03702       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
03703       if (p->jointcapability & fmt) {
03704          p->jointcapability &= fmt;
03705          p->capability &= fmt;
03706       } else
03707          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
03708    } else
03709       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
03710    return;  
03711 }

static int unload_module ( void   )  [static]

PBX unload module API.

Definition at line 18852 of file chan_sip.c.

References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, iflock, 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, and userl.

18853 {
18854    struct sip_pvt *p, *pl;
18855    
18856    /* First, take us out of the channel type list */
18857    ast_channel_unregister(&sip_tech);
18858 
18859    /* Unregister dial plan functions */
18860    ast_custom_function_unregister(&sipchaninfo_function);
18861    ast_custom_function_unregister(&sippeer_function);
18862    ast_custom_function_unregister(&sip_header_function);
18863    ast_custom_function_unregister(&checksipdomain_function);
18864 
18865    /* Unregister dial plan applications */
18866    ast_unregister_application(app_dtmfmode);
18867    ast_unregister_application(app_sipaddheader);
18868 
18869    /* Unregister CLI commands */
18870    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
18871 
18872    /* Disconnect from the RTP subsystem */
18873    ast_rtp_proto_unregister(&sip_rtp);
18874 
18875    /* Disconnect from UDPTL */
18876    ast_udptl_proto_unregister(&sip_udptl);
18877 
18878    /* Unregister AMI actions */
18879    ast_manager_unregister("SIPpeers");
18880    ast_manager_unregister("SIPshowpeer");
18881 
18882    ast_mutex_lock(&iflock);
18883    /* Hangup all interfaces if they have an owner */
18884    for (p = iflist; p ; p = p->next) {
18885       if (p->owner)
18886          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
18887    }
18888    ast_mutex_unlock(&iflock);
18889 
18890    ast_mutex_lock(&monlock);
18891    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
18892       pthread_cancel(monitor_thread);
18893       pthread_kill(monitor_thread, SIGURG);
18894       pthread_join(monitor_thread, NULL);
18895    }
18896    monitor_thread = AST_PTHREADT_STOP;
18897    ast_mutex_unlock(&monlock);
18898 
18899 restartdestroy:
18900    ast_mutex_lock(&iflock);
18901    /* Destroy all the interfaces and free their memory */
18902    p = iflist;
18903    while (p) {
18904       pl = p;
18905       p = p->next;
18906       if (__sip_destroy(pl, TRUE) < 0) {
18907          /* Something is still bridged, let it react to getting a hangup */
18908          iflist = p;
18909          ast_mutex_unlock(&iflock);
18910          usleep(1);
18911          goto restartdestroy;
18912       }
18913    }
18914    iflist = NULL;
18915    ast_mutex_unlock(&iflock);
18916 
18917    /* Free memory for local network address mask */
18918    ast_free_ha(localaddr);
18919 
18920    ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
18921    ASTOBJ_CONTAINER_DESTROY(&userl);
18922    ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);
18923    ASTOBJ_CONTAINER_DESTROY(&peerl);
18924    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
18925    ASTOBJ_CONTAINER_DESTROY(&regl);
18926 
18927    clear_realm_authentication(authl);
18928    clear_sip_domains();
18929    close(sipsock);
18930    sched_context_destroy(sched);
18931       
18932    return 0;
18933 }

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

03243 {
03244    char name[256];
03245    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
03246    int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL);
03247    struct sip_user *u = NULL;
03248    struct sip_peer *p = NULL;
03249 
03250    if (option_debug > 2)
03251       ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
03252 
03253    /* Test if we need to check call limits, in order to avoid 
03254       realtime lookups if we do not need it */
03255    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
03256       return 0;
03257 
03258    ast_copy_string(name, fup->username, sizeof(name));
03259 
03260    /* Check the list of users only for incoming calls */
03261    if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1)))  {
03262       inuse = &u->inUse;
03263       call_limit = &u->call_limit;
03264       inringing = NULL;
03265    } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */
03266       inuse = &p->inUse;
03267       call_limit = &p->call_limit;
03268       inringing = &p->inRinging;
03269       ast_copy_string(name, fup->peername, sizeof(name));
03270    } 
03271    if (!p && !u) {
03272       if (option_debug > 1)
03273          ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
03274       return 0;
03275    }
03276 
03277    switch(event) {
03278    /* incoming and outgoing affects the inUse counter */
03279    case DEC_CALL_LIMIT:
03280       if ( *inuse > 0 ) {
03281          if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
03282             (*inuse)--;
03283             ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
03284          }
03285       } else {
03286          *inuse = 0;
03287       }
03288       if (inringing) {
03289          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03290             if (*inringing > 0)
03291                (*inringing)--;
03292             else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03293                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername);
03294             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03295          }
03296       }
03297       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) {
03298          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
03299          sip_peer_hold(fup, 0);
03300       }
03301       if (option_debug > 1 || sipdebug) {
03302          ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
03303       }
03304       break;
03305 
03306    case INC_CALL_RINGING:
03307    case INC_CALL_LIMIT:
03308       if (*call_limit > 0 ) {
03309          /* Let call limit affect only outgoing calls */
03310          if (outgoing && (*inuse >= *call_limit)) {
03311             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);
03312             if (u)
03313                ASTOBJ_UNREF(u, sip_destroy_user);
03314             else
03315                ASTOBJ_UNREF(p, sip_destroy_peer);
03316             return -1; 
03317          }
03318       }
03319       if (inringing && (event == INC_CALL_RINGING)) {
03320          if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03321             (*inringing)++;
03322             ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03323          }
03324       }
03325       /* Continue */
03326       (*inuse)++;
03327       ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
03328       if (option_debug > 1 || sipdebug) {
03329          ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
03330       }
03331       break;
03332 
03333    case DEC_CALL_RINGING:
03334       if (inringing) {
03335          if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) {
03336             if (*inringing > 0)
03337                (*inringing)--;
03338             else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS))
03339                ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name);
03340             ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING);
03341          }
03342       }
03343       break;
03344 
03345    default:
03346       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
03347    }
03348    if (p) {
03349       ast_device_state_changed("SIP/%s", p->name);
03350       ASTOBJ_UNREF(p, sip_destroy_peer);
03351    } else /* u must be set */
03352       ASTOBJ_UNREF(u, sip_destroy_user);
03353    return 0;
03354 }

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

Update peer data in database (if used).

Definition at line 2517 of file chan_sip.c.

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

Referenced by register_verify().

02518 {
02519    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
02520    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) &&
02521        (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
02522       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
02523    }
02524 }


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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 18939 of file chan_sip.c.

struct in_addr __ourip [static]

Definition at line 1226 of file chan_sip.c.

int allow_external_domains [static]

Accept calls to external SIP domains?

Definition at line 566 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 586 of file chan_sip.c.

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 18416 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 18418 of file chan_sip.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 18939 of file chan_sip.c.

struct sip_auth* authl = NULL [static]

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

struct sockaddr_in bindaddr = { 0, } [static]

The address we bind to

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

Referenced by check_auth().

struct ast_custom_function checksipdomain_function [static]

Definition at line 12043 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip[] [static]

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

int compactheaders [static]

send compact sip headers

Definition at line 560 of file chan_sip.c.

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

Definition at line 232 of file chan_sip.c.

char debug_usage[] [static]

Definition at line 11927 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

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

char default_context[AST_MAX_CONTEXT] [static]

Definition at line 523 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 193 of file chan_sip.c.

char default_fromdomain[AST_MAX_EXTENSION] [static]

Definition at line 527 of file chan_sip.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 223 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Definition at line 525 of file chan_sip.c.

int default_maxcallbitrate [static]

Maximum bitrate for call

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

char default_notifymime[AST_MAX_EXTENSION] [static]

Definition at line 528 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

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

char default_subscribecontext[AST_MAX_CONTEXT] [static]

Definition at line 524 of file chan_sip.c.

char default_vmexten[AST_MAX_EXTENSION] [static]

Definition at line 530 of file chan_sip.c.

char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static]

Definition at line 18415 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 18421 of file chan_sip.c.

int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 562 of file chan_sip.c.

int expiry = DEFAULT_EXPIRY [static]

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

int externrefresh = 10 [static]

Definition at line 1224 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

int global_allowguest [static]

allow unauthenticated users/peers to connect?

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

enum transfermodes global_allowtransfer [static]

SIP Refer restriction scheme

Definition at line 570 of file chan_sip.c.

int global_alwaysauthreject [static]

Send 401 Unauthorized for all failing requests

Definition at line 543 of file chan_sip.c.

int global_autoframing [static]

Turn autoframing on or off.

Definition at line 569 of file chan_sip.c.

int global_callevents [static]

Whether we send manager events or not

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

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

int global_directrtpsetup [static]

Enable support for Direct RTP setup (no re-invites)

Definition at line 538 of file chan_sip.c.

int global_dynamic_exclude_static = 0 [static]

Definition at line 579 of file chan_sip.c.

struct ast_flags global_flags[2] = {{0}} [static]

global SIP_ flags

Definition at line 589 of file chan_sip.c.

Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().

struct ast_jb_conf global_jbconf [static]

Definition at line 230 of file chan_sip.c.

int global_limitonpeers [static]

Match call limit on peers only

Definition at line 539 of file chan_sip.c.

int global_matchexterniplocally [static]

Match externip/externhost setting against localnet setting

Definition at line 572 of file chan_sip.c.

int global_mwitime [static]

Time between MWI checks for peers

Definition at line 556 of file chan_sip.c.

int global_notifyhold [static]

Send notifications on hold

Definition at line 542 of file chan_sip.c.

int global_notifyringing [static]

Send notifications on ringing

Definition at line 541 of file chan_sip.c.

char global_realm[MAXHOSTNAMELEN] [static]

Default realm

Definition at line 563 of file chan_sip.c.

int global_reg_timeout [static]

Definition at line 551 of file chan_sip.c.

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 552 of file chan_sip.c.

char global_regcontext[AST_MAX_CONTEXT] [static]

Context for auto-extensions

Definition at line 564 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 547 of file chan_sip.c.

int global_rtautoclear [static]

Definition at line 540 of file chan_sip.c.

int global_rtpholdtimeout [static]

Definition at line 549 of file chan_sip.c.

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 550 of file chan_sip.c.

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 548 of file chan_sip.c.

int global_t1min [static]

T1 roundtrip time minimum

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

unsigned int global_tos_audio [static]

IP type of service for audio RTP packets

Definition at line 558 of file chan_sip.c.

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 557 of file chan_sip.c.

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 559 of file chan_sip.c.

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

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

struct io_context* io [static]

The IO context

Definition at line 610 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 1225 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 10556 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 10107 of file chan_sip.c.

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 192 of file chan_sip.c.

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

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

ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

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

const char notify_config[] = "sip_notify.conf" [static]

Definition at line 233 of file chan_sip.c.

struct ast_config* notify_types [static]

The list of manual NOTIFY types we know how to send

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

int ourport [static]

Definition at line 1228 of file chan_sip.c.

struct sockaddr_in outboundproxyip [static]

Definition at line 1227 of file chan_sip.c.

int pedanticsipchecking [static]

Extra checking ? Default off

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

int recordhistory [static]

Record SIP history. Off by default

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

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 585 of file chan_sip.c.

int ruserobjs = 0 [static]

Realtime users

Definition at line 583 of file chan_sip.c.

struct sched_context* sched [static]

The scheduling context

Definition at line 609 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 11900 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 11896 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 11871 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 11904 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 11891 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 11957 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 11913 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 11908 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 11923 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 11961 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 11953 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 11886 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 11881 of file chan_sip.c.

struct ast_custom_function sip_header_function [static]

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

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 606 of file chan_sip.c.

enum channelreloadreason sip_reloadreason [static]

Reason for last reload/load of configuration

Definition at line 607 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 1628 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 1570 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 1596 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 1637 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 12202 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 12122 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 1219 of file chan_sip.c.

Referenced by __sip_xmit(), do_monitor(), reg_source_db(), sipsock_read(), and unload_module().

int* sipsock_read_id [static]

ID of IO entry for sipsock FD

Definition at line 611 of file chan_sip.c.

int speerobjs = 0 [static]

Statis peers

Definition at line 584 of file chan_sip.c.

int srvlookup [static]

SRV Lookup on or off. Default is on

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

char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static]

Definition at line 18414 of file chan_sip.c.

char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static]

Definition at line 18419 of file chan_sip.c.

struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = temp_pvt_init , } [static]

Definition at line 1205 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 Wed Mar 4 19:58:36 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7