1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-26 20:24:38 +01:00

Add public interface

This commit is contained in:
Ali 2019-12-24 22:57:22 +04:00
parent 1870f7fa6e
commit 77e1f5d27a
2 changed files with 481 additions and 0 deletions

332
TgVoip.cpp Executable file
View File

@ -0,0 +1,332 @@
#import "TgVoip.h"
#import "VoIPController.h"
#import "VoIPServerConfig.h"
class TgVoipImpl : public TgVoip {
public:
tgvoip::VoIPController *controller_;
std::function<void(TgVoipState)> onStateUpdated_;
std::function<void(int)> onSignalBarsUpdated_;
TgVoipImpl(
TgVoipCrypto const &crypto,
std::vector<TgVoipEndpoint> const &endpoints,
TgVoipPersistentState const &persistentState,
std::unique_ptr<TgVoipProxy> const &proxy,
TgVoipConfig const &config,
TgVoipEncryptionKey const &encryptionKey,
TgVoipNetworkType initialNetworkType
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
,
TgVoipAudioDataCallbacks const &audioDataCallbacks
#endif
) {
tgvoip::VoIPController::crypto.sha1 = crypto.sha1;
tgvoip::VoIPController::crypto.sha256 = crypto.sha256;
tgvoip::VoIPController::crypto.rand_bytes = crypto.rand_bytes;
tgvoip::VoIPController::crypto.aes_ige_encrypt = crypto.aes_ige_encrypt;
tgvoip::VoIPController::crypto.aes_ige_decrypt = crypto.aes_ige_decrypt;
tgvoip::VoIPController::crypto.aes_ctr_encrypt = crypto.aes_ctr_encrypt;
controller_ = new tgvoip::VoIPController();
controller_->implData = this;
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
controller_->SetAudioDataCallbacks(audioDataCallbacks.input, audioDataCallbacks.output, audioDataCallbacks.preprocessed);
#endif
controller_->SetPersistentState(persistentState.value);
if (proxy != nullptr) {
controller_->SetProxy(tgvoip::PROXY_SOCKS5, proxy->host, proxy->port, proxy->login, proxy->password);
}
auto callbacks = tgvoip::VoIPController::Callbacks();
callbacks.connectionStateChanged = &TgVoipImpl::controllerStateCallback;
callbacks.groupCallKeyReceived = NULL;
callbacks.groupCallKeySent = NULL;
callbacks.signalBarCountChanged = &TgVoipImpl::signalBarsCallback;
callbacks.upgradeToGroupCallRequested = NULL;
controller_->SetCallbacks(callbacks);
std::vector<tgvoip::Endpoint> mappedEndpoints;
for (auto endpoint : endpoints) {
bool isIpv6 = false;
struct in6_addr addrIpV6;
if (inet_pton(AF_INET6, endpoint.host.c_str(), &addrIpV6)) {
isIpv6 = true;
}
tgvoip::Endpoint::Type mappedType = tgvoip::Endpoint::Type::UDP_RELAY;
switch (endpoint.type) {
case TgVoipEndpointType::UdpRelay:
mappedType = tgvoip::Endpoint::Type::UDP_RELAY;
break;
case TgVoipEndpointType::Lan:
mappedType = tgvoip::Endpoint::Type::UDP_P2P_LAN;
break;
case TgVoipEndpointType::Inet:
mappedType = tgvoip::Endpoint::Type::UDP_P2P_INET;
break;
case TgVoipEndpointType::TcpRelay:
mappedType = tgvoip::Endpoint::Type::TCP_RELAY;
break;
default:
mappedType = tgvoip::Endpoint::Type::UDP_RELAY;
break;
}
tgvoip::IPv4Address address(isIpv6 ? std::string() : endpoint.host);
tgvoip::IPv6Address addressv6(isIpv6 ? endpoint.host : std::string());
mappedEndpoints.push_back(tgvoip::Endpoint(endpoint.endpointId, endpoint.port, address, addressv6, mappedType, endpoint.peerTag));
}
int mappedDataSaving = tgvoip::DATA_SAVING_NEVER;
switch (config.dataSaving) {
case TgVoipDataSaving::Mobile:
mappedDataSaving = tgvoip::DATA_SAVING_MOBILE;
break;
case TgVoipDataSaving::Always:
mappedDataSaving = tgvoip::DATA_SAVING_ALWAYS;
break;
default:
mappedDataSaving = tgvoip::DATA_SAVING_NEVER;
break;
}
tgvoip::VoIPController::Config mappedConfig(
config.initializationTimeout,
config.receiveTimeout,
mappedDataSaving,
config.enableAEC,
config.enableNS,
config.enableAGC,
config.enableCallUpgrade
);
mappedConfig.logFilePath = config.logPath;
mappedConfig.statsDumpFilePath = "";
controller_->SetConfig(mappedConfig);
setNetworkType(initialNetworkType);
std::vector<uint8_t> encryptionKeyValue = encryptionKey.value;
controller_->SetEncryptionKey((char *)(encryptionKeyValue.data()), encryptionKey.isOutgoing);
controller_->SetRemoteEndpoints(mappedEndpoints, config.enableP2P, config.maxApiLayer);
controller_->Start();
controller_->Connect();
}
~TgVoipImpl() {
}
void setOnStateUpdated(std::function<void(TgVoipState)> onStateUpdated) {
onStateUpdated_ = onStateUpdated;
}
void setOnSignalBarsUpdated(std::function<void(int)> onSignalBarsUpdated) {
onSignalBarsUpdated_ = onSignalBarsUpdated;
}
void setNetworkType(TgVoipNetworkType networkType) {
int mappedType = tgvoip::NET_TYPE_UNKNOWN;
switch (networkType) {
case TgVoipNetworkType::Unknown:
mappedType = tgvoip::NET_TYPE_UNKNOWN;
break;
case TgVoipNetworkType::Gprs:
mappedType = tgvoip::NET_TYPE_GPRS;
break;
case TgVoipNetworkType::Edge:
mappedType = tgvoip::NET_TYPE_EDGE;
break;
case TgVoipNetworkType::ThirdGeneration:
mappedType = tgvoip::NET_TYPE_3G;
break;
case TgVoipNetworkType::Hspa:
mappedType = tgvoip::NET_TYPE_HSPA;
break;
case TgVoipNetworkType::Lte:
mappedType = tgvoip::NET_TYPE_LTE;
break;
case TgVoipNetworkType::WiFi:
mappedType = tgvoip::NET_TYPE_WIFI;
break;
case TgVoipNetworkType::Ethernet:
mappedType = tgvoip::NET_TYPE_ETHERNET;
break;
case TgVoipNetworkType::OtherHighSpeed:
mappedType = tgvoip::NET_TYPE_OTHER_HIGH_SPEED;
break;
case TgVoipNetworkType::OtherLowSpeed:
mappedType = tgvoip::NET_TYPE_OTHER_LOW_SPEED;
break;
case TgVoipNetworkType::OtherMobile:
mappedType = tgvoip::NET_TYPE_OTHER_MOBILE;
break;
case TgVoipNetworkType::Dialup:
mappedType = tgvoip::NET_TYPE_DIALUP;
break;
default:
mappedType = tgvoip::NET_TYPE_UNKNOWN;
break;
}
controller_->SetNetworkType(mappedType);
}
void setMuteMicrophone(bool muteMicrophone) {
controller_->SetMicMute(muteMicrophone);
}
std::string getVersion() {
return controller_->GetVersion();
}
TgVoipPersistentState getPersistentState() {
std::vector<uint8_t> persistentStateValue = controller_->GetPersistentState();
TgVoipPersistentState persistentState = {
.value = persistentStateValue
};
return persistentState;
}
std::string getDebugInfo() {
return controller_->GetDebugString();
}
TgVoipFinalState stop() {
controller_->Stop();
auto debugLog = controller_->GetDebugLog();
tgvoip::VoIPController::TrafficStats stats;
controller_->GetStats(&stats);
TgVoipTrafficStats trafficStats = {
.bytesSentWifi = stats.bytesSentWifi,
.bytesReceivedWifi = stats.bytesRecvdWifi,
.bytesSentMobile = stats.bytesSentMobile,
.bytesReceivedMobile = stats.bytesRecvdMobile
};
std::vector<uint8_t> persistentStateValue = controller_->GetPersistentState();
TgVoipPersistentState persistentState = {
.value = persistentStateValue
};
TgVoipFinalState finalState = {
.persistentState = persistentState,
.debugLog = debugLog,
.trafficStats = trafficStats,
.isRatingSuggested = controller_->NeedRate()
};
delete controller_;
controller_ = NULL;
return finalState;
}
static void controllerStateCallback(tgvoip::VoIPController *controller, int state) {
TgVoipImpl *self = (TgVoipImpl *)controller->implData;
if (self->onStateUpdated_) {
TgVoipState mappedState;
switch (state) {
case tgvoip::STATE_WAIT_INIT:
mappedState = TgVoipState::WaitInit;
break;
case tgvoip::STATE_WAIT_INIT_ACK:
mappedState = TgVoipState::WaitInitAck;
break;
case tgvoip::STATE_ESTABLISHED:
mappedState = TgVoipState::Estabilished;
break;
case tgvoip::STATE_FAILED:
mappedState = TgVoipState::Failed;
break;
case tgvoip::STATE_RECONNECTING:
mappedState = TgVoipState::Reconnecting;
break;
default:
mappedState = TgVoipState::Estabilished;
break;
}
self->onStateUpdated_(mappedState);
}
}
static void signalBarsCallback(tgvoip::VoIPController *controller, int signalBars) {
TgVoipImpl *self = (TgVoipImpl *)controller->implData;
if (self->onSignalBarsUpdated_) {
self->onSignalBarsUpdated_(signalBars);
}
}
};
std::function<void(std::string const &)> globalLoggingFunction;
void __tgvoip_call_tglog(const char *format, ...){
va_list vaArgs;
va_start(vaArgs, format);
va_list vaCopy;
va_copy(vaCopy, vaArgs);
const int length = std::vsnprintf(NULL, 0, format, vaCopy);
va_end(vaCopy);
std::vector<char> zc(length + 1);
std::vsnprintf(zc.data(), zc.size(), format, vaArgs);
va_end(vaArgs);
if (globalLoggingFunction != nullptr) {
globalLoggingFunction(std::string(zc.data(), zc.size()));
}
}
void TgVoip::setLoggingFunction(std::function<void(std::string const &)> loggingFunction) {
globalLoggingFunction = loggingFunction;
}
void TgVoip::setGlobalServerConfig(const std::string &serverConfig) {
tgvoip::ServerConfig::GetSharedInstance()->Update(serverConfig);
}
TgVoip *TgVoip::makeInstance(
TgVoipCrypto const &crypto,
TgVoipConfig const &config,
TgVoipPersistentState const &persistentState,
std::vector<TgVoipEndpoint> const &endpoints,
std::unique_ptr<TgVoipProxy> const &proxy,
TgVoipNetworkType initialNetworkType,
TgVoipEncryptionKey const &encryptionKey
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
,
TgVoipAudioDataCallbacks const &audioDataCallbacks
#endif
) {
return new TgVoipImpl(
crypto,
endpoints,
persistentState,
proxy,
config,
encryptionKey,
initialNetworkType
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
,
audioDataCallbacks
#endif
);
}
TgVoip::~TgVoip() {
}

149
TgVoip.h Executable file
View File

@ -0,0 +1,149 @@
#ifndef __TGVOIP_H
#define __TGVOIP_H
#include <functional>
#include <vector>
#include <string>
#include <memory>
struct TgVoipProxy {
std::string host;
uint16_t port;
std::string login;
std::string password;
};
enum class TgVoipEndpointType {
Inet,
Lan,
UdpRelay,
TcpRelay
};
struct TgVoipEndpoint {
int64_t endpointId;
std::string host;
uint16_t port;
TgVoipEndpointType type;
unsigned char peerTag[16];
};
enum class TgVoipNetworkType {
Unknown,
Gprs,
Edge,
ThirdGeneration,
Hspa,
Lte,
WiFi,
Ethernet,
OtherHighSpeed,
OtherLowSpeed,
OtherMobile,
Dialup
};
enum class TgVoipDataSaving {
Never,
Mobile,
Always
};
struct TgVoipPersistentState {
std::vector<uint8_t> value;
};
struct TgVoipCrypto {
void (*rand_bytes)(uint8_t* buffer, size_t length);
void (*sha1)(uint8_t* msg, size_t length, uint8_t* output);
void (*sha256)(uint8_t* msg, size_t length, uint8_t* output);
void (*aes_ige_encrypt)(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv);
void (*aes_ige_decrypt)(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv);
void (*aes_ctr_encrypt)(uint8_t* inout, size_t length, uint8_t* key, uint8_t* iv, uint8_t* ecount, uint32_t* num);
void (*aes_cbc_encrypt)(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv);
void (*aes_cbc_decrypt)(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv);
};
struct TgVoipConfig {
double initializationTimeout;
double receiveTimeout;
TgVoipDataSaving dataSaving;
bool enableP2P;
bool enableAEC;
bool enableNS;
bool enableAGC;
bool enableCallUpgrade;
std::string logPath;
int maxApiLayer;
};
struct TgVoipEncryptionKey {
std::vector<uint8_t> value;
bool isOutgoing;
};
enum class TgVoipState {
WaitInit,
WaitInitAck,
Estabilished,
Failed,
Reconnecting
};
struct TgVoipTrafficStats {
uint64_t bytesSentWifi;
uint64_t bytesReceivedWifi;
uint64_t bytesSentMobile;
uint64_t bytesReceivedMobile;
};
struct TgVoipFinalState {
TgVoipPersistentState persistentState;
std::string debugLog;
TgVoipTrafficStats trafficStats;
bool isRatingSuggested;
};
struct TgVoipAudioDataCallbacks {
std::function<void(int16_t*, size_t)> input;
std::function<void(int16_t*, size_t)> output;
std::function<void(int16_t*, size_t)> preprocessed;
};
class TgVoip {
protected:
TgVoip() = default;
public:
static void setLoggingFunction(std::function<void(std::string const &)> loggingFunction);
static void setGlobalServerConfig(std::string const &serverConfig);
static TgVoip *makeInstance(
TgVoipCrypto const &crypto,
TgVoipConfig const &config,
TgVoipPersistentState const &persistentState,
std::vector<TgVoipEndpoint> const &endpoints,
std::unique_ptr<TgVoipProxy> const &proxy,
TgVoipNetworkType initialNetworkType,
TgVoipEncryptionKey const &encryptionKey
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
,
TgVoipAudioDataCallbacks const &audioDataCallbacks
#endif
);
virtual ~TgVoip();
virtual void setNetworkType(TgVoipNetworkType networkType) = 0;
virtual void setMuteMicrophone(bool muteMicrophone) = 0;
virtual std::string getVersion() = 0;
virtual TgVoipPersistentState getPersistentState() = 0;
virtual std::string getDebugInfo() = 0;
virtual void setOnStateUpdated(std::function<void(TgVoipState)> onStateUpdated) = 0;
virtual void setOnSignalBarsUpdated(std::function<void(int)> onSignalBarsUpdated) = 0;
virtual TgVoipFinalState stop() = 0;
};
#endif