Commit dd6ec7a0 authored by Ghislain MARY's avatar Ghislain MARY

Rework C++/CX wrapper + implement simple demo application.

parent 7a8f34c9
/*
BackgroundModeLogger.cpp
Copyright (C) 2015 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "BackgroundModeLogger.h"
#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;
Linphone::Core::BackgroundModeLogger::BackgroundModeLogger()
{
}
Linphone::Core::BackgroundModeLogger::~BackgroundModeLogger()
{
}
void Linphone::Core::BackgroundModeLogger::OutputTrace(OutputTraceLevel level, Platform::String^ msg)
{
const char *cMsg = Utils::pstoccs(msg);
switch (level) {
case OutputTraceLevel::Debug:
ms_debug(cMsg);
break;
case OutputTraceLevel::Message:
ms_message(cMsg);
break;
case OutputTraceLevel::Warning:
ms_warning(cMsg);
break;
case OutputTraceLevel::Error:
ms_error(cMsg);
break;
}
}
/*
BackgroundModeLogger.h
Copyright (C) 2015 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#pragma once
#include "LinphoneCoreFactory.h"
#include <mutex>
// Do not treat doxygen documentation as XML
#pragma warning(push)
#pragma warning(disable : 4635)
#include "coreapi\linphonecore.h"
#pragma warning(pop)
namespace Linphone
{
namespace Core
{
ref class Globals;
/// <summary>
/// Object to log the application traces while in background mode.
/// </summary>
public ref class BackgroundModeLogger sealed : OutputTraceListener
{
public:
/// <summary>
/// Method called to output a trace to the logs.
/// </summary>
/// <param name="level">The level of the trace to output</param>
/// <param name="msg">The message to ouput</param>
virtual void OutputTrace(OutputTraceLevel level, Platform::String^ msg);
private:
friend ref class Linphone::Core::Globals;
BackgroundModeLogger();
~BackgroundModeLogger();
};
}
}
\ No newline at end of file
This diff is collapsed.
/*
Globals.h
Copyright (C) 2015 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#pragma once
#include <roapi.h>
namespace Linphone
{
namespace Core
{
ref class CallController;
ref class LinphoneCoreFactory;
ref class LinphoneCore;
ref class BackgroundModeLogger;
/// <summary>
/// Singleton container used to hold global singletons and background process-wide objects.
/// Also used to start out of process server, allowing the UI process managed code to instantiate WinRT objects in this process.
/// </summary>
public ref class Globals sealed
{
public:
/// <summary>
/// Starts the out of process server, allowing the UI process to instantiate WinRT objects in this process.
/// </summary>
void StartServer(const Platform::Array<Platform::String^>^ outOfProcServerClassNames);
/// <summary>
///Returns the id of the background process (HeadlessHost)
/// </summary>
static unsigned int GetCurrentProcessId();
static Platform::String^ GetUiDisconnectedEventName(unsigned int backgroundProcessId);
static Platform::String^ GetBackgroundProcessReadyEventName(unsigned int backgroundProcessId);
/// <summary>
/// Gets the instance of the Globals class, used to directly access any C++/CX objects from C#
/// </summary>
static property Globals^ Instance
{
Globals^ get();
}
/// <summary>
/// Gets the current instance of LinphoneCoreFactory
/// </summary>
property LinphoneCoreFactory^ LinphoneCoreFactory
{
Linphone::Core::LinphoneCoreFactory^ get();
}
/// <summary>
/// Gets the current instance of LinphoneCore from LinphoneCoreFactory
/// </summary>
property LinphoneCore^ LinphoneCore
{
Linphone::Core::LinphoneCore^ get();
}
/// <summary>
/// Gets the current instance of the logger
/// </summary>
property BackgroundModeLogger^ BackgroundModeLogger
{
Linphone::Core::BackgroundModeLogger^ get();
}
/// <summary>
/// Gets the current instance of the native call controller
/// </summary>
property CallController^ CallController
{
Linphone::Core::CallController^ get();
}
#if 0
/// <summary>
/// Access the video renderer instance
/// </summary>
property Mediastreamer2::WP8Video::IVideoRenderer^ VideoRenderer
{
Mediastreamer2::WP8Video::IVideoRenderer^ get();
void set(Mediastreamer2::WP8Video::IVideoRenderer^ value);
}
#endif
private:
Globals();
~Globals();
static const LPCWSTR noOtherBackgroundProcessEventName;
static const LPCWSTR uiDisconnectedEventName;
static const LPCWSTR backgroundProcessReadyEventName;
static Globals^ singleton;
bool started;
// A cookie that is used to unregister remotely activatable objects in this process
RO_REGISTRATION_COOKIE serverRegistrationCookie;
HANDLE noOtherBackgroundProcessEvent;
HANDLE backgroundReadyEvent;
Linphone::Core::LinphoneCoreFactory^ linphoneCoreFactory;
Linphone::Core::BackgroundModeLogger^ backgroundModeLogger;
Linphone::Core::CallController^ callController;
//Mediastreamer2::WP8Video::IVideoRenderer^ videoRenderer;
};
}
}
/*
LinphoneCoreFactory.cpp
Copyright (C) 2015 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "LinphoneAuthInfo.h"
#include "LinphoneCoreFactory.h"
#include "LinphoneCore.h"
#include "LinphoneCoreListener.h"
#include "LinphoneAddress.h"
#include "LpConfig.h"
#include "Server.h"
#include "Transports.h"
#include "VideoPolicy.h"
#include "VideoSize.h"
using namespace Linphone::Core;
using namespace Platform;
#define MAX_TRACE_SIZE 2048
#define MAX_SUITE_NAME_SIZE 128
void LinphoneCoreFactory::CreateLinphoneCore(Linphone::Core::LinphoneCoreListener^ listener)
{
CreateLinphoneCore(listener, nullptr);
}
void LinphoneCoreFactory::CreateLinphoneCore(Linphone::Core::LinphoneCoreListener^ listener, Linphone::Core::LpConfig^ config)
{
if (this->linphoneCore == nullptr) {
API_LOCK;
if (this->linphoneCore == nullptr) {
Utils::LinphoneCoreEnableLogCollection(true);
this->linphoneCore = ref new Linphone::Core::LinphoneCore(listener, config);
this->linphoneCore->Init();
}
}
}
Linphone::Core::LpConfig^ LinphoneCoreFactory::CreateLpConfig(Platform::String^ configPath, Platform::String^ factoryConfigPath)
{
API_LOCK;
return dynamic_cast<Linphone::Core::LpConfig^>(Utils::CreateLpConfig(configPath, factoryConfigPath));
}
Linphone::Core::LinphoneAuthInfo^ LinphoneCoreFactory::CreateAuthInfo(Platform::String^ username, Platform::String^ userid, Platform::String^ password, Platform::String^ ha1, Platform::String^ realm, Platform::String^ domain)
{
API_LOCK;
return dynamic_cast<Linphone::Core::LinphoneAuthInfo^>(Utils::CreateLinphoneAuthInfo(username, userid, password, ha1, realm, domain));
}
Linphone::Core::LinphoneAddress^ LinphoneCoreFactory::CreateLinphoneAddress(Platform::String^ username, Platform::String^ domain, Platform::String^ displayName)
{
API_LOCK;
Linphone::Core::LinphoneAddress^ address = CreateLinphoneAddress("sip:user@domain.com");
address->UserName = username;
address->Domain = domain;
address->DisplayName = displayName;
return address;
}
Linphone::Core::LinphoneAddress^ LinphoneCoreFactory::CreateLinphoneAddress(Platform::String^ uri)
{
API_LOCK;
return dynamic_cast<Linphone::Core::LinphoneAddress^>(Utils::CreateLinphoneAddressFromUri(Utils::pstoccs(uri)));
}
Linphone::Core::Transports^ LinphoneCoreFactory::CreateTransports()
{
API_LOCK;
return dynamic_cast<Linphone::Core::Transports^>(Utils::CreateTransports());
}
Linphone::Core::Transports^ LinphoneCoreFactory::CreateTransports(int udp_port, int tcp_port, int tls_port)
{
API_LOCK;
return dynamic_cast<Linphone::Core::Transports^>(Utils::CreateTransports(udp_port, tcp_port, tls_port));
}
Linphone::Core::Transports^ LinphoneCoreFactory::CreateTransports(Linphone::Core::Transports^ t)
{
API_LOCK;
return dynamic_cast<Linphone::Core::Transports^>(Utils::CreateTransports(t));
}
Linphone::Core::VideoPolicy^ LinphoneCoreFactory::CreateVideoPolicy()
{
API_LOCK;
return dynamic_cast<Linphone::Core::VideoPolicy^>(Utils::CreateVideoPolicy());
}
Linphone::Core::VideoPolicy^ LinphoneCoreFactory::CreateVideoPolicy(Platform::Boolean automaticallyInitiate, Platform::Boolean automaticallyAccept)
{
API_LOCK;
return dynamic_cast<Linphone::Core::VideoPolicy^>(Utils::CreateVideoPolicy(automaticallyInitiate, automaticallyAccept));
}
Linphone::Core::VideoSize^ LinphoneCoreFactory::CreateVideoSize(int width, int height)
{
API_LOCK;
return dynamic_cast<Linphone::Core::VideoSize^>(Utils::CreateVideoSize(width, height));
}
Linphone::Core::VideoSize^ LinphoneCoreFactory::CreateVideoSize(int width, int height, Platform::String^ name)
{
API_LOCK;
return dynamic_cast<Linphone::Core::VideoSize^>(Utils::CreateVideoSize(width, height, name));
}
void LinphoneCoreFactory::SetLogLevel(OutputTraceLevel logLevel)
{
API_LOCK;
Linphone::Core::LinphoneCore::LogLevel = logLevel;
}
void LinphoneCoreFactory::ResetLogCollection()
{
API_LOCK;
Linphone::Core::LinphoneCore::ResetLogCollection();
}
Linphone::Core::LinphoneCore^ LinphoneCoreFactory::LinphoneCore::get()
{
return this->linphoneCore;
}
void LinphoneCoreFactory::Destroy()
{
API_LOCK;
this->linphoneCore->Destroy();
delete this->linphoneCore;
this->linphoneCore = nullptr;
}
LinphoneCoreFactory::LinphoneCoreFactory() :
linphoneCore(nullptr)
{
}
LinphoneCoreFactory::~LinphoneCoreFactory()
{
}
\ No newline at end of file
/*
LinphoneCoreFactory.h
Copyright (C) 2015 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#pragma once
#include "ApiLock.h"
#include "LinphoneCoreListener.h"
namespace Linphone
{
namespace Core
{
ref class Globals;
ref class LinphoneCore;
ref class LinphoneAuthInfo;
ref class LinphoneAddress;
ref class LpConfig;
ref class Transports;
ref class VideoPolicy;
ref class VideoSize;
/// <summary>
/// Definition of the OutputTraceListener interface. The classes that are to be used to ouput trace logs must implement this interface.
/// </summary>
public interface class OutputTraceListener
{
public:
/// <summary>
/// The method to implement to be able to output trace logs.
/// </summary>
/// <param name="level">The log level of the trace to output</param>
/// <param name="msg">The trace message to ouput</param>
void OutputTrace(OutputTraceLevel level, Platform::String^ msg);
};
/// <summary>
/// Class whose role is to create instances of other classes : LinphoneCore, LpConfig, AuthInfo and LinphoneAddress.
/// </summary>
public ref class LinphoneCoreFactory sealed
{
public:
/// <summary>
/// Gets the LinphoneCore instance.
/// </summary>
property LinphoneCore^ LinphoneCore
{
Linphone::Core::LinphoneCore^ get();
}
/// <summary>
/// Creates a LinphoneCore instance.
/// To access the created LinphoneCore use the LinphoneCoreFactory::LinphoneCore property.
/// </summary>
/// <param name="listener">The listener class that will handle the callbacks from the native linphone core</param>
/// <seealso cref="CreateLinphoneCore(LinphoneCoreListener^, LpConfig^)"/>
void CreateLinphoneCore(LinphoneCoreListener^ listener);
/// <summary>
/// Creates a LinphoneCore instance given an existing LpConfig.
/// To access the created LinphoneCore use the LinphoneCoreFactory::LinphoneCore property.
/// </summary>
/// <param name="listener">The listener class that will handle the callbacks from the native linphone core</param>
/// <param name="config">The LpConfig to use for the configuration of the created LinphoneCore</param>
/// <seealso cref="CreateLinphoneCore(LinphoneCoreListener^)"/>
void CreateLinphoneCore(LinphoneCoreListener^ listener, LpConfig^ config);
/// <summary>
/// Creates a LpConfig.
/// </summary>
/// <param name="configPath">The path of the user configuration file that must be readable and writable</param>
/// <param name="factoryConfigPath">The path of the factory configuration file that needs only to be readable</param>
/// <returns>The LpConfig that has been created</returns>
LpConfig^ CreateLpConfig(Platform::String^ configPath, Platform::String^ factoryConfigPath);
/// <summary>
/// Creates a LinphoneAuthInfo.
/// </summary>
/// <param name="username">The authentication username</param>
/// <param name="userid">The authentication userid</param>
/// <param name="password">The authentication password</param>
/// <param name="ha1">The authentication ha1</param>
/// <param name="realm">The authentication realm</param>
/// <param name="domain">The authentication domain</param>
/// <returns>The LinphoneAuthInfo that has been created</returns>
LinphoneAuthInfo^ CreateAuthInfo(Platform::String^ username, Platform::String^ userid, Platform::String^ password, Platform::String^ ha1, Platform::String^ realm, Platform::String^ domain);
/// <summary>
/// Creates a LinphoneAddress.
/// </summary>
/// <param name="username">The username part of the address</param>
/// <param name="domain">The domain part of the address</param>
/// <param name="displayName">The display name of the address</param>
/// <returns>The LinphoneAddress that has been created</returns>
LinphoneAddress^ CreateLinphoneAddress(Platform::String^ username, Platform::String^ domain, Platform::String^ displayName);
/// <summary>
/// Constructs a LinphoneAddress object by parsing the user supplied address, given as a string.
/// </summary>
/// <param name="uri">address, should be like "sip:joe@sip.linphone.org"</param>
/// <returns>The LinphoneAddress that has been created, or null if the URI couldn't be parsed</returns>
LinphoneAddress^ CreateLinphoneAddress(Platform::String^ uri);
/// <summary>
/// Creates a default Transports object (using the UDP 5060 port).
/// </summary>
/// <returns>The Transports that has been created</returns>
Transports^ CreateTransports();
/// <summary>
/// Creates a Transports object specifying the ports to use.
/// </summary>
/// <param name="udp_port">The UDP port to use (0 to disable)</param>
/// <param name="tcp_port">The TCP port to use (0 to disable)</param>
/// <param name="tls_port">The TLS port to use (0 to disable)</param>
/// <returns>The Transports that has been created</returns>
Transports^ CreateTransports(int udp_port, int tcp_port, int tls_port);
/// <summary>
/// Duplicates a Transports object.
/// </summary>
/// <param name="t">The Transports object to duplicate</param>
/// <returns>The duplicated Transports</returns>
Transports^ CreateTransports(Transports^ t);
/// <summary>
/// Creates a default VideoPolicy object (automatically initiate and accept video).
/// </summary>
/// <returns>The VideoPolicy that has been created</returns>
VideoPolicy^ CreateVideoPolicy();
/// <summary>
/// Creates a VideoPolicy object specifying the behaviour for video calls.
/// </summary>
/// <param name="automaticallyInitiate">Whether video shall be automatically proposed for outgoing calls</param>
/// <param name="automaticallyAccept">Whether video shall be automatically accepted for incoming calls</param>
/// <returns>The VideoPolicy that has been created</returns>
VideoPolicy^ CreateVideoPolicy(Platform::Boolean automaticallyInitiate, Platform::Boolean automaticallyAccept);
/// <summary>
/// Creates an unnamed VideoSize object.
/// </summary>
/// <param name="width">The video width</param>
/// <param name="height">The video height</param>
/// <returns>The VideoSize that has been created</returns>
VideoSize^ CreateVideoSize(int width, int height);
/// <summary>
/// Creates a named VideoSize object.
/// </summary>
/// <param name="width">The video width</param>
/// <param name="height">The video height</param>
/// <param name="name">The video size name</param>
/// <returns>The VideoSize that has been created</returns>
VideoSize^ CreateVideoSize(int width, int height, Platform::String^ name);
/// <summary>
/// Sets the global log level of the application.
/// </summary>
/// <param name="logLevel">The log level to use</param>
void SetLogLevel(OutputTraceLevel logLevel);
/// <summary>
/// Resets the log collection by removing the log files.
/// </summary>
void ResetLogCollection();
/// <summary>
/// Destroys the LinphoneCore attached to this factory
/// </summary>
void Destroy();
private:
friend ref class Linphone::Core::Globals;
Linphone::Core::LinphoneCore^ linphoneCore;
LinphoneCoreFactory();
~LinphoneCoreFactory();
};
}
}
\ No newline at end of file
/*
LinphoneProxyConfig.cpp
Copyright (C) 2015 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "LinphoneProxyConfig.h"
#include "LinphoneCore.h"
#include "Server.h"
#include "Utils.h"
void Linphone::Core::LinphoneProxyConfig::Edit()
{
API_LOCK;
linphone_proxy_config_edit(this->proxy_config);
}
void Linphone::Core::LinphoneProxyConfig::Done()
{
API_LOCK;
linphone_proxy_config_done(this->proxy_config);
}
void Linphone::Core::LinphoneProxyConfig::SetIdentity(Platform::String^ displayname, Platform::String^ username, Platform::String^ domain)
{
API_LOCK;
const char* cc_username = Utils::pstoccs(username);
const char* cc_domain = Utils::pstoccs(domain);
const char* cc_displayname = Utils::pstoccs(displayname);
::LinphoneAddress *addr = linphone_address_new(NULL);
linphone_address_set_username(addr, cc_username);
linphone_address_set_domain(addr, cc_domain);
linphone_address_set_display_name(addr, cc_displayname);
linphone_proxy_config_set_identity(this->proxy_config, linphone_address_as_string(addr));
linphone_address_destroy(addr);
delete(cc_username);
delete(cc_domain);
delete(cc_displayname);
}
Platform::String^ Linphone::Core::LinphoneProxyConfig::GetIdentity()
{
API_LOCK;
return Utils::cctops(linphone_proxy_config_get_identity(this->proxy_config));
}
void Linphone::Core::LinphoneProxyConfig::ServerAddr::set(Platform::String^ proxyUri)
{
API_LOCK;
const char* cc = Utils::pstoccs(proxyUri);
linphone_proxy_config_set_server_addr(this->proxy_config, cc);
delete(cc);
}
Platform::String^ Linphone::Core::LinphoneProxyConfig::ServerAddr::get()
{
API_LOCK;
return Utils::cctops(linphone_proxy_config_get_server_addr(this->proxy_config));
}
Linphone::Core::Reason Linphone::Core::LinphoneProxyConfig::Error::get()
{
API_LOCK;
return (Linphone::Core::Reason)linphone_proxy_config_get_error(this->proxy_config);
}
void Linphone::Core::LinphoneProxyConfig::RegisterEnabled::set(Platform::Boolean enable)
{
API_LOCK;
linphone_proxy_config_enable_register(this->proxy_config, enable);
}
Platform::Boolean Linphone::Core::LinphoneProxyConfig::RegisterEnabled::get()
{
API_LOCK;
return (linphone_proxy_config_register_enabled(this->proxy_config) == TRUE);
}
Platform::String^ Linphone::Core::LinphoneProxyConfig::NormalizePhoneNumber(Platform::String^ phoneNumber)
{
API_LOCK;
const char* cc = Utils::pstoccs(phoneNumber);
char* result = (char*) malloc(phoneNumber->Length());
int result_size = 0;
linphone_proxy_config_normalize_number(this->proxy_config, cc, result, result_size);
Platform::String^ val = Utils::cctops(result);
delete(cc);
delete(result);
return val;
}
void Linphone::Core::LinphoneProxyConfig::DialPrefix::set(Platform::String^ prefix)
{
API_LOCK;
const char* cc = Utils::pstoccs(prefix);
linphone_proxy_config_set_dial_prefix(this->proxy_config, cc);
delete(cc);
}
Platform::String^ Linphone::Core::LinphoneProxyConfig::DialPrefix::get()
{
API_LOCK;
return Utils::cctops(linphone_proxy_config_get_dial_prefix(this->proxy_config));
}
void Linphone::Core::LinphoneProxyConfig::DialEscapePlus::set(Platform::Boolean value)
{
API_LOCK;
linphone_proxy_config_set_dial_escape_plus(this->proxy_config, value);
}