TgVoip.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. #include "TgVoip.h"
  2. #include "VoIPController.h"
  3. #include "VoIPServerConfig.h"
  4. #include <stdarg.h>
  5. #ifndef TGVOIP_USE_CUSTOM_CRYPTO
  6. extern "C" {
  7. #include <openssl/sha.h>
  8. #include <openssl/aes.h>
  9. #include <openssl/modes.h>
  10. #include <openssl/rand.h>
  11. }
  12. void tgvoip_openssl_aes_ige_encrypt(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv){
  13. AES_KEY akey;
  14. AES_set_encrypt_key(key, 32*8, &akey);
  15. AES_ige_encrypt(in, out, length, &akey, iv, AES_ENCRYPT);
  16. }
  17. void tgvoip_openssl_aes_ige_decrypt(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv){
  18. AES_KEY akey;
  19. AES_set_decrypt_key(key, 32*8, &akey);
  20. AES_ige_encrypt(in, out, length, &akey, iv, AES_DECRYPT);
  21. }
  22. void tgvoip_openssl_rand_bytes(uint8_t* buffer, size_t len){
  23. RAND_bytes(buffer, len);
  24. }
  25. void tgvoip_openssl_sha1(uint8_t* msg, size_t len, uint8_t* output){
  26. SHA1(msg, len, output);
  27. }
  28. void tgvoip_openssl_sha256(uint8_t* msg, size_t len, uint8_t* output){
  29. SHA256(msg, len, output);
  30. }
  31. void tgvoip_openssl_aes_ctr_encrypt(uint8_t* inout, size_t length, uint8_t* key, uint8_t* iv, uint8_t* ecount, uint32_t* num){
  32. AES_KEY akey;
  33. AES_set_encrypt_key(key, 32*8, &akey);
  34. CRYPTO_ctr128_encrypt(inout, inout, length, &akey, iv, ecount, num, (block128_f) AES_encrypt);
  35. }
  36. void tgvoip_openssl_aes_cbc_encrypt(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv){
  37. AES_KEY akey;
  38. AES_set_encrypt_key(key, 256, &akey);
  39. AES_cbc_encrypt(in, out, length, &akey, iv, AES_ENCRYPT);
  40. }
  41. void tgvoip_openssl_aes_cbc_decrypt(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv){
  42. AES_KEY akey;
  43. AES_set_decrypt_key(key, 256, &akey);
  44. AES_cbc_encrypt(in, out, length, &akey, iv, AES_DECRYPT);
  45. }
  46. tgvoip::CryptoFunctions tgvoip::VoIPController::crypto={
  47. tgvoip_openssl_rand_bytes,
  48. tgvoip_openssl_sha1,
  49. tgvoip_openssl_sha256,
  50. tgvoip_openssl_aes_ige_encrypt,
  51. tgvoip_openssl_aes_ige_decrypt,
  52. tgvoip_openssl_aes_ctr_encrypt,
  53. tgvoip_openssl_aes_cbc_encrypt,
  54. tgvoip_openssl_aes_cbc_decrypt
  55. };
  56. #else
  57. tgvoip::CryptoFunctions tgvoip::VoIPController::crypto; // set it yourself upon initialization
  58. #endif
  59. class TgVoipImpl : public TgVoip {
  60. private:
  61. tgvoip::VoIPController *controller_;
  62. std::function<void(TgVoipState)> onStateUpdated_;
  63. std::function<void(int)> onSignalBarsUpdated_;
  64. public:
  65. TgVoipImpl(
  66. std::vector<TgVoipEndpoint> const &endpoints,
  67. TgVoipPersistentState const &persistentState,
  68. TgVoipProxy const *proxy,
  69. TgVoipConfig const &config,
  70. TgVoipEncryptionKey const &encryptionKey,
  71. TgVoipNetworkType initialNetworkType
  72. #ifdef TGVOIP_USE_CUSTOM_CRYPTO
  73. ,
  74. TgVoipCrypto const &crypto
  75. #endif
  76. #ifdef TGVOIP_USE_CALLBACK_AUDIO_IO
  77. ,
  78. TgVoipAudioDataCallbacks const &audioDataCallbacks
  79. #endif
  80. ) {
  81. #ifdef TGVOIP_USE_CUSTOM_CRYPTO
  82. tgvoip::VoIPController::crypto.sha1 = crypto.sha1;
  83. tgvoip::VoIPController::crypto.sha256 = crypto.sha256;
  84. tgvoip::VoIPController::crypto.rand_bytes = crypto.rand_bytes;
  85. tgvoip::VoIPController::crypto.aes_ige_encrypt = crypto.aes_ige_encrypt;
  86. tgvoip::VoIPController::crypto.aes_ige_decrypt = crypto.aes_ige_decrypt;
  87. tgvoip::VoIPController::crypto.aes_ctr_encrypt = crypto.aes_ctr_encrypt;
  88. #endif
  89. controller_ = new tgvoip::VoIPController();
  90. controller_->implData = this;
  91. #ifdef TGVOIP_USE_CALLBACK_AUDIO_IO
  92. controller_->SetAudioDataCallbacks(audioDataCallbacks.input, audioDataCallbacks.output, audioDataCallbacks.preprocessed);
  93. #endif
  94. controller_->SetPersistentState(persistentState.value);
  95. if (proxy != nullptr) {
  96. controller_->SetProxy(tgvoip::PROXY_SOCKS5, proxy->host, proxy->port, proxy->login, proxy->password);
  97. }
  98. auto callbacks = tgvoip::VoIPController::Callbacks();
  99. callbacks.connectionStateChanged = &TgVoipImpl::controllerStateCallback;
  100. callbacks.groupCallKeyReceived = nullptr;
  101. callbacks.groupCallKeySent = nullptr;
  102. callbacks.signalBarCountChanged = &TgVoipImpl::signalBarsCallback;
  103. callbacks.upgradeToGroupCallRequested = nullptr;
  104. controller_->SetCallbacks(callbacks);
  105. std::vector<tgvoip::Endpoint> mappedEndpoints;
  106. for (auto endpoint : endpoints) {
  107. tgvoip::Endpoint::Type mappedType;
  108. switch (endpoint.type) {
  109. case TgVoipEndpointType::UdpRelay:
  110. mappedType = tgvoip::Endpoint::Type::UDP_RELAY;
  111. break;
  112. case TgVoipEndpointType::Lan:
  113. mappedType = tgvoip::Endpoint::Type::UDP_P2P_LAN;
  114. break;
  115. case TgVoipEndpointType::Inet:
  116. mappedType = tgvoip::Endpoint::Type::UDP_P2P_INET;
  117. break;
  118. case TgVoipEndpointType::TcpRelay:
  119. mappedType = tgvoip::Endpoint::Type::TCP_RELAY;
  120. break;
  121. default:
  122. mappedType = tgvoip::Endpoint::Type::UDP_RELAY;
  123. break;
  124. }
  125. tgvoip::IPv4Address address(endpoint.host.ipv4);
  126. tgvoip::IPv6Address addressv6(endpoint.host.ipv6);
  127. mappedEndpoints.emplace_back(endpoint.endpointId, endpoint.port, address, addressv6, mappedType, endpoint.peerTag);
  128. }
  129. int mappedDataSaving;
  130. switch (config.dataSaving) {
  131. case TgVoipDataSaving::Mobile:
  132. mappedDataSaving = tgvoip::DATA_SAVING_MOBILE;
  133. break;
  134. case TgVoipDataSaving::Always:
  135. mappedDataSaving = tgvoip::DATA_SAVING_ALWAYS;
  136. break;
  137. default:
  138. mappedDataSaving = tgvoip::DATA_SAVING_NEVER;
  139. break;
  140. }
  141. tgvoip::VoIPController::Config mappedConfig(
  142. config.initializationTimeout,
  143. config.receiveTimeout,
  144. mappedDataSaving,
  145. config.enableAEC,
  146. config.enableNS,
  147. config.enableAGC,
  148. config.enableCallUpgrade
  149. );
  150. mappedConfig.enableVolumeControl = config.enableVolumeControl;
  151. mappedConfig.logFilePath = config.logPath;
  152. mappedConfig.statsDumpFilePath = {};
  153. controller_->SetConfig(mappedConfig);
  154. setNetworkType(initialNetworkType);
  155. std::vector<uint8_t> encryptionKeyValue = encryptionKey.value;
  156. controller_->SetEncryptionKey((char *)(encryptionKeyValue.data()), encryptionKey.isOutgoing);
  157. controller_->SetRemoteEndpoints(mappedEndpoints, config.enableP2P, config.maxApiLayer);
  158. controller_->Start();
  159. controller_->Connect();
  160. }
  161. ~TgVoipImpl() {
  162. if (controller_) {
  163. stop();
  164. }
  165. }
  166. void setOnStateUpdated(std::function<void(TgVoipState)> onStateUpdated) override {
  167. onStateUpdated_ = onStateUpdated;
  168. }
  169. void setOnSignalBarsUpdated(std::function<void(int)> onSignalBarsUpdated) override {
  170. onSignalBarsUpdated_ = onSignalBarsUpdated;
  171. }
  172. void setNetworkType(TgVoipNetworkType networkType) override {
  173. int mappedType;
  174. switch (networkType) {
  175. case TgVoipNetworkType::Unknown:
  176. mappedType = tgvoip::NET_TYPE_UNKNOWN;
  177. break;
  178. case TgVoipNetworkType::Gprs:
  179. mappedType = tgvoip::NET_TYPE_GPRS;
  180. break;
  181. case TgVoipNetworkType::Edge:
  182. mappedType = tgvoip::NET_TYPE_EDGE;
  183. break;
  184. case TgVoipNetworkType::ThirdGeneration:
  185. mappedType = tgvoip::NET_TYPE_3G;
  186. break;
  187. case TgVoipNetworkType::Hspa:
  188. mappedType = tgvoip::NET_TYPE_HSPA;
  189. break;
  190. case TgVoipNetworkType::Lte:
  191. mappedType = tgvoip::NET_TYPE_LTE;
  192. break;
  193. case TgVoipNetworkType::WiFi:
  194. mappedType = tgvoip::NET_TYPE_WIFI;
  195. break;
  196. case TgVoipNetworkType::Ethernet:
  197. mappedType = tgvoip::NET_TYPE_ETHERNET;
  198. break;
  199. case TgVoipNetworkType::OtherHighSpeed:
  200. mappedType = tgvoip::NET_TYPE_OTHER_HIGH_SPEED;
  201. break;
  202. case TgVoipNetworkType::OtherLowSpeed:
  203. mappedType = tgvoip::NET_TYPE_OTHER_LOW_SPEED;
  204. break;
  205. case TgVoipNetworkType::OtherMobile:
  206. mappedType = tgvoip::NET_TYPE_OTHER_MOBILE;
  207. break;
  208. case TgVoipNetworkType::Dialup:
  209. mappedType = tgvoip::NET_TYPE_DIALUP;
  210. break;
  211. default:
  212. mappedType = tgvoip::NET_TYPE_UNKNOWN;
  213. break;
  214. }
  215. controller_->SetNetworkType(mappedType);
  216. }
  217. void setMuteMicrophone(bool muteMicrophone) override {
  218. controller_->SetMicMute(muteMicrophone);
  219. }
  220. void setAudioOutputGainControlEnabled(bool enabled) override {
  221. controller_->SetAudioOutputGainControlEnabled(enabled);
  222. }
  223. void setEchoCancellationStrength(int strength) override {
  224. controller_->SetEchoCancellationStrength(strength);
  225. }
  226. void setAudioInputDevice(std::string id) override {
  227. controller_->SetCurrentAudioInput(id);
  228. }
  229. void setAudioOutputDevice(std::string id) override {
  230. controller_->SetCurrentAudioOutput(id);
  231. }
  232. void setInputVolume(float level) override {
  233. controller_->SetInputVolume(level);
  234. }
  235. void setOutputVolume(float level) override {
  236. controller_->SetOutputVolume(level);
  237. }
  238. void setAudioOutputDuckingEnabled(bool enabled) override {
  239. #if defined(__APPLE__) && TARGET_OS_OSX
  240. controller_->SetAudioOutputDuckingEnabled(enabled);
  241. #endif // TARGET_OS_OSX
  242. }
  243. std::string getLastError() override {
  244. switch (controller_->GetLastError()) {
  245. case tgvoip::ERROR_INCOMPATIBLE: return "ERROR_INCOMPATIBLE";
  246. case tgvoip::ERROR_TIMEOUT: return "ERROR_TIMEOUT";
  247. case tgvoip::ERROR_AUDIO_IO: return "ERROR_AUDIO_IO";
  248. case tgvoip::ERROR_PROXY: return "ERROR_PROXY";
  249. default: return "ERROR_UNKNOWN";
  250. }
  251. }
  252. std::string getDebugInfo() override {
  253. return controller_->GetDebugString();
  254. }
  255. int64_t getPreferredRelayId() override {
  256. return controller_->GetPreferredRelayID();
  257. }
  258. TgVoipTrafficStats getTrafficStats() override {
  259. tgvoip::VoIPController::TrafficStats stats;
  260. controller_->GetStats(&stats);
  261. return {
  262. .bytesSentWifi = stats.bytesSentWifi,
  263. .bytesReceivedWifi = stats.bytesRecvdWifi,
  264. .bytesSentMobile = stats.bytesSentMobile,
  265. .bytesReceivedMobile = stats.bytesRecvdMobile
  266. };
  267. }
  268. TgVoipPersistentState getPersistentState() override {
  269. return {controller_->GetPersistentState()};
  270. }
  271. TgVoipFinalState stop() override {
  272. controller_->Stop();
  273. TgVoipFinalState finalState = {
  274. .persistentState = getPersistentState(),
  275. .debugLog = controller_->GetDebugLog(),
  276. .trafficStats = getTrafficStats(),
  277. .isRatingSuggested = controller_->NeedRate()
  278. };
  279. delete controller_;
  280. controller_ = nullptr;
  281. return finalState;
  282. }
  283. static void controllerStateCallback(tgvoip::VoIPController *controller, int state) {
  284. auto *self = (TgVoipImpl *) controller->implData;
  285. if (self->onStateUpdated_) {
  286. TgVoipState mappedState;
  287. switch (state) {
  288. case tgvoip::STATE_WAIT_INIT:
  289. mappedState = TgVoipState::WaitInit;
  290. break;
  291. case tgvoip::STATE_WAIT_INIT_ACK:
  292. mappedState = TgVoipState::WaitInitAck;
  293. break;
  294. case tgvoip::STATE_ESTABLISHED:
  295. mappedState = TgVoipState::Established;
  296. break;
  297. case tgvoip::STATE_FAILED:
  298. mappedState = TgVoipState::Failed;
  299. break;
  300. case tgvoip::STATE_RECONNECTING:
  301. mappedState = TgVoipState::Reconnecting;
  302. break;
  303. default:
  304. mappedState = TgVoipState::Established;
  305. break;
  306. }
  307. self->onStateUpdated_(mappedState);
  308. }
  309. }
  310. static void signalBarsCallback(tgvoip::VoIPController *controller, int signalBars) {
  311. auto *self = (TgVoipImpl *) controller->implData;
  312. if (self->onSignalBarsUpdated_) {
  313. self->onSignalBarsUpdated_(signalBars);
  314. }
  315. }
  316. };
  317. std::function<void(std::string const &)> globalLoggingFunction;
  318. void __tgvoip_call_tglog(const char *format, ...){
  319. va_list vaArgs;
  320. va_start(vaArgs, format);
  321. va_list vaCopy;
  322. va_copy(vaCopy, vaArgs);
  323. const int length = std::vsnprintf(nullptr, 0, format, vaCopy);
  324. va_end(vaCopy);
  325. std::vector<char> zc(length + 1);
  326. std::vsnprintf(zc.data(), zc.size(), format, vaArgs);
  327. va_end(vaArgs);
  328. if (globalLoggingFunction != nullptr) {
  329. globalLoggingFunction(std::string(zc.data(), zc.size()));
  330. }
  331. }
  332. void TgVoip::setLoggingFunction(std::function<void(std::string const &)> loggingFunction) {
  333. globalLoggingFunction = loggingFunction;
  334. }
  335. void TgVoip::setGlobalServerConfig(const std::string &serverConfig) {
  336. tgvoip::ServerConfig::GetSharedInstance()->Update(serverConfig);
  337. }
  338. int TgVoip::getConnectionMaxLayer() {
  339. return tgvoip::VoIPController::GetConnectionMaxLayer();
  340. }
  341. std::string TgVoip::getVersion() {
  342. return tgvoip::VoIPController::GetVersion();
  343. }
  344. std::unique_ptr<TgVoip> TgVoip::makeInstance(
  345. TgVoipConfig const &config,
  346. TgVoipPersistentState const &persistentState,
  347. std::vector<TgVoipEndpoint> const &endpoints,
  348. TgVoipProxy const *proxy,
  349. TgVoipNetworkType initialNetworkType,
  350. TgVoipEncryptionKey const &encryptionKey
  351. #ifdef TGVOIP_USE_CUSTOM_CRYPTO
  352. ,
  353. TgVoipCrypto const &crypto
  354. #endif
  355. #ifdef TGVOIP_USE_CALLBACK_AUDIO_IO
  356. ,
  357. TgVoipAudioDataCallbacks const &audioDataCallbacks
  358. #endif
  359. ) {
  360. return std::make_unique<TgVoipImpl>(
  361. endpoints,
  362. persistentState,
  363. proxy,
  364. config,
  365. encryptionKey,
  366. initialNetworkType
  367. #ifdef TGVOIP_USE_CUSTOM_CRYPTO
  368. ,
  369. crypto
  370. #endif
  371. #ifdef TGVOIP_USE_CALLBACK_AUDIO_IO
  372. ,
  373. audioDataCallbacks
  374. #endif
  375. );
  376. }
  377. TgVoip::~TgVoip() = default;