Commit f3805137 authored by Yann Diorcet's avatar Yann Diorcet
Browse files

Working call with uPnP

parent 9567e2bf
......@@ -253,6 +253,12 @@ static void call_received(SalOp *h){
return;
}
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseUpnp) && (call->upnp_session != NULL)) {
/* Defer ringing until the end of the ICE candidates gathering process. */
ms_message("Defer ringing to gather uPnP candidates");
return;
}
linphone_core_notify_incoming_call(lc,call);
}
......@@ -325,6 +331,11 @@ static void call_accepted(SalOp *op){
if (call->ice_session != NULL) {
linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(op));
}
#ifdef BUILD_UPNP
if (call->upnp_session != NULL) {
linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(op));
}
#endif //BUILD_UPNP
md=sal_call_get_final_media_description(op);
call->params.has_video &= linphone_core_media_description_contains_video_stream(md);
......@@ -418,6 +429,7 @@ static void call_accept_update(LinphoneCore *lc, LinphoneCall *call){
}
#ifdef BUILD_UPNP
if(call->upnp_session != NULL) {
linphone_core_update_upnp_from_remote_media_description(call, rmd);
linphone_core_update_local_media_description_from_upnp(call->localdesc,call->upnp_session);
}
#endif
......@@ -516,6 +528,10 @@ static void call_terminated(SalOp *op, const char *from){
if (lc->vtable.display_status!=NULL)
lc->vtable.display_status(lc,_("Call terminated."));
#ifdef BUILD_UPNP
linphone_call_delete_upnp_session(call);
#endif //BUILD_UPNP
linphone_call_set_state(call, LinphoneCallEnd,"Call ended");
}
......
......@@ -444,7 +444,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
call->op=sal_op_new(lc->sal);
sal_op_set_user_pointer(call->op,call);
call->core=lc;
linphone_core_get_public_ip(lc,linphone_address_get_domain(to),call->localip);
linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip);
linphone_call_init_common(call,from,to);
call->params=*params;
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) {
......@@ -491,7 +491,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
}
linphone_address_clean(from);
linphone_core_get_public_ip(lc,linphone_address_get_domain(from),call->localip);
linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip);
linphone_call_init_common(call, from, to);
call->log->call_id=ms_strdup(sal_op_get_call_id(op)); /*must be known at that time*/
linphone_core_init_default_params(lc, &call->params);
......@@ -524,9 +524,9 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
case LinphonePolicyUseUpnp:
#ifdef BUILD_UPNP
call->upnp_session = upnp_session_new(call);
if (call->ice_session != NULL) {
if (call->upnp_session != NULL) {
linphone_call_init_media_streams(call);
if (linphone_core_update_upnp(call->core,call)<0) {
if (linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(op))<0) {
/* uPnP port mappings failed, proceed with the call anyway. */
linphone_call_delete_upnp_session(call);
}
......
......@@ -1306,7 +1306,7 @@ int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact)
/*result must be an array of chars at least LINPHONE_IPADDR_SIZE */
void linphone_core_get_public_ip(LinphoneCore *lc, const char *dest, char *result){
void linphone_core_get_local_ip(LinphoneCore *lc, const char *dest, char *result){
const char *ip;
if (linphone_core_get_firewall_policy(lc)==LinphonePolicyUseNatAddress
&& (ip=linphone_core_get_nat_address_resolved(lc))!=NULL){
......@@ -1318,6 +1318,7 @@ void linphone_core_get_public_ip(LinphoneCore *lc, const char *dest, char *resul
&& lc->upnp.state == LinphoneUpnpStateOk) {
ip = upnp_igd_get_external_ipaddress(lc->upnp.upnp_igd_ctxt);
strncpy(result,ip,LINPHONE_IPADDR_SIZE);
return;
}
#endif
if (linphone_core_get_local_ip_for(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,dest,result)==0)
......@@ -1340,7 +1341,7 @@ static void update_primary_contact(LinphoneCore *lc){
ms_error("Could not parse identity contact !");
url=linphone_address_new("sip:unknown@unkwownhost");
}
linphone_core_get_public_ip(lc, NULL, tmp);
linphone_core_get_local_ip(lc, NULL, tmp);
if (strcmp(tmp,"127.0.0.1")==0 || strcmp(tmp,"::1")==0 ){
ms_warning("Local loopback network only !");
lc->sip_conf.loopback_only=TRUE;
......@@ -2268,6 +2269,7 @@ static char *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , LinphonePr
int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *call, LinphoneProxyConfig *dest_proxy){
bool_t ice_ready = FALSE;
bool_t upnp_ready = FALSE;
bool_t ping_ready = FALSE;
if (call->ice_session != NULL) {
......@@ -2275,13 +2277,20 @@ int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *c
} else {
ice_ready = TRUE;
}
#ifdef BUILD_UPNP
if (call->upnp_session != NULL) {
if (call->upnp_session->state == LinphoneUpnpStateOk) upnp_ready = TRUE;
} else {
upnp_ready = TRUE;
}
#endif //BUILD_UPNP
if (call->ping_op != NULL) {
if (call->ping_replied == TRUE) ping_ready = TRUE;
} else {
ping_ready = TRUE;
}
if ((ice_ready == TRUE) && (ping_ready == TRUE)) {
if ((ice_ready == TRUE) && (upnp_ready == TRUE) && (ping_ready == TRUE)) {
return linphone_core_start_invite(lc, call);
}
return 0;
......@@ -2843,6 +2852,14 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const
#if BUILD_UPNP
if(call->upnp_session != NULL) {
if ((call->params.has_video) && (call->params.has_video != old_has_video)) {
linphone_call_init_video_stream(call);
video_stream_prepare_video(call->videostream);
if (linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(call->op))<0) {
/* uPnP update failed, proceed with the call anyway. */
linphone_call_delete_upnp_session(call);
} else return 0;
}
}
#endif //BUILD_UPNP
......@@ -4961,6 +4978,10 @@ static void linphone_core_uninit(LinphoneCore *lc)
lc->config = NULL; /* Mark the config as NULL to block further calls */
sip_setup_unregister_all();
#ifdef BUILD_UPNP
upnp_context_uninit(lc);
#endif
ms_list_for_each(lc->call_logs,(void (*)(void*))linphone_call_log_destroy);
lc->call_logs=ms_list_free(lc->call_logs);
......@@ -4973,9 +4994,6 @@ static void linphone_core_uninit(LinphoneCore *lc)
#ifdef TUNNEL_ENABLED
if (lc->tunnel) linphone_tunnel_destroy(lc->tunnel);
#endif
#ifdef BUILD_UPNP
upnp_context_uninit(lc);
#endif
}
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime){
......
......@@ -1021,14 +1021,15 @@ static int get_local_ip_with_getifaddrs(int type, char *address, int size)
if (ifp->ifa_addr && ifp->ifa_addr->sa_family == type
&& (ifp->ifa_flags & UP_FLAG) && !(ifp->ifa_flags & IFF_LOOPBACK))
{
getnameinfo(ifp->ifa_addr,
if(getnameinfo(ifp->ifa_addr,
(type == AF_INET6) ?
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
address, size, NULL, 0, NI_NUMERICHOST);
if (strchr(address, '%') == NULL) { /*avoid ipv6 link-local addresses */
/*ms_message("getifaddrs() found %s",address);*/
ret++;
break;
address, size, NULL, 0, NI_NUMERICHOST) == 0) {
if (strchr(address, '%') == NULL) { /*avoid ipv6 link-local addresses */
/*ms_message("getifaddrs() found %s",address);*/
ret++;
break;
}
}
}
}
......@@ -1099,26 +1100,26 @@ static int get_local_ip_for_with_connect(int type, const char *dest, char *resul
}
int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
strcpy(result,type==AF_INET ? "127.0.0.1" : "::1");
strcpy(result,type==AF_INET ? "127.0.0.1" : "::1");
#ifdef HAVE_GETIFADDRS
if (dest==NULL) {
/*we use getifaddrs for lookup of default interface */
int found_ifs;
found_ifs=get_local_ip_with_getifaddrs(type,result,LINPHONE_IPADDR_SIZE);
if (found_ifs==1){
return 0;
}else if (found_ifs<=0){
/*absolutely no network on this machine */
return -1;
}
}
if (dest==NULL) {
/*we use getifaddrs for lookup of default interface */
int found_ifs;
found_ifs=get_local_ip_with_getifaddrs(type,result,LINPHONE_IPADDR_SIZE);
if (found_ifs==1){
return 0;
}else if (found_ifs<=0){
/*absolutely no network on this machine */
return -1;
}
}
#endif
/*else use connect to find the best local ip address */
if (type==AF_INET)
dest="87.98.157.38"; /*a public IP address*/
else dest="2a00:1450:8002::68";
return get_local_ip_for_with_connect(type,dest,result);
/*else use connect to find the best local ip address */
if (type==AF_INET)
dest="87.98.157.38"; /*a public IP address*/
else dest="2a00:1450:8002::68";
return get_local_ip_for_with_connect(type,dest,result);
}
#ifndef WIN32
......
......@@ -206,7 +206,7 @@ int set_lock_file();
int get_lock_file();
int remove_lock_file();
void check_sound_device(LinphoneCore *lc);
void linphone_core_get_public_ip(LinphoneCore *lc, const char *to, char *result);
void linphone_core_get_local_ip(LinphoneCore *lc, const char *to, char *result);
bool_t host_has_ipv6_network();
bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret);
......@@ -593,9 +593,6 @@ int linphone_core_del_call( LinphoneCore *lc, LinphoneCall *call);
int linphone_core_set_as_current_call(LinphoneCore *lc, LinphoneCall *call);
int linphone_core_get_calls_nb(const LinphoneCore *lc);
void linphone_core_add_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook hook, void *hook_data);
void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook hook, void *hook_data);
void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call);
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md);
......
......@@ -268,7 +268,7 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){
LCSipTransports tr;
LinphoneAddress *contact;
linphone_core_get_public_ip(obj->lc,host,localip);
linphone_core_get_local_ip(obj->lc,host,localip);
contact=linphone_address_new(obj->reg_identity);
linphone_address_set_domain (contact,localip);
linphone_address_set_port_int(contact,linphone_core_get_sip_port(obj->lc));
......
......@@ -53,6 +53,7 @@ UpnpPortBinding *upnp_port_binding_new();
UpnpPortBinding *upnp_port_binding_copy(const UpnpPortBinding *port);
bool_t upnp_port_binding_equal(const UpnpPortBinding *port1, const UpnpPortBinding *port2);
UpnpPortBinding *upnp_port_binding_retain(UpnpPortBinding *port);
void upnp_port_binding_log(int level, const char *msg, const UpnpPortBinding *port);
void upnp_port_binding_release(UpnpPortBinding *port);
MSList *upnp_config_list_port_bindings(struct _LpConfig *lpc);
......@@ -62,6 +63,7 @@ int upnp_config_remove_port_binding(LinphoneCore *lc, const UpnpPortBinding *por
int upnp_context_send_remove_port_binding(LinphoneCore *lc, UpnpPortBinding *port);
int upnp_context_send_add_port_binding(LinphoneCore *lc, UpnpPortBinding *port);
/**
* uPnP Callbacks
*/
......@@ -74,10 +76,10 @@ void linphone_upnp_igd_print(void *cookie, upnp_igd_print_level level, const cha
ortp_level = ORTP_MESSAGE;
break;
case UPNP_IGD_WARNING:
ortp_level = ORTP_WARNING;
ortp_level = ORTP_DEBUG; // Too verbose otherwise
break;
case UPNP_IGD_ERROR:
ortp_level = ORTP_ERROR;
ortp_level = ORTP_DEBUG; // Too verbose otherwise
break;
default:
break;
......@@ -121,11 +123,7 @@ void linphone_upnp_igd_callback(void *cookie, upnp_igd_event event, void *arg) {
port_mapping = (UpnpPortBinding*) mapping->cookie;
port_mapping->external_port = mapping->remote_port;
port_mapping->state = LinphoneUpnpStateOk;
ms_message("uPnP IGD: Added port binding %s|%d->%s:%d",
(port_mapping->protocol == UPNP_IGD_IP_PROTOCOL_TCP)? "TCP":"UDP",
port_mapping->external_port,
port_mapping->local_addr,
port_mapping->local_port);
upnp_port_binding_log(ORTP_MESSAGE, "Added port binding", port_mapping);
upnp_config_add_port_binding(lc, port_mapping);
upnp_port_binding_release(port_mapping);
......@@ -135,11 +133,7 @@ void linphone_upnp_igd_callback(void *cookie, upnp_igd_event event, void *arg) {
mapping = (upnp_igd_port_mapping *) arg;
port_mapping = (UpnpPortBinding*) mapping->cookie;
if(upnp_context_send_add_port_binding(lc, port_mapping) != 0) {
ms_error("uPnP IGD: Can't add port binding %s|%d->%s:%d",
(port_mapping->protocol == UPNP_IGD_IP_PROTOCOL_TCP)? "TCP":"UDP",
port_mapping->external_port,
port_mapping->local_addr,
port_mapping->local_port);
upnp_port_binding_log(ORTP_ERROR, "Can't add port binding", port_mapping);
}
upnp_port_binding_release(port_mapping);
......@@ -149,10 +143,7 @@ void linphone_upnp_igd_callback(void *cookie, upnp_igd_event event, void *arg) {
mapping = (upnp_igd_port_mapping *) arg;
port_mapping = (UpnpPortBinding*) mapping->cookie;
port_mapping->state = LinphoneUpnpStateIdle;
ms_message("uPnP IGD: Removed port binding %s|%d->%d",
(port_mapping->protocol == UPNP_IGD_IP_PROTOCOL_TCP)? "TCP":"UDP",
port_mapping->external_port,
port_mapping->local_port);
upnp_port_binding_log(ORTP_MESSAGE, "Removed port binding", port_mapping);
upnp_config_remove_port_binding(lc, port_mapping);
upnp_port_binding_release(port_mapping);
......@@ -162,10 +153,7 @@ void linphone_upnp_igd_callback(void *cookie, upnp_igd_event event, void *arg) {
mapping = (upnp_igd_port_mapping *) arg;
port_mapping = (UpnpPortBinding*) mapping->cookie;
if(upnp_context_send_remove_port_binding(lc, port_mapping) != 0) {
ms_error("uPnP IGD: Can't remove port binding %s|%d->%d",
(port_mapping->protocol == UPNP_IGD_IP_PROTOCOL_TCP)? "TCP":"UDP",
port_mapping->external_port,
port_mapping->local_port);
upnp_port_binding_log(ORTP_ERROR, "Can't remove port binding", port_mapping);
upnp_config_remove_port_binding(lc, port_mapping);
}
......@@ -304,7 +292,7 @@ int upnp_context_send_remove_port_binding(LinphoneCore *lc, UpnpPortBinding *por
UpnpContext *lupnp = &lc->upnp;
upnp_igd_port_mapping mapping;
int ret;
if(port->state == LinphoneUpnpStateIdle) {
if(port->state == LinphoneUpnpStateOk) {
port->retry = 0;
port->state = LinphoneUpnpStateRemoving;
} else if(port->state != LinphoneUpnpStateRemoving) {
......@@ -332,11 +320,10 @@ int upnp_context_send_remove_port_binding(LinphoneCore *lc, UpnpPortBinding *por
* uPnP Core interfaces
*/
int upnp_call_process(LinphoneCall *call) {
int linphone_core_update_upnp_audio_video(LinphoneCall *call, bool_t audio, bool_t video) {
LinphoneCore *lc = call->core;
UpnpContext *lupnp = &lc->upnp;
int ret = -1;
UpnpState oldState;
const char *local_addr, *external_addr;
ms_mutex_lock(&lupnp->mutex);
......@@ -355,34 +342,20 @@ int upnp_call_process(LinphoneCall *call) {
strncpy(call->upnp_session->audio->rtcp->local_addr, local_addr, LINPHONE_IPADDR_SIZE);
strncpy(call->upnp_session->audio->rtcp->external_addr, external_addr, LINPHONE_IPADDR_SIZE);
call->upnp_session->audio->rtcp->local_port = call->audio_port+1;
if(call->upnp_session->audio->rtp->state == LinphoneUpnpStateIdle && call->audiostream != NULL) {
if(call->upnp_session->audio->rtp->state == LinphoneUpnpStateIdle && audio) {
// Add audio port binding
upnp_context_send_add_port_binding(lc, call->upnp_session->audio->rtp);
} else if(call->upnp_session->audio->rtp->state == LinphoneUpnpStateOk && call->audiostream == NULL) {
} else if(call->upnp_session->audio->rtp->state == LinphoneUpnpStateOk && !audio) {
// Remove audio port binding
upnp_context_send_remove_port_binding(lc, call->upnp_session->audio->rtp);
}
if(call->upnp_session->audio->rtcp->state == LinphoneUpnpStateIdle && call->audiostream != NULL) {
if(call->upnp_session->audio->rtcp->state == LinphoneUpnpStateIdle && audio) {
// Add audio port binding
upnp_context_send_add_port_binding(lc, call->upnp_session->audio->rtcp);
} else if(call->upnp_session->audio->rtcp->state == LinphoneUpnpStateOk && call->audiostream == NULL) {
} else if(call->upnp_session->audio->rtcp->state == LinphoneUpnpStateOk && !audio) {
// Remove audio port binding
upnp_context_send_remove_port_binding(lc, call->upnp_session->audio->rtcp);
}
if((call->upnp_session->audio->rtp->state == LinphoneUpnpStateOk || call->upnp_session->audio->rtp->state == LinphoneUpnpStateIdle) &&
(call->upnp_session->audio->rtcp->state == LinphoneUpnpStateOk || call->upnp_session->audio->rtcp->state == LinphoneUpnpStateIdle)) {
call->upnp_session->audio->state = LinphoneUpnpStateOk;
} else if(call->upnp_session->audio->rtp->state == LinphoneUpnpStateAdding ||
call->upnp_session->audio->rtp->state == LinphoneUpnpStateRemoving ||
call->upnp_session->audio->rtcp->state == LinphoneUpnpStateAdding ||
call->upnp_session->audio->rtcp->state == LinphoneUpnpStateRemoving) {
call->upnp_session->audio->state = LinphoneUpnpStatePending;
} else if(call->upnp_session->audio->rtcp->state == LinphoneUpnpStateKo ||
call->upnp_session->audio->rtp->state == LinphoneUpnpStateKo) {
call->upnp_session->audio->state = LinphoneUpnpStateKo;
} else {
call->upnp_session->audio->state = LinphoneUpnpStateIdle;
}
/*
* Video part
......@@ -393,20 +366,82 @@ int upnp_call_process(LinphoneCall *call) {
strncpy(call->upnp_session->video->rtcp->local_addr, local_addr, LINPHONE_IPADDR_SIZE);
strncpy(call->upnp_session->video->rtcp->external_addr, external_addr, LINPHONE_IPADDR_SIZE);
call->upnp_session->video->rtcp->local_port = call->video_port+1;
if(call->upnp_session->video->rtp->state == LinphoneUpnpStateIdle && call->videostream != NULL) {
if(call->upnp_session->video->rtp->state == LinphoneUpnpStateIdle && video) {
// Add video port binding
upnp_context_send_add_port_binding(lc, call->upnp_session->video->rtp);
} else if(call->upnp_session->video->rtp->state == LinphoneUpnpStateOk && call->videostream == NULL) {
} else if(call->upnp_session->video->rtp->state == LinphoneUpnpStateOk && !video) {
// Remove video port binding
upnp_context_send_remove_port_binding(lc, call->upnp_session->video->rtp);
}
if(call->upnp_session->video->rtcp->state == LinphoneUpnpStateIdle && call->videostream != NULL) {
if(call->upnp_session->video->rtcp->state == LinphoneUpnpStateIdle && video) {
// Add video port binding
upnp_context_send_add_port_binding(lc, call->upnp_session->video->rtcp);
} else if(call->upnp_session->video->rtcp->state == LinphoneUpnpStateOk && call->videostream == NULL) {
} else if(call->upnp_session->video->rtcp->state == LinphoneUpnpStateOk && !video) {
// Remove video port binding
upnp_context_send_remove_port_binding(lc, call->upnp_session->video->rtcp);
}
}
ms_mutex_unlock(&lupnp->mutex);
return ret;
}
int linphone_core_update_upnp_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md) {
bool_t audio = FALSE;
bool_t video = FALSE;
int i;
const SalStreamDescription *stream;
for (i = 0; i < md->nstreams; i++) {
stream = &md->streams[i];
if(stream->type == SalAudio) {
audio = TRUE;
} else if(stream->type == SalVideo) {
video = TRUE;
}
}
return linphone_core_update_upnp_audio_video(call, audio, video);
}
int linphone_core_update_upnp(LinphoneCore *lc, LinphoneCall *call) {
return linphone_core_update_upnp_audio_video(call, call->audiostream!=NULL, call->videostream!=NULL);
}
int upnp_call_process(LinphoneCall *call) {
LinphoneCore *lc = call->core;
UpnpContext *lupnp = &lc->upnp;
int ret = -1;
UpnpState oldState;
ms_mutex_lock(&lupnp->mutex);
// Don't handle when the call
if(lupnp->state == LinphoneUpnpStateOk && call->upnp_session != NULL) {
ret = 0;
/*
* Update Audio state
*/
if((call->upnp_session->audio->rtp->state == LinphoneUpnpStateOk || call->upnp_session->audio->rtp->state == LinphoneUpnpStateIdle) &&
(call->upnp_session->audio->rtcp->state == LinphoneUpnpStateOk || call->upnp_session->audio->rtcp->state == LinphoneUpnpStateIdle)) {
call->upnp_session->audio->state = LinphoneUpnpStateOk;
} else if(call->upnp_session->audio->rtp->state == LinphoneUpnpStateAdding ||
call->upnp_session->audio->rtp->state == LinphoneUpnpStateRemoving ||
call->upnp_session->audio->rtcp->state == LinphoneUpnpStateAdding ||
call->upnp_session->audio->rtcp->state == LinphoneUpnpStateRemoving) {
call->upnp_session->audio->state = LinphoneUpnpStatePending;
} else if(call->upnp_session->audio->rtcp->state == LinphoneUpnpStateKo ||
call->upnp_session->audio->rtp->state == LinphoneUpnpStateKo) {
call->upnp_session->audio->state = LinphoneUpnpStateKo;
} else {
call->upnp_session->audio->state = LinphoneUpnpStateIdle;
}
/*
* Update Video state
*/
if((call->upnp_session->video->rtp->state == LinphoneUpnpStateOk || call->upnp_session->video->rtp->state == LinphoneUpnpStateIdle) &&
(call->upnp_session->video->rtcp->state == LinphoneUpnpStateOk || call->upnp_session->video->rtcp->state == LinphoneUpnpStateIdle)) {
call->upnp_session->video->state = LinphoneUpnpStateOk;
......@@ -442,18 +477,23 @@ int upnp_call_process(LinphoneCall *call) {
/* When change is done proceed update */
if(oldState != LinphoneUpnpStateOk && oldState != LinphoneUpnpStateKo &&
(call->upnp_session->state == LinphoneUpnpStateOk || call->upnp_session->state == LinphoneUpnpStateKo)) {
if(call->upnp_session->state == LinphoneUpnpStateOk)
ms_message("uPnP IGD: uPnP for Call %p is ok", call);
else
ms_message("uPnP IGD: uPnP for Call %p is ko", call);
switch (call->state) {
case LinphoneCallUpdating:
linphone_core_start_update_call(call->core, call);
linphone_core_start_update_call(lc, call);
break;
case LinphoneCallUpdatedByRemote:
linphone_core_start_accept_call_update(call->core, call);
linphone_core_start_accept_call_update(lc, call);
break;
case LinphoneCallOutgoingInit:
linphone_core_proceed_with_invite_if_ready(call->core, call, NULL);
linphone_core_proceed_with_invite_if_ready(lc, call, NULL);
break;
case LinphoneCallIdle:
linphone_core_notify_incoming_call(call->core, call);
linphone_core_notify_incoming_call(lc, call);
break;
default:
break;
......@@ -465,10 +505,6 @@ int upnp_call_process(LinphoneCall *call) {
return ret;
}
int linphone_core_update_upnp(LinphoneCore *lc, LinphoneCall *call) {
return upnp_call_process(call);
}
bool_t linphone_core_upnp_hook(void *data) {
char key[64];
MSList *port_bindings = NULL;
......@@ -512,7 +548,7 @@ bool_t linphone_core_upnp_hook(void *data) {
(port_mapping->protocol == UPNP_IGD_IP_PROTOCOL_TCP)? "TCP":"UDP",
port_mapping->external_port,
port_mapping->local_port);
lp_config_set_string(lc->config, UPNP_SECTION_NAME, key, "");
lp_config_set_string(lc->config, UPNP_SECTION_NAME, key, "uPnP");
}
if(port_mapping->state == LinphoneUpnpStateRemoving) {
snprintf(key, sizeof(key), "%s-%d-%d",
......@@ -583,6 +619,21 @@ UpnpPortBinding *upnp_port_binding_copy(const UpnpPortBinding *port) {
return new_port;
}
void upnp_port_binding_log(int level, const char *msg, const UpnpPortBinding *port) {
if(strlen(port->local_addr)) {
ortp_log(level, "uPnP IGD: %s %s|%d->%s:%d", msg,
(port->protocol == UPNP_IGD_IP_PROTOCOL_TCP)? "TCP":"UDP",
port->external_port,
port->local_addr,
port->local_port);
} else {
ortp_log(level, "uPnP IGD: %s %s|%d->%d", msg,
(port->protocol == UPNP_IGD_IP_PROTOCOL_TCP)? "TCP":"UDP",
port->external_port,
port->local_port);
}
}
bool_t upnp_port_binding_equal(const UpnpPortBinding *port1, const UpnpPortBinding *port2) {
return port1->protocol == port2->protocol && port1->local_port == port2->local_port &&
port1->external_port && port2->external_port;
......@@ -606,6 +657,7 @@ void upnp_port_binding_release(UpnpPortBinding *port) {
ms_mutex_unlock(&port->mutex);
}
/*
* uPnP Stream
*/
......@@ -617,7 +669,7 @@ UpnpStream* upnp_stream_new() {
stream->rtp->protocol = UPNP_IGD_IP_PROTOCOL_UDP;
stream->rtcp = upnp_port_binding_new();
stream->rtcp->protocol = UPNP_IGD_IP_PROTOCOL_UDP;
return NULL;
return stream;
}
void upnp_stream_destroy(UpnpStream* stream) {
......@@ -636,7 +688,7 @@ UpnpSession* upnp_session_new() {
session->state = LinphoneUpnpStateIdle;
session->audio = upnp_stream_new();
session->video = upnp_stream_new();
return NULL;
return session;
}
void upnp_session_destroy(LinphoneCall* call) {
......@@ -696,6 +748,7 @@ MSList *upnp_config_list_port_bindings(struct _LpConfig *lpc) {
}
if(valid) {
port = upnp_port_binding_new();
port->state = LinphoneUpnpStateOk;
port->protocol = protocol;
port->external_port = external_port;
port->local_port = local_port;
......
......@@ -72,6 +72,7 @@ typedef struct _UpnpContext {
} UpnpContext;
void linphone_core_update_local_media_description_from_upnp(SalMediaDescription *desc, UpnpSession *session);
int linphone_core_update_upnp_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md);
int linphone_core_update_upnp(LinphoneCore *lc, LinphoneCall *call);
int upnp_call_process(LinphoneCall *call);
UpnpSession* upnp_session_new();
......
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