*/
/*** MODULEINFO
- <depend>uuid</depend>
+ <use type="external">uuid</use>
<support_level>core</support_level>
***/
#include <openssl/bio.h>
#endif
+#ifdef USE_PJPROJECT
/* Asterisk discourages the use of bzero in favor of memset, in fact if you try to use bzero it will tell you to use memset. As a result bzero has to be undefined
* here since it is used internally by pjlib. The only other option would be to modify pjlib... which won't happen. */
#undef bzero
#include "pjlib.h"
#include "pjlib-util.h"
#include "pjnath.h"
+#endif
#include "asterisk/stun.h"
#include "asterisk/pbx.h"
static int learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL; /*< Number of sequential RTP frames needed from a single source during learning mode to accept new source. */
static int icesupport = DEFAULT_ICESUPPORT;
static struct sockaddr_in stunaddr;
+
+#ifdef USE_PJPROJECT
static pj_str_t turnaddr;
static int turnport = DEFAULT_TURN_PORT;
static pj_str_t turnusername;
/*! \brief Notification that the ICE/TURN worker thread should stop */
static int worker_terminate;
+#endif
#define FLAG_3389_WARNING (1 << 0)
#define FLAG_NAT_ACTIVE (3 << 1)
struct rtp_red *red;
+#ifdef USE_PJPROJECT
pj_ice_sess *ice; /*!< ICE session */
pj_turn_sock *turn_rtp; /*!< RTP TURN relay */
pj_turn_sock *turn_rtcp; /*!< RTCP TURN relay */
struct ao2_container *local_candidates; /*!< The local ICE candidates */
struct ao2_container *remote_candidates; /*!< The remote ICE candidates */
+#endif
#ifdef HAVE_OPENSSL_SRTP
SSL_CTX *ssl_ctx; /*!< SSL context */
static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp, int *ice, int use_srtp);
+#ifdef USE_PJPROJECT
/*! \brief Destructor for locally created ICE candidates */
static void ast_rtp_ice_candidate_destroy(void *obj)
{
.get_local_candidates = ast_rtp_ice_get_local_candidates,
.ice_lite = ast_rtp_ice_lite,
};
+#endif
#ifdef HAVE_OPENSSL_SRTP
static void dtls_info_callback(const SSL *ssl, int where, int ret)
.stop = ast_rtp_stop,
.qos = ast_rtp_qos_set,
.sendcng = ast_rtp_sendcng,
+#ifdef USE_PJPROJECT
.ice = &ast_rtp_ice,
+#endif
#ifdef HAVE_OPENSSL_SRTP
.dtls = &ast_rtp_dtls,
.activate = ast_rtp_activate,
static void rtp_learning_seq_init(struct rtp_learning_info *info, uint16_t seq);
+#ifdef USE_PJPROJECT
static void ast_rtp_on_ice_complete(pj_ice_sess *ice, pj_status_t status)
{
struct ast_rtp *rtp = ice->user_data;
return 0;
}
+#endif
static inline int rtp_debug_test_addr(struct ast_sockaddr *addr)
{
}
#endif
+#ifdef USE_PJPROJECT
if (rtp->ice) {
pj_str_t combined = pj_str(ast_sockaddr_stringify(sa));
pj_sockaddr address;
}
rtp->passthrough = 0;
}
+#endif
if ((*in & 0xC0) && res_srtp && srtp && res_srtp->unprotect(srtp, buf, &len, rtcp) < 0) {
return -1;
return -1;
}
+#ifdef USE_PJPROJECT
if (rtp->ice) {
pj_thread_register_check();
return 0;
}
}
+#endif
return ast_sendto(rtcp ? rtp->rtcp->s : rtp->s, temp, len, flags, sa);
}
return (info->packets == 0);
}
+#ifdef USE_PJPROJECT
static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *addr, int port, int component,
int transport, const pj_turn_sock_cb *turn_cb, pj_turn_sock **turn_sock)
{
}
}
}
+#endif
static int ast_rtp_new(struct ast_rtp_instance *instance,
struct ast_sched_context *sched, struct ast_sockaddr *addr,
{
struct ast_rtp *rtp = NULL;
int x, startplace;
+#ifdef USE_PJPROJECT
pj_stun_config stun_config;
pj_str_t ufrag, passwd;
+#endif
/* Create a new RTP structure to hold all of our data */
if (!(rtp = ast_calloc(1, sizeof(*rtp)))) {
return -1;
}
+#ifdef USE_PJPROJECT
/* Initialize synchronization aspects */
ast_mutex_init(&rtp->lock);
ast_cond_init(&rtp->cond, NULL);
+#endif
/* Set default parameters on the newly created RTP structure */
rtp->ssrc = ast_random();
}
}
+ ast_rtp_instance_set_data(instance, rtp);
+
+#ifdef USE_PJPROJECT
pj_thread_register_check();
pj_stun_config_init(&stun_config, &cachingpool.factory, 0, ioqueue, timerheap);
generate_random_string(rtp->local_passwd, sizeof(rtp->local_passwd));
passwd = pj_str(rtp->local_passwd);
- ast_rtp_instance_set_data(instance, rtp);
-
/* Create an ICE session for ICE negotiation */
if (icesupport && pj_ice_sess_create(&stun_config, NULL, PJ_ICE_SESS_ROLE_UNKNOWN, 2, &ast_rtp_ice_sess_cb, &ufrag, &passwd, &rtp->ice) == PJ_SUCCESS) {
/* Make this available for the callbacks */
/* Add all of the available candidates to the ICE session */
rtp_add_candidates_to_ice(instance, rtp, addr, x, COMPONENT_RTP, TRANSPORT_SOCKET_RTP, &ast_rtp_turn_rtp_sock_cb, &rtp->turn_rtp);
}
+#endif
/* Record any information we may need */
rtp->sched = sched;
ast_free(rtp->red);
}
+#ifdef USE_PJPROJECT
pj_thread_register_check();
/* Destroy the ICE session if being used */
ao2_ref(rtp->remote_candidates, -1);
}
+ /* Destroy synchronization items */
+ ast_mutex_destroy(&rtp->lock);
+ ast_cond_destroy(&rtp->cond);
+#endif
+
#ifdef HAVE_OPENSSL_SRTP
/* Destroy the SSL context if present */
if (rtp->ssl_ctx) {
}
#endif
- /* Destroy synchronization items */
- ast_mutex_destroy(&rtp->lock);
- ast_cond_destroy(&rtp->cond);
-
/* Finally destroy ourselves */
ast_free(rtp);
ast_sockaddr_stringify(&remote_address),
strerror(errno));
}
+#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+#endif
if (rtp_debug_test_addr(&remote_address)) {
ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
ast_sockaddr_stringify(&remote_address),
strerror(errno));
}
+#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+#endif
if (rtp_debug_test_addr(&remote_address)) {
ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
strerror(errno));
}
+#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+#endif
if (rtp_debug_test_addr(&remote_address)) {
ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
rtp->rtcp->rr_count++;
+#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTCP, &remote_address);
+#endif
if (rtcp_debug_test_addr(&remote_address)) {
ast_verbose("\n* Sending RTCP RR to %s%s\n"
rtp->rtcp->lastsrtxcount = rtp->txcount;
+#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTCP, &remote_address);
+#endif
if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
ast_verbose("* Sent RTCP SR to %s%s\n", ast_sockaddr_stringify(&remote_address), ice ? " (via ICE)" : "");
}
}
+#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+#endif
if (rtp_debug_test_addr(&remote_address)) {
ast_verbose("Sent RTP packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
return 0;
}
+#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+#endif
if (rtp_debug_test_addr(&remote_address)) {
ast_verbose("Sent RTP P2P packet to %s%s (type %-2.2d, len %-6.6u)\n",
ast_debug(1, "Setup RTCP on RTP instance '%p'\n", instance);
rtp->rtcp->schedid = -1;
+#ifdef USE_PJPROJECT
if (rtp->ice) {
rtp_add_candidates_to_ice(instance, rtp, &rtp->rtcp->us, ast_sockaddr_port(&rtp->rtcp->us), COMPONENT_RTCP, TRANSPORT_SOCKET_RTCP,
&ast_rtp_turn_rtcp_sock_cb, &rtp->turn_rtcp);
}
+#endif
return;
} else {
return res;
}
+#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+#endif
if (rtp_debug_test_addr(&remote_address)) {
ast_verbose("Sent Comfort Noise RTP packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
*/
icesupport = DEFAULT_ICESUPPORT;
- turnport = DEFAULT_TURN_PORT;
memset(&stunaddr, 0, sizeof(stunaddr));
+#ifdef USE_PJPROJECT
+ turnport = DEFAULT_TURN_PORT;
turnaddr = pj_str(NULL);
turnusername = pj_str(NULL);
turnpassword = pj_str(NULL);
+#endif
if (cfg) {
if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
ast_log(LOG_WARNING, "Invalid STUN server address: %s\n", s);
}
}
+#ifdef USE_PJPROJECT
if ((s = ast_variable_retrieve(cfg, "general", "turnaddr"))) {
struct sockaddr_in addr;
addr.sin_port = htons(DEFAULT_TURN_PORT);
if ((s = ast_variable_retrieve(cfg, "general", "turnpassword"))) {
pj_strdup2(pool, &turnpassword, s);
}
+#endif
ast_config_destroy(cfg);
}
if (rtpstart >= rtpend) {
static int load_module(void)
{
+#ifdef USE_PJPROJECT
pj_lock_t *lock;
pj_log_set_level(0);
pj_shutdown();
return AST_MODULE_LOAD_DECLINE;
}
+#endif
if (ast_rtp_engine_register(&asterisk_rtp_engine)) {
+#ifdef USE_PJPROJECT
worker_terminate = 1;
pj_thread_join(thread);
pj_thread_destroy(thread);
pj_caching_pool_destroy(&cachingpool);
pj_shutdown();
+#endif
return AST_MODULE_LOAD_DECLINE;
}
if (ast_cli_register_multiple(cli_rtp, ARRAY_LEN(cli_rtp))) {
+#ifdef USE_PJPROJECT
worker_terminate = 1;
pj_thread_join(thread);
pj_thread_destroy(thread);
ast_rtp_engine_unregister(&asterisk_rtp_engine);
pj_caching_pool_destroy(&cachingpool);
pj_shutdown();
+#endif
return AST_MODULE_LOAD_DECLINE;
}
ast_rtp_engine_unregister(&asterisk_rtp_engine);
ast_cli_unregister_multiple(cli_rtp, ARRAY_LEN(cli_rtp));
+#ifdef USE_PJPROJECT
worker_terminate = 1;
pj_thread_register_check();
pj_caching_pool_destroy(&cachingpool);
pj_shutdown();
+#endif
return 0;
}