Commit 22a45aaf authored by Ghislain MARY's avatar Ghislain MARY

Add TCPRemote logger method to sent logs over the network.

parent c27eacf8
......@@ -2,32 +2,81 @@
#include "Utils.h"
#include <ppltasks.h>
#include <iostream>
#include <fstream>
#include <cstring>
using namespace concurrency;
using namespace Windows::Networking;
using namespace Windows::Networking::Sockets;
using namespace Windows::Storage;
using namespace Windows::Storage::Streams;
using namespace Linphone::Core;
namespace Linphone
{
namespace Core
{
private class BackgroundModeLoggerPrivate
{
private:
friend ref class BackgroundModeLogger;
BackgroundModeLoggerPrivate() : stream(nullptr) {}
~BackgroundModeLoggerPrivate() {}
std::ofstream *stream;
StreamSocket^ streamSocket;
DataWriter^ dataWriter;
Platform::String^ remoteHost;
Platform::String^ remotePort;
};
}
}
Linphone::Core::BackgroundModeLogger::BackgroundModeLogger() :
stream(nullptr), enabled(false), dest(OutputTraceDest::File), filename(nullptr)
enabled(false), dest(OutputTraceDest::File), filename(nullptr), d(new BackgroundModeLoggerPrivate())
{
}
Linphone::Core::BackgroundModeLogger::~BackgroundModeLogger()
{
delete d;
}
void Linphone::Core::BackgroundModeLogger::Configure(bool enable, OutputTraceDest dest, Platform::String^ filename)
void Linphone::Core::BackgroundModeLogger::Configure(bool enable, OutputTraceDest dest, Platform::String^ option)
{
std::lock_guard<std::recursive_mutex> lock(this->lock);
if ((this->dest == OutputTraceDest::File) && (this->d->stream != nullptr)) {
this->d->stream->close();
delete this->d->stream;
this->d->stream = nullptr;
}
if ((this->dest == OutputTraceDest::TCPRemote) && (this->d->dataWriter != nullptr)) {
this->d->dataWriter = nullptr;
this->d->streamSocket = nullptr;
}
this->enabled = enable;
this->dest = dest;
if ((dest == OutputTraceDest::File) && (filename != this->filename) && (this->stream != nullptr)) {
stream->close();
delete stream;
stream = nullptr;
if (dest == OutputTraceDest::File) {
this->filename = option;
}
else if (dest == OutputTraceDest::TCPRemote) {
char buffer[256];
const char *cOption = Utils::pstoccs(option);
strncpy(buffer, cOption, sizeof(buffer));
char *portPtr = strrchr(buffer, ':');
if (portPtr != nullptr) {
*portPtr = '\0';
portPtr += 1;
this->d->remoteHost = Utils::cctops(buffer);
this->d->remotePort = Utils::cctops(portPtr);
}
delete cOption;
}
this->filename = filename;
}
void Linphone::Core::BackgroundModeLogger::OutputTrace(OutputTraceLevel level, Platform::String^ msg)
......@@ -38,15 +87,38 @@ void Linphone::Core::BackgroundModeLogger::OutputTrace(OutputTraceLevel level, P
OutputDebugString(msg->Data());
}
else if (this->dest == OutputTraceDest::File) {
if (this->stream == nullptr) {
if (this->d->stream == nullptr) {
StorageFolder^ localFolder = ApplicationData::Current->LocalFolder;
task<StorageFile^>(localFolder->CreateFileAsync(this->filename, CreationCollisionOption::ReplaceExisting)).then([this](StorageFile^ file) {
this->stream = new std::ofstream(file->Path->Data());
this->d->stream = new std::ofstream(file->Path->Data());
}).wait();
}
if (this->d->stream != nullptr) {
const char *cMsg = Utils::pstoccs(msg);
*(this->d->stream) << cMsg;
this->d->stream->flush();
delete cMsg;
}
}
else if (this->dest == OutputTraceDest::TCPRemote) {
if (this->d->streamSocket == nullptr) {
this->d->streamSocket = ref new StreamSocket();
HostName^ remoteHost = ref new HostName(this->d->remoteHost);
EndpointPair^ ep = ref new EndpointPair(nullptr, "", remoteHost, this->d->remotePort);
task<void>(this->d->streamSocket->ConnectAsync(ep)).then([this]() {
this->d->dataWriter = ref new DataWriter(this->d->streamSocket->OutputStream);
this->d->dataWriter->ByteOrder = ByteOrder::BigEndian;
}).wait();
}
if (this->stream != nullptr) {
*(this->stream) << Utils::pstoccs(msg);
this->stream->flush();
if (this->d->dataWriter != nullptr) {
this->d->dataWriter->WriteByte(static_cast<unsigned char>(level));
this->d->dataWriter->WriteUInt16(msg->Length());
this->d->dataWriter->WriteString(msg);
DataWriterStoreOperation^ op = this->d->dataWriter->StoreAsync();
create_task(op).then([this](task<unsigned int> written) {
return this->d->dataWriter->FlushAsync();
}).wait();
}
}
}
......
#pragma once
#include "LinphoneCoreFactory.h"
#include <iostream>
#include <fstream>
namespace Linphone
......@@ -10,12 +8,13 @@ namespace Linphone
namespace Core
{
ref class Globals;
class BackgroundModeLoggerPrivate;
public ref class BackgroundModeLogger sealed : OutputTraceListener
{
public:
virtual void OutputTrace(OutputTraceLevel level, Platform::String^ msg);
void Configure(bool enable, OutputTraceDest dest, Platform::String^ filename);
void Configure(bool enable, OutputTraceDest dest, Platform::String^ option);
private:
friend ref class Linphone::Core::Globals;
......@@ -23,11 +22,11 @@ namespace Linphone
BackgroundModeLogger();
~BackgroundModeLogger();
std::ofstream *stream;
std::recursive_mutex lock;
bool enabled;
OutputTraceDest dest;
Platform::String^ filename;
BackgroundModeLoggerPrivate *d;
};
}
}
\ No newline at end of file
......@@ -116,8 +116,7 @@ namespace Linphone
Debug = 0,
Message = 1,
Warning = 2,
Error = 3,
Raw = 4
Error = 3
};
/// <summary>
......@@ -126,7 +125,8 @@ namespace Linphone
public enum class OutputTraceDest : int
{
Debugger = 0,
File = 1
File = 1,
TCPRemote = 2
};
}
}
\ No newline at end of file
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