summaryrefslogtreecommitdiff
path: root/src/Erebos/ICE/pjproject.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Erebos/ICE/pjproject.c')
-rw-r--r--src/Erebos/ICE/pjproject.c136
1 files changed, 97 insertions, 39 deletions
diff --git a/src/Erebos/ICE/pjproject.c b/src/Erebos/ICE/pjproject.c
index d3037bf..e9446fe 100644
--- a/src/Erebos/ICE/pjproject.c
+++ b/src/Erebos/ICE/pjproject.c
@@ -1,6 +1,7 @@
#include "pjproject.h"
#include "Erebos/ICE_stub.h"
+#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -12,10 +13,16 @@ static struct
{
pj_caching_pool cp;
pj_pool_t * pool;
- pj_ice_strans_cfg cfg;
pj_sockaddr def_addr;
} ice;
+struct erebos_ice_cfg
+{
+ pj_ice_strans_cfg cfg;
+ pj_thread_t * thread;
+ atomic_bool exit;
+};
+
struct user_data
{
pj_ice_sess_role role;
@@ -31,17 +38,17 @@ static void ice_perror(const char * msg, pj_status_t status)
fprintf(stderr, "ICE: %s: %s\n", msg, err);
}
-static int ice_worker_thread(void * unused)
+static int ice_worker_thread( void * vcfg )
{
- PJ_UNUSED_ARG(unused);
+ struct erebos_ice_cfg * ecfg = (struct erebos_ice_cfg *)( vcfg );
- while (true) {
+ while( ! ecfg->exit ){
pj_time_val max_timeout = { 0, 0 };
pj_time_val timeout = { 0, 0 };
max_timeout.msec = 500;
- pj_timer_heap_poll(ice.cfg.stun_cfg.timer_heap, &timeout);
+ pj_timer_heap_poll( ecfg->cfg.stun_cfg.timer_heap, &timeout );
pj_assert(timeout.sec >= 0 && timeout.msec >= 0);
if (timeout.msec >= 1000)
@@ -50,7 +57,7 @@ static int ice_worker_thread(void * unused)
if (PJ_TIME_VAL_GT(timeout, max_timeout))
timeout = max_timeout;
- int c = pj_ioqueue_poll(ice.cfg.stun_cfg.ioqueue, &timeout);
+ int c = pj_ioqueue_poll( ecfg->cfg.stun_cfg.ioqueue, &timeout );
if (c < 0)
pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout));
}
@@ -105,7 +112,7 @@ static void ice_init(void)
if (done) {
pthread_mutex_unlock(&mutex);
- goto exit;
+ return;
}
pj_log_set_level(1);
@@ -125,48 +132,99 @@ static void ice_init(void)
pj_caching_pool_init(&ice.cp, NULL, 0);
- pj_ice_strans_cfg_default(&ice.cfg);
- ice.cfg.stun_cfg.pf = &ice.cp.factory;
-
ice.pool = pj_pool_create(&ice.cp.factory, "ice", 512, 512, NULL);
- if (pj_timer_heap_create(ice.pool, 100,
- &ice.cfg.stun_cfg.timer_heap) != PJ_SUCCESS) {
- fprintf(stderr, "pj_timer_heap_create failed\n");
- goto exit;
+exit:
+ done = true;
+ pthread_mutex_unlock(&mutex);
+}
+
+struct erebos_ice_cfg * ice_cfg_create( const char * stun_server, uint16_t stun_port,
+ const char * turn_server, uint16_t turn_port )
+{
+ ice_init();
+
+ struct erebos_ice_cfg * ecfg = malloc( sizeof(struct erebos_ice_cfg) );
+ pj_ice_strans_cfg_default( &ecfg->cfg );
+ ecfg->exit = false;
+ ecfg->thread = NULL;
+
+ ecfg->cfg.stun_cfg.pf = &ice.cp.factory;
+ if( pj_timer_heap_create( ice.pool, 100,
+ &ecfg->cfg.stun_cfg.timer_heap ) != PJ_SUCCESS ){
+ fprintf( stderr, "pj_timer_heap_create failed\n" );
+ goto fail;
}
- if (pj_ioqueue_create(ice.pool, 16, &ice.cfg.stun_cfg.ioqueue) != PJ_SUCCESS) {
- fprintf(stderr, "pj_ioqueue_create failed\n");
- goto exit;
+ if( pj_ioqueue_create( ice.pool, 16, &ecfg->cfg.stun_cfg.ioqueue ) != PJ_SUCCESS ){
+ fprintf( stderr, "pj_ioqueue_create failed\n" );
+ goto fail;
}
- pj_thread_t * thread;
- if (pj_thread_create(ice.pool, "ice", &ice_worker_thread,
- NULL, 0, 0, &thread) != PJ_SUCCESS) {
- fprintf(stderr, "pj_thread_create failed\n");
- goto exit;
+ if( pj_thread_create( ice.pool, NULL, &ice_worker_thread,
+ ecfg, 0, 0, &ecfg->thread ) != PJ_SUCCESS ){
+ fprintf( stderr, "pj_thread_create failed\n" );
+ goto fail;
}
- ice.cfg.af = pj_AF_INET();
- ice.cfg.opt.aggressive = PJ_TRUE;
+ ecfg->cfg.af = pj_AF_INET();
+ ecfg->cfg.opt.aggressive = PJ_TRUE;
- ice.cfg.stun.server.ptr = "discovery1.erebosprotocol.net";
- ice.cfg.stun.server.slen = strlen(ice.cfg.stun.server.ptr);
- ice.cfg.stun.port = 29670;
+ if( stun_server ){
+ ecfg->cfg.stun.server.ptr = malloc( strlen( stun_server ));
+ pj_strcpy2( &ecfg->cfg.stun.server, stun_server );
+ if( stun_port )
+ ecfg->cfg.stun.port = stun_port;
+ }
- ice.cfg.turn.server = ice.cfg.stun.server;
- ice.cfg.turn.port = ice.cfg.stun.port;
- ice.cfg.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
- ice.cfg.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
- ice.cfg.turn.conn_type = PJ_TURN_TP_UDP;
+ if( turn_server ){
+ ecfg->cfg.turn.server.ptr = malloc( strlen( turn_server ));
+ pj_strcpy2( &ecfg->cfg.turn.server, turn_server );
+ if( turn_port )
+ ecfg->cfg.turn.port = turn_port;
+ ecfg->cfg.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
+ ecfg->cfg.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
+ ecfg->cfg.turn.conn_type = PJ_TURN_TP_UDP;
+ }
-exit:
- done = true;
- pthread_mutex_unlock(&mutex);
+ return ecfg;
+fail:
+ ice_cfg_free( ecfg );
+ return NULL;
+}
+
+void ice_cfg_free( struct erebos_ice_cfg * ecfg )
+{
+ if( ! ecfg )
+ return;
+
+ ecfg->exit = true;
+ pj_thread_join( ecfg->thread );
+
+ if( ecfg->cfg.turn.server.ptr )
+ free( ecfg->cfg.turn.server.ptr );
+
+ if( ecfg->cfg.stun.server.ptr )
+ free( ecfg->cfg.stun.server.ptr );
+
+ if( ecfg->cfg.stun_cfg.ioqueue )
+ pj_ioqueue_destroy( ecfg->cfg.stun_cfg.ioqueue );
+
+ if( ecfg->cfg.stun_cfg.timer_heap )
+ pj_timer_heap_destroy( ecfg->cfg.stun_cfg.timer_heap );
+
+ free( ecfg );
+}
+
+void ice_cfg_stop_thread( struct erebos_ice_cfg * ecfg )
+{
+ if( ! ecfg )
+ return;
+ ecfg->exit = true;
}
-pj_ice_strans * ice_create(pj_ice_sess_role role, HsStablePtr sptr, HsStablePtr cb)
+pj_ice_strans * ice_create( const struct erebos_ice_cfg * ecfg, pj_ice_sess_role role,
+ HsStablePtr sptr, HsStablePtr cb )
{
ice_init();
@@ -182,8 +240,8 @@ pj_ice_strans * ice_create(pj_ice_sess_role role, HsStablePtr sptr, HsStablePtr
.on_ice_complete = cb_on_ice_complete,
};
- pj_status_t status = pj_ice_strans_create(NULL, &ice.cfg, 1,
- udata, &icecb, &res);
+ pj_status_t status = pj_ice_strans_create( NULL, &ecfg->cfg, 1,
+ udata, &icecb, &res );
if (status != PJ_SUCCESS)
ice_perror("error creating ice", status);
@@ -358,7 +416,7 @@ void ice_send(pj_ice_strans * strans, const char * data, size_t len)
return;
}
- pj_status_t status = pj_ice_strans_sendto(strans, 1, data, len,
+ pj_status_t status = pj_ice_strans_sendto2(strans, 1, data, len,
&ice.def_addr, pj_sockaddr_get_len(&ice.def_addr));
if (status != PJ_SUCCESS && status != PJ_EPENDING)
ice_perror("error sending data", status);