mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-07 05:53:06 +00:00
Merge branch 'master' of git.linphone.org:linphone
This commit is contained in:
commit
49b1b61b5a
25 changed files with 1980 additions and 1264 deletions
|
|
@ -61,7 +61,7 @@ case $target in
|
|||
CONSOLE_FLAGS="-mconsole"
|
||||
mingw_found=yes
|
||||
;;
|
||||
armv6-apple-darwin|armv7-apple-darwin|i386-apple-darwin)
|
||||
armv6-apple-darwin|armv7-apple-darwin|i386-apple-darwin|armv7s-apple-darwin)
|
||||
CFLAGS="$CFLAGS -DTARGET_OS_IPHONE "
|
||||
build_tests=no
|
||||
ios_found=yes
|
||||
|
|
|
|||
|
|
@ -212,7 +212,6 @@ TunnelManager::TunnelManager(LinphoneCore* lc) :TunnelClientController()
|
|||
mExosipTransport.recvfrom=eXosipRecvfrom;
|
||||
mExosipTransport.sendto=eXosipSendto;
|
||||
mExosipTransport.select=eXosipSelect;
|
||||
mStateChanged=false;
|
||||
linphone_core_add_iterate_hook(mCore,(LinphoneCoreIterateHook)sOnIterate,this);
|
||||
mTransportFactories.audio_rtcp_func=sCreateRtpTransport;
|
||||
mTransportFactories.audio_rtcp_func_data=this;
|
||||
|
|
@ -242,12 +241,13 @@ void TunnelManager::stopClient(){
|
|||
}
|
||||
}
|
||||
|
||||
void TunnelManager::processTunnelEvent(){
|
||||
void TunnelManager::processTunnelEvent(const Event &ev){
|
||||
LinphoneProxyConfig* lProxy;
|
||||
linphone_core_get_default_proxy(mCore, &lProxy);
|
||||
|
||||
if (mEnabled && mTunnelClient->isReady()){
|
||||
ms_message("Tunnel is up, registering now");
|
||||
ms_message("Tunnel is up, registering now");
|
||||
linphone_core_set_firewall_policy(mCore,LinphonePolicyNoFirewall);
|
||||
linphone_core_set_rtp_transport_factories(mCore,&mTransportFactories);
|
||||
eXosip_transport_hook_register(&mExosipTransport);
|
||||
//force transport to udp
|
||||
|
|
@ -296,8 +296,9 @@ void TunnelManager::enable(bool isEnable) {
|
|||
ms_message("Turning tunnel [%s]",(isEnable?"on":"off"));
|
||||
if (isEnable && !mEnabled){
|
||||
mEnabled=true;
|
||||
//1 save transport
|
||||
//1 save transport and firewall policy
|
||||
linphone_core_get_sip_transports(mCore, &mRegularTransport);
|
||||
mPreviousFirewallPolicy=linphone_core_get_firewall_policy(mCore);
|
||||
//2 unregister
|
||||
waitUnRegistration();
|
||||
//3 insert tunnel
|
||||
|
|
@ -312,8 +313,9 @@ void TunnelManager::enable(bool isEnable) {
|
|||
linphone_core_set_rtp_transport_factories(mCore,NULL);
|
||||
|
||||
eXosip_transport_hook_register(NULL);
|
||||
//Restore transport
|
||||
//Restore transport and firewall policy
|
||||
linphone_core_set_sip_transports(mCore, &mRegularTransport);
|
||||
linphone_core_set_firewall_policy(mCore, mPreviousFirewallPolicy);
|
||||
//register
|
||||
LinphoneProxyConfig* lProxy;
|
||||
linphone_core_get_default_proxy(mCore, &lProxy);
|
||||
|
|
@ -325,15 +327,31 @@ void TunnelManager::enable(bool isEnable) {
|
|||
}
|
||||
|
||||
void TunnelManager::tunnelCallback(bool connected, TunnelManager *zis){
|
||||
zis->mStateChanged=true;
|
||||
Event ev;
|
||||
ev.mType=TunnelEvent;
|
||||
ev.mData.mConnected=connected;
|
||||
zis->postEvent(ev);
|
||||
}
|
||||
|
||||
void TunnelManager::onIterate(){
|
||||
mMutex.lock();
|
||||
while(!mEvq.empty()){
|
||||
Event ev=mEvq.front();
|
||||
mEvq.pop();
|
||||
mMutex.unlock();
|
||||
if (ev.mType==TunnelEvent)
|
||||
processTunnelEvent(ev);
|
||||
else if (ev.mType==UdpMirrorClientEvent){
|
||||
processUdpMirrorEvent(ev);
|
||||
}
|
||||
mMutex.lock();
|
||||
}
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
/*invoked from linphone_core_iterate() */
|
||||
void TunnelManager::sOnIterate(TunnelManager *zis){
|
||||
if (zis->mStateChanged){
|
||||
zis->mStateChanged=false;
|
||||
zis->processTunnelEvent();
|
||||
}
|
||||
zis->onIterate();
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
|
|
@ -374,26 +392,39 @@ void TunnelManager::enableLogs(bool isEnabled,LogHandler logHandler) {
|
|||
bool TunnelManager::isEnabled() {
|
||||
return mEnabled;
|
||||
}
|
||||
void TunnelManager::UdpMirrorClientListener(bool isUdpAvailable, void* data) {
|
||||
TunnelManager* thiz = (TunnelManager*)data;
|
||||
if (isUdpAvailable) {
|
||||
|
||||
void TunnelManager::processUdpMirrorEvent(const Event &ev){
|
||||
if (ev.mData.mHaveUdp) {
|
||||
LOGI("Tunnel is not required, disabling");
|
||||
thiz->enable(false);
|
||||
thiz->mAutoDetectStarted = false;
|
||||
enable(false);
|
||||
mAutoDetectStarted = false;
|
||||
} else {
|
||||
if (++thiz->mCurrentUdpMirrorClient !=thiz->mUdpMirrorClients.end()) {
|
||||
//1 enable tunnable but also try backup server
|
||||
if (mCurrentUdpMirrorClient !=mUdpMirrorClients.end()) {
|
||||
// enable tunnel but also try backup server
|
||||
LOGI("Tunnel is required, enabling; Trying backup udp mirror");
|
||||
|
||||
UdpMirrorClient &lUdpMirrorClient=*thiz->mCurrentUdpMirrorClient;
|
||||
lUdpMirrorClient.start(TunnelManager::UdpMirrorClientListener,(void*)thiz);
|
||||
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
|
||||
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
|
||||
} else {
|
||||
LOGI("Tunnel is required, enabling; no backup udp mirror available");
|
||||
thiz->mAutoDetectStarted = false;
|
||||
mAutoDetectStarted = false;
|
||||
}
|
||||
thiz->enable(true);
|
||||
enable(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void TunnelManager::postEvent(const Event &ev){
|
||||
mMutex.lock();
|
||||
mEvq.push(ev);
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void TunnelManager::sUdpMirrorClientCallback(bool isUdpAvailable, void* data) {
|
||||
TunnelManager* thiz = (TunnelManager*)data;
|
||||
Event ev;
|
||||
ev.mType=UdpMirrorClientEvent;
|
||||
ev.mData.mHaveUdp=isUdpAvailable;
|
||||
thiz->postEvent(ev);
|
||||
}
|
||||
|
||||
void TunnelManager::autoDetect() {
|
||||
|
|
@ -409,7 +440,7 @@ void TunnelManager::autoDetect() {
|
|||
mAutoDetectStarted=true;
|
||||
mCurrentUdpMirrorClient =mUdpMirrorClients.begin();
|
||||
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
|
||||
lUdpMirrorClient.start(TunnelManager::UdpMirrorClientListener,(void*)this);
|
||||
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -130,9 +130,21 @@ class UdpMirrorClient;
|
|||
LinphoneCore *getLinphoneCore();
|
||||
virtual void setHttpProxy(const char *host,int port, const char *username, const char *passwd);
|
||||
private:
|
||||
enum EventType{
|
||||
UdpMirrorClientEvent,
|
||||
TunnelEvent,
|
||||
};
|
||||
struct Event{
|
||||
EventType mType;
|
||||
union EventData{
|
||||
bool mConnected;
|
||||
bool mHaveUdp;
|
||||
}mData;
|
||||
};
|
||||
typedef std::list<UdpMirrorClient> UdpMirrorClientList;
|
||||
virtual bool isStarted();
|
||||
virtual bool isReady() const;
|
||||
void onIterate();
|
||||
static int customSendto(struct _RtpTransport *t, mblk_t *msg , int flags, const struct sockaddr *to, socklen_t tolen);
|
||||
static int customRecvfrom(struct _RtpTransport *t, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen);
|
||||
static int eXosipSendto(int fd,const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen,void* userdata);
|
||||
|
|
@ -140,9 +152,11 @@ class UdpMirrorClient;
|
|||
static int eXosipSelect(int nfds, fd_set *s1, fd_set *s2, fd_set *s3, struct timeval *tv,void* userdata);
|
||||
static void tunnelCallback(bool connected, TunnelManager *zis);
|
||||
static void sOnIterate(TunnelManager *zis);
|
||||
static void UdpMirrorClientListener(bool result, void* data);
|
||||
static void sUdpMirrorClientCallback(bool result, void* data);
|
||||
void waitUnRegistration();
|
||||
void processTunnelEvent();
|
||||
void processTunnelEvent(const Event &ev);
|
||||
void processUdpMirrorEvent(const Event &ev);
|
||||
void postEvent(const Event &ev);
|
||||
LinphoneCore* mCore;
|
||||
LCSipTransports mRegularTransport;
|
||||
TunnelSocket *mSipSocket;
|
||||
|
|
@ -150,19 +164,21 @@ class UdpMirrorClient;
|
|||
StateCallback mCallback;
|
||||
void * mCallbackData;
|
||||
bool mEnabled;
|
||||
bool mStateChanged;
|
||||
std::queue<Event> mEvq;
|
||||
std::list <ServerAddr> mServerAddrs;
|
||||
UdpMirrorClientList mUdpMirrorClients;
|
||||
UdpMirrorClientList::iterator mCurrentUdpMirrorClient;
|
||||
TunnelClient* mTunnelClient;
|
||||
void stopClient();
|
||||
Mutex mMutex;
|
||||
static Mutex sMutex;
|
||||
bool mAutoDetectStarted;
|
||||
LinphoneRtpTransportFactories mTransportFactories;
|
||||
std::string mHttpUserName;
|
||||
std::string mHttpPasswd;
|
||||
std::string mHttpProxyHost;
|
||||
int mHttpProxyPort;
|
||||
int mHttpProxyPort;
|
||||
LinphoneFirewallPolicy mPreviousFirewallPolicy;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
|
|||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
|
|
@ -231,5 +232,11 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneChatMessage message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
|
|||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
|
|
@ -146,5 +147,12 @@ public class TutorialChatRoom implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr,
|
||||
LinphoneChatMessage message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
|
|||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
|
|
@ -156,5 +157,12 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr,
|
||||
LinphoneChatMessage message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
|
|||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
|
|
@ -187,6 +188,13 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr,
|
||||
LinphoneChatMessage message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,17 +173,26 @@ void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel){
|
|||
bcTunnel(tunnel)->autoDetect();
|
||||
}
|
||||
|
||||
static void tunnel_add_servers_from_config(LinphoneTunnel *tunnel, char* confaddress){
|
||||
char *str1;
|
||||
for(str1=confaddress;;str1=NULL){
|
||||
char *port;
|
||||
char *address=strtok(str1," "); // Not thread safe
|
||||
if (!address) break;
|
||||
port=strchr(address, ':');
|
||||
if (!port) ms_fatal("Bad tunnel address %s",confaddress);
|
||||
*port++='\0';
|
||||
linphone_tunnel_add_server(tunnel, address, atoi(port));
|
||||
}
|
||||
static void tunnel_add_servers_from_config(LinphoneTunnel *tunnel, const char* confaddress){
|
||||
char *tmp=(char*)ms_malloc0(strlen(confaddress)+1);
|
||||
const char *it=confaddress;
|
||||
int adv;
|
||||
do{
|
||||
int ret=sscanf(it,"%s%n",tmp,&adv);
|
||||
if (ret>=1){
|
||||
it+=adv;
|
||||
char *port=strchr(tmp,':');
|
||||
if (!port){
|
||||
ms_error("Tunnel server addresses incorrectly specified from config file: %s",it);
|
||||
break;
|
||||
}else{
|
||||
*port='\0';
|
||||
port++;
|
||||
bcTunnel(tunnel)->addServer(tmp, atoi(port));
|
||||
}
|
||||
}else break;
|
||||
}while(1);
|
||||
ms_free(tmp);
|
||||
}
|
||||
|
||||
static void my_ortp_logv(OrtpLogLevel level, const char *fmt, va_list args){
|
||||
|
|
@ -197,13 +206,9 @@ static void my_ortp_logv(OrtpLogLevel level, const char *fmt, va_list args){
|
|||
void linphone_tunnel_configure(LinphoneTunnel *tunnel){
|
||||
bool_t enabled=(bool_t)lp_config_get_int(config(tunnel),"tunnel","enabled",FALSE);
|
||||
const char* addresses=lp_config_get_string(config(tunnel),"tunnel","server_addresses", NULL);
|
||||
char *copy=addresses ? ms_strdup(addresses) : NULL;
|
||||
linphone_tunnel_enable_logs_with_handler(tunnel,TRUE,my_ortp_logv);
|
||||
linphone_tunnel_clean_servers(tunnel);
|
||||
if (copy){
|
||||
tunnel_add_servers_from_config(tunnel,copy);
|
||||
ms_free(copy);
|
||||
}
|
||||
if (addresses)
|
||||
tunnel_add_servers_from_config(tunnel,addresses);
|
||||
linphone_tunnel_enable(tunnel, enabled);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,10 +62,10 @@ void linphone_tunnel_add_server(LinphoneTunnel *tunnel, const char *host, int po
|
|||
* @param tunnel object
|
||||
* @param host tunnel server ip address
|
||||
* @param port tunnel server tls port, recommended value is 443
|
||||
* @param remote_udp_mirror remote port on the tunnel server side used to test udp reachability
|
||||
* @param remote_udp_mirror_port remote port on the tunnel server side used to test udp reachability
|
||||
* @param delay udp packet round trip delay in ms considered as acceptable. recommended value is 1000 ms.
|
||||
*/
|
||||
void linphone_tunnel_add_server_and_mirror(LinphoneTunnel *tunnel, const char *host, int port, int remote_udp_mirror, int delay);
|
||||
void linphone_tunnel_add_server_and_mirror(LinphoneTunnel *tunnel, const char *host, int port, int remote_udp_mirror_port, int delay);
|
||||
/**
|
||||
* @param tunnel object
|
||||
* returns a string of space separated list of host:port of tunnel server addresses
|
||||
|
|
@ -98,16 +98,37 @@ bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel);
|
|||
**/
|
||||
void linphone_tunnel_reconnect(LinphoneTunnel *tunnel);
|
||||
/**
|
||||
* Start tunnel need detection.
|
||||
* @param tunnel object
|
||||
* In auto detect mode, the tunnel manager try to establish a real time rtp cummunication with the tunnel server on specified port.
|
||||
*<br>In case of success, the tunnel is automatically turned off. Otherwise, if no udp commmunication is feasible, tunnel mode is turned on.
|
||||
*<br> Call this method each time to run the auto detection algorithm
|
||||
*/
|
||||
void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel);
|
||||
|
||||
/**
|
||||
* Set an optional http proxy to go through when connecting to tunnel server.
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @param host Http proxy host.
|
||||
* @param port http proxy port.
|
||||
* @param username optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed.
|
||||
* @param password optional http proxy password. Use NULL if not needed.
|
||||
**/
|
||||
void linphone_tunnel_set_http_proxy(LinphoneTunnel *tunnel, const char *host, int port, const char* username,const char* passwd);
|
||||
void linphone_tunnel_set_http_proxy_auth_info(LinphoneTunnel*tunnel, const char* username,const char* passwd);
|
||||
|
||||
/**
|
||||
* Retrieve optional http proxy configuration previously set with linphone_tunnel_set_http_proxy().
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @param host Http proxy host.
|
||||
* @param port http proxy port.
|
||||
* @param username optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed.
|
||||
* @param password optional http proxy password. Use NULL if not needed.
|
||||
**/
|
||||
void linphone_tunnel_get_http_proxy(LinphoneTunnel*tunnel,const char **host, int *port, const char **username, const char **passwd);
|
||||
|
||||
void linphone_tunnel_set_http_proxy_auth_info(LinphoneTunnel*tunnel, const char* username,const char* passwd);
|
||||
|
||||
|
||||
void linphone_tunnel_enable_logs(LinphoneTunnel *tunnel, bool_t enabled);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1732,12 +1732,17 @@ const LinphoneCallStats *linphone_call_get_video_stats(const LinphoneCall *call)
|
|||
* @}
|
||||
**/
|
||||
|
||||
static void display_bandwidth(RtpSession *as, RtpSession *vs){
|
||||
static void report_bandwidth(LinphoneCall *call, RtpSession *as, RtpSession *vs){
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].download_bandwidth=(as!=NULL) ? (rtp_session_compute_recv_bandwidth(as)*1e-3) : 0;
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].upload_bandwidth=(as!=NULL) ? (rtp_session_compute_send_bandwidth(as)*1e-3) : 0;
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].download_bandwidth=(vs!=NULL) ? (rtp_session_compute_recv_bandwidth(vs)*1e-3) : 0;
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].upload_bandwidth=(vs!=NULL) ? (rtp_session_compute_send_bandwidth(vs)*1e-3) : 0;
|
||||
ms_message("bandwidth usage: audio=[d=%.1f,u=%.1f] video=[d=%.1f,u=%.1f] kbit/sec",
|
||||
(as!=NULL) ? (rtp_session_compute_recv_bandwidth(as)*1e-3) : 0,
|
||||
(as!=NULL) ? (rtp_session_compute_send_bandwidth(as)*1e-3) : 0,
|
||||
(vs!=NULL) ? (rtp_session_compute_recv_bandwidth(vs)*1e-3) : 0,
|
||||
(vs!=NULL) ? (rtp_session_compute_send_bandwidth(vs)*1e-3) : 0);
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].download_bandwidth,
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].upload_bandwidth ,
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].download_bandwidth,
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].upload_bandwidth
|
||||
);
|
||||
}
|
||||
|
||||
static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){
|
||||
|
|
@ -1769,7 +1774,6 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
|
|||
if (ice_session_role(call->ice_session) == IR_Controlling) {
|
||||
ice_session_select_candidates(call->ice_session);
|
||||
linphone_core_update_call(call->core, call, &call->current_params);
|
||||
linphone_core_update_ice_state_in_call_stats(call);
|
||||
}
|
||||
break;
|
||||
case IS_Failed:
|
||||
|
|
@ -1778,13 +1782,13 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
|
|||
/* At least one ICE session has succeeded, so perform a call update. */
|
||||
ice_session_select_candidates(call->ice_session);
|
||||
linphone_core_update_call(call->core, call, &call->current_params);
|
||||
linphone_core_update_ice_state_in_call_stats(call);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
linphone_core_update_ice_state_in_call_stats(call);
|
||||
} else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) {
|
||||
int ping_time = -1;
|
||||
if (evd->info.ice_processing_successful==TRUE) {
|
||||
|
|
@ -1848,7 +1852,7 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
video_load=ms_ticker_get_average_load(call->videostream->ticker);
|
||||
vs=call->videostream->session;
|
||||
}
|
||||
display_bandwidth(as,vs);
|
||||
report_bandwidth(call,as,vs);
|
||||
ms_message("Thread processing load: audio=%f\tvideo=%f",audio_load,video_load);
|
||||
}
|
||||
#ifdef VIDEO_ENABLED
|
||||
|
|
|
|||
|
|
@ -844,6 +844,7 @@ static void video_config_read(LinphoneCore *lc){
|
|||
ms_message("we are using a specific display:%s\n",lc->video_conf.displaytype);
|
||||
|
||||
linphone_core_enable_video(lc,capture,display);
|
||||
linphone_core_enable_video_preview(lc,lp_config_get_int(lc->config,"video","show_local",0));
|
||||
linphone_core_enable_self_view(lc,self_view);
|
||||
linphone_core_set_video_policy(lc,&vpol);
|
||||
#endif
|
||||
|
|
@ -4095,6 +4096,8 @@ void linphone_core_set_native_preview_window_id(LinphoneCore *lc, unsigned long
|
|||
LinphoneCall *call=linphone_core_get_current_call(lc);
|
||||
if (call!=NULL && call->videostream){
|
||||
video_stream_set_native_preview_window_id(call->videostream,id);
|
||||
}else if (lc->previewstream){
|
||||
video_preview_set_native_window_id(lc->previewstream,id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,6 +267,7 @@ typedef struct _LinphoneCall LinphoneCall;
|
|||
**/
|
||||
enum _LinphoneIceState{
|
||||
LinphoneIceStateNotActivated, /**< ICE has not been activated for this call */
|
||||
LinphoneIceStateFailed, /**< ICE processing has failed */
|
||||
LinphoneIceStateInProgress, /**< ICE process is in progress */
|
||||
LinphoneIceStateHostConnection, /**< ICE has established a direct connection to the remote host */
|
||||
LinphoneIceStateReflexiveConnection, /**< ICE has established a connection to the remote host through one or several NATs */
|
||||
|
|
@ -304,6 +305,8 @@ struct _LinphoneCallStats {
|
|||
mblk_t* sent_rtcp;/**<Last RTCP packet sent, as a mblk_t structure. See oRTP documentation for details how to extract information from it*/
|
||||
float round_trip_delay; /**<Round trip propagation time in seconds if known, -1 if unknown.*/
|
||||
LinphoneIceState ice_state; /**< State of ICE processing. */
|
||||
float download_bandwidth; /**<Download bandwidth measurement of received stream, expressed in kbit/s, including IP/UDP/RTP headers*/
|
||||
float upload_bandwidth; /**<Download bandwidth measurement of sent stream, expressed in kbit/s, including IP/UDP/RTP headers*/
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ public:
|
|||
|
||||
/*void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);*/
|
||||
textReceivedId = env->GetMethodID(listenerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V");
|
||||
messageReceivedId = env->GetMethodID(listenerClass,"messageReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Lorg/linphone/core/LinphoneChatMessage;)V");
|
||||
messageReceivedId = env->GetMethodID(listenerClass,"messageReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneChatMessage;)V");
|
||||
|
||||
proxyClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl"));
|
||||
proxyCtrId = env->GetMethodID(proxyClass,"<init>", "(J)V");
|
||||
|
|
@ -161,7 +161,7 @@ public:
|
|||
callCtrId = env->GetMethodID(callClass,"<init>", "(J)V");
|
||||
|
||||
chatMessageClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessageImpl"));
|
||||
chatMessageCtrId = env->GetMethodID(chatMessageClass,"<init>", "(J)V");
|
||||
if (chatMessageClass) chatMessageCtrId = env->GetMethodID(chatMessageClass,"<init>", "(J)V");
|
||||
|
||||
chatRoomClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatRoomImpl"));
|
||||
chatRoomCtrId = env->GetMethodID(chatRoomClass,"<init>", "(J)V");
|
||||
|
|
@ -402,7 +402,6 @@ public:
|
|||
,lcData->messageReceivedId
|
||||
,lcData->core
|
||||
,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room)
|
||||
,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)msg->from)
|
||||
,env->NewObject(lcData->chatMessageClass,lcData->chatMessageCtrId,(jlong)msg));
|
||||
}
|
||||
static void ecCalibrationStatus(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data) {
|
||||
|
|
@ -1426,10 +1425,15 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setExternalBodyUr
|
|||
linphone_chat_message_set_external_body_url((LinphoneChatMessage *)ptr, url);
|
||||
env->ReleaseStringUTFChars(jurl, url);
|
||||
}
|
||||
extern "C" long Java_org_linphone_core_LinphoneChatMessageImpl_getPeerAddress(JNIEnv* env
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneChatMessageImpl_getFrom(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (long) linphone_chat_message_get_peer_address((LinphoneChatMessage*)ptr);
|
||||
return (jlong) linphone_chat_message_get_from((LinphoneChatMessage*)ptr);
|
||||
}
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneChatMessageImpl_getPeerAddress(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (jlong) linphone_chat_message_get_peer_address((LinphoneChatMessage*)ptr);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage(JNIEnv* env
|
||||
,jobject thiz
|
||||
|
|
|
|||
|
|
@ -641,37 +641,46 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
|
|||
{
|
||||
IceCheckList *audio_check_list;
|
||||
IceCheckList *video_check_list;
|
||||
IceSessionState session_state;
|
||||
|
||||
if (call->ice_session == NULL) return;
|
||||
audio_check_list = ice_session_check_list(call->ice_session, 0);
|
||||
video_check_list = ice_session_check_list(call->ice_session, 1);
|
||||
if (audio_check_list == NULL) return;
|
||||
|
||||
switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) {
|
||||
case ICT_HostCandidate:
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection;
|
||||
break;
|
||||
case ICT_ServerReflexiveCandidate:
|
||||
case ICT_PeerReflexiveCandidate:
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection;
|
||||
break;
|
||||
case ICT_RelayedCandidate:
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection;
|
||||
break;
|
||||
}
|
||||
if (call->params.has_video && (video_check_list != NULL)) {
|
||||
switch (ice_check_list_selected_valid_candidate_type(video_check_list)) {
|
||||
session_state = ice_session_state(call->ice_session);
|
||||
if ((session_state == IS_Completed) || ((session_state == IS_Failed) && (ice_session_has_completed_check_list(call->ice_session) == TRUE))) {
|
||||
switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) {
|
||||
case ICT_HostCandidate:
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateHostConnection;
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection;
|
||||
break;
|
||||
case ICT_ServerReflexiveCandidate:
|
||||
case ICT_PeerReflexiveCandidate:
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateReflexiveConnection;
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection;
|
||||
break;
|
||||
case ICT_RelayedCandidate:
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateRelayConnection;
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection;
|
||||
break;
|
||||
}
|
||||
if (call->params.has_video && (video_check_list != NULL)) {
|
||||
switch (ice_check_list_selected_valid_candidate_type(video_check_list)) {
|
||||
case ICT_HostCandidate:
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateHostConnection;
|
||||
break;
|
||||
case ICT_ServerReflexiveCandidate:
|
||||
case ICT_PeerReflexiveCandidate:
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateReflexiveConnection;
|
||||
break;
|
||||
case ICT_RelayedCandidate:
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateRelayConnection;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed;
|
||||
if (call->params.has_video && (video_check_list != NULL)) {
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -685,8 +694,12 @@ void linphone_core_update_local_media_description_from_ice(SalMediaDescription *
|
|||
|
||||
if (session_state == IS_Completed) {
|
||||
desc->ice_completed = TRUE;
|
||||
ice_check_list_selected_valid_local_candidate(ice_session_check_list(session, 0), &rtp_addr, NULL, NULL, NULL);
|
||||
strncpy(desc->addr, rtp_addr, sizeof(desc->addr));
|
||||
result = ice_check_list_selected_valid_local_candidate(ice_session_check_list(session, 0), &rtp_addr, NULL, NULL, NULL);
|
||||
if (result == TRUE) {
|
||||
strncpy(desc->addr, rtp_addr, sizeof(desc->addr));
|
||||
} else {
|
||||
ms_warning("If ICE has completed successfully, rtp_addr should be set!");
|
||||
}
|
||||
}
|
||||
else {
|
||||
desc->ice_completed = FALSE;
|
||||
|
|
@ -879,6 +892,10 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call,
|
|||
ice_session_remove_check_list(call->ice_session, ice_session_check_list(call->ice_session, i - 1));
|
||||
}
|
||||
ice_session_check_mismatch(call->ice_session);
|
||||
} else {
|
||||
/* Response from remote does not contain mandatory ICE attributes, delete the session. */
|
||||
linphone_call_delete_ice_session(call);
|
||||
return;
|
||||
}
|
||||
if (ice_session_nb_check_lists(call->ice_session) == 0) {
|
||||
linphone_call_delete_ice_session(call);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ UI_FILES= about.ui \
|
|||
buddylookup.ui \
|
||||
tunnel_config.ui \
|
||||
waiting.ui \
|
||||
dscp_settings.ui
|
||||
dscp_settings.ui \
|
||||
call_statistics.ui
|
||||
|
||||
PIXMAPS= \
|
||||
stock_people.png
|
||||
|
|
|
|||
212
gtk/call_statistics.ui
Normal file
212
gtk/call_statistics.ui
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.24"/>
|
||||
<!-- interface-naming-policy project-wide -->
|
||||
<object class="GtkDialog" id="call_statistics">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Call statistics</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<signal name="response" handler="linphone_gtk_call_statistics_closed" swapped="no"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="n_rows">6</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="audio_codec_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Audio codec</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="video_codec_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Video codec</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Audio IP bandwidth usage</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="audio_codec">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="video_codec">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="audio_bandwidth_usage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Media connectivity</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="media_connectivity">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Video IP bandwidth usage</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="video_bandwidth_usage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="call_statistics_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Call statistics and information</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="0">button1</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -193,6 +193,100 @@ void linphone_gtk_enable_conference_button(LinphoneCore *lc, gboolean value){
|
|||
}
|
||||
}
|
||||
|
||||
static void show_used_codecs(GtkWidget *callstats, LinphoneCall *call){
|
||||
const LinphoneCallParams *params=linphone_call_get_current_params(call);
|
||||
if (params){
|
||||
const PayloadType *acodec=linphone_call_params_get_used_audio_codec(params);
|
||||
const PayloadType *vcodec=linphone_call_params_get_used_video_codec(params);
|
||||
GtkWidget *acodec_ui=linphone_gtk_get_widget(callstats,"audio_codec");
|
||||
GtkWidget *vcodec_ui=linphone_gtk_get_widget(callstats,"video_codec");
|
||||
if (acodec){
|
||||
|
||||
char tmp[64]={0};
|
||||
snprintf(tmp,sizeof(tmp)-1,"%s/%i/%i",acodec->mime_type,acodec->clock_rate,acodec->channels);
|
||||
gtk_label_set_label(GTK_LABEL(acodec_ui),tmp);
|
||||
}else gtk_label_set_label(GTK_LABEL(acodec_ui),_("Not used"));
|
||||
if (vcodec){
|
||||
gtk_label_set_label(GTK_LABEL(vcodec_ui),vcodec->mime_type);
|
||||
}else gtk_label_set_label(GTK_LABEL(vcodec_ui),_("Not used"));
|
||||
}
|
||||
}
|
||||
|
||||
static const char *ice_state_to_string(LinphoneIceState ice_state){
|
||||
switch(ice_state){
|
||||
case LinphoneIceStateNotActivated:
|
||||
return _("Ice not activated");
|
||||
case LinphoneIceStateInProgress:
|
||||
return _("ICE in progress");
|
||||
case LinphoneIceStateReflexiveConnection:
|
||||
return _("Going through one or more NATs");
|
||||
case LinphoneIceStateHostConnection:
|
||||
return _("Direct");
|
||||
case LinphoneIceStateRelayConnection:
|
||||
return _("Through a relay server");
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
static void _refresh_call_stats(GtkWidget *callstats, LinphoneCall *call){
|
||||
const LinphoneCallStats *as=linphone_call_get_audio_stats(call);
|
||||
const LinphoneCallStats *vs=linphone_call_get_video_stats(call);
|
||||
LinphoneIceState ice_state=as->ice_state;
|
||||
gchar *tmp=g_strdup_printf(_("download: %f\nupload: %f (kbit/s)"),
|
||||
as->download_bandwidth,as->upload_bandwidth);
|
||||
gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"audio_bandwidth_usage")),tmp);
|
||||
g_free(tmp);
|
||||
tmp=g_strdup_printf(_("download: %f\nupload: %f (kbit/s)"),
|
||||
vs->download_bandwidth,vs->upload_bandwidth);
|
||||
gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"video_bandwidth_usage")),tmp);
|
||||
g_free(tmp);
|
||||
gtk_label_set_text(GTK_LABEL(linphone_gtk_get_widget(callstats,"media_connectivity")),ice_state_to_string(ice_state));
|
||||
}
|
||||
|
||||
static gboolean refresh_call_stats(GtkWidget *callstats){
|
||||
LinphoneCall *call=(LinphoneCall*)g_object_get_data(G_OBJECT(callstats),"call");
|
||||
switch (linphone_call_get_state(call)){
|
||||
case LinphoneCallError:
|
||||
case LinphoneCallEnd:
|
||||
case LinphoneCallReleased:
|
||||
gtk_widget_destroy(callstats);
|
||||
return FALSE;
|
||||
break;
|
||||
case LinphoneCallStreamsRunning:
|
||||
_refresh_call_stats(callstats,call);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void on_call_stats_destroyed(GtkWidget *call_view){
|
||||
GtkWidget *call_stats=(GtkWidget*)g_object_get_data(G_OBJECT(call_view),"call_stats");
|
||||
LinphoneCall *call=(LinphoneCall*)g_object_get_data(G_OBJECT(call_stats),"call");
|
||||
g_source_remove(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(call_stats),"tid")));
|
||||
g_object_set_data(G_OBJECT(call_view),"call_stats",NULL);
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
|
||||
static void linphone_gtk_show_call_stats(LinphoneCall *call){
|
||||
GtkWidget *w=(GtkWidget*)linphone_call_get_user_pointer(call);
|
||||
GtkWidget *call_stats=(GtkWidget*)g_object_get_data(G_OBJECT(w),"call_stats");
|
||||
if (call_stats==NULL){
|
||||
guint tid;
|
||||
call_stats=linphone_gtk_create_window("call_statistics");
|
||||
g_object_set_data(G_OBJECT(w),"call_stats",call_stats);
|
||||
g_object_set_data(G_OBJECT(call_stats),"call",linphone_call_ref(call));
|
||||
tid=g_timeout_add(1000,(GSourceFunc)refresh_call_stats,call_stats);
|
||||
g_object_set_data(G_OBJECT(call_stats),"tid",GINT_TO_POINTER(tid));
|
||||
g_signal_connect_swapped(G_OBJECT(call_stats),"destroy",(GCallback)on_call_stats_destroyed,(gpointer)w);
|
||||
show_used_codecs(call_stats,call);
|
||||
refresh_call_stats(call_stats);
|
||||
gtk_widget_show(call_stats);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void linphone_gtk_create_in_call_view(LinphoneCall *call){
|
||||
GtkWidget *call_view=linphone_gtk_create_widget("main","in_call_frame");
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window ();
|
||||
|
|
@ -217,6 +311,7 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){
|
|||
linphone_gtk_enable_hold_button (call,FALSE,TRUE);
|
||||
linphone_gtk_enable_mute_button(
|
||||
GTK_BUTTON(linphone_gtk_get_widget(call_view,"incall_mute")),FALSE);
|
||||
g_signal_connect_swapped(G_OBJECT(linphone_gtk_get_widget(call_view,"quality_indicator")),"button-press-event",(GCallback)linphone_gtk_show_call_stats,call);
|
||||
}
|
||||
|
||||
static void video_button_clicked(GtkWidget *button, LinphoneCall *call){
|
||||
|
|
@ -506,6 +601,7 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){
|
|||
GtkWidget *duration=linphone_gtk_get_widget(callview,"in_call_duration");
|
||||
guint taskid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(callview),"taskid"));
|
||||
gboolean in_conf=linphone_call_params_local_conference_mode(linphone_call_get_current_params(call));
|
||||
GtkWidget *call_stats=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"call_stats");
|
||||
|
||||
display_peer_name_in_label(callee,linphone_call_get_remote_address (call));
|
||||
|
||||
|
|
@ -524,6 +620,7 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){
|
|||
linphone_gtk_in_call_view_enable_audio_view(call, !in_conf);
|
||||
linphone_gtk_in_call_view_show_encryption(call);
|
||||
if (in_conf) linphone_gtk_set_in_conference(call);
|
||||
if (call_stats) show_used_codecs(call_stats,call);
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_set_paused(LinphoneCall *call){
|
||||
|
|
@ -676,3 +773,8 @@ void linphone_gtk_enable_hold_button(LinphoneCall *call, gboolean sensitive, gbo
|
|||
gtk_widget_set_visible(GTK_WIDGET(button),sensitive);
|
||||
linphone_gtk_draw_hold_button(GTK_BUTTON(button),!holdon);
|
||||
}
|
||||
|
||||
void linphone_gtk_call_statistics_closed(GtkWidget *call_stats){
|
||||
gtk_widget_destroy(call_stats);
|
||||
}
|
||||
|
||||
|
|
|
|||
2593
gtk/main.ui
2593
gtk/main.ui
File diff suppressed because it is too large
Load diff
|
|
@ -74,6 +74,13 @@ public interface LinphoneChatMessage {
|
|||
*/
|
||||
LinphoneAddress getPeerAddress();
|
||||
|
||||
/**
|
||||
* get from address associated to this LinphoneChatMessage
|
||||
*
|
||||
* @return LinphoneAddress from address
|
||||
*/
|
||||
LinphoneAddress getFrom();
|
||||
|
||||
/**
|
||||
* Linphone message can carry external body as defined by rfc2017
|
||||
* @param message #LinphoneChatMessage
|
||||
|
|
|
|||
|
|
@ -40,12 +40,6 @@ public interface LinphoneChatRoom {
|
|||
* @param chat message
|
||||
*/
|
||||
void sendMessage(LinphoneChatMessage message, LinphoneChatMessage.StateListener listener);
|
||||
/**
|
||||
* DEPRECATED
|
||||
* @param opaque
|
||||
* @param message
|
||||
*/
|
||||
void sendMessage(Object opaque, String message);
|
||||
|
||||
/**
|
||||
* Create a LinphoneChatMessage
|
||||
|
|
|
|||
|
|
@ -491,11 +491,17 @@ public interface LinphoneCore {
|
|||
*/
|
||||
void clearCallLogs();
|
||||
/***
|
||||
* get payload type from mime type an clock rate
|
||||
* get payload type from mime type, clock rate, and number of channels.-
|
||||
*
|
||||
* return null if not found
|
||||
*/
|
||||
PayloadType findPayloadType(String mime, int clockRate, int channels);
|
||||
/***
|
||||
* get payload type from mime type and clock rate..
|
||||
*
|
||||
* return null if not found
|
||||
*/
|
||||
PayloadType findPayloadType(String mime, int clockRate);
|
||||
/**
|
||||
* not implemented yet
|
||||
* @param pt
|
||||
|
|
@ -677,6 +683,10 @@ public interface LinphoneCore {
|
|||
void startEchoCalibration(Object data) throws LinphoneCoreException;
|
||||
|
||||
void enableIpv6(boolean enable);
|
||||
/**
|
||||
* @deprecated
|
||||
* @param i
|
||||
*/
|
||||
void adjustSoftwareVolume(int i);
|
||||
|
||||
boolean pauseCall(LinphoneCall call);
|
||||
|
|
|
|||
|
|
@ -82,10 +82,9 @@ public interface LinphoneCoreListener {
|
|||
* invoked when a new linphone chat message is received
|
||||
* @param lc LinphoneCore
|
||||
* @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room.
|
||||
* @param from LinphoneAddress from
|
||||
* @param message incoming linphone chat message message
|
||||
*/
|
||||
void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneAddress from, LinphoneChatMessage message);
|
||||
void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneChatMessage message);
|
||||
|
||||
/**
|
||||
* Invoked when echo cancalation calibration is completed
|
||||
|
|
|
|||
|
|
@ -5,13 +5,7 @@ AC_REQUIRE([LP_CHECK_OSIP2])
|
|||
|
||||
|
||||
case $host_alias in
|
||||
i386-apple*)
|
||||
OSIP_LIBS="$OSIP_LIBS -framework CoreFoundation -framework CFNetwork -lresolv"
|
||||
;;
|
||||
armv6-apple*)
|
||||
OSIP_LIBS="$OSIP_LIBS -framework CoreFoundation -framework CFNetwork -lresolv"
|
||||
;;
|
||||
armv7-apple*)
|
||||
i386-apple*|armv6-apple*|armv7-apple*|armv7s-apple*)
|
||||
OSIP_LIBS="$OSIP_LIBS -framework CoreFoundation -framework CFNetwork -lresolv"
|
||||
;;
|
||||
x86_64-apple*)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 88b9146ccbd33c9d8d3317be92078f6211498907
|
||||
Subproject commit f225ee612009009075ab6caf7ef91bb3a21fa25f
|
||||
|
|
@ -25,6 +25,7 @@ gtk/loginframe.c
|
|||
[type: gettext/glade]gtk/buddylookup.ui
|
||||
[type: gettext/glade]gtk/waiting.ui
|
||||
[type: gettext/glade]gtk/dscp_settings.ui
|
||||
[type: gettext/glade]gtk/call_statistics.ui
|
||||
[type: gettext/glade]gtk/tunnel_config.ui
|
||||
coreapi/linphonecore.c
|
||||
coreapi/misc.c
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue