freeswitch/src/mod/endpoints/mod_sofia/mod_sofia.h

1256 lines
43 KiB
C
Raw Normal View History

/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
2014-02-05 21:02:28 +00:00
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Ken Rice <krice@freeswitch.org>
* Paul D. Tinsley <pdt at jackhammer.org>
* Bret McDanel <trixter AT 0xdecafbad.com>
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
2012-06-04 19:16:30 +00:00
* Raymond Chandler <intralanman@gmail.com>
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
*
*
* mod_sofia.h -- SOFIA SIP Endpoint
*
*/
2011-08-16 16:52:34 +00:00
/*Defines etc..*/
/*************************************************************************************************************************************************************/
#define SOFIA_RECOVER "sofia"
#define MANUAL_BYE 1
#define SQL_CACHE_TIMEOUT 300
#define DEFAULT_NONCE_TTL 60
#define IREG_SECONDS 30
#define IPING_SECONDS 30
#define IPING_FREQUENCY 1
#define GATEWAY_SECONDS 1
#define SOFIA_QUEUE_SIZE 50000
#define HAVE_APR
#include <switch.h>
#define SOFIA_NAT_SESSION_TIMEOUT 90
#define SOFIA_MAX_ACL 100
#ifdef _MSC_VER
#define HAVE_FUNCTION 1
#else
#define HAVE_FUNC 1
#endif
#define MAX_CODEC_CHECK_FRAMES 50
#define MAX_MISMATCH_FRAMES 5
#define MODNAME "mod_sofia"
#define SOFIA_DEFAULT_CONTACT_USER MODNAME
static const switch_state_handler_table_t noop_state_handler = { 0 };
struct sofia_gateway;
typedef struct sofia_gateway sofia_gateway_t;
struct sofia_gateway_subscription;
typedef struct sofia_gateway_subscription sofia_gateway_subscription_t;
struct sofia_profile;
typedef struct sofia_profile sofia_profile_t;
#define NUA_MAGIC_T sofia_profile_t
typedef struct sofia_private sofia_private_t;
struct private_object;
typedef struct private_object private_object_t;
#define NUA_HMAGIC_T sofia_private_t
#define SOFIA_SESSION_TIMEOUT "sofia_session_timeout"
#define MY_EVENT_REGISTER "sofia::register"
2010-10-27 17:00:30 +00:00
#define MY_EVENT_PRE_REGISTER "sofia::pre_register"
#define MY_EVENT_REGISTER_ATTEMPT "sofia::register_attempt"
#define MY_EVENT_REGISTER_FAILURE "sofia::register_failure"
#define MY_EVENT_UNREGISTER "sofia::unregister"
#define MY_EVENT_EXPIRE "sofia::expire"
#define MY_EVENT_GATEWAY_STATE "sofia::gateway_state"
#define MY_EVENT_SIP_USER_STATE "sofia::sip_user_state"
#define MY_EVENT_NOTIFY_REFER "sofia::notify_refer"
#define MY_EVENT_REINVITE "sofia::reinvite"
#define MY_EVENT_GATEWAY_ADD "sofia::gateway_add"
#define MY_EVENT_GATEWAY_DEL "sofia::gateway_delete"
2010-07-01 14:37:49 +00:00
#define MY_EVENT_RECOVERY "sofia::recovery_recv"
2010-06-30 15:35:03 +00:00
#define MY_EVENT_RECOVERY_SEND "sofia::recovery_send"
2011-12-15 02:56:00 +00:00
#define MY_EVENT_RECOVERY_RECOVERED "sofia::recovery_recovered"
2012-07-09 15:56:04 +00:00
#define MY_EVENT_ERROR "sofia::error"
2014-07-09 13:53:14 +00:00
#define MY_EVENT_PROFILE_START "sofia::profile_start"
#define MY_EVENT_NOTIFY_WATCHED_HEADER "sofia::notify_watched_header"
#define MY_EVENT_WRONG_CALL_STATE "sofia::wrong_call_state"
#define MY_EVENT_TRANSFEROR "sofia::transferor"
#define MY_EVENT_TRANSFEREE "sofia::transferee"
#define MY_EVENT_REPLACED "sofia::replaced"
#define MY_EVENT_INTERCEPTED "sofia::intercepted"
#define MY_EVENT_BYE_RESPONSE "sofia::bye_response"
#define MULTICAST_EVENT "multicast::event"
#define SOFIA_REPLACES_HEADER "_sofia_replaces_"
#define SOFIA_CHAT_PROTO "sip"
#define SOFIA_MULTIPART_PREFIX "sip_mp_"
#define SOFIA_MULTIPART_PREFIX_T "~sip_mp_"
#define SOFIA_SIP_HEADER_PREFIX "sip_h_"
#define SOFIA_SIP_INFO_HEADER_PREFIX "sip_info_h_"
#define SOFIA_SIP_INFO_HEADER_PREFIX_T "~sip_info_h_"
#define SOFIA_SIP_RESPONSE_HEADER_PREFIX "sip_rh_"
#define SOFIA_SIP_RESPONSE_HEADER_PREFIX_T "~sip_rh_"
#define SOFIA_SIP_BYE_HEADER_PREFIX "sip_bye_h_"
2011-09-26 14:03:10 +00:00
#define SOFIA_SIP_BYE_HEADER_PREFIX_T "~sip_bye_h_"
#define SOFIA_SIP_PROGRESS_HEADER_PREFIX "sip_ph_"
#define SOFIA_SIP_PROGRESS_HEADER_PREFIX_T "~sip_ph_"
#define SOFIA_SIP_HEADER_PREFIX_T "~sip_h_"
#define SOFIA_DEFAULT_PORT "5060"
#define SOFIA_DEFAULT_TLS_PORT "5061"
#define SOFIA_REFER_TO_VARIABLE "sip_refer_to"
2013-04-02 18:10:00 +00:00
//#define SOFIA_HAS_CRYPTO_VARIABLE "rtp_has_crypto"
2012-12-21 04:57:47 +00:00
//#define SOFIA_HAS_VIDEO_CRYPTO_VARIABLE "sip_has_video_crypto"
//#define SOFIA_CRYPTO_MANDATORY_VARIABLE "sip_crypto_mandatory"
#define FREESWITCH_SUPPORT "update_display,send_info"
2010-09-09 03:53:57 +00:00
#include <switch_stun.h>
#include <sofia-sip/nua.h>
#include <sofia-sip/sip_status.h>
#include <sofia-sip/sdp.h>
#include <sofia-sip/sip_protos.h>
#include <sofia-sip/auth_module.h>
#include <sofia-sip/su_md5.h>
#include <sofia-sip/su_log.h>
#include <sofia-sip/su_strlst.h>
#include <sofia-sip/nea.h>
#include <sofia-sip/msg_addr.h>
#include <sofia-sip/tport_tag.h>
#include <sofia-sip/sip_extra.h>
#include "nua_stack.h"
#include "sofia-sip/msg_parser.h"
#include "sofia-sip/sip_parser.h"
#include "sofia-sip/tport_tag.h"
#include <sofia-sip/msg.h>
#include <sofia-sip/uniqueid.h>
typedef enum {
SOFIA_CONFIG_LOAD = 0,
SOFIA_CONFIG_RESCAN,
SOFIA_CONFIG_RESPAWN
} sofia_config_t;
typedef enum {
FILTER_UNKOWN = 0,
FILTER_BEGIN = 1,
FILTER_END = 2
} filter_packet_state_t;
typedef struct sofia_dispatch_event_s {
nua_saved_event_t event[1];
nua_handle_t *nh;
nua_event_data_t const *data;
su_time_t when;
sip_t *sip;
nua_t *nua;
sofia_profile_t *profile;
2011-07-12 02:27:28 +00:00
int save;
switch_core_session_t *session;
2012-08-21 05:04:58 +00:00
switch_core_session_t *init_session;
switch_memory_pool_t *pool;
2012-08-16 17:09:19 +00:00
struct sofia_dispatch_event_s *next;
} sofia_dispatch_event_t;
struct sofia_private {
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
char *uuid;
char gateway_name[256];
char auth_gateway_name[256];
2013-01-27 05:16:26 +00:00
char *call_id;
char *network_ip;
char *network_port;
char *key;
2013-10-17 17:39:55 +00:00
char *user;
char *realm;
int destroy_nh;
int destroy_me;
int is_call;
int is_static;
switch_time_t ping_sent;
};
#define set_param(ptr,val) if (ptr) {free(ptr) ; ptr = NULL;} if (val) {ptr = strdup(val);}
#define set_anchor(t,m) if (t->Anchor) {delete t->Anchor;} t->Anchor = new SipMessage(m);
2011-07-16 16:30:36 +00:00
#define sofia_private_free(_pvt) if (_pvt && ! _pvt->is_static) {free(_pvt);} _pvt = NULL;
/* Local Structures */
/*************************************************************************************************************************************************************/
struct sip_alias_node {
char *url;
nua_t *nua;
struct sip_alias_node *next;
};
typedef struct sip_alias_node sip_alias_node_t;
typedef enum {
MFLAG_REFER = (1 << 0),
MFLAG_REGISTER = (1 << 1)
} MFLAGS;
typedef enum {
PFLAG_AUTH_CALLS,
PFLAG_AUTH_MESSAGES,
2012-12-22 03:30:14 +00:00
PFLAG_PASS_RFC2833,
PFLAG_BLIND_REG,
PFLAG_AUTH_ALL,
PFLAG_FULL_ID,
PFLAG_MULTIREG_CONTACT,
PFLAG_DISABLE_TRANSCODING,
PFLAG_RUNNING,
PFLAG_RESPAWN,
PFLAG_MULTIREG,
PFLAG_TLS,
PFLAG_CHECKUSER,
PFLAG_SECURE,
PFLAG_BLIND_AUTH,
PFLAG_WORKER_RUNNING,
PFLAG_UNREG_OPTIONS_FAIL,
PFLAG_DISABLE_TIMER,
PFLAG_ENABLE_RFC5626,
PFLAG_DISABLE_100REL,
PFLAG_AGGRESSIVE_NAT_DETECTION,
PFLAG_RECIEVED_IN_NAT_REG_CONTACT,
PFLAG_3PCC,
PFLAG_3PCC_PROXY,
PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK,
PFLAG_CALLID_AS_UUID,
PFLAG_UUID_AS_CALLID,
PFLAG_MANAGE_SHARED_APPEARANCE,
PFLAG_STANDBY,
PFLAG_DISABLE_SRV,
2011-08-19 21:34:39 +00:00
PFLAG_DISABLE_SRV503,
PFLAG_DISABLE_NAPTR,
PFLAG_NAT_OPTIONS_PING,
2013-07-03 16:21:47 +00:00
PFLAG_UDP_NAT_OPTIONS_PING,
PFLAG_ALL_REG_OPTIONS_PING,
PFLAG_MESSAGE_QUERY_ON_REGISTER,
PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER,
PFLAG_MANUAL_REDIRECT,
2013-06-26 15:47:40 +00:00
PFLAG_T38_PASSTHRU,
PFLAG_AUTO_NAT,
PFLAG_SIPCOMPACT,
2011-12-15 18:20:27 +00:00
PFLAG_PRESENCE_PRIVACY,
PFLAG_PASS_CALLEE_ID,
PFLAG_LOG_AUTH_FAIL,
2010-08-19 23:22:06 +00:00
PFLAG_FORWARD_MWI_NOTIFY,
PFLAG_TRACK_CALLS,
PFLAG_DESTROY,
PFLAG_EXTENDED_INFO_PARSING,
PFLAG_CID_IN_1XX,
2010-08-18 19:58:14 +00:00
PFLAG_IN_DIALOG_CHAT,
PFLAG_DEL_SUBS_ON_REG_REUSE,
PFLAG_IGNORE_183NOSDP,
PFLAG_PRESENCE_PROBE_ON_REGISTER,
PFLAG_PRESENCE_ON_REGISTER,
PFLAG_PRESENCE_ON_FIRST_REGISTER,
PFLAG_NO_CONNECTION_REUSE,
PFLAG_RTP_NOTIMER_DURING_BRIDGE,
PFLAG_LIBERAL_DTMF,
2011-06-27 15:15:03 +00:00
PFLAG_AUTO_ASSIGN_PORT,
PFLAG_AUTO_ASSIGN_TLS_PORT,
2011-09-06 17:53:29 +00:00
PFLAG_SHUTDOWN,
2011-10-22 14:40:59 +00:00
PFLAG_PRESENCE_MAP,
2011-11-15 20:26:42 +00:00
PFLAG_OPTIONS_RESPOND_503_ON_BUSY,
PFLAG_PRESENCE_DISABLE_EARLY,
PFLAG_CONFIRM_BLIND_TRANSFER,
PFLAG_THREAD_PER_REG,
2012-05-21 18:55:50 +00:00
PFLAG_MWI_USE_REG_CALLID,
2012-08-29 20:34:17 +00:00
PFLAG_FIRE_MESSAGE_EVENTS,
PFLAG_ALLOW_UPDATE,
PFLAG_SEND_DISPLAY_UPDATE,
PFLAG_RUNNING_TRANS,
PFLAG_SOCKET_TCP_KEEPALIVE,
PFLAG_TCP_KEEPALIVE,
PFLAG_TCP_PINGPONG,
PFLAG_TCP_PING2PONG,
2014-01-22 21:13:10 +00:00
PFLAG_MESSAGES_RESPOND_200_OK,
2014-03-04 21:41:34 +00:00
PFLAG_SUBSCRIBE_RESPOND_200_OK,
PFLAG_PARSE_ALL_INVITE_HEADERS,
PFLAG_TCP_UNREG_ON_SOCKET_CLOSE,
PFLAG_TLS_ALWAYS_NAT,
PFLAG_TCP_ALWAYS_NAT,
PFLAG_ENABLE_CHAT,
PFLAG_AUTH_SUBSCRIPTIONS,
PFLAG_PROXY_REFER,
PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER,
PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE,
PFLAG_FIRE_TRANFER_EVENTS,
PFLAG_BLIND_AUTH_ENFORCE_RESULT,
PFLAG_PROXY_HOLD,
PFLAG_PROXY_INFO,
PFLAG_PROXY_MESSAGE,
PFLAG_FIRE_BYE_RESPONSE_EVENTS,
PFLAG_AUTO_INVITE_100,
PFLAG_UPDATE_REFRESHER,
/* No new flags below this line */
PFLAG_MAX
} PFLAGS;
typedef enum {
PFLAG_NDLB_TO_IN_200_CONTACT = (1 << 0),
PFLAG_NDLB_BROKEN_AUTH_HASH = (1 << 1),
2012-12-21 22:57:59 +00:00
PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE = (1 << 2)
} sofia_NDLB_t;
typedef enum {
TFLAG_IO,
TFLAG_CHANGE_MEDIA,
TFLAG_OUTBOUND,
TFLAG_READING,
TFLAG_WRITING,
TFLAG_HUP,
TFLAG_RTP,
TFLAG_BYE,
TFLAG_ANS,
TFLAG_EARLY_MEDIA,
TFLAG_3PCC,
TFLAG_READY,
TFLAG_REFER,
TFLAG_NOHUP,
TFLAG_NOSDP_REINVITE,
TFLAG_NAT,
2011-07-16 07:33:39 +00:00
TFLAG_SIMPLIFY,
TFLAG_SIP_HOLD,
TFLAG_SIP_HOLD_INACTIVE,
TFLAG_INB_NOMEDIA,
TFLAG_LATE_NEGOTIATION,
TFLAG_SDP,
2013-05-09 19:05:09 +00:00
TFLAG_NEW_SDP,
TFLAG_TPORT_LOG,
TFLAG_SENT_UPDATE,
TFLAG_PROXY_MEDIA,
add enhanced zrtp passthrough (zrtp passthru) mode ZRTP passthrough mode allows two ZRTP-capable clients to negotiate an end-to-end security association through FreeSWITCH. The clients are therefore able to be certain that the FreeSWITCH instance mediating the call cannot eavesdrop on their conversation. Importantly, this capability is maintained across multiple FreeSWITCH hops. If widely deployed, this enables a global network architecture where two people can speak securely with strong cryptographically protected authentication and confidentiality. With this commit we implement a zrtp-passthru mode that handles all the details of the negotiation intelligently. This mode can be selected by setting the boolean parameter inbound-zrtp-passthru in the sofia profile. This will also force late-negotiation as it is essential for correctly negotiating an end-to-end ZRTP security association. When an incoming call with a zrtp-hash is received and this mode is enabled, we find the first audio and the first video zrtp-hash in the SDP and store them as remote values on this channel. Once a b-leg is available, we set the local zrtp-hash values on that channel to the remote zrtp-hash values collected from the a-leg. Because zrtp-passthru absolutely requires that the channels negotiate the same codec, we offer to the b-leg only codecs that the a-leg can speak. Once the b-leg accepts a codec, we will force that choice onto the a-leg. If the b-leg sends us zrtp-hash values in the signaling, we store those as remote values on the b-leg and copy them to the local values on the a-leg. At this point, each leg has the zrtp-hash values from the other, and we know we can do ZRTP passthrough mode on the call. We send the b-leg's zrtp-hash back to the a-leg in the 200 OK. We then enable UDPTL mode on the rtp streams for both the audio and the video so that we don't interfere in the ZRTP negotiation. If the b-leg fails to return a zrtp-hash in the signaling, we set up a ZRTP security association with the a-leg ourselves, if we are so equipped. Likewise, if the a-leg fails to send a zrtp-hash in the signaling, we attempt to set up a ZRTP security association ourselves with the b-leg. The zrtp-passthru mode can also be enabled in the dialplan by setting the boolean channel variable zrtp_passthru. If enabled in this manner, we can't force late-negotiation, so the user would need to be sure this is configured. If ZRTP passthrough mode is not enabled in either manner, this change should have no effect. Channel variables for each of the various zrtp-hash values are set, though it is anticipated that there is no good reason to use them, so they may be removed without warning. For checking whether zrtp passthrough mode was successful, we provide the channel variable zrtp_passthru_active which is set on both legs. Though not implemented by this commit, the changes here should make it more straightforward to add correct zrtp-hash values to the signaling and verify that correct hello hash values are received when FreeSWITCH is acting as a terminating leg of the ZRTP security association. A historical note... This commit replaces the recently-added sdp_zrtp_hash_string method, commit 2ab1605a8887adc62be1b75f6ef67af87ff080de. This prior method sets a channel variable from the a-leg's zrtp-hash, then relies on the dialplan to export this channel variable to the b-leg, where it is put into the SDP. While it was a great start and wonderful for testing, this approach has some drawbacks that motivated the present work: * There's no good way to pass the zrtp-hash from the b-leg back to the a-leg. In fact, the implementation seems to send the a-leg's zrtp-hash back to the originating client in the 200 OK. This is not correct. * To support video, we'd need to have a separate dialplan variable, and the dialplan author would need to deal with that explicitly. * The API is problematic as it requires the dialplan author to understand intricate details of how ZRTP works to implement a correct dialplan. Further, by providing too fine-grained control (but at the same time, not enough control) it would limit our ability to make the behavior smarter once people started relying on this.
2012-05-24 20:39:03 +00:00
TFLAG_ZRTP_PASSTHRU,
TFLAG_HOLD_LOCK,
TFLAG_3PCC_HAS_ACK,
TFLAG_UPDATING_DISPLAY,
TFLAG_ENABLE_SOA,
TFLAG_RECOVERED,
TFLAG_AUTOFLUSH_DURING_BRIDGE,
2011-06-03 14:45:07 +00:00
TFLAG_3PCC_INVITE,
2011-06-09 15:22:40 +00:00
TFLAG_NOREPLY,
2011-07-16 07:33:39 +00:00
TFLAG_GOT_ACK,
2011-07-31 23:36:23 +00:00
TFLAG_CAPTURE,
TFLAG_REINVITED,
2012-09-05 18:11:32 +00:00
TFLAG_PASS_ACK,
TFLAG_KEEPALIVE,
TFLAG_SKIP_EARLY,
/* No new flags below this line */
TFLAG_MAX
} TFLAGS;
2012-05-03 21:31:21 +00:00
#define SOFIA_MAX_MSG_QUEUE 64
2012-08-21 05:04:58 +00:00
#define SOFIA_MSG_QUEUE_SIZE 1000
struct mod_sofia_globals {
switch_memory_pool_t *pool;
switch_hash_t *profile_hash;
switch_hash_t *gateway_hash;
switch_mutex_t *hash_mutex;
uint32_t callid;
int32_t running;
int32_t threads;
2012-05-03 21:31:21 +00:00
int cpu_count;
int max_msg_queues;
switch_mutex_t *mutex;
char guess_ip[80];
char hostname[512];
switch_queue_t *presence_queue;
switch_queue_t *msg_queue;
2016-02-17 22:22:46 +00:00
switch_queue_t *general_event_queue;
switch_thread_t *msg_queue_thread[SOFIA_MAX_MSG_QUEUE];
int msg_queue_len;
struct sofia_private destroy_private;
struct sofia_private keep_private;
int guess_mask;
char guess_mask_str[16];
int debug_presence;
int debug_sla;
int auto_restart;
int reg_deny_binding_fetch_and_no_lookup; /* backwards compatibility */
int auto_nat;
int tracelevel;
char *capture_server;
int rewrite_multicasted_fs_path;
int presence_flush;
2013-02-18 18:58:33 +00:00
switch_thread_t *presence_thread;
uint32_t max_reg_threads;
time_t presence_epoch;
2014-09-08 19:09:31 +00:00
int presence_year;
char filter_expression[100];
switch_regex_t *filter_re;
switch_bool_t filtering;
};
extern struct mod_sofia_globals mod_sofia_globals;
typedef enum {
REG_FLAG_AUTHED,
REG_FLAG_CALLERID,
/* No new flags below this line */
REG_FLAG_MAX
} reg_flags_t;
2010-06-05 00:37:04 +00:00
typedef enum {
CID_TYPE_RPID,
CID_TYPE_PID,
CID_TYPE_NONE
} sofia_cid_type_t;
typedef enum {
REG_STATE_UNREGED,
REG_STATE_TRYING,
REG_STATE_REGISTER,
REG_STATE_REGED,
REG_STATE_UNREGISTER,
REG_STATE_FAILED,
REG_STATE_FAIL_WAIT,
REG_STATE_EXPIRED,
REG_STATE_NOREG,
2010-11-02 22:58:24 +00:00
REG_STATE_TIMEOUT,
REG_STATE_LAST
} reg_state_t;
typedef enum {
SOFIA_TRANSPORT_UNKNOWN = 0,
SOFIA_TRANSPORT_UDP,
SOFIA_TRANSPORT_TCP,
SOFIA_TRANSPORT_TCP_TLS,
2013-02-06 15:48:04 +00:00
SOFIA_TRANSPORT_SCTP,
SOFIA_TRANSPORT_WS,
SOFIA_TRANSPORT_WSS
} sofia_transport_t;
typedef enum {
SOFIA_TLS_VERSION_SSLv2 = (1 << 0),
SOFIA_TLS_VERSION_SSLv3 = (1 << 1),
SOFIA_TLS_VERSION_TLSv1 = (1 << 2),
SOFIA_TLS_VERSION_TLSv1_1 = (1 << 3),
SOFIA_TLS_VERSION_TLSv1_2 = (1 << 4),
} sofia_tls_version_t;
typedef enum {
SOFIA_GATEWAY_DOWN,
SOFIA_GATEWAY_UP,
SOFIA_GATEWAY_INVALID
} sofia_gateway_status_t;
typedef enum {
SOFIA_REG_REACHABLE,
SOFIA_REG_UNREACHABLE,
SOFIA_REG_INVALID
} sofia_sip_user_status_t;
typedef enum {
SUB_STATE_UNSUBED,
SUB_STATE_TRYING,
SUB_STATE_SUBSCRIBE,
SUB_STATE_SUBED,
SUB_STATE_UNSUBSCRIBE,
SUB_STATE_FAILED,
SUB_STATE_FAIL_WAIT,
SUB_STATE_EXPIRED,
SUB_STATE_NOSUB,
v_STATE_LAST
} sub_state_t;
struct sofia_gateway_subscription {
sofia_gateway_t *gateway;
sofia_private_t *sofia_private;
nua_handle_t *nh;
char *expires_str;
char *event; /* eg, 'message-summary' to subscribe to MWI events */
char *content_type; /* eg, application/simple-message-summary in the case of MWI events */
char *request_uri;
uint32_t freq;
int32_t retry_seconds;
time_t expires;
time_t retry;
sub_state_t state;
struct sofia_gateway_subscription *next;
};
struct sofia_gateway {
sofia_private_t *sofia_private;
nua_handle_t *nh;
sofia_profile_t *profile;
char *name;
char *register_scheme;
char *register_realm;
char *register_username;
char *auth_username;
char *register_password;
char *register_from;
char *options_from_uri;
char *options_to_uri;
char *options_user_agent;
char *register_contact;
char *extension;
char *real_extension;
char *register_to;
char *register_proxy;
char *register_sticky_proxy;
char *outbound_sticky_proxy;
char *register_context;
char *expires_str;
char *register_url;
char *destination_prefix;
char *from_domain;
sofia_transport_t register_transport;
uint32_t freq;
time_t expires;
time_t retry;
time_t ping;
time_t reg_timeout;
int pinging;
sofia_gateway_status_t status;
switch_time_t uptime;
uint32_t ping_freq;
int ping_count;
int ping_max;
int ping_min;
switch_time_t ping_sent;
float ping_time;
switch_bool_t ping_monitoring;
uint8_t flags[REG_FLAG_MAX];
int32_t retry_seconds;
int32_t fail_908_retry_seconds;
int32_t reg_timeout_seconds;
int32_t failure_status;
reg_state_t state;
switch_memory_pool_t *pool;
int deleted;
switch_event_t *ib_vars;
switch_event_t *ob_vars;
uint32_t ib_calls;
uint32_t ob_calls;
uint32_t ib_failed_calls;
uint32_t ob_failed_calls;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
int failures;
struct sofia_gateway *next;
sofia_gateway_subscription_t *subscriptions;
int distinct_to;
2010-06-05 00:37:04 +00:00
sofia_cid_type_t cid_type;
};
typedef enum {
PRES_TYPE_NONE = 0,
PRES_TYPE_FULL = 1,
2012-06-04 19:16:30 +00:00
PRES_TYPE_PASSIVE = 2,
PRES_TYPE_PNP = 3
} sofia_presence_type_t;
2012-04-13 16:18:09 +00:00
typedef enum {
PRES_HELD_EARLY = 0,
PRES_HELD_CONFIRMED = 1,
PRES_HELD_TERMINATED = 2
} sofia_presence_held_calls_type_t;
typedef enum {
MEDIA_OPT_NONE = 0,
MEDIA_OPT_MEDIA_ON_HOLD = (1 << 0),
MEDIA_OPT_BYPASS_AFTER_ATT_XFER = (1 << 1),
MEDIA_OPT_BYPASS_AFTER_HOLD = (1 << 2)
} sofia_media_options_t;
2012-04-10 20:46:27 +00:00
typedef enum {
PAID_DEFAULT = 0,
PAID_USER,
PAID_USER_DOMAIN,
PAID_VERBATIM
2012-04-10 20:46:27 +00:00
} sofia_paid_type_t;
#define MAX_RTPIP 50
typedef enum {
KA_MESSAGE,
KA_INFO
} ka_type_t;
struct sofia_profile {
int debug;
2014-04-15 16:47:48 +00:00
int parse_invite_tel_params;
char *name;
char *domain_name;
char *dbname;
char *dialplan;
char *context;
char *shutdown_type;
char *extrtpip;
char *rtpip[MAX_RTPIP];
char *rtpip6[MAX_RTPIP];
2012-12-22 03:30:14 +00:00
char *jb_msec;
2012-12-22 17:51:03 +00:00
switch_payload_t te;
switch_payload_t recv_te;
uint32_t rtpip_index;
uint32_t rtpip_next;
uint32_t rtpip_index6;
uint32_t rtpip_next6;
2012-12-22 03:30:14 +00:00
char *rtcp_audio_interval_msec;
char *rtcp_video_interval_msec;
char *sdp_username;
char *sipip;
char *extsipip;
char *url;
char *public_url;
char *bindurl;
char *ws_bindurl;
char *wss_bindurl;
char *tls_url;
char *tls_public_url;
char *tls_bindurl;
char *tcp_public_contact;
char *tls_public_contact;
char *tcp_contact;
char *tls_contact;
char *sla_contact;
char *sipdomain;
char *timer_name;
char *hold_music;
char *outbound_proxy;
char *bind_params;
char *tls_bind_params;
char *tls_cert_dir;
char *reg_domain;
char *sub_domain;
char *reg_db_domain;
char *user_agent;
char *record_template;
char *record_path;
char *presence_hosts;
2011-12-15 18:20:27 +00:00
char *presence_privacy;
char *challenge_realm;
2012-06-04 19:16:30 +00:00
char *pnp_prov_url;
char *pnp_notify_profile;
int sip_user_ping_max;
int sip_user_ping_min;
sofia_cid_type_t cid_type;
2012-12-21 04:57:47 +00:00
switch_core_media_dtmf_t dtmf_type;
int auto_restart;
switch_port_t sip_port;
2012-11-21 16:32:41 +00:00
switch_port_t extsipport;
switch_port_t tls_sip_port;
char *tls_ciphers;
int tls_version;
unsigned int tls_timeout;
char *inbound_codec_string;
char *outbound_codec_string;
int running;
int dtmf_duration;
uint8_t flags[TFLAG_MAX];
uint8_t pflags[PFLAG_MAX];
2012-12-21 04:57:47 +00:00
switch_core_media_flag_t media_flags[SCMF_MAX];
unsigned int mflags;
unsigned int ndlb;
2012-12-22 03:30:14 +00:00
unsigned int mndlb;
uint32_t max_calls;
uint32_t nonce_ttl;
uint32_t max_auth_validity;
nua_t *nua;
switch_memory_pool_t *pool;
su_root_t *s_root;
sip_alias_node_t *aliases;
switch_payload_t cng_pt;
uint32_t codec_flags;
switch_mutex_t *ireg_mutex;
switch_mutex_t *dbh_mutex;
switch_mutex_t *gateway_mutex;
sofia_gateway_t *gateways;
//su_home_t *home;
switch_hash_t *chat_hash;
2013-04-24 21:35:58 +00:00
switch_hash_t *reg_nh_hash;
switch_hash_t *mwi_debounce_hash;
//switch_core_db_t *master_db;
switch_thread_rwlock_t *rwlock;
switch_mutex_t *flag_mutex;
uint32_t inuse;
time_t started;
uint32_t session_timeout;
uint32_t minimum_session_expires;
uint32_t max_proceeding;
uint32_t rtp_timeout_sec;
uint32_t rtp_hold_timeout_sec;
char *odbc_dsn;
char *pre_trans_execute;
char *post_trans_execute;
char *inner_pre_trans_execute;
char *inner_post_trans_execute;
switch_sql_queue_manager_t *qm;
char *acl[SOFIA_MAX_ACL];
char *acl_pass_context[SOFIA_MAX_ACL];
char *acl_fail_context[SOFIA_MAX_ACL];
uint32_t acl_count;
char *proxy_acl[SOFIA_MAX_ACL];
uint32_t proxy_acl_count;
char *reg_acl[SOFIA_MAX_ACL];
uint32_t reg_acl_count;
char *nat_acl[SOFIA_MAX_ACL];
uint32_t nat_acl_count;
2013-01-10 04:31:25 +00:00
char *cand_acl[SWITCH_MAX_CAND_ACL];
uint32_t cand_acl_count;
int server_rport_level;
int client_rport_level;
sofia_presence_type_t pres_type;
2012-04-13 16:18:09 +00:00
sofia_presence_held_calls_type_t pres_held_type;
sofia_media_options_t media_options;
uint32_t force_subscription_expires;
uint32_t force_publish_expires;
char *user_agent_filter;
uint32_t max_registrations_perext;
switch_rtp_bug_flag_t auto_rtp_bugs;
switch_rtp_bug_flag_t manual_rtp_bugs;
2012-10-16 22:42:54 +00:00
switch_rtp_bug_flag_t manual_video_rtp_bugs;
uint32_t ib_calls;
uint32_t ob_calls;
uint32_t ib_failed_calls;
uint32_t ob_failed_calls;
uint32_t timer_t1;
uint32_t timer_t1x64;
uint32_t timer_t2;
uint32_t timer_t4;
char *contact_user;
char *local_network;
uint32_t trans_timeout;
switch_time_t last_sip_event;
switch_time_t last_root_step;
uint32_t step_timeout;
uint32_t event_timeout;
2010-10-06 20:17:48 +00:00
int watchdog_enabled;
switch_mutex_t *gw_mutex;
2011-10-03 23:53:17 +00:00
uint32_t queued_events;
uint32_t last_cseq;
int tls_only;
int tls_verify_date;
enum tport_tls_verify_policy tls_verify_policy;
int tls_verify_depth;
char *tls_passphrase;
char *tls_verify_in_subjects_str;
su_strlst_t *tls_verify_in_subjects;
2011-12-22 20:03:32 +00:00
uint32_t sip_force_expires;
uint32_t sip_force_expires_min;
uint32_t sip_force_expires_max;
2011-12-22 20:03:32 +00:00
uint32_t sip_expires_max_deviation;
uint32_t sip_expires_late_margin;
2013-07-03 16:21:03 +00:00
uint32_t sip_subscription_max_deviation;
int ireg_seconds;
int iping_seconds;
int iping_freq;
2012-04-10 20:46:27 +00:00
sofia_paid_type_t paid_type;
uint32_t rtp_digit_delay;
switch_queue_t *event_queue;
switch_thread_t *thread;
2012-12-21 20:22:25 +00:00
switch_core_media_vflag_t vflags;
char *ws_ip;
switch_port_t ws_port;
char *wss_ip;
switch_port_t wss_port;
int socket_tcp_keepalive;
int tcp_keepalive;
int tcp_pingpong;
int tcp_ping2pong;
ka_type_t keepalive;
int bind_attempts;
int bind_attempt_interval;
char *proxy_notify_events;
char *proxy_info_content_types;
};
2012-12-22 17:51:03 +00:00
struct private_object {
sofia_private_t *sofia_private;
uint8_t flags[TFLAG_MAX];
switch_core_session_t *session;
switch_channel_t *channel;
2012-12-18 22:06:29 +00:00
switch_media_handle_t *media_handle;
2012-12-22 14:29:19 +00:00
switch_core_media_params_t mparams;
switch_caller_profile_t *caller_profile;
sofia_profile_t *profile;
char *reply_contact;
char *from_uri;
char *from_user;
char *to_uri;
char *callid;
char *contact_url;
char *from_str;
char *rpid;
char *asserted_id;
char *preferred_id;
char *privacy;
char *gateway_from_str;
char *dest;
char *dest_to;
char *key;
char *kick;
char *origin;
char *hash_key;
char *chat_from;
char *chat_to;
char *e_dest;
char *call_id;
char *invite_contact;
char *local_url;
char *gateway_name;
char *record_route;
char *route_uri;
char *x_freeswitch_support_remote;
char *x_freeswitch_support_local;
char *last_sent_callee_id_name;
char *last_sent_callee_id_number;
char *proxy_refer_uuid;
msg_t *proxy_refer_msg;
switch_mutex_t *flag_mutex;
switch_mutex_t *sofia_mutex;
switch_payload_t te;
switch_payload_t recv_te;
switch_payload_t bte;
switch_payload_t cng_pt;
switch_payload_t bcng_pt;
sofia_transport_t transport;
nua_handle_t *nh;
nua_handle_t *nh2;
sip_contact_t *contact;
int q850_cause;
int got_bye;
int sent_100;
nua_event_t want_event;
switch_rtp_bug_flag_t rtp_bugs;
char *user_via;
char *redirected;
sofia_cid_type_t cid_type;
uint32_t session_timeout;
enum nua_session_refresher session_refresher;
int update_refresher;
char **watch_headers;
char *respond_phrase;
int respond_code;
2012-06-27 17:25:03 +00:00
char *respond_dest;
switch_time_t last_vid_info;
uint32_t keepalive;
2014-10-03 16:34:37 +00:00
uint32_t sent_invites;
2014-11-06 23:13:02 +00:00
uint32_t recv_invites;
uint8_t sent_last_invite;
uint32_t req_media_counter;
};
struct callback_t {
char *val;
switch_size_t len;
2010-08-18 19:58:14 +00:00
switch_console_callback_match_t *list;
int matches;
2012-11-27 18:48:57 +00:00
time_t time;
const char *contact_str;
long exptime;
};
typedef enum {
REG_REGISTER,
REG_AUTO_REGISTER,
REG_INVITE,
} sofia_regtype_t;
typedef enum {
AUTH_OK,
AUTH_FORBIDDEN,
AUTH_STALE,
2011-12-16 19:31:15 +00:00
AUTH_RENEWED,
} auth_res_t;
typedef struct {
char *to;
char *contact;
char *route;
char *route_uri;
} sofia_destination_t;
typedef struct {
char network_ip[80];
int network_port;
const char *is_nat;
int is_auto_nat;
2012-01-26 10:46:48 +00:00
int fs_path;
} sofia_nat_parse_t;
#define NUTAG_WITH_THIS_MSG(msg) nutag_with, tag_ptr_v(msg)
2012-12-21 04:57:47 +00:00
#define sofia_test_media_flag(obj, flag) ((obj)->media_flags[flag] ? 1 : 0)
#define sofia_set_media_flag(obj, flag) (obj)->media_flags[flag] = 1
#define sofia_set_media_flag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
switch_mutex_lock(obj->flag_mutex);\
(obj)->media_flags[flag] = 1;\
switch_mutex_unlock(obj->flag_mutex);
#define sofia_clear_media_flag_locked(obj, flag) switch_mutex_lock(obj->flag_mutex); (obj)->media_flags[flag] = 0; switch_mutex_unlock(obj->flag_mutex);
#define sofia_clear_media_flag(obj, flag) (obj)->media_flags[flag] = 0
#define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0)
#define sofia_set_pflag(obj, flag) (obj)->pflags[flag] = 1
#define sofia_set_pflag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
switch_mutex_lock(obj->flag_mutex);\
(obj)->pflags[flag] = 1;\
switch_mutex_unlock(obj->flag_mutex);
#define sofia_clear_pflag_locked(obj, flag) switch_mutex_lock(obj->flag_mutex); (obj)->pflags[flag] = 0; switch_mutex_unlock(obj->flag_mutex);
#define sofia_clear_pflag(obj, flag) (obj)->pflags[flag] = 0
2012-12-21 04:57:47 +00:00
#define sofia_set_flag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
switch_mutex_lock(obj->flag_mutex);\
(obj)->flags[flag] = 1;\
switch_mutex_unlock(obj->flag_mutex);
#define sofia_set_flag(obj, flag) (obj)->flags[flag] = 1
#define sofia_clear_flag(obj, flag) (obj)->flags[flag] = 0
#define sofia_clear_flag_locked(obj, flag) switch_mutex_lock(obj->flag_mutex); (obj)->flags[flag] = 0; switch_mutex_unlock(obj->flag_mutex);
#define sofia_test_flag(obj, flag) ((obj)->flags[flag] ? 1 : 0)
/* Function Prototypes */
/*************************************************************************************************************************************************************/
void sofia_glue_global_standby(switch_bool_t on);
2012-12-18 22:06:29 +00:00
switch_status_t sofia_media_activate_rtp(private_object_t *tech_pvt);
2012-12-19 20:51:28 +00:00
const char *sofia_media_get_codec_string(private_object_t *tech_pvt);
void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *profile, private_object_t *tech_pvt, const char *channame);
switch_status_t sofia_glue_do_invite(switch_core_session_t *session);
2013-05-17 20:39:21 +00:00
uint8_t sofia_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp, switch_sdp_type_t type);
void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
sofia_dispatch_event_t *de, tagi_t tags[]);
switch_status_t sofia_proxy_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
sofia_dispatch_event_t *de, tagi_t tags[]);
switch_status_t sofia_proxy_sip_i_message(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
sofia_dispatch_event_t *de, tagi_t tags[]);
2012-08-21 05:04:58 +00:00
void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, sofia_dispatch_event_t *de, tagi_t tags[]);
2013-01-27 05:16:26 +00:00
void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t **sofia_private, sip_t const *sip,
sofia_dispatch_event_t *de,
tagi_t tags[]);
void sofia_event_callback(nua_event_t event,
int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
tagi_t tags[]);
void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj);
void launch_sofia_profile_thread(sofia_profile_t *profile);
switch_status_t sofia_presence_chat_send(switch_event_t *message_event);
/*
* \brief Sets the "ep_codec_string" channel variable, parsing r_sdp and taing codec_string in consideration
* \param channel Current channel
* \param codec_string The profile's codec string or NULL if inexistant
* \param sdp The parsed SDP content
*/
2012-12-19 20:51:28 +00:00
void sofia_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp);
switch_status_t sofia_media_tech_media(private_object_t *tech_pvt, const char *r_sdp);
char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const char *host, char *val, switch_size_t len);
void event_handler(switch_event_t *event);
void sofia_presence_event_handler(switch_event_t *event);
void sofia_presence_cancel(void);
switch_status_t config_sofia(sofia_config_t reload, char *profile_name);
switch_status_t config_gateway(const char *profile_name, const char *gateway_name);
2011-06-30 16:59:58 +00:00
void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de,
2013-04-23 19:49:07 +00:00
sofia_regtype_t regtype, const char *realm, int stale, long exptime);
auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization,
sip_t const *sip,
sofia_dispatch_event_t *de, const char *regstr, char *np, size_t nplen, char *ip, int network_port, switch_event_t **v_event,
2013-07-19 17:03:46 +00:00
long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count, switch_xml_t *user_xml);
void sofia_reg_handle_sip_r_challenge(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile,
nua_handle_t *nh, sofia_private_t *sofia_private,
switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip,
sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_reg_handle_sip_r_register(int status,
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
sofia_dispatch_event_t *de,
tagi_t tags[]);
void sofia_handle_sip_i_options(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private,
sip_t const *sip,
sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
sofia_dispatch_event_t *de,
tagi_t tags[]);
void sofia_presence_handle_sip_i_message(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
switch_core_session_t *session, sofia_private_t *sofia_private, sip_t const *sip,
sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_presence_handle_sip_r_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
sofia_private_t *sofia_private, sip_t const *sip,
sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_presence_handle_sip_i_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
sofia_private_t *sofia_private, sip_t const *sip,
sofia_dispatch_event_t *de, tagi_t tags[]);
void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic);
void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex);
void sofia_glue_actually_execute_sql_trans(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex);
void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic);
2012-11-17 02:09:38 +00:00
void sofia_glue_execute_sql_soon(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic);
void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot);
void sofia_reg_check_ping_expire(sofia_profile_t *profile, time_t now, int interval);
void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now);
void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now);
void sofia_reg_unregister(sofia_profile_t *profile);
2012-12-21 20:22:25 +00:00
void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp);
switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status);
void sofia_glue_do_xfer_invite(switch_core_session_t *session);
2014-03-13 15:23:08 +00:00
uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
2013-01-27 05:16:26 +00:00
sofia_dispatch_event_t *de,
sofia_regtype_t regtype, char *key,
uint32_t keylen, switch_event_t **v_event, const char *is_nat, sofia_private_t **sofia_private_p, switch_xml_t *user_xml, const char *sw_acl_token);
2014-03-13 15:23:08 +00:00
#define sofia_reg_handle_register(_nua_, _profile_, _nh_, _sip_, _de_, _regtype_, _key_, _keylen_, _v_event_, _is_nat_, _sofia_private_p_, _user_xml_) sofia_reg_handle_register_token(_nua_, _profile_, _nh_, _sip_, _de_, _regtype_, _key_, _keylen_, _v_event_, _is_nat_, _sofia_private_p_, _user_xml_, NULL)
extern switch_endpoint_interface_t *sofia_endpoint_interface;
void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip);
switch_status_t sofia_on_hangup(switch_core_session_t *session);
char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup);
2013-04-04 17:35:18 +00:00
char *sofia_glue_get_path_from_contact(char *buf);
char *sofia_glue_get_profile_url(sofia_profile_t *profile, char *remote_ip, const sofia_transport_t transport);
void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip);
void sofia_glue_sql_close(sofia_profile_t *profile, time_t prune);
int sofia_glue_init_sql(sofia_profile_t *profile);
char *sofia_overcome_sip_uri_weakness(switch_core_session_t *session, const char *uri, const sofia_transport_t transport, switch_bool_t uri_only,
2013-02-27 15:04:51 +00:00
const char *params, const char *invite_tel_params);
switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback,
void *pdata);
char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len);
void sofia_glue_del_profile(sofia_profile_t *profile);
switch_status_t sofia_glue_add_profile(char *key, sofia_profile_t *profile);
void sofia_glue_release_profile__(const char *file, const char *func, int line, sofia_profile_t *profile);
#define sofia_glue_release_profile(x) sofia_glue_release_profile__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
sofia_profile_t *sofia_glue_find_profile__(const char *file, const char *func, int line, const char *key);
#define sofia_glue_find_profile(x) sofia_glue_find_profile__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
#define sofia_glue_profile_rdlock(x) sofia_glue_profile_rdlock__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
switch_status_t sofia_glue_profile_rdlock__(const char *file, const char *func, int line, sofia_profile_t *profile);
switch_status_t sofia_reg_add_gateway(sofia_profile_t *profile, const char *key, sofia_gateway_t *gateway);
sofia_gateway_t *sofia_reg_find_gateway__(const char *file, const char *func, int line, const char *key);
#define sofia_reg_find_gateway(x) sofia_reg_find_gateway__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
sofia_gateway_t *sofia_reg_find_gateway_by_realm__(const char *file, const char *func, int line, const char *key);
#define sofia_reg_find_gateway_by_realm(x) sofia_reg_find_gateway_by_realm__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
sofia_gateway_subscription_t *sofia_find_gateway_subscription(sofia_gateway_t *gateway_ptr, const char *event);
#define sofia_reg_gateway_rdlock(x) sofia_reg_gateway_rdlock__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
switch_status_t sofia_reg_gateway_rdlock__(const char *file, const char *func, int line, sofia_gateway_t *gateway);
void sofia_reg_release_gateway__(const char *file, const char *func, int line, sofia_gateway_t *gateway);
#define sofia_reg_release_gateway(x) sofia_reg_release_gateway__(__FILE__, __SWITCH_FUNC__, __LINE__, x);
#define sofia_use_soa(_t) sofia_test_flag(_t, TFLAG_ENABLE_SOA)
#define sofia_test_extra_headers(val) (((!strncasecmp(val, "X-", 2) && strncasecmp(val, "X-FS-", 5)) || !strncasecmp(val, "P-", 2) || !strncasecmp(val, "On", 2)) ? 1 : 0)
#define check_decode(_var, _session) do { \
assert(_session); \
if (!zstr(_var)) { \
int d = 0; \
char *p; \
if (strchr(_var, '%')) { \
char *tmp = switch_core_session_strdup(_session, _var); \
switch_url_decode(tmp); \
_var = tmp; \
d++; \
} \
if ((p = strchr(_var, '"'))) { \
if (!d) { \
char *tmp = switch_core_session_strdup(_session, _var); \
_var = tmp; \
} \
if ((p = strchr(_var, '"'))) { \
_var = p+1; \
} \
if ((p = strrchr(_var, '"'))) { \
*p = '\0'; \
} \
} \
} \
\
if (_session) break; \
} while(!_session)
/*
* Transport handling helper functions
*/
2010-06-30 15:35:03 +00:00
sofia_transport_t sofia_glue_via2transport(const sip_via_t * via);
sofia_transport_t sofia_glue_url2transport(const url_t *url);
sofia_transport_t sofia_glue_str2transport(const char *str);
enum tport_tls_verify_policy sofia_glue_str2tls_verify_policy(const char * str);
const char *sofia_glue_transport2str(const sofia_transport_t tp);
char *sofia_glue_find_parameter(const char *str, const char *param);
char *sofia_glue_find_parameter_value(switch_core_session_t *session, const char *str, const char *param);
char *sofia_glue_create_via(switch_core_session_t *session, const char *ip, switch_port_t port, sofia_transport_t transport);
char *sofia_glue_create_external_via(switch_core_session_t *session, sofia_profile_t *profile, sofia_transport_t transport);
char *sofia_glue_strip_uri(const char *str);
2012-12-21 20:22:25 +00:00
int sofia_glue_transport_has_tls(const sofia_transport_t tp);
const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name);
switch_status_t sofia_media_build_crypto(private_object_t *tech_pvt, int index, switch_rtp_crypto_key_type_t type, switch_rtp_crypto_direction_t direction);
void sofia_presence_event_thread_start(void);
void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int reboot);
void sofia_reg_check_call_id(sofia_profile_t *profile, const char *call_id);
void sofia_reg_check_sync(sofia_profile_t *profile);
2012-12-21 20:22:25 +00:00
2010-11-22 20:59:25 +00:00
char *sofia_glue_get_register_host(const char *uri);
const char *sofia_glue_strip_proto(const char *uri);
void sofia_glue_del_gateway(sofia_gateway_t *gp);
void sofia_glue_gateway_list(sofia_profile_t *profile, switch_stream_handle_t *stream, int up);
2010-03-31 20:02:50 +00:00
void sofia_glue_del_every_gateway(sofia_profile_t *profile);
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *callid, const char *user, const char *host, const char *contact, const char *user_agent,
const char *network_ip);
void sofia_glue_restart_all_profiles(void);
const char *sofia_state_string(int state);
void sofia_wait_for_reply(struct private_object *tech_pvt, nua_event_t event, uint32_t timeout);
/*
* Logging control functions
*/
/*!
* \brief Changes the loglevel of a sofia component
* \param name the sofia component on which to change the loglevel, or "all" to change them all
* \note Valid components are "all", "default" (sofia's default logger), "tport", "iptsec", "nea", "nta", "nth_client", "nth_server", "nua", "soa", "sresolv", "stun"
* \return SWITCH_STATUS_SUCCESS or SWITCH_STATUS_FALSE if the component isnt valid, or the level is out of range
*/
switch_status_t sofia_set_loglevel(const char *name, int level);
/*!
* \brief Gets the loglevel of a sofia component
* \param name the sofia component on which to change the loglevel
* \note Valid components are "default" (sofia's default logger), "tport", "iptsec", "nea", "nta", "nth_client", "nth_server", "nua", "soa", "sresolv", "stun"
* \return the component's loglevel, or -1 if the component isn't valid
*/
int sofia_get_loglevel(const char *name);
switch_status_t list_profiles_full(const char *line, const char *cursor, switch_console_callback_match_t **matches, switch_bool_t show_aliases);
switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches);
sofia_cid_type_t sofia_cid_name2type(const char *name);
void sofia_glue_get_addr(msg_t *msg, char *buf, size_t buflen, int *port);
sofia_destination_t *sofia_glue_get_destination(char *data);
void sofia_glue_free_destination(sofia_destination_t *dst);
switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *user, const char *host, const char *event, const char *contenttype,
2012-05-21 18:55:50 +00:00
const char *body, const char *o_contact, const char *network_ip, const char *call_id);
char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix);
void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *sip, const char *prefix);
2012-02-22 21:26:38 +00:00
char *sofia_glue_get_extra_headers_from_event(switch_event_t *event, const char *prefix);
char *sofia_glue_get_non_extra_unknown_headers(sip_t const *sip);
void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t send);
void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number);
int sofia_sla_supported(sip_t const *sip);
int sofia_glue_recover(switch_bool_t flush);
2011-12-23 21:07:33 +00:00
int sofia_glue_profile_recover(sofia_profile_t *profile, switch_bool_t flush);
void sofia_profile_destroy(sofia_profile_t *profile);
switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream);
const char *sofia_gateway_status_name(sofia_gateway_status_t status);
void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int status, const char *phrase);
const char *sofia_sip_user_status_name(sofia_sip_user_status_t status);
void sofia_reg_fire_custom_sip_user_state_event(sofia_profile_t *profile, const char *sip_user, const char *contact,
const char* from_user, const char* from_host, const char *call_id, sofia_sip_user_status_t status, int options_res, const char *phrase);
2011-01-03 22:40:49 +00:00
uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const char *host);
2012-12-19 20:51:28 +00:00
char *sofia_media_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type);
2012-11-30 00:34:27 +00:00
int sofia_glue_tech_simplify(private_object_t *tech_pvt);
2010-08-18 19:58:14 +00:00
switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host);
2012-11-27 18:48:57 +00:00
switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host, time_t reg_time, const char *contact_str, long exptime);
2010-09-03 17:46:21 +00:00
switch_bool_t sofia_glue_profile_exists(const char *key);
void sofia_glue_global_siptrace(switch_bool_t on);
2011-07-31 23:36:23 +00:00
void sofia_glue_global_capture(switch_bool_t on);
2010-10-06 20:17:48 +00:00
void sofia_glue_global_watchdog(switch_bool_t on);
uint32_t sofia_presence_get_cseq(sofia_profile_t *profile);
void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl);
2012-01-26 10:46:48 +00:00
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np);
void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on);
2011-11-18 23:00:30 +00:00
void sofia_process_dispatch_event(sofia_dispatch_event_t **dep);
2012-11-29 05:12:35 +00:00
void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep);
char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool);
void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now);
void sofia_msg_thread_start(int idx);
void crtp_init(switch_loadable_module_interface_t *module_interface);
int sofia_recover_callback(switch_core_session_t *session);
void sofia_glue_set_name(private_object_t *tech_pvt, const char *channame);
private_object_t *sofia_glue_new_pvt(switch_core_session_t *session);
switch_status_t sofia_init(void);
void sofia_glue_fire_events(sofia_profile_t *profile);
void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event);
2012-11-29 05:12:35 +00:00
void sofia_queue_message(sofia_dispatch_event_t *de);
2012-12-22 03:30:14 +00:00
int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip);
2016-02-17 22:22:46 +00:00
void general_event_handler(switch_event_t *event);
2012-12-22 03:30:14 +00:00
switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, char **ip, switch_port_t *port,
const char *sourceip, switch_memory_pool_t *pool);
2013-01-27 05:16:26 +00:00
void sofia_reg_check_socket(sofia_profile_t *profile, const char *call_id, const char *network_addr, const char *network_ip);
2013-04-24 21:35:58 +00:00
void sofia_reg_close_handles(sofia_profile_t *profile);
2012-05-23 05:20:13 +00:00
void write_csta_xml_chunk(switch_event_t *event, switch_stream_handle_t stream, const char *csta_event, char *fwd_type);
void sofia_glue_clear_soa(switch_core_session_t *session, switch_bool_t partner);
2012-05-23 05:20:13 +00:00
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
2012-05-23 05:20:13 +00:00
*/