report call faillure because of no network at all.
strncpy(result,linphone_core_get_nat_address(lc),LINPHONE_IPADDR_SIZE);
return;
}
- if (dest==NULL) dest="87.98.157.38"; /*a public IP address*/
- if (linphone_core_get_local_ip_for(dest,result)==0)
+ if (linphone_core_get_local_ip_for(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,dest,result)==0)
return;
/*else fallback to SAL routine that will attempt to find the most realistic interface */
sal_get_default_local_ip(lc->sal,lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,result,LINPHONE_IPADDR_SIZE);
/* only do the network up checking every five seconds */
if (last_check==0 || (curtime-last_check)>=5){
- sal_get_default_local_ip(lc->sal,
- lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,
- result,LINPHONE_IPADDR_SIZE);
+ linphone_core_get_local_ip_for(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,NULL,result);
if (strcmp(result,"::1")!=0 && strcmp(result,"127.0.0.1")!=0){
new_status=TRUE;
}else new_status=FALSE;
last_check=curtime;
if (new_status!=last_status) {
+ if (new_status){
+ ms_message("New local ip address is %s",result);
+ }
set_network_reachable(lc,new_status);
last_status=new_status;
}
#undef snprintf
#include <ortp/stun.h>
+#ifdef HAVE_GETIFADDRS
+#include <net/if.h>
+#include <ifaddrs.h>
+#endif
+
#if !defined(WIN32)
return -1;
}
-int linphone_core_get_local_ip_for(const char *dest, char *result){
+#ifdef HAVE_GETIFADDRS
+
+#include <ifaddrs.h>
+static int get_local_ip_with_getifaddrs(int type, char *address, int size)
+{
+ struct ifaddrs *ifp;
+ struct ifaddrs *ifpstart;
+ int ret = 0;
+
+ if (getifaddrs(&ifpstart) < 0) {
+ return -1;
+ }
+
+ for (ifp = ifpstart; ifp != NULL; ifp = ifp->ifa_next) {
+ if (ifp->ifa_addr && ifp->ifa_addr->sa_family == type
+ && (ifp->ifa_flags & IFF_RUNNING) && !(ifp->ifa_flags & IFF_LOOPBACK))
+ {
+ 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++;
+ }
+ }
+ }
+ freeifaddrs(ifpstart);
+ return ret;
+}
+#endif
+
+
+static int get_local_ip_for_with_connect(const char *dest, char *result){
int err,tmp;
struct addrinfo hints;
struct addrinfo *res=NULL;
ms_message("Local interface to reach %s is %s.",dest,result);
return 0;
}
+
+int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
+ if (dest==NULL) {
+ if (type==AF_INET)
+ dest="87.98.157.38"; /*a public IP address*/
+ else dest="2a00:1450:8002::68";
+ }
+#ifdef HAVE_GETIFADDRS
+ {
+ 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 */
+ strcpy(result,type==AF_INET ? "127.0.0.1" : "::1");
+ return -1;
+ }
+ }
+#endif
+ /*else use connect to find the best local ip address */
+ return get_local_ip_for_with_connect(dest,result);
+}
void linphone_proxy_config_update(LinphoneProxyConfig *cfg);
void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip, int *port);
LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri);
-int linphone_core_get_local_ip_for(const char *dest, char *result);
+int linphone_core_get_local_ip_for(int type, const char *dest, char *result);
LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(struct _LpConfig *config, int index);
void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,LinphoneProxyConfig *obj, int index);
#include "sal_eXosip2.h"
#include "offeranswer.h"
-/*this function is not declared in some versions of eXosip*/
-extern void *eXosip_call_get_reference(int cid);
static void text_received(Sal *sal, eXosip_event_t *ev);
}
}
+
+static SalOp * sal_find_call(Sal *sal, int cid){
+ const MSList *elem;
+ SalOp *op;
+ for(elem=sal->calls;elem!=NULL;elem=elem->next){
+ op=(SalOp*)elem->data;
+ if (op->cid==cid) return op;
+ }
+ return NULL;
+}
+
+static void sal_add_call(Sal *sal, SalOp *op){
+ sal->calls=ms_list_append(sal->calls,op);
+}
+
+static void sal_remove_call(Sal *sal, SalOp *op){
+ sal->calls=ms_list_remove(sal->calls, op);
+}
+
static SalOp * sal_find_register(Sal *sal, int rid){
const MSList *elem;
SalOp *op;
}
if (op->cid!=-1){
ms_message("Cleaning cid %i",op->cid);
- eXosip_call_set_reference(op->cid,NULL);
+ sal_remove_call(op->base.root,op);
}
if (op->sid!=-1){
sal_remove_out_subscribe(op->base.root,op);
ms_error("Fail to send invite !");
return -1;
}else{
- eXosip_call_set_reference(h->cid,h);
+ sal_add_call(h->base.root,h);
}
return 0;
}
int sal_call_terminate(SalOp *h){
eXosip_lock();
eXosip_call_terminate(h->cid,h->did);
- eXosip_call_set_reference(h->cid,NULL);
eXosip_unlock();
+ sal_remove_call(h->base.root,h);
return 0;
}
static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
if (ev->cid>0){
-#ifdef HAVE_EXOSIP_GET_REF
- return (SalOp*)eXosip_call_get_ref(ev->cid);
-#else
- return (SalOp*)eXosip_call_get_reference(ev->cid);
-#endif
+ return sal_find_call(sal,ev->cid);
}
if (ev->rid>0){
return sal_find_register(sal,ev->rid);
op->cid=ev->cid;
op->did=ev->did;
- eXosip_call_set_reference(op->cid,op);
+ sal_add_call(op->base.root,op);
sal->callbacks.call_received(op);
}
return;
}
osip_from_to_str(ev->request->from,&from);
- eXosip_call_set_reference(ev->cid,NULL);
+ sal_remove_call(sal,op);
op->cid=-1;
sal->callbacks.call_terminated(op,from);
osip_free(from);
static void call_released(Sal *sal, eXosip_event_t *ev){
SalOp *op=find_op(sal,ev);
if (op==NULL){
+ ms_warning("No op associated to this call_released()");
return;
}
op->cid=-1;
ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
return call_failure(sal,ev);
break;
+ case EXOSIP_CALL_RELEASED:
+ ms_message("CALL_RELEASED\n");
+ call_released(sal, ev);
+ break;
case EXOSIP_CALL_INVITE:
ms_message("CALL_NEW\n");
inc_new_call(sal,ev);
case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
sal_exosip_subscription_closed(sal,ev);
break;
- case EXOSIP_CALL_RELEASED:
- ms_message("CALL_RELEASED\n");
- call_released(sal, ev);
- break;
case EXOSIP_REGISTRATION_FAILURE:
ms_message("REGISTRATION_FAILURE\n");
return registration_failure(sal,ev);
struct Sal{
SalCallbacks callbacks;
+ MSList *calls; /*MSList of SalOp */
MSList *registers;/*MSList of SalOp */
MSList *out_subscribes;/*MSList of SalOp */
MSList *in_subscribes;/*MSList of SalOp */