summaryrefslogtreecommitdiff
path: root/src/Erebos/ICE
diff options
context:
space:
mode:
Diffstat (limited to 'src/Erebos/ICE')
-rw-r--r--src/Erebos/ICE/pjproject.c146
-rw-r--r--src/Erebos/ICE/pjproject.h16
2 files changed, 113 insertions, 49 deletions
diff --git a/src/Erebos/ICE/pjproject.c b/src/Erebos/ICE/pjproject.c
index d3037bf..8d91eac 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));
}
@@ -71,7 +78,7 @@ static void cb_on_ice_complete(pj_ice_strans * strans,
{
if (status != PJ_SUCCESS) {
ice_perror("cb_on_ice_complete", status);
- ice_destroy(strans);
+ erebos_ice_destroy(strans);
return;
}
@@ -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 * erebos_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:
+ erebos_ice_cfg_free( ecfg );
+ return NULL;
+}
+
+void erebos_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 erebos_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 * erebos_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);
@@ -191,7 +249,7 @@ pj_ice_strans * ice_create(pj_ice_sess_role role, HsStablePtr sptr, HsStablePtr
return res;
}
-void ice_destroy(pj_ice_strans * strans)
+void erebos_ice_destroy(pj_ice_strans * strans)
{
struct user_data * udata = pj_ice_strans_get_user_data(strans);
if (udata->sptr)
@@ -206,7 +264,7 @@ void ice_destroy(pj_ice_strans * strans)
pj_ice_strans_destroy(strans);
}
-ssize_t ice_encode_session(pj_ice_strans * strans, char * ufrag, char * pass,
+ssize_t erebos_ice_encode_session(pj_ice_strans * strans, char * ufrag, char * pass,
char * def, char * candidates[], size_t maxlen, size_t maxcand)
{
int n;
@@ -260,7 +318,7 @@ ssize_t ice_encode_session(pj_ice_strans * strans, char * ufrag, char * pass,
return cand_cnt;
}
-void ice_connect(pj_ice_strans * strans, HsStablePtr cb,
+void erebos_ice_connect(pj_ice_strans * strans, HsStablePtr cb,
const char * ufrag, const char * pass,
const char * defcand, const char * tcandidates[], size_t ncand)
{
@@ -351,14 +409,14 @@ void ice_connect(pj_ice_strans * strans, HsStablePtr cb,
}
}
-void ice_send(pj_ice_strans * strans, const char * data, size_t len)
+void erebos_ice_send(pj_ice_strans * strans, const char * data, size_t len)
{
if (!pj_ice_strans_sess_is_complete(strans)) {
fprintf(stderr, "ICE: negotiation has not been started or is in progress\n");
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);
diff --git a/src/Erebos/ICE/pjproject.h b/src/Erebos/ICE/pjproject.h
index e230e75..7a1b96d 100644
--- a/src/Erebos/ICE/pjproject.h
+++ b/src/Erebos/ICE/pjproject.h
@@ -3,12 +3,18 @@
#include <pjnath.h>
#include <HsFFI.h>
-pj_ice_strans * ice_create(pj_ice_sess_role role, HsStablePtr sptr, HsStablePtr cb);
-void ice_destroy(pj_ice_strans * strans);
+struct erebos_ice_cfg * erebos_ice_cfg_create( const char * stun_server, uint16_t stun_port,
+ const char * turn_server, uint16_t turn_port );
+void erebos_ice_cfg_free( struct erebos_ice_cfg * cfg );
+void erebos_ice_cfg_stop_thread( struct erebos_ice_cfg * cfg );
-ssize_t ice_encode_session(pj_ice_strans *, char * ufrag, char * pass,
+pj_ice_strans * erebos_ice_create( const struct erebos_ice_cfg *, pj_ice_sess_role role,
+ HsStablePtr sptr, HsStablePtr cb );
+void erebos_ice_destroy(pj_ice_strans * strans);
+
+ssize_t erebos_ice_encode_session(pj_ice_strans *, char * ufrag, char * pass,
char * def, char * candidates[], size_t maxlen, size_t maxcand);
-void ice_connect(pj_ice_strans * strans, HsStablePtr cb,
+void erebos_ice_connect(pj_ice_strans * strans, HsStablePtr cb,
const char * ufrag, const char * pass,
const char * defcand, const char * candidates[], size_t ncand);
-void ice_send(pj_ice_strans *, const char * data, size_t len);
+void erebos_ice_send(pj_ice_strans *, const char * data, size_t len);