summaryrefslogtreecommitdiff
path: root/pjnath
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-03-21 13:24:02 +0000
committerBenny Prijono <bennylp@teluu.com>2007-03-21 13:24:02 +0000
commit33fe5e64b9b0482a127d8137aae43e5e29e1adc8 (patch)
tree196893dfe87166ec25b87cca72eeed1ff01c3284 /pjnath
parent191eab5e65e06a3ca03bf81e05aa8522253f9267 (diff)
ICE complete, ready for testing
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1092 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjnath')
-rw-r--r--pjnath/include/pjnath/errno.h15
-rw-r--r--pjnath/include/pjnath/ice.h56
-rw-r--r--pjnath/src/pjnath/ice.c445
3 files changed, 235 insertions, 281 deletions
diff --git a/pjnath/include/pjnath/errno.h b/pjnath/include/pjnath/errno.h
index 9e1881f1..0a4d5888 100644
--- a/pjnath/include/pjnath/errno.h
+++ b/pjnath/include/pjnath/errno.h
@@ -143,6 +143,21 @@
* No ICE checklist is formed.
*/
#define PJ_EICENOCHECKLIST -1
+/**
+ * @hideinitializer
+ * No suitable default ICE candidate for the component.
+ */
+#define PJ_EICENOCAND -1
+/**
+ * @hideinitializer
+ * Invalid ICE component ID
+ */
+#define PJ_EICEINCOMPID -1
+/**
+ * @hideinitializer
+ * ICE check is in progress
+ */
+#define PJ_EICEINPROGRESS -1
diff --git a/pjnath/include/pjnath/ice.h b/pjnath/include/pjnath/ice.h
index 3b3325d3..568a2825 100644
--- a/pjnath/include/pjnath/ice.h
+++ b/pjnath/include/pjnath/ice.h
@@ -25,7 +25,6 @@
*/
#include <pjnath/types.h>
#include <pjnath/stun_session.h>
-#include <pjlib-util/resolver.h>
#include <pj/sock.h>
#include <pj/timer.h>
@@ -47,8 +46,8 @@ PJ_BEGIN_DECL
typedef enum pj_ice_cand_type
{
PJ_ICE_CAND_TYPE_HOST,
- PJ_ICE_CAND_TYPE_MAPPED,
- PJ_ICE_CAND_TYPE_PEER_MAPPED,
+ PJ_ICE_CAND_TYPE_SRFLX,
+ PJ_ICE_CAND_TYPE_PRFLX,
PJ_ICE_CAND_TYPE_RELAYED
} pj_ice_cand_type;
@@ -58,8 +57,8 @@ typedef enum pj_ice_cand_type
enum pj_ice_type_pref
{
PJ_ICE_HOST_PREF = 126,
- PJ_ICE_MAPPED_PREF = 100,
- PJ_ICE_PEER_MAPPED_PREF = 110,
+ PJ_ICE_SRFLX_PREF = 100,
+ PJ_ICE_PRFLX_PREF = 110,
PJ_ICE_RELAYED_PREF = 0
};
@@ -77,9 +76,9 @@ typedef struct pj_ice pj_ice;
typedef struct pj_ice_comp
{
unsigned comp_id;
- pj_sock_t sock;
pj_stun_session *stun_sess;
pj_sockaddr local_addr;
+ int nominated_check_id;
} pj_ice_comp;
@@ -140,10 +139,15 @@ typedef struct pj_ice_checklist
*/
typedef struct pj_ice_cb
{
- pj_status_t (*on_send_pkt)(pj_ice *ice,
- const void *pkt, pj_size_t size,
- const pj_sockaddr_t *dst_addr,
- unsigned addr_len);
+ void (*on_ice_complete)(pj_ice *ice, pj_status_t status);
+ pj_status_t (*on_tx_pkt)(pj_ice *ice, unsigned comp_id,
+ const void *pkt, pj_size_t size,
+ const pj_sockaddr_t *dst_addr,
+ unsigned dst_addr_len);
+ pj_status_t (*on_rx_data)(pj_ice *ice, unsigned comp_id,
+ void *pkt, pj_size_t size,
+ const pj_sockaddr_t *src_addr,
+ unsigned src_addr_len);
} pj_ice_cb;
@@ -165,6 +169,8 @@ struct pj_ice
int af;
int sock_type;
pj_ice_role role;
+ pj_bool_t is_complete;
+ pj_status_t ice_status;
pj_ice_cb cb;
pj_stun_config stun_cfg;
@@ -193,12 +199,6 @@ struct pj_ice
/* Valid list */
unsigned valid_cnt;
unsigned valid_list[PJ_ICE_MAX_CHECKS];
-
- /* STUN servers */
- pj_dns_resolver *resv;
- pj_dns_async_query *resv_q;
- pj_bool_t relay_enabled;
- pj_sockaddr stun_srv;
};
@@ -210,14 +210,6 @@ PJ_DECL(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
int sock_type,
pj_ice **p_ice);
PJ_DECL(pj_status_t) pj_ice_destroy(pj_ice *ice);
-PJ_DECL(pj_status_t) pj_ice_set_srv(pj_ice *ice,
- pj_bool_t enable_relay,
- pj_dns_resolver *resolver,
- const pj_str_t *domain);
-PJ_DECL(pj_status_t) pj_ice_set_srv_addr(pj_ice *ice,
- pj_bool_t enable_relay,
- const pj_sockaddr_t *srv_addr,
- unsigned addr_len);
PJ_DECL(pj_status_t) pj_ice_add_comp(pj_ice *ice,
unsigned comp_id,
const pj_sockaddr_t *local_addr,
@@ -230,9 +222,6 @@ PJ_DECL(pj_status_t) pj_ice_set_credentials(pj_ice *ice,
const pj_str_t *local_pass,
const pj_str_t *remote_ufrag,
const pj_str_t *remote_pass);
-PJ_DECL(pj_status_t) pj_ice_start_gather(pj_ice *ice,
- unsigned flags);
-
PJ_DECL(pj_status_t) pj_ice_add_cand(pj_ice *ice,
unsigned comp_id,
pj_ice_cand_type type,
@@ -258,9 +247,20 @@ PJ_DECL(pj_status_t) pj_ice_get_cand(pj_ice *ice,
PJ_DECL(pj_status_t) pj_ice_create_check_list(pj_ice *ice,
unsigned rem_cand_cnt,
const pj_ice_cand rem_cand[]);
-
PJ_DECL(pj_status_t) pj_ice_start_check(pj_ice *ice);
+PJ_DECL(pj_status_t) pj_ice_send_data(pj_ice *ice,
+ unsigned comp_id,
+ const void *data,
+ pj_size_t data_len);
+PJ_DECL(pj_status_t) pj_ice_on_rx_pkt(pj_ice *ice,
+ unsigned comp_id,
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_sockaddr_t *src_addr,
+ int src_addr_len);
+
+
/**
* @}
diff --git a/pjnath/src/pjnath/ice.c b/pjnath/src/pjnath/ice.c
index 334262ea..e5d8fb6f 100644
--- a/pjnath/src/pjnath/ice.c
+++ b/pjnath/src/pjnath/ice.c
@@ -59,8 +59,26 @@ const pj_str_t mapped_foundation = {"srfx", 4};
const pj_str_t relayed_foundation = {"rlyd", 4};
const pj_str_t peer_mapped_foundation = {"peer", 4};
-#define CHECK_NAME_LEN 128
-#define LOG(expr) PJ_LOG(4,expr)
+#define CHECK_NAME_LEN 128
+#define LOG(expr) PJ_LOG(4,expr)
+#define GET_LCAND_ID(cand) (cand - ice->lcand)
+#define GET_CHECK_ID(chk) (chk - ice->clist.checks)
+
+
+typedef struct stun_data
+{
+ pj_ice *ice;
+ unsigned comp_id;
+ pj_ice_comp *comp;
+} stun_data;
+
+typedef struct timer_data
+{
+ pj_ice *ice;
+ pj_ice_checklist *clist;
+} timer_data;
+
+
static void destroy_ice(pj_ice *ice,
pj_status_t reason);
@@ -124,6 +142,7 @@ PJ_DEF(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
{
pj_pool_t *pool;
pj_ice *ice;
+ unsigned i;
pj_status_t status;
PJ_ASSERT_RETURN(stun_cfg && cb && p_ice, PJ_EINVAL);
@@ -153,11 +172,14 @@ PJ_DEF(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
pj_memcpy(&ice->cb, cb, sizeof(*cb));
pj_memcpy(&ice->stun_cfg, stun_cfg, sizeof(*stun_cfg));
+ for (i=0; i<PJ_ICE_MAX_COMP; ++i) {
+ ice->comp[i].nominated_check_id = -1;
+ }
/* Done */
*p_ice = ice;
- LOG((ice->obj_name, "ICE session created"));
+ LOG((ice->obj_name, "ICE media stream created"));
return PJ_SUCCESS;
}
@@ -186,11 +208,6 @@ static void destroy_ice(pj_ice *ice,
ice->clist.timer.id = PJ_FALSE;
}
- if (ice->resv_q) {
- pj_dns_resolver_cancel_query(ice->resv_q, PJ_FALSE);
- ice->resv_q = NULL;
- }
-
if (ice->mutex) {
pj_mutex_destroy(ice->mutex);
ice->mutex = NULL;
@@ -211,183 +228,39 @@ PJ_DEF(pj_status_t) pj_ice_destroy(pj_ice *ice)
}
-static void resolver_cb(void *user_data,
- pj_status_t status,
- pj_dns_parsed_packet *response)
-{
- pj_assert(!"Not implemented yet!");
- PJ_UNUSED_ARG(user_data);
- PJ_UNUSED_ARG(status);
- PJ_UNUSED_ARG(response);
-}
-
-PJ_DEF(pj_status_t) pj_ice_set_srv(pj_ice *ice,
- pj_bool_t enable_relay,
- pj_dns_resolver *resolver,
- const pj_str_t *domain)
+static pj_ice_comp *find_comp(const pj_ice *ice, unsigned comp_id)
{
- char namebuf[128];
- char *tp_name;
- pj_str_t name;
- pj_status_t status;
-
-
- /* Not implemented yet! */
- return PJ_ENOTSUP;
-
-
- PJ_ASSERT_RETURN(ice && resolver && domain, PJ_EINVAL);
-
- /* Must not have a running resolver. This is because we couldn't
- * safely cancel the query (there is a race condition situation
- * between the callback acquiring the mutex and this function
- * acquiring the mutex)
- */
- PJ_ASSERT_RETURN(ice->resv_q==NULL, PJ_EBUSY);
-
- pj_mutex_lock(ice->mutex);
-
- /* Reset resolver and server addresses */
- ice->relay_enabled = enable_relay;
- ice->resv = resolver;
- pj_bzero(&ice->stun_srv, sizeof(ice->stun_srv));
-
- /* Build SRV record name */
- if (ice->sock_type == PJ_SOCK_DGRAM) {
- tp_name = "_udp";
- } else if (ice->sock_type == PJ_SOCK_STREAM) {
- tp_name = "_tcp";
- } else {
- pj_assert(!"Invalid sock_type");
- pj_mutex_unlock(ice->mutex);
- return PJ_EBUG;
- }
-
- if (enable_relay) {
- name.ptr = namebuf;
- name.slen = pj_ansi_snprintf(namebuf, sizeof(namebuf),
- "_stun-relay.%s.%.*s",
- tp_name,
- (int)domain->slen,
- domain->ptr);
- } else {
- name.ptr = namebuf;
- name.slen = pj_ansi_snprintf(namebuf, sizeof(namebuf),
- "_stun.%s.%.*s",
- tp_name,
- (int)domain->slen,
- domain->ptr);
- }
-
- if (name.slen < 1 || name.slen >= sizeof(namebuf)) {
- pj_mutex_unlock(ice->mutex);
- return PJ_ENAMETOOLONG;
- }
-
- /* Start DNS query */
- status = pj_dns_resolver_start_query(ice->resv, &name,
- PJ_DNS_TYPE_SRV, 0,
- &resolver_cb,
- ice, &ice->resv_q);
- if (status != PJ_SUCCESS) {
- pj_mutex_unlock(ice->mutex);
- return status;
+ unsigned i;
+ for (i=0; i<ice->comp_cnt; ++i) {
+ if (ice->comp[i].comp_id == comp_id)
+ return (pj_ice_comp*) &ice->comp[i];
}
- pj_mutex_unlock(ice->mutex);
-
- return PJ_SUCCESS;
+ return NULL;
}
-PJ_DEF(pj_status_t) pj_ice_set_srv_addr(pj_ice *ice,
- pj_bool_t enable_relay,
- const pj_sockaddr_t *srv_addr,
- unsigned addr_len)
-{
- PJ_ASSERT_RETURN(ice && srv_addr, PJ_EINVAL);
- /* Must not have a running resolver. This is because we couldn't
- * safely cancel the query (there is a race condition situation
- * between the callback acquiring the mutex and this function
- * acquiring the mutex)
- */
- PJ_ASSERT_RETURN(ice->resv_q==NULL, PJ_EBUSY);
-
- pj_mutex_lock(ice->mutex);
-
- ice->relay_enabled = enable_relay;
- pj_memcpy(&ice->stun_srv, srv_addr, addr_len);
-
- pj_mutex_unlock(ice->mutex);
-
- return PJ_SUCCESS;
-
-}
-
-
-
PJ_DEF(pj_status_t) pj_ice_add_comp(pj_ice *ice,
unsigned comp_id,
const pj_sockaddr_t *local_addr,
unsigned addr_len)
{
- pj_status_t status;
- pj_sock_t sock;
-
- PJ_ASSERT_RETURN(ice && local_addr && addr_len, PJ_EINVAL);
-
- status = pj_sock_socket(ice->af, ice->sock_type, 0, &sock);
- if (status != PJ_SUCCESS)
- return status;
-
- status = pj_sock_bind(sock, local_addr, addr_len);
- if (status != PJ_SUCCESS)
- return status;
-
- status = pj_ice_add_sock_comp(ice, comp_id, sock);
- if (status != PJ_SUCCESS) {
- pj_sock_close(sock);
- return status;
- }
-
- return PJ_SUCCESS;
-}
-
-typedef struct stun_data
-{
- pj_ice *ice;
- unsigned comp_id;
- pj_ice_comp *comp;
-} stun_data;
-
-
-PJ_DEF(pj_status_t) pj_ice_add_sock_comp( pj_ice *ice,
- unsigned comp_id,
- pj_sock_t sock)
-{
pj_stun_session_cb sess_cb;
pj_ice_comp *comp;
pj_stun_auth_cred auth_cred;
stun_data *sd;
- int addr_len;
pj_status_t status;
- PJ_ASSERT_RETURN(ice && sock != PJ_INVALID_SOCKET, PJ_EINVAL);
+ PJ_ASSERT_RETURN(ice && local_addr && addr_len, PJ_EINVAL);
PJ_ASSERT_RETURN(ice->comp_cnt < PJ_ARRAY_SIZE(ice->comp), PJ_ETOOMANY);
+ PJ_ASSERT_RETURN(find_comp(ice, comp_id) == NULL, PJ_EEXISTS);
pj_mutex_lock(ice->mutex);
comp = &ice->comp[ice->comp_cnt];
comp->comp_id = comp_id;
- comp->sock = sock;
-
- addr_len = sizeof(comp->local_addr);
- status = pj_sock_getsockname(sock, &comp->local_addr, &addr_len);
- if (status != PJ_SUCCESS) {
- pj_mutex_unlock(ice->mutex);
- return status;
- }
-
+ comp->nominated_check_id = -1;
+ pj_memcpy(&comp->local_addr, local_addr, addr_len);
/* Init STUN callbacks */
pj_bzero(&sess_cb, sizeof(sess_cb));
@@ -429,7 +302,6 @@ PJ_DEF(pj_status_t) pj_ice_add_sock_comp( pj_ice *ice,
return PJ_SUCCESS;
}
-
static pj_status_t stun_auth_get_auth(void *user_data,
pj_pool_t *pool,
pj_str_t *realm,
@@ -576,74 +448,6 @@ PJ_DEF(pj_status_t) pj_ice_set_credentials(pj_ice *ice,
}
-static pj_status_t gather_host_cands(pj_ice *ice)
-{
- unsigned i;
- pj_status_t status;
-
- for (i=0; i<ice->comp_cnt; ++i) {
- pj_ice_comp *comp = &ice->comp[i];
- pj_sockaddr addr;
- int addr_len;
-
- addr_len = sizeof(addr);
- status = pj_sock_getsockname(comp->sock, &addr, &addr_len);
- if (status != PJ_SUCCESS)
- return status;
-
- if (addr.ipv4.sin_addr.s_addr == 0) {
- status = pj_gethostip(&addr.ipv4.sin_addr);
- if (status != PJ_SUCCESS)
- return status;
- }
-
- status = pj_ice_add_cand(ice, i, PJ_ICE_CAND_TYPE_HOST, 65535,
- &host_foundation, &addr, &addr, NULL,
- sizeof(pj_sockaddr_in), NULL);
- if (status != PJ_SUCCESS)
- return status;
- }
-
- return PJ_SUCCESS;
-}
-
-/* Eliminate redundant candidates. */
-static void eliminate_redundant_cand(unsigned *cnt,
- pj_ice_cand cand[])
-{
-
- /* A candidate is redundant if its transport address equals another
- * candidate, and its base equals the base of that other candidate.
- * Note that two candidates can have the same transport address yet
- * have different bases, and these would not be considered redundant.
- */
- PJ_TODO(ELIMINATE_REDUNDANT_CANDIDATES);
- PJ_UNUSED_ARG(cnt);
- PJ_UNUSED_ARG(cand);
-}
-
-
-PJ_DEF(pj_status_t) pj_ice_start_gather(pj_ice *ice,
- unsigned flags)
-{
- pj_status_t status;
-
- PJ_UNUSED_ARG(flags);
-
- /* Gather host candidate */
- status = gather_host_cands(ice);
- if (status != PJ_SUCCESS)
- return status;
-
- /* Eliminate redundant host candidates. */
- eliminate_redundant_cand(&ice->lcand_cnt, ice->lcand);
-
- PJ_TODO(GATHER_MAPPED_AND_RELAYED_CANDIDATES);
-
- return PJ_SUCCESS;
-}
-
-
static pj_uint32_t CALC_CAND_PRIO(pj_ice_cand_type type,
pj_uint32_t local_pref,
pj_uint32_t comp_id)
@@ -651,8 +455,8 @@ static pj_uint32_t CALC_CAND_PRIO(pj_ice_cand_type type,
static pj_uint32_t type_pref[] =
{
PJ_ICE_HOST_PREF,
- PJ_ICE_MAPPED_PREF,
- PJ_ICE_PEER_MAPPED_PREF,
+ PJ_ICE_SRFLX_PREF,
+ PJ_ICE_PRFLX_PREF,
PJ_ICE_RELAYED_PREF
};
@@ -757,24 +561,67 @@ PJ_DEF(pj_status_t) pj_ice_get_default_cand(pj_ice *ice,
unsigned comp_id,
int *cand_id)
{
+ unsigned i;
+
PJ_ASSERT_RETURN(ice && comp_id && cand_id, PJ_EINVAL);
+ *cand_id = -1;
+
pj_mutex_lock(ice->mutex);
/* First find in valid list if we have nominated pair */
+ for (i=0; i<ice->valid_cnt; ++i) {
+ pj_ice_cand *lcand;
+
+ lcand = ice->clist.checks[ice->valid_list[i]].lcand;
+ if (lcand->comp_id==comp_id) {
+ *cand_id = GET_LCAND_ID(lcand);
+ pj_mutex_unlock(ice->mutex);
+ return PJ_SUCCESS;
+ }
+ }
/* If there's no nominated pair, find relayed candidate */
+ for (i=0; i<ice->lcand_cnt; ++i) {
+ pj_ice_cand *lcand = &ice->lcand[i];
+ if (lcand->comp_id==comp_id &&
+ lcand->type == PJ_ICE_CAND_TYPE_RELAYED)
+ {
+ *cand_id = GET_LCAND_ID(lcand);
+ pj_mutex_unlock(ice->mutex);
+ return PJ_SUCCESS;
+ }
+ }
/* If there's no relayed candidate, find server reflexive candidate */
+ for (i=0; i<ice->lcand_cnt; ++i) {
+ pj_ice_cand *lcand = &ice->lcand[i];
+ if (lcand->comp_id==comp_id &&
+ lcand->type == PJ_ICE_CAND_TYPE_SRFLX)
+ {
+ *cand_id = GET_LCAND_ID(lcand);
+ pj_mutex_unlock(ice->mutex);
+ return PJ_SUCCESS;
+ }
+ }
/* Otherwise return host candidate */
+ for (i=0; i<ice->lcand_cnt; ++i) {
+ pj_ice_cand *lcand = &ice->lcand[i];
+ if (lcand->comp_id==comp_id &&
+ lcand->type == PJ_ICE_CAND_TYPE_HOST)
+ {
+ *cand_id = GET_LCAND_ID(lcand);
+ pj_mutex_unlock(ice->mutex);
+ return PJ_SUCCESS;
+ }
+ }
- pj_assert(!"Not implemented yet");
- PJ_TODO(IMPLEMENT_GET_DEFAULT_CAND);
-
+ /* Still no candidate is found! :( */
pj_mutex_unlock(ice->mutex);
- return PJ_SUCCESS;
+ pj_assert(!"Should have a candidate by now");
+ return PJ_EICENOCAND;
}
@@ -986,7 +833,7 @@ static void prune_checklist(pj_ice *ice, pj_ice_checklist *clist)
const pj_sockaddr *liaddr;
unsigned j;
- if (licand->type == PJ_ICE_CAND_TYPE_MAPPED)
+ if (licand->type == PJ_ICE_CAND_TYPE_SRFLX)
liaddr = &licand->base_addr;
else
liaddr = &licand->addr;
@@ -996,7 +843,7 @@ static void prune_checklist(pj_ice *ice, pj_ice_checklist *clist)
pj_ice_cand *rjcand = clist->checks[j].rcand;
const pj_sockaddr *ljaddr;
- if (ljcand->type == PJ_ICE_CAND_TYPE_MAPPED)
+ if (ljcand->type == PJ_ICE_CAND_TYPE_SRFLX)
ljaddr = &licand->base_addr;
else
ljaddr = &licand->addr;
@@ -1024,6 +871,14 @@ static void prune_checklist(pj_ice *ice, pj_ice_checklist *clist)
/* This function is called when ICE processing completes */
static void on_ice_complete(pj_ice *ice, pj_status_t status)
{
+ if (!ice->is_complete) {
+
+ ice->is_complete = PJ_TRUE;
+ ice->ice_status = status;
+
+ /* Call callback */
+ (*ice->cb.on_ice_complete)(ice, status);
+ }
}
@@ -1033,6 +888,8 @@ static pj_bool_t on_check_complete(pj_ice *ice,
{
unsigned i;
+ pj_assert(check->state >= PJ_ICE_CHECK_STATE_SUCCEEDED);
+
/* If there is at least one nominated pair in the valid list:
* - The agent MUST remove all Waiting and Frozen pairs in the check
* list for the same component as the nominated pairs for that
@@ -1042,7 +899,9 @@ static pj_bool_t on_check_complete(pj_ice *ice,
* retransmissions for its check if its pair priority is lower
* than the lowest priority nominated pair for that component
*/
- if (check->nominated) {
+ if (check->err_code==PJ_SUCCESS && check->nominated) {
+ pj_ice_comp *comp;
+
for (i=0; i<ice->clist.count; ++i) {
pj_ice_check *c = &ice->clist.checks[i];
if (c->lcand->comp_id == check->lcand->comp_id &&
@@ -1053,6 +912,17 @@ static pj_bool_t on_check_complete(pj_ice *ice,
PJ_ECANCELLED);
}
}
+
+ /* Update the nominated check for the component */
+ comp = find_comp(ice, check->lcand->comp_id);
+ if (comp->nominated_check_id < 0) {
+ comp->nominated_check_id = GET_CHECK_ID(check);
+ } else {
+ pj_ice_check *nom_check;
+ nom_check = &ice->clist.checks[comp->nominated_check_id];
+ if (nom_check->prio < check->prio)
+ comp->nominated_check_id = GET_CHECK_ID(check);
+ }
}
/* Once there is at least one nominated pair in the valid list for
@@ -1124,14 +994,6 @@ static pj_bool_t on_check_complete(pj_ice *ice,
-
-
-typedef struct timer_data
-{
- pj_ice *ice;
- pj_ice_checklist *clist;
-} timer_data;
-
PJ_DEF(pj_status_t) pj_ice_create_check_list(pj_ice *ice,
unsigned rcand_cnt,
const pj_ice_cand rcand[])
@@ -1261,7 +1123,7 @@ static pj_status_t perform_check(pj_ice *ice, pj_ice_checklist *clist,
tdata->user_data = (void*) rd;
/* Add PRIORITY */
- prio = CALC_CAND_PRIO(PJ_ICE_CAND_TYPE_PEER_MAPPED, 65535,
+ prio = CALC_CAND_PRIO(PJ_ICE_CAND_TYPE_PRFLX, 65535,
lcand->comp_id);
pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, PJ_STUN_ATTR_PRIORITY,
prio);
@@ -1422,8 +1284,10 @@ static pj_status_t on_stun_send_msg(pj_stun_session *sess,
const pj_sockaddr_t *dst_addr,
unsigned addr_len)
{
- pj_ice *ice = (pj_ice*) pj_stun_session_get_user_data(sess);
- return (*ice->cb.on_send_pkt)(ice, pkt, pkt_size, dst_addr, addr_len);
+ stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);
+ return (*sd->ice->cb.on_tx_pkt)(sd->ice, sd->comp_id,
+ pkt, pkt_size,
+ dst_addr, addr_len);
}
@@ -1499,7 +1363,7 @@ static void on_stun_request_complete(pj_stun_session *stun_sess,
/* Add new peer reflexive candidate */
status = pj_ice_add_cand(ice, lcand->comp_id,
- PJ_ICE_CAND_TYPE_PEER_MAPPED,
+ PJ_ICE_CAND_TYPE_PRFLX,
65535, &peer_mapped_foundation,
&xaddr->sockaddr, &lcand->base_addr, NULL,
sizeof(pj_sockaddr_in), &cand_id);
@@ -1678,7 +1542,7 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess,
if (i == ice->rcand_cnt) {
rcand = &ice->rcand[ice->rcand_cnt++];
rcand->comp_id = comp->comp_id;
- rcand->type = PJ_ICE_CAND_TYPE_PEER_MAPPED;
+ rcand->type = PJ_ICE_CAND_TYPE_PRFLX;
rcand->prio = ap->value;
pj_memcpy(&rcand->addr, src_addr, src_addr_len);
@@ -1823,3 +1687,78 @@ static pj_status_t on_stun_rx_indication(pj_stun_session *sess,
return PJ_ENOTSUP;
}
+
+PJ_DEF(pj_status_t) pj_ice_send_data( pj_ice *ice,
+ unsigned comp_id,
+ const void *data,
+ pj_size_t data_len)
+{
+ pj_status_t status = PJ_SUCCESS;
+ pj_ice_comp *comp;
+ pj_ice_check *check;
+
+ PJ_ASSERT_RETURN(ice, PJ_EINVAL);
+
+ pj_mutex_lock(ice->mutex);
+
+ comp = find_comp(ice, comp_id);
+ if (comp == NULL) {
+ status = PJ_EICEINCOMPID;
+ goto on_return;
+ }
+
+ if (comp->nominated_check_id == -1) {
+ status = PJ_EICEINPROGRESS;
+ goto on_return;
+ }
+
+ check = &ice->clist.checks[comp->nominated_check_id];
+
+ status = (*ice->cb.on_tx_pkt)(ice, comp_id, data, data_len,
+ &check->rcand->addr,
+ sizeof(pj_sockaddr_in));
+
+on_return:
+ pj_mutex_unlock(ice->mutex);
+ return status;
+}
+
+
+PJ_DEF(pj_status_t) pj_ice_on_rx_pkt( pj_ice *ice,
+ unsigned comp_id,
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_sockaddr_t *src_addr,
+ int src_addr_len)
+{
+ pj_status_t status = PJ_SUCCESS;
+ pj_ice_comp *comp;
+ pj_bool_t is_stun;
+
+ PJ_ASSERT_RETURN(ice, PJ_EINVAL);
+
+ pj_mutex_lock(ice->mutex);
+
+ comp = find_comp(ice, comp_id);
+ if (comp == NULL) {
+ status = PJ_EICEINCOMPID;
+ goto on_return;
+ }
+
+ is_stun = pj_stun_msg_check(pkt, pkt_size, PJ_STUN_IS_DATAGRAM);
+ if (is_stun) {
+ status = pj_stun_session_on_rx_pkt(comp->stun_sess, pkt, pkt_size,
+ PJ_STUN_IS_DATAGRAM,
+ NULL, src_addr, src_addr_len);
+ } else {
+ status = (*ice->cb.on_rx_data)(ice, comp_id, pkt, pkt_size,
+ src_addr, src_addr_len);
+ }
+
+
+on_return:
+ pj_mutex_unlock(ice->mutex);
+ return status;
+}
+
+