Commit fb68f79c authored by Ghislain MARY's avatar Ghislain MARY

Handle ICE candidate foundations.

parent cd7142ac
......@@ -49,16 +49,17 @@ typedef enum {
typedef struct _IceTransportAddress {
char ip[64];
int port;
// TODO: Handling of transport type: TCP, UDP...
// TODO: Handling of IP version (4 or 6) and transport type: TCP, UDP...
} IceTransportAddress;
typedef struct _IceCandidate {
char foundation[32];
IceTransportAddress taddr;
IceCandidateType type;
uint32_t priority;
uint16_t componentID; /**< component ID between 1 and 256: usually 1 for RTP component and 2 for RTCP component */
struct _IceCandidate *base;
// TODO: foundation, relatedAddr, base
// TODO: relatedAddr
} IceCandidate;
typedef struct _IceCandidatePair {
......@@ -76,6 +77,7 @@ typedef struct _IceCheckList {
MSList *remote_candidates; /**< List of IceCandidate structures */
MSList *pairs; /**< List of IceCandidatePair structures */
IceCheckListState state;
uint32_t foundation_generator;
} IceCheckList;
......@@ -95,12 +97,14 @@ IceCheckListState ice_check_list_state(IceCheckList *cl);
*/
IceCandidate * ice_add_local_candidate(IceCheckList *cl, const char *type, const char *ip, int port, uint16_t componentID, IceCandidate *base);
IceCandidate * ice_add_remote_candidate(IceCheckList *cl, const char *type, const char *ip, int port, uint16_t componentID, uint32_t priority);
IceCandidate * ice_add_remote_candidate(IceCheckList *cl, const char *type, const char *ip, int port, uint16_t componentID, uint32_t priority, const char * const foundation);
void ice_handle_stun_packet(IceCheckList *cl, RtpSession *session, mblk_t *m);
void ice_gather_candidates(IceCheckList *cl);
void ice_compute_candidate_foundations(IceCheckList *cl);
void ice_pair_candidates(IceCheckList *cl);
/**
......
......@@ -56,6 +56,7 @@ static void ice_check_list_init(IceCheckList *cl)
{
cl->local_candidates = cl->remote_candidates = cl->pairs = NULL;
cl->state = ICL_Running;
cl->foundation_generator = 1;
}
static void ice_free_candidate_pair(IceCandidatePair *pair)
......@@ -162,13 +163,14 @@ IceCandidate * ice_add_local_candidate(IceCheckList *cl, const char *type, const
return candidate;
}
IceCandidate * ice_add_remote_candidate(IceCheckList *cl, const char *type, const char *ip, int port, uint16_t componentID, uint32_t priority)
IceCandidate * ice_add_remote_candidate(IceCheckList *cl, const char *type, const char *ip, int port, uint16_t componentID, uint32_t priority, const char * const foundation)
{
IceCandidate *candidate = ice_add_candidate(&cl->remote_candidates, type, ip, port, componentID);
if (candidate == NULL) return NULL;
/* If the priority is 0, compute it. It is used for debugging purpose in mediastream to set priorities of remote candidates. */
if (priority == 0) ice_compute_candidate_priority(candidate);
strncpy(candidate->foundation, foundation, sizeof(candidate->foundation) - 1);
return candidate;
}
......@@ -240,6 +242,38 @@ static int ice_prune_duplicate_pair(IceCandidatePair *pair, MSList **pairs)
return 0;
}
static int ice_find_candidate_with_same_foundation(IceCandidate *c1, IceCandidate *c2)
{
if ((c1 != c2) && c1->base && c2->base && (c1->type == c2->type)
&& (strlen(c1->base->taddr.ip) == strlen(c2->base->taddr.ip))
&& (strcmp(c1->base->taddr.ip, c2->base->taddr.ip) == 0))
return 0;
else return 1;
}
static void ice_compute_candidate_foundation(IceCandidate *candidate, IceCheckList *cl)
{
MSList *l = ms_list_find_custom(cl->local_candidates, (MSCompareFunc)ice_find_candidate_with_same_foundation, candidate);
if (l != NULL) {
/* We found a candidate that should have the same foundation, so copy it from this candidate. */
IceCandidate *other_candidate = (IceCandidate *)l->data;
if (strlen(other_candidate->foundation) > 0) {
strncpy(candidate->foundation, other_candidate->foundation, sizeof(candidate->foundation) - 1);
return;
}
/* If the foundation of the other candidate is empty we need to assign a new one, so continue. */
}
/* No candidate that should have the same foundation has been found, assign a new one. */
snprintf(candidate->foundation, sizeof(candidate->foundation) - 1, "%u", cl->foundation_generator);
cl->foundation_generator++;
}
void ice_compute_candidate_foundations(IceCheckList *cl)
{
ms_list_for_each2(cl->local_candidates, (void (*)(void*,void*))ice_compute_candidate_foundation, cl);
}
void ice_pair_candidates(IceCheckList *cl)
{
MSList *local_list = cl->local_candidates;
......@@ -310,8 +344,9 @@ void ice_set_base_for_srflx_candidates(IceCheckList *cl)
static void ice_dump_candidate(IceCandidate *candidate, const char * const prefix)
{
ms_debug("%s[%p]: type=%s ip=%s port=%u, componentID=%d priority=%u, base=%p", prefix,
candidate, candidate_type_values[candidate->type], candidate->taddr.ip, candidate->taddr.port, candidate->componentID, candidate->priority, candidate->base);
ms_debug("%s[%p]: type=%s ip=%s port=%u componentID=%d priority=%u foundation=%s base=%p", prefix,
candidate, candidate_type_values[candidate->type], candidate->taddr.ip, candidate->taddr.port,
candidate->componentID, candidate->priority, candidate->foundation, candidate->base);
}
void ice_dump_candidates(IceCheckList *cl)
......
......@@ -606,14 +606,18 @@ void setup_media_streams(MediastreamDatas* args) {
ice_add_local_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port+1,2,NULL);
}
ice_set_base_for_srflx_candidates(args->audio->ice_check_list);
ice_compute_candidate_foundations(args->audio->ice_check_list);
}
if (args->ice_remote_candidates_nb) {
char foundation[4];
MediastreamIceCandidate *candidate;
int c;
for (c=0;c<args->ice_remote_candidates_nb;c++){
candidate=&args->ice_remote_candidates[c];
ice_add_remote_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port,1,0);
ice_add_remote_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port+1,2,0);
memset(foundation, '\0', sizeof(foundation));
snprintf(foundation, sizeof(foundation) - 1, "%u", c + 1);
ice_add_remote_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port,1,0,foundation);
ice_add_remote_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port+1,2,0,foundation);
}
}
ice_pair_candidates(args->audio->ice_check_list);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment