Commit 3910894b authored by Ghislain MARY's avatar Ghislain MARY

Allow random selection of media ports without configured ranges.

parent d5f8a6f9
......@@ -298,17 +298,35 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCa
return _create_local_media_description(lc,call,id,id);
}
static int find_port_offset(LinphoneCore *lc){
static int find_port_offset(LinphoneCore *lc, SalStreamType type){
int offset;
MSList *elem;
int audio_port;
int tried_port;
int existing_port;
bool_t already_used=FALSE;
for(offset=0;offset<100;offset+=2){
audio_port=linphone_core_get_audio_port (lc)+offset;
switch (type) {
default:
case SalAudio:
tried_port=linphone_core_get_audio_port (lc)+offset;
break;
case SalVideo:
tried_port=linphone_core_get_video_port (lc)+offset;
break;
}
already_used=FALSE;
for(elem=lc->calls;elem!=NULL;elem=elem->next){
LinphoneCall *call=(LinphoneCall*)elem->data;
if (call->audio_port==audio_port) {
switch (type) {
default:
case SalAudio:
existing_port = call->audio_port;
break;
case SalVideo:
existing_port = call->video_port;
break;
}
if (existing_port==tried_port) {
already_used=TRUE;
break;
}
......@@ -322,8 +340,54 @@ static int find_port_offset(LinphoneCore *lc){
return offset;
}
static int select_random_port(LinphoneCore *lc, SalStreamType type) {
MSList *elem;
int nb_tries;
int tried_port = 0;
int existing_port = 0;
int min_port = 0, max_port = 0;
bool_t already_used = FALSE;
switch (type) {
default:
case SalAudio:
linphone_core_get_audio_port_range(lc, &min_port, &max_port);
break;
case SalVideo:
linphone_core_get_video_port_range(lc, &min_port, &max_port);
break;
}
tried_port = (rand() % (max_port - min_port) + min_port) & ~0x1;
if (tried_port < min_port) tried_port = min_port + 2;
for (nb_tries = 0; nb_tries < 100; nb_tries++) {
for (elem = lc->calls; elem != NULL; elem = elem->next) {
LinphoneCall *call = (LinphoneCall *)elem->data;
switch (type) {
default:
case SalAudio:
existing_port = call->audio_port;
break;
case SalVideo:
existing_port = call->video_port;
break;
}
if (existing_port == tried_port) {
already_used = TRUE;
break;
}
}
if (!already_used) break;
}
if (nb_tries == 100) {
ms_error("Could not find any free port!");
return -1;
}
return tried_port;
}
static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
int port_offset;
int min_port, max_port;
call->magic=linphone_call_magic;
call->refcnt=1;
call->state=LinphoneCallIdle;
......@@ -333,10 +397,26 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from,
call->log=linphone_call_log_new(call, from, to);
call->owns_call_log=TRUE;
linphone_core_notify_all_friends(call->core,LinphoneStatusOnThePhone);
port_offset=find_port_offset (call->core);
if (port_offset==-1) return;
call->audio_port=linphone_core_get_audio_port(call->core)+port_offset;
call->video_port=linphone_core_get_video_port(call->core)+port_offset;
linphone_core_get_audio_port_range(call->core, &min_port, &max_port);
if (min_port == max_port) {
/* Used fixed RTP audio port. */
port_offset=find_port_offset (call->core, SalAudio);
if (port_offset==-1) return;
call->audio_port=linphone_core_get_audio_port(call->core)+port_offset;
} else {
/* Select random RTP audio port in the specified range. */
call->audio_port = select_random_port(call->core, SalAudio);
}
linphone_core_get_video_port_range(call->core, &min_port, &max_port);
if (min_port == max_port) {
/* Used fixed RTP video port. */
port_offset=find_port_offset (call->core, SalVideo);
if (port_offset==-1) return;
call->video_port=linphone_core_get_video_port(call->core)+port_offset;
} else {
/* Select random RTP video port in the specified range. */
call->video_port = select_random_port(call->core, SalVideo);
}
linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], LINPHONE_CALL_STATS_AUDIO);
linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], LINPHONE_CALL_STATS_VIDEO);
}
......
......@@ -624,18 +624,29 @@ static void sip_config_read(LinphoneCore *lc)
static void rtp_config_read(LinphoneCore *lc)
{
int port;
int min_port, max_port;
int jitt_comp;
int nortp_timeout;
bool_t rtp_no_xmit_on_audio_mute;
bool_t adaptive_jitt_comp_enabled;
port=lp_config_get_int(lc->config,"rtp","audio_rtp_port",7078);
linphone_core_set_audio_port(lc,port);
if (lp_config_get_range(lc->config, "rtp", "audio_rtp_port", &min_port, &max_port, 7078, 7078) == TRUE) {
if (min_port <= 0) min_port = 1;
if (max_port > 65535) max_port = 65535;
linphone_core_set_audio_port_range(lc, min_port, max_port);
} else {
min_port = lp_config_get_int(lc->config, "rtp", "audio_rtp_port", 7078);
linphone_core_set_audio_port(lc, min_port);
}
port=lp_config_get_int(lc->config,"rtp","video_rtp_port",9078);
if (port==0) port=9078;
linphone_core_set_video_port(lc,port);
if (lp_config_get_range(lc->config, "rtp", "video_rtp_port", &min_port, &max_port, 9078, 9078) == TRUE) {
if (min_port <= 0) min_port = 1;
if (max_port > 65535) max_port = 65535;
linphone_core_set_video_port_range(lc, min_port, max_port);
} else {
min_port = lp_config_get_int(lc->config, "rtp", "video_rtp_port", 9078);
linphone_core_set_video_port(lc, min_port);
}
jitt_comp=lp_config_get_int(lc->config,"rtp","audio_jitt_comp",60);
linphone_core_set_audio_jittcomp(lc,jitt_comp);
......@@ -1440,7 +1451,18 @@ int linphone_core_get_video_jittcomp(LinphoneCore *lc)
**/
int linphone_core_get_audio_port(const LinphoneCore *lc)
{
return lc->rtp_conf.audio_rtp_port;
return lc->rtp_conf.audio_rtp_min_port;
}
/**
* Get the audio port range from which is randomly chosen the UDP port used for audio streaming.
*
* @ingroup network_parameters
*/
void linphone_core_get_audio_port_range(const LinphoneCore *lc, int *min_port, int *max_port)
{
*min_port = lc->rtp_conf.audio_rtp_min_port;
*max_port = lc->rtp_conf.audio_rtp_max_port;
}
/**
......@@ -1449,7 +1471,18 @@ int linphone_core_get_audio_port(const LinphoneCore *lc)
* @ingroup network_parameters
**/
int linphone_core_get_video_port(const LinphoneCore *lc){
return lc->rtp_conf.video_rtp_port;
return lc->rtp_conf.video_rtp_min_port;
}
/**
* Get the video port range from which is randomly chosen the UDP port used for video streaming.
*
* @ingroup network_parameters
*/
void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, int *max_port)
{
*min_port = lc->rtp_conf.video_rtp_min_port;
*max_port = lc->rtp_conf.video_rtp_max_port;
}
......@@ -1501,7 +1534,16 @@ void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc,bool_t rtp_no_
**/
void linphone_core_set_audio_port(LinphoneCore *lc, int port)
{
lc->rtp_conf.audio_rtp_port=port;
lc->rtp_conf.audio_rtp_min_port=lc->rtp_conf.audio_rtp_max_port=port;
}
/**
* Sets the UDP port range from which to randomly select the port used for audio streaming.
*/
void linphone_core_set_audio_port_range(LinphoneCore *lc, int min_port, int max_port)
{
lc->rtp_conf.audio_rtp_min_port=min_port;
lc->rtp_conf.audio_rtp_max_port=max_port;
}
/**
......@@ -1510,7 +1552,16 @@ void linphone_core_set_audio_port(LinphoneCore *lc, int port)
* @ingroup network_parameters
**/
void linphone_core_set_video_port(LinphoneCore *lc, int port){
lc->rtp_conf.video_rtp_port=port;
lc->rtp_conf.video_rtp_min_port=lc->rtp_conf.video_rtp_max_port=port;
}
/**
* Sets the UDP port range from which to randomly select the port used for video streaming.
*/
void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_port)
{
lc->rtp_conf.video_rtp_min_port=min_port;
lc->rtp_conf.video_rtp_max_port=max_port;
}
/**
......@@ -4556,8 +4607,16 @@ void sip_config_uninit(LinphoneCore *lc)
void rtp_config_uninit(LinphoneCore *lc)
{
rtp_config_t *config=&lc->rtp_conf;
lp_config_set_int(lc->config,"rtp","audio_rtp_port",config->audio_rtp_port);
lp_config_set_int(lc->config,"rtp","video_rtp_port",config->video_rtp_port);
if (config->audio_rtp_min_port == config->audio_rtp_max_port) {
lp_config_set_int(lc->config, "rtp", "audio_rtp_port", config->audio_rtp_min_port);
} else {
lp_config_set_range(lc->config, "rtp", "audio_rtp_port", config->audio_rtp_min_port, config->audio_rtp_max_port);
}
if (config->video_rtp_min_port == config->video_rtp_max_port) {
lp_config_set_int(lc->config, "rtp", "video_rtp_port", config->video_rtp_min_port);
} else {
lp_config_set_range(lc->config, "rtp", "video_rtp_port", config->video_rtp_min_port, config->video_rtp_max_port);
}
lp_config_set_int(lc->config,"rtp","audio_jitt_comp",config->audio_jitt_comp);
lp_config_set_int(lc->config,"rtp","video_jitt_comp",config->video_jitt_comp);
lp_config_set_int(lc->config,"rtp","nortp_timeout",config->nortp_timeout);
......
......@@ -1115,14 +1115,22 @@ void linphone_core_set_video_jittcomp(LinphoneCore *lc, int value);
int linphone_core_get_audio_port(const LinphoneCore *lc);
void linphone_core_get_audio_port_range(const LinphoneCore *lc, int *min_port, int *max_port);
int linphone_core_get_video_port(const LinphoneCore *lc);
void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, int *max_port);
int linphone_core_get_nortp_timeout(const LinphoneCore *lc);
void linphone_core_set_audio_port(LinphoneCore *lc, int port);
void linphone_core_set_audio_port_range(LinphoneCore *lc, int min_port, int max_port);
void linphone_core_set_video_port(LinphoneCore *lc, int port);
void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_port);
void linphone_core_set_nortp_timeout(LinphoneCore *lc, int port);
void linphone_core_set_use_info_for_dtmf(LinphoneCore *lc, bool_t use_info);
......
......@@ -398,8 +398,10 @@ typedef struct sip_config
typedef struct rtp_config
{
int audio_rtp_port;
int video_rtp_port;
int audio_rtp_min_port;
int audio_rtp_max_port;
int video_rtp_min_port;
int video_rtp_max_port;
int audio_jitt_comp; /*jitter compensation*/
int video_jitt_comp; /*jitter compensation*/
int nortp_timeout;
......
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