Commit 677ae278 authored by Ghislain MARY's avatar Ghislain MARY

Add ICE candidates from mediastream command line to the stream ICE check lists.

parent 01735a67
......@@ -25,10 +25,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "ortp/ortp.h"
#define ICE_MAX_NB_CANDIDATES 10
#define ICE_MAX_NB_CANDIDATE_PAIRS (ICE_MAX_NB_CANDIDATES*ICE_MAX_NB_CANDIDATES)
typedef enum {
ICT_HostCandidate,
ICT_ServerReflexiveCandidate,
......@@ -59,7 +55,9 @@ typedef struct {
typedef struct {
IceTransportAddress taddr;
IceCandidateType type;
// TODO: priority, foundation, componentID, relatedAddr, base
uint32_t priority;
uint16_t componentID; /**< component ID between 1 and 256: usually 1 for RTP component and 2 for RTCP component */
// TODO: foundation, relatedAddr, base
} IceCandidate;
typedef struct {
......@@ -72,9 +70,9 @@ typedef struct {
} IceCandidatePair;
typedef struct {
IceCandidate local_candidates[ICE_MAX_NB_CANDIDATES];
IceCandidate remote_candidates[ICE_MAX_NB_CANDIDATES];
IceCandidatePair pairs[ICE_MAX_NB_CANDIDATE_PAIRS];
MSList *local_candidates; /**< List of IceCandidate structures */
MSList *remote_candidates; /**< List of IceCandidate structures */
MSList *pairs; /**< List of IceCandidatePair structures */
IceCheckListState state;
} IceCheckList;
......@@ -89,8 +87,16 @@ void ice_check_list_destroy(IceCheckList *cl);
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 * ice_add_remote_candidate(IceCheckList *cl, const char *type, const char *ip, int port, uint16_t componentID, uint32_t priority);
void ice_handle_stun_packet(IceCheckList *cl, RtpSession *session, mblk_t *m);
void ice_gather_candidates(IceCheckList *cl);
void ice_dump_candidates(IceCheckList *cl);
#ifdef __cplusplus
}
#endif
......
......@@ -30,14 +30,89 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/ice.h"
#define ICE_MAX_NB_CANDIDATES 10
#define ICE_MAX_NB_CANDIDATE_PAIRS (ICE_MAX_NB_CANDIDATES*ICE_MAX_NB_CANDIDATES)
static const char * const candidate_type_values[] = {
"host", /* ICT_HostCandidate */
"srflx", /* ICT_ServerReflexiveCandidate */
"prflx", /* ICT_PeerReflexiveCandidate */
"relay" /* ICT_RelayedCandidate */
};
/**
* ICE candidate type preference values as recommended in 4.1.1.2.
*/
static const uint8_t type_preference_values[] = {
126, /* ICT_HostCandidate */
100, /* ICT_ServerReflexiveCandidate */
110, /* ICT_PeerReflexiveCandidate */
0 /* ICT_RelayedCandidate */
};
static void ice_check_list_init(IceCheckList *cl)
{
cl->local_candidates = cl->remote_candidates = cl->pairs = NULL;
cl->state = ICL_Running;
}
static void ice_free_candidate(IceCandidate *candidate)
{
ms_free(candidate);
}
static IceCandidate * ice_add_candidate(MSList **list, const char *type, const char *ip, int port, uint16_t componentID)
{
IceCandidate *candidate;
IceCandidateType candidate_type;
int iplen;
if (ms_list_size(*list) >= ICE_MAX_NB_CANDIDATES) {
ms_error("ice_add_candidate: Candidate list limited to %d candidates", ICE_MAX_NB_CANDIDATES);
return NULL;
}
if (strcmp(type, "host") == 0) {
candidate_type = ICT_HostCandidate;
}
else if (strcmp(type, "srflx") == 0) {
candidate_type = ICT_ServerReflexiveCandidate;
}
else if (strcmp(type, "prflx") == 0) {
candidate_type = ICT_PeerReflexiveCandidate;
}
else if (strcmp(type, "relay") == 0) {
candidate_type = ICT_RelayedCandidate;
}
else {
ms_error("ice_add_candidate: Invalid candidate type");
return NULL;
}
candidate = ms_new(IceCandidate, 1);
iplen = MIN(strlen(ip), sizeof(candidate->taddr.ip));
strncpy(candidate->taddr.ip, ip, iplen);
candidate->taddr.port = port;
candidate->type = candidate_type;
candidate->componentID = componentID;
*list = ms_list_append(*list, candidate);
return candidate;
}
static void ice_compute_candidate_priority(IceCandidate *candidate)
{
// TODO: Handle local preferences for multihomed hosts.
uint8_t type_preference = type_preference_values[candidate->type];
uint16_t local_preference = 65535; /* Value recommended for non-multihomed hosts in 4.1.2.1 */
candidate->priority = (type_preference << 24) | (local_preference << 8) | (256 - candidate->componentID);
}
IceCheckList * ice_check_list_new(void)
{
IceCheckList *cl = ms_new0(IceCheckList, 1);
IceCheckList *cl = ms_new(IceCheckList, 1);
if (cl == NULL) {
ms_error("ice_check_list_new: Memory allocation failed");
return NULL;
......@@ -48,6 +123,10 @@ IceCheckList * ice_check_list_new(void)
void ice_check_list_destroy(IceCheckList *cl)
{
ms_list_for_each(cl->remote_candidates, (void (*)(void*))ice_free_candidate);
ms_list_for_each(cl->local_candidates, (void (*)(void*))ice_free_candidate);
ms_list_free(cl->remote_candidates);
ms_list_free(cl->local_candidates);
ms_free(cl);
}
......@@ -56,7 +135,41 @@ IceCheckListState ice_check_list_state(IceCheckList *cl)
return cl->state;
}
IceCandidate * ice_add_local_candidate(IceCheckList *cl, const char *type, const char *ip, int port, uint16_t componentID)
{
IceCandidate *candidate = ice_add_candidate(&cl->local_candidates, type, ip, port, componentID);
ice_compute_candidate_priority(candidate);
return candidate;
}
IceCandidate * ice_add_remote_candidate(IceCheckList *cl, const char *type, const char *ip, int port, uint16_t componentID, uint32_t priority)
{
IceCandidate *candidate = ice_add_candidate(&cl->remote_candidates, type, ip, port, componentID);
/* 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);
return candidate;
}
void ice_handle_stun_packet(IceCheckList *cl, RtpSession* session, mblk_t* m)
{
//TODO
}
void ice_gather_candidates(IceCheckList *cl)
{
//TODO
}
static void ice_dump_candidate(IceCandidate *candidate)
{
ms_debug("\ttype=%s ip=%s port=%u, componentID=%d priority=%u",
candidate_type_values[candidate->type], candidate->taddr.ip, candidate->taddr.port, candidate->componentID, candidate->priority);
}
void ice_dump_candidates(IceCheckList *cl)
{
ms_debug("Local candidates:");
ms_list_for_each(cl->local_candidates, (void (*)(void*))ice_dump_candidate);
ms_debug("Remote candidates:");
ms_list_for_each(cl->remote_candidates, (void (*)(void*))ice_dump_candidate);
}
......@@ -597,6 +597,26 @@ void setup_media_streams(MediastreamDatas* args) {
audio_stream_start_full(args->audio,args->profile,args->ip,args->remoteport,args->remoteport+1, args->payload, args->jitter,args->infile,args->outfile,
args->outfile==NULL ? play : NULL ,args->infile==NULL ? capt : NULL,args->infile!=NULL ? FALSE: args->ec);
if (args->ice_local_candidates_nb) {
MediastreamIceCandidate *candidate;
int c;
for (c=0;c<args->ice_local_candidates_nb;c++){
candidate=&args->ice_local_candidates[c];
ice_add_local_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port,1);
ice_add_local_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port+1,2);
}
}
if (args->ice_remote_candidates_nb) {
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);
}
}
ice_dump_candidates(args->audio->ice_check_list);
if (args->audio) {
if (args->el) {
if (args->el_speed!=-1)
......
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