Commit a846e812 authored by Sylvain Berfini's avatar Sylvain Berfini

Updated liblinphone to add RFC3994 and improve calculation of call stats

parent 859fb3ea
......@@ -147,6 +147,13 @@ namespace Linphone.Agents
public void MessageReceived(LinphoneChatMessage message)
{
}
/// <summary>
/// Callback for LinphoneCoreListener
/// </summary>
public void ComposingReceived(LinphoneChatRoom room)
{
}
#endregion
}
}
......@@ -3,12 +3,6 @@
#include "LinphoneCall.h"
#include "Server.h"
// Do not treat doxygen documentation as XML
#pragma warning(push)
#pragma warning(disable : 4635)
#include "coreapi\private.h"
#pragma warning(pop)
Linphone::Core::MediaType Linphone::Core::LinphoneCallStats::GetMediaType()
{
return this->mediaType;
......@@ -100,140 +94,44 @@ Linphone::Core::LinphoneCallStats::~LinphoneCallStats()
}
float Linphone::Core::LinphoneCallStats::UpdateSenderLossRate(const ::LinphoneCallStats *stats)
{
const report_block_t *srb = NULL;
if (!stats || !stats->sent_rtcp)
return 0.0;
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
if (stats->sent_rtcp->b_cont != NULL)
msgpullup(stats->sent_rtcp, -1);
if (rtcp_is_SR(stats->sent_rtcp))
srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0);
else if (rtcp_is_RR(stats->sent_rtcp))
srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0);
if (!srb)
return 0.0;
return (100.0f * report_block_get_fraction_lost(srb) / 256.0f);
gApiLock.Lock();
float value = linphone_call_stats_update_sender_loss_rate(stats);
gApiLock.Unlock();
return value;
}
float Linphone::Core::LinphoneCallStats::UpdateReceiverLossRate(const ::LinphoneCallStats *stats)
{
const report_block_t* rrb = NULL;
if (!stats || !stats->received_rtcp)
return 0.0;
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
if (stats->received_rtcp->b_cont != NULL)
msgpullup(stats->received_rtcp, -1);
if (rtcp_is_RR(stats->received_rtcp))
rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0);
else if (rtcp_is_SR(stats->received_rtcp))
rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0);
if (!rrb)
return 0.0;
return (100.0f * report_block_get_fraction_lost(rrb) / 256.0f);
gApiLock.Lock();
float value = linphone_call_stats_update_receiver_loss_rate(stats);
gApiLock.Unlock();
return value;
}
float Linphone::Core::LinphoneCallStats::UpdateSenderInterarrivalJitter(const ::LinphoneCallStats *stats)
{
const ::LinphoneCallParams* params;
const ::PayloadType* pt;
const report_block_t* srb = NULL;
if (!stats || !this->call || !stats->sent_rtcp)
return 0.0;
params = linphone_call_get_current_params(this->call);
if (!params)
return 0.0;
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
if (stats->sent_rtcp->b_cont != NULL)
msgpullup(stats->sent_rtcp, -1);
if (rtcp_is_SR(stats->sent_rtcp))
srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0);
else if (rtcp_is_RR(stats->sent_rtcp))
srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0);
if (!srb)
return 0.0;
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
pt = linphone_call_params_get_used_audio_codec(params);
else
pt = linphone_call_params_get_used_video_codec(params);
if (!pt || (pt->clock_rate == 0))
return 0.0;
return ((float)report_block_get_interarrival_jitter(srb) / (float)pt->clock_rate);
gApiLock.Lock();
float value = linphone_call_stats_update_sender_interarrival_jitter(stats, this->call);
gApiLock.Unlock();
return value;
}
float Linphone::Core::LinphoneCallStats::UpdateReceiverInterarrivalJitter(const ::LinphoneCallStats *stats)
{
const ::LinphoneCallParams* params;
const ::PayloadType* pt;
const report_block_t* rrb = NULL;
if (!stats || !this->call || !stats->received_rtcp)
return 0.0;
params = linphone_call_get_current_params(this->call);
if (!params)
return 0.0;
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
if (stats->received_rtcp->b_cont != NULL)
msgpullup(stats->received_rtcp, -1);
if (rtcp_is_SR(stats->received_rtcp))
rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0);
else if (rtcp_is_RR(stats->received_rtcp))
rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0);
if (!rrb)
return 0.0;
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
pt = linphone_call_params_get_used_audio_codec(params);
else
pt = linphone_call_params_get_used_video_codec(params);
if (!pt || (pt->clock_rate == 0))
return 0.0;
return ((float)report_block_get_interarrival_jitter(rrb) / (float)pt->clock_rate);
gApiLock.Lock();
float value = linphone_call_stats_update_receiver_interarrival_jitter(stats, this->call);
gApiLock.Unlock();
return value;
}
int64 Linphone::Core::LinphoneCallStats::UpdateLatePacketsCumulativeNumber(const ::LinphoneCallStats *stats)
{
rtp_stats_t rtp_stats;
if (!stats || !this->call)
return 0;
memset(&rtp_stats, 0, sizeof(rtp_stats));
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
audio_stream_get_local_rtp_stats(this->call->audiostream, &rtp_stats);
#ifdef VIDEO_ENABLED
else
video_stream_get_local_rtp_stats(this->call->videostream, &rtp_stats);
#endif
return rtp_stats.outoftime;
gApiLock.Lock();
int64 value = linphone_call_stats_update_late_packets_cumulative_number(stats, this->call);
gApiLock.Unlock();
return value;
}
void Linphone::Core::LinphoneCallStats::FillStats(const ::LinphoneCallStats *stats)
......
......@@ -43,6 +43,21 @@ Linphone::Core::LinphoneChatMessage^ Linphone::Core::LinphoneChatRoom::CreateLin
return chatMessage;
}
Platform::Boolean Linphone::Core::LinphoneChatRoom::IsRemoteComposing()
{
gApiLock.Lock();
Platform::Boolean isComposing = (linphone_chat_room_is_remote_composing(this->room) == TRUE);
gApiLock.Unlock();
return isComposing;
}
void Linphone::Core::LinphoneChatRoom::Compose()
{
gApiLock.Lock();
linphone_chat_room_compose(this->room);
gApiLock.Unlock();
}
Linphone::Core::LinphoneChatRoom::LinphoneChatRoom(::LinphoneChatRoom *cr) :
room(cr)
{
......
......@@ -27,6 +27,16 @@ namespace Linphone
/// Sends a LinphoneChatMessage using the current ChatRoom, and sets the listener to be called when the massge state changes.
/// </summary>
void SendMessage(Linphone::Core::LinphoneChatMessage^ message, Linphone::Core::LinphoneChatMessageListener^ listener);
/// <summary>
/// Tells whether the remote is currently composing a message.
/// </summary>
Platform::Boolean IsRemoteComposing();
/// <summary>
/// Notify the destination of the chat message being composed that the user is typing a new message.
/// </summary>
void Compose();
/// <summary>
/// Creates a LinphoneChatMessage from a String.
......
......@@ -1550,6 +1550,22 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom* chat_room, LinphoneCha
Linphone::Core::gApiLock.LeaveListener();
}
void composing_received(LinphoneCore *lc, LinphoneChatRoom *room)
{
Linphone::Core::gApiLock.EnterListener();
Linphone::Core::LinphoneCoreListener^ listener = Linphone::Core::Globals::Instance->LinphoneCore->CoreListener;
if (listener != nullptr)
{
Linphone::Core::RefToPtrProxy<Linphone::Core::LinphoneChatRoom^> *proxy = reinterpret_cast< Linphone::Core::RefToPtrProxy<Linphone::Core::LinphoneChatRoom^> *>(linphone_chat_room_get_user_data(room));
Linphone::Core::LinphoneChatRoom^ lRoom = (proxy) ? proxy->Ref() : nullptr;
if (lRoom == nullptr) {
lRoom = (Linphone::Core::LinphoneChatRoom^)Linphone::Core::Utils::CreateLinphoneChatRoom(room);
}
listener->ComposingReceived(lRoom);
}
Linphone::Core::gApiLock.LeaveListener();
}
Linphone::Core::LinphoneCore::LinphoneCore(LinphoneCoreListener^ coreListener) :
lc(nullptr),
listener(coreListener)
......@@ -1610,6 +1626,7 @@ void Linphone::Core::LinphoneCore::Init()
vtable->call_encryption_changed = call_encryption_changed;
vtable->call_stats_updated = call_stats_updated;
vtable->message_received = message_received;
vtable->is_composing_received = composing_received;
this->lc = linphone_core_new_with_config(vtable, config ? config->config : NULL, NULL);
RefToPtrProxy<LinphoneCore^> *proxy = new RefToPtrProxy<LinphoneCore^>(this);
......
......@@ -10,6 +10,7 @@ namespace Linphone
ref class LinphoneProxyConfig;
ref class LinphoneCallStats;
ref class LinphoneChatMessage;
ref class LinphoneChatRoom;
/// <summary>
/// Definition of the LinphoneCoreListener interface.
......@@ -76,6 +77,12 @@ namespace Linphone
void CallStatsUpdated(LinphoneCall^ call, LinphoneCallStats^ stats);
void MessageReceived(LinphoneChatMessage^ message);
/// <summary>
/// Callback method called when the composing status for this room has been updated.
/// </summary>
/// <param name="room">The room for which the composing status has been updated</param>
void ComposingReceived(LinphoneChatRoom^ room);
};
}
}
\ No newline at end of file
......@@ -960,6 +960,14 @@ namespace Linphone.Model
});
}
}
/// <summary>
/// Callback for LinphoneCoreListener
/// </summary>
public void ComposingReceived(LinphoneChatRoom room)
{
}
#endregion
/// <summary>
......
linphone @ be96cb43
Subproject commit b0d827bae5b590a2da8d6d7e2b718a687372cb30
Subproject commit be96cb432e8ec0f821b9bc45402b34a001a97d21
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