298 lines
8.2 KiB
C
298 lines
8.2 KiB
C
|
#pragma once
|
|||
|
|
|||
|
#include "../../VoIPController.h"
|
|||
|
#include "../../VoIPServerConfig.h"
|
|||
|
#include <robuffer.h>
|
|||
|
#include <vector>
|
|||
|
#include <windows.storage.streams.h>
|
|||
|
#include <wrl.h>
|
|||
|
#include <wrl/implements.h>
|
|||
|
|
|||
|
using namespace Platform;
|
|||
|
|
|||
|
#define STACK_ARRAY(TYPE, LEN) \
|
|||
|
static_cast<TYPE*>(::alloca((LEN) * sizeof(TYPE)))
|
|||
|
|
|||
|
inline std::wstring ToUtf16(const char* utf8, std::size_t len)
|
|||
|
{
|
|||
|
int len16 = ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast<int>(len),
|
|||
|
nullptr, 0);
|
|||
|
wchar_t* ws = STACK_ARRAY(wchar_t, len16);
|
|||
|
::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast<int>(len), ws, len16);
|
|||
|
return std::wstring(ws, static_cast<std::size_t>(len16));
|
|||
|
}
|
|||
|
|
|||
|
inline std::wstring ToUtf16(const std::string& str)
|
|||
|
{
|
|||
|
return ToUtf16(str.data(), str.length());
|
|||
|
}
|
|||
|
|
|||
|
inline std::string ToUtf8(const wchar_t* wide, std::size_t len)
|
|||
|
{
|
|||
|
int len8 = ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast<int>(len),
|
|||
|
nullptr, 0, nullptr, nullptr);
|
|||
|
char* ns = STACK_ARRAY(char, len8);
|
|||
|
::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast<int>(len), ns, len8,
|
|||
|
nullptr, nullptr);
|
|||
|
return std::string(ns, len8);
|
|||
|
}
|
|||
|
|
|||
|
inline std::string ToUtf8(const wchar_t* wide)
|
|||
|
{
|
|||
|
return ToUtf8(wide, wcslen(wide));
|
|||
|
}
|
|||
|
|
|||
|
inline std::string ToUtf8(const std::wstring& wstr)
|
|||
|
{
|
|||
|
return ToUtf8(wstr.data(), wstr.length());
|
|||
|
}
|
|||
|
|
|||
|
namespace libtgvoip
|
|||
|
{
|
|||
|
public
|
|||
|
ref class Endpoint sealed
|
|||
|
{
|
|||
|
public:
|
|||
|
property int64 id;
|
|||
|
property uint16 port;
|
|||
|
property Platform::String ^ ipv4;
|
|||
|
property Platform::String ^ ipv6;
|
|||
|
property Platform::Array<uint8> ^ peerTag;
|
|||
|
};
|
|||
|
|
|||
|
public
|
|||
|
ref class TrafficStats sealed
|
|||
|
{
|
|||
|
public:
|
|||
|
property std::uint64_t bytesSentWifi;
|
|||
|
property std::uint64_t bytesRecvdWifi;
|
|||
|
property std::uint64_t bytesSentMobile;
|
|||
|
property std::uint64_t bytesRecvdMobile;
|
|||
|
};
|
|||
|
|
|||
|
public
|
|||
|
enum class CallState : int
|
|||
|
{
|
|||
|
WaitInit = 1,
|
|||
|
WaitInitAck,
|
|||
|
Established,
|
|||
|
Failed
|
|||
|
};
|
|||
|
|
|||
|
public
|
|||
|
enum class Error : int
|
|||
|
{
|
|||
|
Unknown = 0,
|
|||
|
Incompatible,
|
|||
|
Timeout,
|
|||
|
AudioIO
|
|||
|
};
|
|||
|
|
|||
|
public
|
|||
|
enum class NetworkType : int
|
|||
|
{
|
|||
|
Unknown = 0,
|
|||
|
GPRS,
|
|||
|
EDGE,
|
|||
|
UMTS,
|
|||
|
HSPA,
|
|||
|
LTE,
|
|||
|
WiFi,
|
|||
|
Ethernet,
|
|||
|
OtherHighSpeed,
|
|||
|
OtherLowSpeed,
|
|||
|
Dialup,
|
|||
|
OtherMobile
|
|||
|
};
|
|||
|
|
|||
|
public
|
|||
|
enum class DataSavingMode
|
|||
|
{
|
|||
|
Never = 0,
|
|||
|
MobileOnly,
|
|||
|
Always
|
|||
|
};
|
|||
|
|
|||
|
public
|
|||
|
enum class ProxyProtocol
|
|||
|
{
|
|||
|
None = 0,
|
|||
|
SOCKS5
|
|||
|
};
|
|||
|
|
|||
|
public
|
|||
|
ref class VoIPConfig sealed
|
|||
|
{
|
|||
|
public:
|
|||
|
VoIPConfig()
|
|||
|
{
|
|||
|
logPacketStats = false;
|
|||
|
enableVolumeControl = false;
|
|||
|
enableVideoSend = false;
|
|||
|
enableVideoReceive = false;
|
|||
|
}
|
|||
|
|
|||
|
property double initTimeout;
|
|||
|
property double recvTimeout;
|
|||
|
property DataSavingMode dataSaving;
|
|||
|
property String ^ logFilePath;
|
|||
|
property String ^ statsDumpFilePath;
|
|||
|
|
|||
|
property bool enableAEC;
|
|||
|
property bool enableNS;
|
|||
|
property bool enableAGC;
|
|||
|
|
|||
|
property bool enableCallUpgrade;
|
|||
|
|
|||
|
property bool logPacketStats;
|
|||
|
property bool enableVolumeControl;
|
|||
|
|
|||
|
property bool enableVideoSend;
|
|||
|
property bool enableVideoReceive;
|
|||
|
};
|
|||
|
|
|||
|
ref class VoIPControllerWrapper;
|
|||
|
public
|
|||
|
delegate void CallStateChangedEventHandler(VoIPControllerWrapper ^ sender, CallState newState);
|
|||
|
|
|||
|
ref class VoIPControllerWrapper;
|
|||
|
public
|
|||
|
delegate void SignalBarsChangedEventHandler(VoIPControllerWrapper ^ sender, int newCount);
|
|||
|
|
|||
|
public
|
|||
|
ref class VoIPControllerWrapper sealed
|
|||
|
{
|
|||
|
public:
|
|||
|
VoIPControllerWrapper();
|
|||
|
virtual ~VoIPControllerWrapper();
|
|||
|
void Start();
|
|||
|
void Connect();
|
|||
|
void SetPublicEndpoints(const Platform::Array<Endpoint ^> ^ endpoints, bool allowP2P, std::int32_t connectionMaxLayer);
|
|||
|
void SetNetworkType(NetworkType type);
|
|||
|
void SetMicMute(bool mute);
|
|||
|
void SetEncryptionKey(const Platform::Array<uint8> ^ key, bool isOutgoing);
|
|||
|
void SetConfig(VoIPConfig ^ config);
|
|||
|
void SetProxy(ProxyProtocol protocol, Platform::String ^ address, std::uint16_t port, Platform::String ^ username, Platform::String ^ password);
|
|||
|
int GetSignalBarsCount();
|
|||
|
CallState GetConnectionState();
|
|||
|
TrafficStats ^ GetStats();
|
|||
|
Platform::String ^ GetDebugString();
|
|||
|
Platform::String ^ GetDebugLog();
|
|||
|
Error GetLastError();
|
|||
|
static Platform::String ^ GetVersion();
|
|||
|
int64 GetPreferredRelayID();
|
|||
|
void SetAudioOutputGainControlEnabled(bool enabled);
|
|||
|
|
|||
|
void SetInputVolume(float level);
|
|||
|
void SetOutputVolume(float level);
|
|||
|
|
|||
|
property String ^ CurrentAudioInput {
|
|||
|
String ^ get() {
|
|||
|
return ref new String(ToUtf16(controller->GetCurrentAudioInputID()).data());
|
|||
|
} void set(String ^ value)
|
|||
|
{
|
|||
|
controller->SetCurrentAudioInput(ToUtf8(value->Data()));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
property String
|
|||
|
^ CurrentAudioOutput {
|
|||
|
String ^ get() {
|
|||
|
return ref new String(ToUtf16(controller->GetCurrentAudioOutputID()).data());
|
|||
|
} void set(String ^ value)
|
|||
|
{
|
|||
|
controller->SetCurrentAudioOutput(ToUtf8(value->Data()));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static std::int32_t
|
|||
|
GetConnectionMaxLayer();
|
|||
|
static void UpdateServerConfig(Platform::String ^ json);
|
|||
|
static void SwitchSpeaker(bool external);
|
|||
|
//static Platform::String^ TestAesIge();
|
|||
|
|
|||
|
event CallStateChangedEventHandler ^ CallStateChanged;
|
|||
|
event SignalBarsChangedEventHandler ^ SignalBarsChanged;
|
|||
|
|
|||
|
private:
|
|||
|
static void OnStateChanged(tgvoip::VoIPController* c, int state);
|
|||
|
static void OnSignalBarsChanged(tgvoip::VoIPController* c, int count);
|
|||
|
void OnStateChangedInternal(int state);
|
|||
|
void OnSignalBarsChangedInternal(int count);
|
|||
|
tgvoip::VoIPController* controller;
|
|||
|
};
|
|||
|
|
|||
|
ref class MicrosoftCryptoImpl
|
|||
|
{
|
|||
|
public:
|
|||
|
static void AesIgeEncrypt(std::uint8_t* in, std::uint8_t* out, std::size_t len, std::uint8_t* key, std::uint8_t* iv);
|
|||
|
static void AesIgeDecrypt(std::uint8_t* in, std::uint8_t* out, std::size_t len, std::uint8_t* key, std::uint8_t* iv);
|
|||
|
static void AesCtrEncrypt(std::uint8_t* inout, std::size_t len, std::uint8_t* key, std::uint8_t* iv, std::uint8_t* ecount, std::uint32_t* num);
|
|||
|
static void SHA1(std::uint8_t* msg, std::size_t len, std::uint8_t* out);
|
|||
|
static void SHA256(std::uint8_t* msg, std::size_t len, std::uint8_t* out);
|
|||
|
static void RandBytes(std::uint8_t* buffer, std::size_t len);
|
|||
|
static void Init();
|
|||
|
|
|||
|
private:
|
|||
|
static inline void XorInt128(std::uint8_t* a, std::uint8_t* b, std::uint8_t* out);
|
|||
|
static void IBufferToPtr(Windows::Storage::Streams::IBuffer ^ buffer, std::size_t len, std::uint8_t* out);
|
|||
|
static Windows::Storage::Streams::IBuffer ^ IBufferFromPtr(std::uint8_t* msg, std::size_t len);
|
|||
|
/*static Windows::Security::Cryptography::Core::CryptographicHash^ sha1Hash;
|
|||
|
static Windows::Security::Cryptography::Core::CryptographicHash^ sha256Hash;*/
|
|||
|
static Windows::Security::Cryptography::Core::HashAlgorithmProvider ^ sha1Provider;
|
|||
|
static Windows::Security::Cryptography::Core::HashAlgorithmProvider ^ sha256Provider;
|
|||
|
static Windows::Security::Cryptography::Core::SymmetricKeyAlgorithmProvider ^ aesKeyProvider;
|
|||
|
};
|
|||
|
|
|||
|
class NativeBuffer : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::WinRtClassicComMix>,
|
|||
|
ABI::Windows::Storage::Streams::IBuffer,
|
|||
|
Windows::Storage::Streams::IBufferByteAccess>
|
|||
|
{
|
|||
|
public:
|
|||
|
NativeBuffer(byte* buffer, UINT totalSize)
|
|||
|
{
|
|||
|
m_length = totalSize;
|
|||
|
m_buffer = buffer;
|
|||
|
}
|
|||
|
|
|||
|
virtual ~NativeBuffer()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
STDMETHODIMP RuntimeClassInitialize(byte* buffer, UINT totalSize)
|
|||
|
{
|
|||
|
m_length = totalSize;
|
|||
|
m_buffer = buffer;
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
STDMETHODIMP Buffer(byte** value)
|
|||
|
{
|
|||
|
*value = m_buffer;
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
STDMETHODIMP get_Capacity(UINT32* value)
|
|||
|
{
|
|||
|
*value = m_length;
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
STDMETHODIMP get_Length(UINT32* value)
|
|||
|
{
|
|||
|
*value = m_length;
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
STDMETHODIMP put_Length(UINT32 value)
|
|||
|
{
|
|||
|
m_length = value;
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
private:
|
|||
|
UINT32 m_length;
|
|||
|
byte* m_buffer;
|
|||
|
};
|
|||
|
}
|