#pragma once #include "../../VoIPController.h" #include "../../VoIPServerConfig.h" #include #include #include #include #include using namespace Platform; #define STACK_ARRAY(TYPE, LEN) \ static_cast(::alloca((LEN) * sizeof(TYPE))) inline std::wstring ToUtf16(const char* utf8, std::size_t len) { int len16 = ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast(len), nullptr, 0); wchar_t* ws = STACK_ARRAY(wchar_t, len16); ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast(len), ws, len16); return std::wstring(ws, static_cast(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(len), nullptr, 0, nullptr, nullptr); char* ns = STACK_ARRAY(char, len8); ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast(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 ^ 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 ^ endpoints, bool allowP2P, std::int32_t connectionMaxLayer); void SetNetworkType(NetworkType type); void SetMicMute(bool mute); void SetEncryptionKey(const Platform::Array ^ 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, 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; }; }