mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-06 21:33:08 +00:00
Working call with uPnP
This commit is contained in:
parent
9567e2bf62
commit
f3805137e6
8 changed files with 184 additions and 98 deletions
|
|
@ -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));
|
||||
|
|
|
|||
171
coreapi/upnp.c
171
coreapi/upnp.c
|
|
@ -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,20 +342,88 @@ 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Video part
|
||||
*/
|
||||
strncpy(call->upnp_session->video->rtp->local_addr, local_addr, LINPHONE_IPADDR_SIZE);
|
||||
strncpy(call->upnp_session->video->rtp->external_addr, external_addr, LINPHONE_IPADDR_SIZE);
|
||||
call->upnp_session->video->rtp->local_port = call->video_port;
|
||||
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 && 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 && !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 && 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 && !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;
|
||||
|
|
@ -385,28 +440,8 @@ int upnp_call_process(LinphoneCall *call) {
|
|||
}
|
||||
|
||||
/*
|
||||
* Video part
|
||||
* Update Video state
|
||||
*/
|
||||
strncpy(call->upnp_session->video->rtp->local_addr, local_addr, LINPHONE_IPADDR_SIZE);
|
||||
strncpy(call->upnp_session->video->rtp->external_addr, external_addr, LINPHONE_IPADDR_SIZE);
|
||||
call->upnp_session->video->rtp->local_port = call->video_port;
|
||||
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) {
|
||||
// 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) {
|
||||
// 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) {
|
||||
// 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) {
|
||||
// Remove video port binding
|
||||
upnp_context_send_remove_port_binding(lc, call->upnp_session->video->rtcp);
|
||||
}
|
||||
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();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue