Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
1774
TMessagesProj/jni/tgnet/ApiScheme.cpp
Normal file
1774
TMessagesProj/jni/tgnet/ApiScheme.cpp
Normal file
File diff suppressed because it is too large
Load diff
964
TMessagesProj/jni/tgnet/ApiScheme.h
Normal file
964
TMessagesProj/jni/tgnet/ApiScheme.h
Normal file
|
|
@ -0,0 +1,964 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef APISCHEME_H
|
||||
#define APISCHEME_H
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "TLObject.h"
|
||||
|
||||
class ByteArray;
|
||||
class NativeByteBuffer;
|
||||
|
||||
class Bool : public TLObject {
|
||||
|
||||
public:
|
||||
static Bool *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_boolTrue : public Bool {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x997275b5;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_boolFalse : public Bool {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xbc799737;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_dcOption : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x18b7a10d;
|
||||
|
||||
int32_t flags;
|
||||
bool ipv6;
|
||||
bool media_only;
|
||||
bool tcpo_only;
|
||||
bool cdn;
|
||||
bool isStatic;
|
||||
bool thisPortOnly;
|
||||
bool force_try_ipv6;
|
||||
int32_t id;
|
||||
std::string ip_address;
|
||||
int32_t port;
|
||||
std::unique_ptr<ByteArray> secret;
|
||||
|
||||
static TL_dcOption *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_cdnPublicKey : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xc982eaba;
|
||||
|
||||
int32_t dc_id;
|
||||
std::string public_key;
|
||||
|
||||
static TL_cdnPublicKey *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_cdnConfig : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x5725e40a;
|
||||
|
||||
std::vector<std::unique_ptr<TL_cdnPublicKey>> public_keys;
|
||||
|
||||
static TL_cdnConfig *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_help_getCdnConfig : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x52029342;
|
||||
|
||||
bool isNeedLayer();
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class Reaction : public TLObject {
|
||||
|
||||
public:
|
||||
static Reaction *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
|
||||
class TL_config : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xcc1a241e;
|
||||
|
||||
int32_t flags;
|
||||
int32_t date;
|
||||
int32_t expires;
|
||||
bool test_mode;
|
||||
int32_t this_dc;
|
||||
std::vector<std::unique_ptr<TL_dcOption>> dc_options;
|
||||
std::string dc_txt_domain_name;
|
||||
int32_t chat_size_max;
|
||||
int32_t megagroup_size_max;
|
||||
int32_t forwarded_count_max;
|
||||
int32_t online_update_period_ms;
|
||||
int32_t offline_blur_timeout_ms;
|
||||
int32_t offline_idle_timeout_ms;
|
||||
int32_t online_cloud_timeout_ms;
|
||||
int32_t notify_cloud_delay_ms;
|
||||
int32_t notify_default_delay_ms;
|
||||
int32_t push_chat_period_ms;
|
||||
int32_t push_chat_limit;
|
||||
// int32_t saved_gifs_limit;
|
||||
int32_t edit_time_limit;
|
||||
int32_t revoke_time_limit;
|
||||
int32_t revoke_pm_time_limit;
|
||||
int32_t rating_e_decay;
|
||||
int32_t stickers_recent_limit;
|
||||
// int32_t stickers_faved_limit;
|
||||
int32_t channels_read_media_period;
|
||||
int32_t tmp_sessions;
|
||||
// int32_t pinned_dialogs_count_max;
|
||||
// int32_t pinned_infolder_count_max;
|
||||
int32_t call_receive_timeout_ms;
|
||||
int32_t call_ring_timeout_ms;
|
||||
int32_t call_connect_timeout_ms;
|
||||
int32_t call_packet_timeout_ms;
|
||||
std::string me_url_prefix;
|
||||
std::string autoupdate_url_prefix;
|
||||
std::string gif_search_username;
|
||||
std::string venue_search_username;
|
||||
std::string img_search_username;
|
||||
std::string static_maps_provider;
|
||||
int32_t caption_length_max;
|
||||
int32_t message_length_max;
|
||||
int32_t webfile_dc_id;
|
||||
std::string suggested_lang_code;
|
||||
int32_t lang_pack_version;
|
||||
int32_t base_lang_pack_version;
|
||||
std::unique_ptr<Reaction> reactions_default;
|
||||
std::string autologin_token;
|
||||
|
||||
static TL_config *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_help_getConfig : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xc4f9186b;
|
||||
|
||||
bool isNeedLayer();
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_account_registerDevice : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x637ea878;
|
||||
|
||||
int32_t token_type;
|
||||
std::string token;
|
||||
|
||||
bool isNeedLayer();
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class UserStatus : public TLObject {
|
||||
|
||||
public:
|
||||
int32_t expires;
|
||||
|
||||
static UserStatus *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_userStatusOffline : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x8c703f;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_userStatusLastWeek : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x7bf09fc;
|
||||
|
||||
uint32_t flags;
|
||||
bool by_me;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_userStatusLastWeek_layer171 : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x7bf09fc;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_userStatusEmpty : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x9d05049;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_userStatusLastMonth : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x65899777;
|
||||
|
||||
uint32_t flags;
|
||||
bool by_me;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_userStatusLastMonth_layer171 : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x77ebc742;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_userStatusOnline : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xedb93949;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_userStatusRecently : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x7b197dc8;
|
||||
|
||||
uint32_t flags;
|
||||
bool by_me;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_userStatusRecently_layer171 : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xe26f42f1;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_userStatusHidden : public UserStatus {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xcf7d64b1;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class FileLocation : public TLObject {
|
||||
|
||||
public:
|
||||
int64_t volume_id;
|
||||
int32_t local_id;
|
||||
|
||||
static FileLocation *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_fileLocationToBeDeprecated : public FileLocation {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xbc7fc6cd;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class UserProfilePhoto : public TLObject {
|
||||
|
||||
public:
|
||||
int32_t flags;
|
||||
bool has_video;
|
||||
int64_t photo_id;
|
||||
std::unique_ptr<ByteArray> stripped_thumb;
|
||||
int32_t dc_id;
|
||||
|
||||
static UserProfilePhoto *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_userProfilePhotoEmpty : public UserProfilePhoto {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x4f11bae1;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_userProfilePhoto : public UserProfilePhoto {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x82d1f706;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_restrictionReason : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xd072acb4;
|
||||
|
||||
std::string platform;
|
||||
std::string reason;
|
||||
std::string text;
|
||||
|
||||
static TL_restrictionReason *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_recentStory : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x711d692d;
|
||||
|
||||
int32_t flags;
|
||||
bool is_live;
|
||||
int32_t max_id;
|
||||
|
||||
static TL_recentStory *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_username : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xb4073647;
|
||||
int32_t flags;
|
||||
bool editable;
|
||||
bool active;
|
||||
std::string username;
|
||||
|
||||
static TL_username *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_peerColor : public TLObject {
|
||||
public:
|
||||
static const uint32_t constructor = 0xb54b5acf;
|
||||
|
||||
int32_t flags;
|
||||
int32_t color;
|
||||
int64_t background_emoji_id;
|
||||
|
||||
static TL_peerColor *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class EmojiStatus : public TLObject {
|
||||
public:
|
||||
static EmojiStatus *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_emojiStatusEmpty : public EmojiStatus {
|
||||
public:
|
||||
static const uint32_t constructor = 0xb54b5acf;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_emojiStatus : public EmojiStatus {
|
||||
public:
|
||||
static const uint32_t constructor = 0xe7ff068a;
|
||||
|
||||
int32_t flags;
|
||||
int64_t document_id;
|
||||
int32_t until;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_emojiStatus_layer197 : public EmojiStatus {
|
||||
public:
|
||||
static const uint32_t constructor = 0x929b619d;
|
||||
|
||||
int64_t document_id;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_emojiStatusUntil_layer197 : public EmojiStatus {
|
||||
public:
|
||||
static const uint32_t constructor = 0xfa30a8c7;
|
||||
|
||||
int64_t document_id;
|
||||
int32_t until;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_emojiStatusCollectible : public EmojiStatus {
|
||||
public:
|
||||
static const uint32_t constructor = 0x7184603b;
|
||||
|
||||
int32_t flags;
|
||||
int64_t collectible_id;
|
||||
int64_t document_id;
|
||||
std::string title;
|
||||
std::string slug;
|
||||
int64_t pattern_document_id;
|
||||
int32_t center_color;
|
||||
int32_t edge_color;
|
||||
int32_t pattern_color;
|
||||
int32_t text_color;
|
||||
int32_t until;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class User : public TLObject {
|
||||
|
||||
public:
|
||||
int64_t id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
std::string username;
|
||||
int64_t access_hash;
|
||||
std::string phone;
|
||||
std::unique_ptr<UserProfilePhoto> photo;
|
||||
std::unique_ptr<UserStatus> status;
|
||||
int32_t flags;
|
||||
int32_t flags2;
|
||||
int32_t bot_info_version;
|
||||
std::vector<std::unique_ptr<TL_restrictionReason>> restriction_reason;
|
||||
std::string bot_inline_placeholder;
|
||||
std::string lang_code;
|
||||
std::vector<std::unique_ptr<TL_username>> usernames;
|
||||
std::unique_ptr<TL_recentStory> stories_max_id;
|
||||
std::unique_ptr<EmojiStatus> emoji_status;
|
||||
std::unique_ptr<TL_peerColor> color;
|
||||
std::unique_ptr<TL_peerColor> profile_color;
|
||||
int32_t bot_active_users;
|
||||
int64_t bot_verification_icon;
|
||||
int64_t send_paid_messages_stars;
|
||||
|
||||
static User *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_userEmpty : public User {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x31774388;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_user : public User {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xd3bc4b7a;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_user_layer216 : public TL_user {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x20b1422;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class InputPeer : public TLObject {
|
||||
|
||||
public:
|
||||
int64_t user_id;
|
||||
int64_t chat_id;
|
||||
int64_t channel_id;
|
||||
int64_t access_hash;
|
||||
|
||||
static InputPeer *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_inputPeerSelf : public InputPeer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x7da07ec9;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputPeerUser : public InputPeer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xdde8a54c;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputPeerChat : public InputPeer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x35a95cb9;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputPeerUserFromMessage : public InputPeer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xa87b0a1c;
|
||||
|
||||
std::unique_ptr<InputPeer> peer;
|
||||
int32_t msg_id;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputPeerChannelFromMessage : public InputPeer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xbd2a0840;
|
||||
|
||||
std::unique_ptr<InputPeer> peer;
|
||||
int32_t msg_id;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputPeerChannel : public InputPeer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x27bcbbfc;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputPeerEmpty : public InputPeer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x7f3b18ea;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class InputUser : public TLObject {
|
||||
|
||||
public:
|
||||
int64_t user_id;
|
||||
int64_t access_hash;
|
||||
|
||||
static InputUser *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_inputUserSelf : public InputUser {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xf7c1b13f;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputUser : public InputUser {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xf21158c6;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputUserEmpty : public InputUser {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xb98886cf;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputUserFromMessage : public InputUser {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x1da448e2;
|
||||
|
||||
std::unique_ptr<InputPeer> peer;
|
||||
int32_t msg_id;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class MessageEntity : public TLObject {
|
||||
|
||||
public:
|
||||
int32_t flags;
|
||||
int32_t offset;
|
||||
int32_t length;
|
||||
std::string url;
|
||||
std::string language;
|
||||
|
||||
static MessageEntity *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_messageEntityTextUrl : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x76a6d327;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityBotCommand : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x6cef8ac7;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityEmail : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x64e475c2;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityPre : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x73924be0;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityUnknown : public MessageEntity {
|
||||
public:
|
||||
static const uint32_t constructor = 0xbb92ba95;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityUrl : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x6ed02538;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityItalic : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x826f8b60;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityMention : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xfa04579d;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityMentionName : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xdc7b1140;
|
||||
|
||||
int64_t user_id;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputMessageEntityMentionName : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x208e68c9;
|
||||
|
||||
std::unique_ptr<InputUser> user_id;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityCashtag : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x4c4e743f;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityBold : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xbd610bc9;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityHashtag : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x6f635b0d;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityCode : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x28a20571;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityStrike : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xbf0693d4;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityBlockquote : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xf1ccaaac;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityBlockquote_layer180 : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x20df5d0;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityUnderline : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x9c4e7e8b;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_messageEntityPhone : public MessageEntity {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x9b69e34b;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_dataJSON : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x7d748d04;
|
||||
|
||||
std::string data;
|
||||
|
||||
static TL_dataJSON *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_help_termsOfService : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x780a0310;
|
||||
|
||||
int32_t flags;
|
||||
bool popup;
|
||||
std::unique_ptr<TL_dataJSON> id;
|
||||
std::string text;
|
||||
std::vector<std::unique_ptr<MessageEntity>> entities;
|
||||
int32_t min_age_confirm;
|
||||
|
||||
static TL_help_termsOfService *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class auth_Authorization : public TLObject {
|
||||
|
||||
public:
|
||||
static auth_Authorization *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_auth_authorizationSignUpRequired : public auth_Authorization {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x44747e9a;
|
||||
|
||||
int32_t flags;
|
||||
std::unique_ptr<TL_help_termsOfService> terms_of_service;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_auth_authorization : public auth_Authorization {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x2ea2c0d4;
|
||||
|
||||
int32_t flags;
|
||||
int32_t tmp_sessions;
|
||||
int32_t otherwise_relogin_days;
|
||||
std::unique_ptr<ByteArray> future_auth_token;
|
||||
std::unique_ptr<User> user;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_auth_exportedAuthorization : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xb434e2b8;
|
||||
|
||||
int64_t id;
|
||||
std::unique_ptr<ByteArray> bytes;
|
||||
|
||||
static TL_auth_exportedAuthorization *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_auth_exportAuthorization : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xe5bfffcd;
|
||||
|
||||
int32_t dc_id;
|
||||
|
||||
bool isNeedLayer();
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_auth_importAuthorization : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xa57a7dad;
|
||||
|
||||
int64_t id;
|
||||
std::unique_ptr<ByteArray> bytes;
|
||||
|
||||
bool isNeedLayer();
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_updatesTooLong : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xe317af7e;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
|
||||
class TL_reactionCustomEmoji : public Reaction {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x8935fc73;
|
||||
int64_t document_id;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
|
||||
class TL_reactionEmoji : public Reaction {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x1b2286b8;
|
||||
std::string emoticon;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TL_reactionEmpty : public Reaction {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x79f5d419;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
#endif
|
||||
123
TMessagesProj/jni/tgnet/BuffersStorage.cpp
Normal file
123
TMessagesProj/jni/tgnet/BuffersStorage.cpp
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include "BuffersStorage.h"
|
||||
#include "FileLog.h"
|
||||
#include "NativeByteBuffer.h"
|
||||
|
||||
BuffersStorage &BuffersStorage::getInstance() {
|
||||
static BuffersStorage instance(true);
|
||||
return instance;
|
||||
}
|
||||
|
||||
BuffersStorage::BuffersStorage(bool threadSafe) {
|
||||
isThreadSafe = threadSafe;
|
||||
if (isThreadSafe) {
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
}
|
||||
for (uint32_t a = 0; a < 4; a++) {
|
||||
freeBuffers8.push_back(new NativeByteBuffer((uint32_t) 8));
|
||||
}
|
||||
for (uint32_t a = 0; a < 5; a++) {
|
||||
freeBuffers128.push_back(new NativeByteBuffer((uint32_t) 128));
|
||||
}
|
||||
}
|
||||
|
||||
NativeByteBuffer *BuffersStorage::getFreeBuffer(uint32_t size) {
|
||||
uint32_t byteCount = 0;
|
||||
std::vector<NativeByteBuffer *> *arrayToGetFrom = nullptr;
|
||||
NativeByteBuffer *buffer = nullptr;
|
||||
if (size <= 8) {
|
||||
arrayToGetFrom = &freeBuffers8;
|
||||
byteCount = 8;
|
||||
} else if (size <= 128) {
|
||||
arrayToGetFrom = &freeBuffers128;
|
||||
byteCount = 128;
|
||||
} else if (size <= 1024 + 200) {
|
||||
arrayToGetFrom = &freeBuffers1024;
|
||||
byteCount = 1024 + 200;
|
||||
} else if (size <= 4096 + 200) {
|
||||
arrayToGetFrom = &freeBuffers4096;
|
||||
byteCount = 4096 + 200;
|
||||
} else if (size <= 16384 + 200) {
|
||||
arrayToGetFrom = &freeBuffers16384;
|
||||
byteCount = 16384 + 200;
|
||||
} else if (size <= 40000) {
|
||||
arrayToGetFrom = &freeBuffers32768;
|
||||
byteCount = 40000;
|
||||
} else if (size <= 160000) {
|
||||
arrayToGetFrom = &freeBuffersBig;
|
||||
byteCount = 160000;
|
||||
} else {
|
||||
buffer = new NativeByteBuffer(size);
|
||||
}
|
||||
|
||||
if (arrayToGetFrom != nullptr) {
|
||||
if (isThreadSafe) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
if (arrayToGetFrom->size() > 0) {
|
||||
buffer = (*arrayToGetFrom)[0];
|
||||
arrayToGetFrom->erase(arrayToGetFrom->begin());
|
||||
}
|
||||
if (isThreadSafe) {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
if (buffer == nullptr) {
|
||||
buffer = new NativeByteBuffer(byteCount);
|
||||
if (LOGS_ENABLED) DEBUG_D("create new %u buffer", byteCount);
|
||||
}
|
||||
}
|
||||
if (buffer != nullptr) {
|
||||
buffer->limit(size);
|
||||
buffer->rewind();
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void BuffersStorage::reuseFreeBuffer(NativeByteBuffer *buffer) {
|
||||
if (buffer == nullptr) {
|
||||
return;
|
||||
}
|
||||
std::vector<NativeByteBuffer *> *arrayToReuse = nullptr;
|
||||
uint32_t capacity = buffer->capacity();
|
||||
uint32_t maxCount = 10;
|
||||
if (capacity == 8) {
|
||||
arrayToReuse = &freeBuffers8;
|
||||
maxCount = 80;
|
||||
} else if (capacity == 128) {
|
||||
arrayToReuse = &freeBuffers128;
|
||||
maxCount = 80;
|
||||
} else if (capacity == 1024 + 200) {
|
||||
arrayToReuse = &freeBuffers1024;
|
||||
} else if (capacity == 4096 + 200) {
|
||||
arrayToReuse = &freeBuffers4096;
|
||||
} else if (capacity == 16384 + 200) {
|
||||
arrayToReuse = &freeBuffers16384;
|
||||
} else if (capacity == 40000) {
|
||||
arrayToReuse = &freeBuffers32768;
|
||||
} else if (capacity == 160000) {
|
||||
arrayToReuse = &freeBuffersBig;
|
||||
}
|
||||
if (arrayToReuse != nullptr) {
|
||||
if (isThreadSafe) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
if (arrayToReuse->size() < maxCount) {
|
||||
arrayToReuse->push_back(buffer);
|
||||
} else {
|
||||
if (LOGS_ENABLED) DEBUG_D("too much %d buffers", capacity);
|
||||
delete buffer;
|
||||
}
|
||||
if (isThreadSafe) {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
} else {
|
||||
delete buffer;
|
||||
}
|
||||
}
|
||||
38
TMessagesProj/jni/tgnet/BuffersStorage.h
Normal file
38
TMessagesProj/jni/tgnet/BuffersStorage.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef BUFFERSSTORAGE_H
|
||||
#define BUFFERSSTORAGE_H
|
||||
|
||||
#include <vector>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
class NativeByteBuffer;
|
||||
|
||||
class BuffersStorage {
|
||||
|
||||
public:
|
||||
BuffersStorage(bool threadSafe);
|
||||
NativeByteBuffer *getFreeBuffer(uint32_t size);
|
||||
void reuseFreeBuffer(NativeByteBuffer *buffer);
|
||||
static BuffersStorage &getInstance();
|
||||
|
||||
private:
|
||||
std::vector<NativeByteBuffer *> freeBuffers8;
|
||||
std::vector<NativeByteBuffer *> freeBuffers128;
|
||||
std::vector<NativeByteBuffer *> freeBuffers1024;
|
||||
std::vector<NativeByteBuffer *> freeBuffers4096;
|
||||
std::vector<NativeByteBuffer *> freeBuffers16384;
|
||||
std::vector<NativeByteBuffer *> freeBuffers32768;
|
||||
std::vector<NativeByteBuffer *> freeBuffersBig;
|
||||
bool isThreadSafe = true;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
71
TMessagesProj/jni/tgnet/ByteArray.cpp
Normal file
71
TMessagesProj/jni/tgnet/ByteArray.cpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include "ByteArray.h"
|
||||
#include "FileLog.h"
|
||||
|
||||
ByteArray::ByteArray() {
|
||||
bytes = nullptr;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
ByteArray::ByteArray(uint32_t len) {
|
||||
bytes = new uint8_t[len];
|
||||
if (bytes == nullptr) {
|
||||
if (LOGS_ENABLED) DEBUG_E("unable to allocate byte buffer %u", len);
|
||||
exit(1);
|
||||
}
|
||||
length = len;
|
||||
}
|
||||
|
||||
|
||||
ByteArray::ByteArray(ByteArray *byteArray) {
|
||||
bytes = new uint8_t[byteArray->length];
|
||||
if (bytes == nullptr) {
|
||||
if (LOGS_ENABLED) DEBUG_E("unable to allocate byte buffer %u", byteArray->length);
|
||||
exit(1);
|
||||
}
|
||||
length = byteArray->length;
|
||||
memcpy(bytes, byteArray->bytes, length);
|
||||
}
|
||||
|
||||
ByteArray::ByteArray(uint8_t *buffer, uint32_t len) {
|
||||
bytes = new uint8_t[len];
|
||||
if (bytes == nullptr) {
|
||||
if (LOGS_ENABLED) DEBUG_E("unable to allocate byte buffer %u", len);
|
||||
exit(1);
|
||||
}
|
||||
length = len;
|
||||
memcpy(bytes, buffer, length);
|
||||
}
|
||||
|
||||
ByteArray::~ByteArray() {
|
||||
if (bytes != nullptr) {
|
||||
delete[] bytes;
|
||||
bytes = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ByteArray::alloc(uint32_t len) {
|
||||
if (bytes != nullptr) {
|
||||
delete[] bytes;
|
||||
bytes = nullptr;
|
||||
}
|
||||
bytes = new uint8_t[len];
|
||||
if (bytes == nullptr) {
|
||||
if (LOGS_ENABLED) DEBUG_E("unable to allocate byte buffer %u", len);
|
||||
exit(1);
|
||||
}
|
||||
length = len;
|
||||
}
|
||||
|
||||
bool ByteArray::isEqualTo(ByteArray *byteArray) {
|
||||
return byteArray->length == length && !memcmp(byteArray->bytes, bytes, length);
|
||||
}
|
||||
31
TMessagesProj/jni/tgnet/ByteArray.h
Normal file
31
TMessagesProj/jni/tgnet/ByteArray.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef BYTEARRAY_H
|
||||
#define BYTEARRAY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class ByteArray {
|
||||
|
||||
public:
|
||||
ByteArray();
|
||||
ByteArray(uint32_t len);
|
||||
ByteArray(ByteArray *byteArray);
|
||||
ByteArray(uint8_t *buffer, uint32_t len);
|
||||
~ByteArray();
|
||||
void alloc(uint32_t len);
|
||||
|
||||
uint32_t length;
|
||||
uint8_t *bytes;
|
||||
|
||||
bool isEqualTo(ByteArray *byteArray);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
86
TMessagesProj/jni/tgnet/ByteStream.cpp
Normal file
86
TMessagesProj/jni/tgnet/ByteStream.cpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include "ByteStream.h"
|
||||
#include "NativeByteBuffer.h"
|
||||
|
||||
ByteStream::ByteStream() {
|
||||
|
||||
}
|
||||
|
||||
ByteStream::~ByteStream() {
|
||||
|
||||
}
|
||||
|
||||
void ByteStream::append(NativeByteBuffer *buffer) {
|
||||
if (buffer == nullptr) {
|
||||
return;
|
||||
}
|
||||
buffersQueue.push_back(buffer);
|
||||
}
|
||||
|
||||
bool ByteStream::hasData() {
|
||||
size_t size = buffersQueue.size();
|
||||
for (uint32_t a = 0; a < size; a++) {
|
||||
if (buffersQueue[a]->hasRemaining()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ByteStream::get(NativeByteBuffer *dst) {
|
||||
if (dst == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size = buffersQueue.size();
|
||||
NativeByteBuffer *buffer;
|
||||
for (uint32_t a = 0; a < size; a++) {
|
||||
buffer = buffersQueue[a];
|
||||
if (buffer->remaining() > dst->remaining()) {
|
||||
dst->writeBytes(buffer->bytes(), buffer->position(), dst->remaining());
|
||||
break;
|
||||
}
|
||||
dst->writeBytes(buffer->bytes(), buffer->position(), buffer->remaining());
|
||||
if (!dst->hasRemaining()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ByteStream::discard(uint32_t count) {
|
||||
uint32_t remaining;
|
||||
NativeByteBuffer *buffer;
|
||||
while (count > 0) {
|
||||
if (buffersQueue.empty()) {
|
||||
break;
|
||||
}
|
||||
buffer = buffersQueue[0];
|
||||
remaining = buffer->remaining();
|
||||
if (count < remaining) {
|
||||
buffer->position(buffer->position() + count);
|
||||
break;
|
||||
}
|
||||
buffer->reuse();
|
||||
buffersQueue.erase(buffersQueue.begin());
|
||||
count -= remaining;
|
||||
}
|
||||
}
|
||||
|
||||
void ByteStream::clean() {
|
||||
if (buffersQueue.empty()) {
|
||||
return;
|
||||
}
|
||||
size_t size = buffersQueue.size();
|
||||
for (uint32_t a = 0; a < size; a++) {
|
||||
NativeByteBuffer *buffer = buffersQueue[a];
|
||||
buffer->reuse();
|
||||
}
|
||||
buffersQueue.clear();
|
||||
}
|
||||
32
TMessagesProj/jni/tgnet/ByteStream.h
Normal file
32
TMessagesProj/jni/tgnet/ByteStream.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef BYTESTREAM_H
|
||||
#define BYTESTREAM_H
|
||||
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
class NativeByteBuffer;
|
||||
|
||||
class ByteStream {
|
||||
|
||||
public:
|
||||
ByteStream();
|
||||
~ByteStream();
|
||||
void append(NativeByteBuffer *buffer);
|
||||
bool hasData();
|
||||
void get(NativeByteBuffer *dst);
|
||||
void discard(uint32_t count);
|
||||
void clean();
|
||||
|
||||
private:
|
||||
std::vector<NativeByteBuffer *> buffersQueue;
|
||||
};
|
||||
|
||||
#endif
|
||||
131
TMessagesProj/jni/tgnet/Config.cpp
Normal file
131
TMessagesProj/jni/tgnet/Config.cpp
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <cstring>
|
||||
#include "Config.h"
|
||||
#include "ConnectionsManager.h"
|
||||
#include "FileLog.h"
|
||||
#include "BuffersStorage.h"
|
||||
|
||||
Config::Config(int32_t instance, std::string fileName) {
|
||||
instanceNum = instance;
|
||||
configPath = ConnectionsManager::getInstance(instanceNum).currentConfigPath + fileName;
|
||||
backupPath = configPath + ".bak";
|
||||
FILE *backup = fopen(backupPath.c_str(), "rb");
|
||||
if (backup != nullptr) {
|
||||
if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) backup file found %s", this, configPath.c_str(), backupPath.c_str());
|
||||
fclose(backup);
|
||||
remove(configPath.c_str());
|
||||
rename(backupPath.c_str(), configPath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
NativeByteBuffer *Config::readConfig() {
|
||||
NativeByteBuffer *buffer = nullptr;
|
||||
FILE *file = fopen(configPath.c_str(), "rb");
|
||||
if (file != nullptr) {
|
||||
fseek(file, 0, SEEK_END);
|
||||
long fileSize = ftell(file);
|
||||
if (fseek(file, 0, SEEK_SET)) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) failed fseek to begin, reopen it", this, configPath.c_str());
|
||||
fclose(file);
|
||||
file = fopen(configPath.c_str(), "rb");
|
||||
}
|
||||
uint32_t size = 0;
|
||||
size_t bytesRead = fread(&size, sizeof(uint32_t), 1, file);
|
||||
if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) load, size = %u, fileSize = %u", this, configPath.c_str(), size, (uint32_t) fileSize);
|
||||
if (bytesRead > 0 && size > 0 && (int32_t) size < fileSize) {
|
||||
buffer = BuffersStorage::getInstance().getFreeBuffer(size);
|
||||
if (fread(buffer->bytes(), sizeof(uint8_t), size, file) != size) {
|
||||
buffer->reuse();
|
||||
buffer = nullptr;
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void Config::writeConfig(NativeByteBuffer *buffer) {
|
||||
if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) start write config", this, configPath.c_str());
|
||||
FILE *file = fopen(configPath.c_str(), "rb");
|
||||
FILE *backup = fopen(backupPath.c_str(), "rb");
|
||||
bool error = false;
|
||||
bool hasBackupFile = false;
|
||||
if (file != nullptr) {
|
||||
if (backup == nullptr) {
|
||||
fclose(file);
|
||||
if (rename(configPath.c_str(), backupPath.c_str()) != 0) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p) unable to rename file %s to backup file %s", this, configPath.c_str(), backupPath.c_str());
|
||||
error = true;
|
||||
} else {
|
||||
hasBackupFile = true;
|
||||
}
|
||||
} else {
|
||||
fclose(file);
|
||||
fclose(backup);
|
||||
remove(configPath.c_str());
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
file = fopen(configPath.c_str(), "wb");
|
||||
if (chmod(configPath.c_str(), 0660)) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) chmod failed", this, configPath.c_str());
|
||||
}
|
||||
if (file == nullptr) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) unable to open file for writing", this, configPath.c_str());
|
||||
return;
|
||||
}
|
||||
uint32_t size = buffer->position();
|
||||
if (fwrite(&size, sizeof(uint32_t), 1, file) == 1) {
|
||||
if (fwrite(buffer->bytes(), sizeof(uint8_t), size, file) != size) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) failed to write config data to file", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
} else {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) failed to write config size to file", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
if (fflush(file)) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) fflush failed", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
int fd = fileno(file);
|
||||
if (fd == -1) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) fileno failed", this, configPath.c_str());
|
||||
error = true;
|
||||
} else {
|
||||
if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) fileno = %d", this, configPath.c_str(), fd);
|
||||
}
|
||||
if (fd != -1 && fsync(fd) == -1) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) fsync failed", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
if (fclose(file)) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) fclose failed", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
if (error) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) failed to write config", this, configPath.c_str());
|
||||
if (remove(configPath.c_str())) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) remove config failed", this, configPath.c_str());
|
||||
}
|
||||
} else {
|
||||
if (hasBackupFile && remove(backupPath.c_str())) {
|
||||
if (LOGS_ENABLED) DEBUG_E("Config(%p, %s) remove backup failed, %s", this, backupPath.c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
if (!error) {
|
||||
if (LOGS_ENABLED) DEBUG_D("Config(%p, %s) config write ok", this, configPath.c_str());
|
||||
}
|
||||
}
|
||||
29
TMessagesProj/jni/tgnet/Config.h
Normal file
29
TMessagesProj/jni/tgnet/Config.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <string>
|
||||
#include "NativeByteBuffer.h"
|
||||
|
||||
class Config {
|
||||
|
||||
public:
|
||||
Config(int32_t instance, std::string fileName);
|
||||
|
||||
NativeByteBuffer *readConfig();
|
||||
void writeConfig(NativeByteBuffer *buffer);
|
||||
|
||||
private:
|
||||
int32_t instanceNum;
|
||||
std::string configPath;
|
||||
std::string backupPath;
|
||||
};
|
||||
|
||||
#endif
|
||||
761
TMessagesProj/jni/tgnet/Connection.cpp
Normal file
761
TMessagesProj/jni/tgnet/Connection.cpp
Normal file
|
|
@ -0,0 +1,761 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <stdlib.h>
|
||||
#include <cstring>
|
||||
#include <openssl/sha.h>
|
||||
#include <algorithm>
|
||||
#include "Connection.h"
|
||||
#include "ConnectionsManager.h"
|
||||
#include "BuffersStorage.h"
|
||||
#include "FileLog.h"
|
||||
#include "Timer.h"
|
||||
#include "Datacenter.h"
|
||||
#include "NativeByteBuffer.h"
|
||||
#include "ByteArray.h"
|
||||
|
||||
thread_local static uint32_t lastConnectionToken = 1;
|
||||
|
||||
Connection::Connection(Datacenter *datacenter, ConnectionType type, int8_t num) : ConnectionSession(datacenter->instanceNum), ConnectionSocket(datacenter->instanceNum) {
|
||||
currentDatacenter = datacenter;
|
||||
connectionNum = num;
|
||||
connectionType = type;
|
||||
genereateNewSessionId();
|
||||
connectionState = TcpConnectionStageIdle;
|
||||
reconnectTimer = new Timer(datacenter->instanceNum, [&] {
|
||||
reconnectTimer->stop();
|
||||
waitForReconnectTimer = false;
|
||||
connect();
|
||||
});
|
||||
}
|
||||
|
||||
Connection::~Connection() {
|
||||
if (reconnectTimer != nullptr) {
|
||||
reconnectTimer->stop();
|
||||
delete reconnectTimer;
|
||||
reconnectTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::suspendConnection() {
|
||||
suspendConnection(false);
|
||||
}
|
||||
|
||||
void Connection::suspendConnection(bool idle) {
|
||||
reconnectTimer->stop();
|
||||
waitForReconnectTimer = false;
|
||||
if (connectionState == TcpConnectionStageIdle || connectionState == TcpConnectionStageSuspended) {
|
||||
return;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) suspend", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType);
|
||||
connectionState = idle ? TcpConnectionStageIdle : TcpConnectionStageSuspended;
|
||||
dropConnection();
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionClosed(this, 0);
|
||||
generation++;
|
||||
firstPacketSent = false;
|
||||
if (restOfTheData != nullptr) {
|
||||
restOfTheData->reuse();
|
||||
restOfTheData = nullptr;
|
||||
}
|
||||
lastPacketLength = 0;
|
||||
connectionToken = 0;
|
||||
wasConnected = false;
|
||||
}
|
||||
|
||||
void Connection::onReceivedData(NativeByteBuffer *buffer) {
|
||||
AES_ctr128_encrypt(buffer->bytes(), buffer->bytes(), buffer->limit(), &decryptKey, decryptIv, decryptCount, &decryptNum);
|
||||
|
||||
failedConnectionCount = 0;
|
||||
|
||||
if (connectionType == ConnectionTypeGeneric || connectionType == ConnectionTypeTemp || connectionType == ConnectionTypeGenericMedia) {
|
||||
receivedDataAmount += buffer->limit();
|
||||
if (receivedDataAmount >= 512 * 1024) {
|
||||
if (currentTimeout > 4) {
|
||||
currentTimeout -= 2;
|
||||
setTimeout(currentTimeout);
|
||||
}
|
||||
receivedDataAmount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
NativeByteBuffer *parseLaterBuffer = nullptr;
|
||||
if (restOfTheData != nullptr) {
|
||||
if (lastPacketLength == 0) {
|
||||
if (restOfTheData->capacity() - restOfTheData->position() >= buffer->limit()) {
|
||||
restOfTheData->limit(restOfTheData->position() + buffer->limit());
|
||||
restOfTheData->writeBytes(buffer);
|
||||
buffer = restOfTheData;
|
||||
} else {
|
||||
NativeByteBuffer *newBuffer = BuffersStorage::getInstance().getFreeBuffer(restOfTheData->limit() + buffer->limit());
|
||||
restOfTheData->rewind();
|
||||
newBuffer->writeBytes(restOfTheData);
|
||||
newBuffer->writeBytes(buffer);
|
||||
buffer = newBuffer;
|
||||
restOfTheData->reuse();
|
||||
restOfTheData = newBuffer;
|
||||
}
|
||||
} else {
|
||||
uint32_t len;
|
||||
if (lastPacketLength - restOfTheData->position() <= buffer->limit()) {
|
||||
len = lastPacketLength - restOfTheData->position();
|
||||
} else {
|
||||
len = buffer->limit();
|
||||
}
|
||||
uint32_t oldLimit = buffer->limit();
|
||||
buffer->limit(len);
|
||||
restOfTheData->writeBytes(buffer);
|
||||
buffer->limit(oldLimit);
|
||||
if (restOfTheData->position() == lastPacketLength) {
|
||||
parseLaterBuffer = buffer->hasRemaining() ? buffer : nullptr;
|
||||
buffer = restOfTheData;
|
||||
} else {
|
||||
// if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received packet size less(%u) then message size(%u)", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, restOfTheData->position(), lastPacketLength);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer->rewind();
|
||||
|
||||
NativeByteBuffer *reuseLater = nullptr;
|
||||
while (buffer->hasRemaining()) {
|
||||
if (!hasSomeDataSinceLastConnect) {
|
||||
currentDatacenter->storeCurrentAddressAndPortNum();
|
||||
isTryingNextPort = false;
|
||||
if (connectionType == ConnectionTypeProxy) {
|
||||
setTimeout(5);
|
||||
} else if (connectionType == ConnectionTypePush) {
|
||||
setTimeout(60 * 15);
|
||||
} else if (connectionType == ConnectionTypeUpload) {
|
||||
if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).networkSlow) {
|
||||
setTimeout(40);
|
||||
} else {
|
||||
setTimeout(25);
|
||||
}
|
||||
} else if (connectionType == ConnectionTypeDownload) {
|
||||
setTimeout(25);
|
||||
} else {
|
||||
setTimeout(currentTimeout);
|
||||
}
|
||||
}
|
||||
hasSomeDataSinceLastConnect = true;
|
||||
|
||||
uint32_t currentPacketLength = 0;
|
||||
uint32_t mark = buffer->position();
|
||||
uint32_t len;
|
||||
|
||||
if (currentProtocolType == ProtocolTypeEF) {
|
||||
uint8_t fByte = buffer->readByte(nullptr);
|
||||
|
||||
if ((fByte & (1 << 7)) != 0) {
|
||||
buffer->position(mark);
|
||||
if (buffer->remaining() < 4) {
|
||||
reuseLater = restOfTheData;
|
||||
restOfTheData = BuffersStorage::getInstance().getFreeBuffer(16384);
|
||||
restOfTheData->writeBytes(buffer);
|
||||
restOfTheData->limit(restOfTheData->position());
|
||||
lastPacketLength = 0;
|
||||
break;
|
||||
}
|
||||
int32_t ackId = buffer->readBigInt32(nullptr) & (~(1 << 31));
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionQuickAckReceived(this, ackId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fByte != 0x7f) {
|
||||
currentPacketLength = ((uint32_t) fByte) * 4;
|
||||
} else {
|
||||
buffer->position(mark);
|
||||
if (buffer->remaining() < 4) {
|
||||
if (restOfTheData == nullptr || (restOfTheData != nullptr && restOfTheData->position() != 0)) {
|
||||
reuseLater = restOfTheData;
|
||||
restOfTheData = BuffersStorage::getInstance().getFreeBuffer(16384);
|
||||
restOfTheData->writeBytes(buffer);
|
||||
restOfTheData->limit(restOfTheData->position());
|
||||
lastPacketLength = 0;
|
||||
} else {
|
||||
restOfTheData->position(restOfTheData->limit());
|
||||
}
|
||||
break;
|
||||
}
|
||||
currentPacketLength = ((uint32_t) buffer->readInt32(nullptr) >> 8) * 4;
|
||||
}
|
||||
|
||||
len = currentPacketLength + (fByte != 0x7f ? 1 : 4);
|
||||
} else {
|
||||
if (buffer->remaining() < 4) {
|
||||
if (restOfTheData == nullptr || (restOfTheData != nullptr && restOfTheData->position() != 0)) {
|
||||
reuseLater = restOfTheData;
|
||||
restOfTheData = BuffersStorage::getInstance().getFreeBuffer(16384);
|
||||
restOfTheData->writeBytes(buffer);
|
||||
restOfTheData->limit(restOfTheData->position());
|
||||
lastPacketLength = 0;
|
||||
} else {
|
||||
restOfTheData->position(restOfTheData->limit());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t fInt = buffer->readUint32(nullptr);
|
||||
|
||||
if ((fInt & (0x80000000)) != 0) {
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionQuickAckReceived(this, fInt & (~(1 << 31)));
|
||||
continue;
|
||||
}
|
||||
|
||||
currentPacketLength = fInt;
|
||||
len = currentPacketLength + 4;
|
||||
}
|
||||
|
||||
if (currentProtocolType != ProtocolTypeDD && currentProtocolType != ProtocolTypeTLS && currentPacketLength % 4 != 0 || currentPacketLength > 2 * 1024 * 1024) {
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received invalid packet length", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType);
|
||||
reconnect();
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentPacketLength < buffer->remaining()) {
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received message len %u but packet larger %u", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, currentPacketLength, buffer->remaining());
|
||||
} else if (currentPacketLength == buffer->remaining()) {
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received message len %u equal to packet size", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, currentPacketLength);
|
||||
} else {
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received packet size less(%u) then message size(%u)", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, buffer->remaining(), currentPacketLength);
|
||||
|
||||
if (restOfTheData != nullptr && restOfTheData->capacity() < len) {
|
||||
reuseLater = restOfTheData;
|
||||
restOfTheData = nullptr;
|
||||
}
|
||||
if (restOfTheData == nullptr) {
|
||||
buffer->position(mark);
|
||||
restOfTheData = BuffersStorage::getInstance().getFreeBuffer(len);
|
||||
restOfTheData->writeBytes(buffer);
|
||||
} else {
|
||||
restOfTheData->position(restOfTheData->limit());
|
||||
restOfTheData->limit(len);
|
||||
}
|
||||
lastPacketLength = len;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t old = buffer->limit();
|
||||
buffer->limit(buffer->position() + currentPacketLength);
|
||||
uint32_t current_generation = generation;
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionDataReceived(this, buffer, currentPacketLength);
|
||||
if (current_generation != generation) {
|
||||
break;
|
||||
}
|
||||
buffer->position(buffer->limit());
|
||||
buffer->limit(old);
|
||||
|
||||
if (restOfTheData != nullptr) {
|
||||
if ((lastPacketLength != 0 && restOfTheData->position() == lastPacketLength) || (lastPacketLength == 0 && !restOfTheData->hasRemaining())) {
|
||||
reuseLater = restOfTheData;
|
||||
restOfTheData = nullptr;
|
||||
} else {
|
||||
restOfTheData->compact();
|
||||
restOfTheData->limit(restOfTheData->position());
|
||||
restOfTheData->position(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (parseLaterBuffer != nullptr) {
|
||||
buffer = parseLaterBuffer;
|
||||
parseLaterBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
if (reuseLater != nullptr) {
|
||||
reuseLater->reuse();
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::connect() {
|
||||
if (waitForReconnectTimer) {
|
||||
return;
|
||||
}
|
||||
if (!ConnectionsManager::getInstance(currentDatacenter->instanceNum).isNetworkAvailable()) {
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionClosed(this, 0);
|
||||
return;
|
||||
}
|
||||
if (connectionState == TcpConnectionStageConnected || connectionState == TcpConnectionStageConnecting) {
|
||||
return;
|
||||
}
|
||||
connectionInProcess = true;
|
||||
connectionState = TcpConnectionStageConnecting;
|
||||
isMediaConnection = false;
|
||||
uint8_t strategy = ConnectionsManager::getInstance(currentDatacenter->instanceNum).getIpStratagy();
|
||||
uint32_t ipv6;
|
||||
if (strategy == USE_IPV6_ONLY) {
|
||||
ipv6 = TcpAddressFlagIpv6;
|
||||
} else if (strategy == USE_IPV4_IPV6_RANDOM) {
|
||||
if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).lastProtocolUsefullData) {
|
||||
ipv6 = ConnectionsManager::getInstance(currentDatacenter->instanceNum).lastProtocolIsIpv6 ? TcpAddressFlagIpv6 : 0;
|
||||
} else {
|
||||
uint8_t value;
|
||||
RAND_bytes(&value, 1);
|
||||
ipv6 = value % 3 == 0 ? TcpAddressFlagIpv6 : 0;
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).lastProtocolIsIpv6 = ipv6 != 0;
|
||||
}
|
||||
if (connectionType == ConnectionTypeGeneric) {
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).lastProtocolUsefullData = false;
|
||||
}
|
||||
} else {
|
||||
ipv6 = 0;
|
||||
}
|
||||
uint32_t isStatic = connectionType == ConnectionTypeProxy || !ConnectionsManager::getInstance(currentDatacenter->instanceNum).proxyAddress.empty() ? TcpAddressFlagStatic : 0;
|
||||
TcpAddress *tcpAddress = nullptr;
|
||||
if (isMediaConnectionType(connectionType)) {
|
||||
currentAddressFlags = TcpAddressFlagDownload | isStatic;
|
||||
tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags | ipv6);
|
||||
if (tcpAddress == nullptr) {
|
||||
currentAddressFlags = isStatic;
|
||||
tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags | ipv6);
|
||||
} else {
|
||||
isMediaConnection = true;
|
||||
}
|
||||
if (tcpAddress == nullptr && ipv6) {
|
||||
ipv6 = 0;
|
||||
currentAddressFlags = TcpAddressFlagDownload | isStatic;
|
||||
tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags);
|
||||
if (tcpAddress == nullptr) {
|
||||
currentAddressFlags = isStatic;
|
||||
tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags);
|
||||
} else {
|
||||
isMediaConnection = true;
|
||||
}
|
||||
}
|
||||
} else if (connectionType == ConnectionTypeTemp) {
|
||||
currentAddressFlags = TcpAddressFlagTemp;
|
||||
tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags);
|
||||
ipv6 = 0;
|
||||
} else {
|
||||
currentAddressFlags = isStatic;
|
||||
tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags | ipv6);
|
||||
if (tcpAddress == nullptr && ipv6) {
|
||||
ipv6 = 0;
|
||||
tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags);
|
||||
}
|
||||
}
|
||||
if (tcpAddress == nullptr) {
|
||||
hostAddress = "";
|
||||
} else {
|
||||
hostAddress = tcpAddress->address;
|
||||
secret = tcpAddress->secret;
|
||||
}
|
||||
if (tcpAddress != nullptr && isStatic) {
|
||||
hostPort = (uint16_t) tcpAddress->port;
|
||||
} else {
|
||||
hostPort = (uint16_t) currentDatacenter->getCurrentPort(currentAddressFlags);
|
||||
}
|
||||
|
||||
reconnectTimer->stop();
|
||||
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) connecting (%s:%hu)", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, hostAddress.c_str(), hostPort);
|
||||
generation++;
|
||||
firstPacketSent = false;
|
||||
if (restOfTheData != nullptr) {
|
||||
restOfTheData->reuse();
|
||||
restOfTheData = nullptr;
|
||||
}
|
||||
lastPacketLength = 0;
|
||||
wasConnected = false;
|
||||
hasSomeDataSinceLastConnect = false;
|
||||
openConnection(hostAddress, hostPort, secret, ipv6 != 0, ConnectionsManager::getInstance(currentDatacenter->instanceNum).currentNetworkType);
|
||||
if (connectionType == ConnectionTypeProxy) {
|
||||
setTimeout(5);
|
||||
} else if (connectionType == ConnectionTypePush) {
|
||||
if (isTryingNextPort) {
|
||||
setTimeout(20);
|
||||
} else {
|
||||
setTimeout(30);
|
||||
}
|
||||
} else if (connectionType == ConnectionTypeUpload) {
|
||||
if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).networkSlow) {
|
||||
setTimeout(40);
|
||||
} else {
|
||||
setTimeout(25);
|
||||
}
|
||||
} else {
|
||||
if (isTryingNextPort) {
|
||||
setTimeout(8);
|
||||
} else {
|
||||
setTimeout(12);
|
||||
}
|
||||
}
|
||||
connectionInProcess = false;
|
||||
}
|
||||
|
||||
void Connection::reconnect() {
|
||||
if (connectionType == ConnectionTypeProxy) {
|
||||
suspendConnection(false);
|
||||
} else {
|
||||
forceNextPort = true;
|
||||
suspendConnection(true);
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
bool Connection::hasUsefullData() {
|
||||
int64_t time = ConnectionsManager::getInstance(currentDatacenter->instanceNum).getCurrentTimeMonotonicMillis();
|
||||
if (usefullData && llabs(time - usefullDataReceiveTime) < 4 * 1000L) {
|
||||
return false;
|
||||
}
|
||||
return usefullData;
|
||||
}
|
||||
|
||||
bool Connection::isSuspended() {
|
||||
return connectionState == TcpConnectionStageSuspended;
|
||||
}
|
||||
|
||||
bool Connection::isMediaConnectionType(ConnectionType type) {
|
||||
return (type & ConnectionTypeGenericMedia) != 0 || (type & ConnectionTypeDownload) != 0;
|
||||
}
|
||||
|
||||
void Connection::setHasUsefullData() {
|
||||
if (!usefullData) {
|
||||
usefullDataReceiveTime = ConnectionsManager::getInstance(currentDatacenter->instanceNum).getCurrentTimeMonotonicMillis();
|
||||
usefullData = true;
|
||||
lastReconnectTimeout = 50;
|
||||
}
|
||||
}
|
||||
|
||||
bool Connection::allowsCustomPadding() {
|
||||
return currentProtocolType == ProtocolTypeTLS || currentProtocolType == ProtocolTypeDD || currentProtocolType == ProtocolTypeEF;
|
||||
}
|
||||
|
||||
void Connection::sendData(NativeByteBuffer *buff, bool reportAck, bool encrypted) {
|
||||
if (buff == nullptr) {
|
||||
return;
|
||||
}
|
||||
buff->rewind();
|
||||
if (connectionState == TcpConnectionStageIdle || connectionState == TcpConnectionStageReconnecting || connectionState == TcpConnectionStageSuspended) {
|
||||
connect();
|
||||
}
|
||||
|
||||
if (isDisconnected()) {
|
||||
buff->reuse();
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) disconnected, don't send data", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t bufferLen = 0;
|
||||
uint32_t packetLength;
|
||||
|
||||
uint8_t useSecret = 0;
|
||||
if (!firstPacketSent) {
|
||||
if (!overrideProxyAddress.empty()) {
|
||||
if (!overrideProxySecret.empty()) {
|
||||
useSecret = 1;
|
||||
} else if (!secret.empty()) {
|
||||
useSecret = 2;
|
||||
}
|
||||
} else if (!ConnectionsManager::getInstance(currentDatacenter->instanceNum).proxyAddress.empty() && !ConnectionsManager::getInstance(currentDatacenter->instanceNum).proxySecret.empty()) {
|
||||
useSecret = 1;
|
||||
} else if (!secret.empty()) {
|
||||
useSecret = 2;
|
||||
}
|
||||
if (useSecret != 0) {
|
||||
std::string *currentSecret = getCurrentSecret(useSecret);
|
||||
if (currentSecret->length() >= 17 && (*currentSecret)[0] == '\xdd') {
|
||||
currentProtocolType = ProtocolTypeDD;
|
||||
} else if (currentSecret->length() > 17 && (*currentSecret)[0] == '\xee') {
|
||||
currentProtocolType = ProtocolTypeTLS;
|
||||
} else {
|
||||
currentProtocolType = ProtocolTypeEF;
|
||||
}
|
||||
} else {
|
||||
currentProtocolType = ProtocolTypeEF;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t additinalPacketSize = 0;
|
||||
if (currentProtocolType == ProtocolTypeEF) {
|
||||
packetLength = buff->limit() / 4;
|
||||
if (packetLength < 0x7f) {
|
||||
bufferLen++;
|
||||
} else {
|
||||
bufferLen += 4;
|
||||
}
|
||||
} else {
|
||||
packetLength = buff->limit();
|
||||
if (currentProtocolType == ProtocolTypeDD || currentProtocolType == ProtocolTypeTLS) {
|
||||
RAND_bytes((uint8_t *) &additinalPacketSize, 4);
|
||||
if (!encrypted) {
|
||||
additinalPacketSize = additinalPacketSize % 257;
|
||||
} else {
|
||||
additinalPacketSize = additinalPacketSize % 16;
|
||||
}
|
||||
packetLength += additinalPacketSize;
|
||||
} else {
|
||||
RAND_bytes((uint8_t *) &additinalPacketSize, 4);
|
||||
if (!encrypted) {
|
||||
additinalPacketSize = additinalPacketSize % 257;
|
||||
uint32_t additionalSize = additinalPacketSize % 4;
|
||||
if (additionalSize != 0) {
|
||||
additinalPacketSize += (4 - additionalSize);
|
||||
}
|
||||
}
|
||||
packetLength += additinalPacketSize;
|
||||
}
|
||||
bufferLen += 4;
|
||||
}
|
||||
|
||||
if (!firstPacketSent) {
|
||||
bufferLen += 64;
|
||||
}
|
||||
|
||||
NativeByteBuffer *buffer = BuffersStorage::getInstance().getFreeBuffer(bufferLen);
|
||||
NativeByteBuffer *buffer2;
|
||||
if (additinalPacketSize > 0) {
|
||||
buffer2 = BuffersStorage::getInstance().getFreeBuffer(additinalPacketSize);
|
||||
RAND_bytes(buffer2->bytes(), additinalPacketSize);
|
||||
} else {
|
||||
buffer2 = nullptr;
|
||||
}
|
||||
uint8_t *bytes = buffer->bytes();
|
||||
|
||||
if (!firstPacketSent) {
|
||||
buffer->position(64);
|
||||
while (true) {
|
||||
RAND_bytes(bytes, 64);
|
||||
uint32_t val = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | (bytes[0]);
|
||||
uint32_t val2 = (bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | (bytes[4]);
|
||||
if (currentProtocolType == ProtocolTypeTLS || bytes[0] != 0xef && val != 0x44414548 && val != 0x54534f50 && val != 0x20544547 && val != 0x4954504f && val != 0xeeeeeeee && val != 0xdddddddd && val != 0x02010316 && val2 != 0x00000000) {
|
||||
if (currentProtocolType == ProtocolTypeEF) {
|
||||
bytes[56] = bytes[57] = bytes[58] = bytes[59] = 0xef;
|
||||
} else if (currentProtocolType == ProtocolTypeDD || currentProtocolType == ProtocolTypeTLS) {
|
||||
bytes[56] = bytes[57] = bytes[58] = bytes[59] = 0xdd;
|
||||
} else if (currentProtocolType == ProtocolTypeEE) {
|
||||
bytes[56] = bytes[57] = bytes[58] = bytes[59] = 0xee;
|
||||
}
|
||||
|
||||
if (useSecret != 0) {
|
||||
int16_t datacenterId;
|
||||
if (isMediaConnection) {
|
||||
if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).testBackend) {
|
||||
datacenterId = -(int16_t) (10000 + currentDatacenter->getDatacenterId());
|
||||
} else {
|
||||
datacenterId = -(int16_t) currentDatacenter->getDatacenterId();
|
||||
}
|
||||
} else {
|
||||
if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).testBackend) {
|
||||
datacenterId = (int16_t) (10000 + currentDatacenter->getDatacenterId());
|
||||
} else {
|
||||
datacenterId = (int16_t) currentDatacenter->getDatacenterId();
|
||||
}
|
||||
}
|
||||
bytes[60] = (uint8_t) (datacenterId & 0xff);
|
||||
bytes[61] = (uint8_t) ((datacenterId >> 8) & 0xff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
encryptNum = decryptNum = 0;
|
||||
memset(encryptCount, 0, 16);
|
||||
memset(decryptCount, 0, 16);
|
||||
|
||||
for (int32_t a = 0; a < 48; a++) {
|
||||
temp[a] = bytes[a + 8];
|
||||
}
|
||||
encryptKeyWithSecret(temp, useSecret);
|
||||
if (AES_set_encrypt_key(temp, 256, &encryptKey) < 0) {
|
||||
if (LOGS_ENABLED) DEBUG_E("unable to set encryptKey");
|
||||
exit(1);
|
||||
}
|
||||
memcpy(encryptIv, temp + 32, 16);
|
||||
|
||||
for (int32_t a = 0; a < 48; a++) {
|
||||
temp[a] = bytes[55 - a];
|
||||
}
|
||||
encryptKeyWithSecret(temp, useSecret);
|
||||
if (AES_set_encrypt_key(temp, 256, &decryptKey) < 0) {
|
||||
if (LOGS_ENABLED) DEBUG_E("unable to set decryptKey");
|
||||
exit(1);
|
||||
}
|
||||
memcpy(decryptIv, temp + 32, 16);
|
||||
|
||||
AES_ctr128_encrypt(bytes, temp, 64, &encryptKey, encryptIv, encryptCount, &encryptNum);
|
||||
memcpy(bytes + 56, temp + 56, 8);
|
||||
|
||||
firstPacketSent = true;
|
||||
}
|
||||
if (currentProtocolType == ProtocolTypeEF) {
|
||||
if (packetLength < 0x7f) {
|
||||
if (reportAck) {
|
||||
packetLength |= (1 << 7);
|
||||
}
|
||||
buffer->writeByte((uint8_t) packetLength);
|
||||
bytes += (buffer->limit() - 1);
|
||||
AES_ctr128_encrypt(bytes, bytes, 1, &encryptKey, encryptIv, encryptCount, &encryptNum);
|
||||
} else {
|
||||
packetLength = (packetLength << 8) + 0x7f;
|
||||
if (reportAck) {
|
||||
packetLength |= (1 << 7);
|
||||
}
|
||||
buffer->writeInt32(packetLength);
|
||||
bytes += (buffer->limit() - 4);
|
||||
AES_ctr128_encrypt(bytes, bytes, 4, &encryptKey, encryptIv, encryptCount, &encryptNum);
|
||||
}
|
||||
} else {
|
||||
if (reportAck) {
|
||||
packetLength |= 0x80000000;
|
||||
}
|
||||
buffer->writeInt32(packetLength);
|
||||
bytes += (buffer->limit() - 4);
|
||||
AES_ctr128_encrypt(bytes, bytes, 4, &encryptKey, encryptIv, encryptCount, &encryptNum);
|
||||
}
|
||||
|
||||
buffer->rewind();
|
||||
writeBuffer(buffer);
|
||||
buff->rewind();
|
||||
AES_ctr128_encrypt(buff->bytes(), buff->bytes(), buff->limit(), &encryptKey, encryptIv, encryptCount, &encryptNum);
|
||||
writeBuffer(buff);
|
||||
if (buffer2 != nullptr) {
|
||||
AES_ctr128_encrypt(buffer2->bytes(), buffer2->bytes(), buffer2->limit(), &encryptKey, encryptIv, encryptCount, &encryptNum);
|
||||
writeBuffer(buffer2);
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string *Connection::getCurrentSecret(uint8_t secretType) {
|
||||
if (secretType == 2) {
|
||||
return &secret;
|
||||
} else if (!overrideProxySecret.empty()) {
|
||||
return &overrideProxySecret;
|
||||
} else {
|
||||
return &ConnectionsManager::getInstance(currentDatacenter->instanceNum).proxySecret;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Connection::encryptKeyWithSecret(uint8_t *bytes, uint8_t secretType) {
|
||||
if (secretType == 0) {
|
||||
return;
|
||||
}
|
||||
std::string *currentSecret = getCurrentSecret(secretType);
|
||||
size_t a = 0;
|
||||
size_t size = std::min((size_t) 16, currentSecret->length());
|
||||
if (currentSecret->length() >= 17 && ((*currentSecret)[0] == '\xdd' || (*currentSecret)[0] == '\xee')) {
|
||||
a = 1;
|
||||
size = 17;
|
||||
}
|
||||
|
||||
SHA256_CTX sha256Ctx;
|
||||
SHA256_Init(&sha256Ctx);
|
||||
SHA256_Update(&sha256Ctx, bytes, 32);
|
||||
char b[1];
|
||||
for (; a < size; a++) {
|
||||
b[0] = (char) (*currentSecret)[a];
|
||||
SHA256_Update(&sha256Ctx, b, 1);
|
||||
}
|
||||
SHA256_Final(bytes, &sha256Ctx);
|
||||
}
|
||||
|
||||
void Connection::onDisconnectedInternal(int32_t reason, int32_t error) {
|
||||
reconnectTimer->stop();
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) disconnected with reason %d", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, reason);
|
||||
bool switchToNextPort = reason == 2 && wasConnected && (!hasSomeDataSinceLastConnect || currentDatacenter->isCustomPort(currentAddressFlags)) || forceNextPort;
|
||||
if (connectionType == ConnectionTypeGeneric || connectionType == ConnectionTypeTemp || connectionType == ConnectionTypeGenericMedia) {
|
||||
if (wasConnected && reason == 2 && currentTimeout < 16) {
|
||||
currentTimeout += 2;
|
||||
}
|
||||
}
|
||||
generation++;
|
||||
firstPacketSent = false;
|
||||
if (restOfTheData != nullptr) {
|
||||
restOfTheData->reuse();
|
||||
restOfTheData = nullptr;
|
||||
}
|
||||
lastPacketLength = 0;
|
||||
receivedDataAmount = 0;
|
||||
wasConnected = false;
|
||||
if (connectionState != TcpConnectionStageSuspended && connectionState != TcpConnectionStageIdle) {
|
||||
connectionState = TcpConnectionStageIdle;
|
||||
}
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionClosed(this, reason);
|
||||
connectionToken = 0;
|
||||
|
||||
uint32_t datacenterId = currentDatacenter->getDatacenterId();
|
||||
if (connectionState == TcpConnectionStageIdle) {
|
||||
connectionState = TcpConnectionStageReconnecting;
|
||||
failedConnectionCount++;
|
||||
if (failedConnectionCount == 1) {
|
||||
if (hasUsefullData()) {
|
||||
willRetryConnectCount = 3;
|
||||
} else {
|
||||
willRetryConnectCount = 1;
|
||||
}
|
||||
}
|
||||
if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).isNetworkAvailable() && connectionType != ConnectionTypeProxy) {
|
||||
isTryingNextPort = true;
|
||||
if (failedConnectionCount > willRetryConnectCount || switchToNextPort) {
|
||||
currentDatacenter->nextAddressOrPort(currentAddressFlags);
|
||||
if (currentDatacenter->isRepeatCheckingAddresses() && (ConnectionsManager::getInstance(currentDatacenter->instanceNum).getIpStratagy() == USE_IPV4_ONLY || ConnectionsManager::getInstance(currentDatacenter->instanceNum).getIpStratagy() == USE_IPV6_ONLY)) {
|
||||
if (LOGS_ENABLED) DEBUG_D("started retrying connection, set ipv4 ipv6 random strategy");
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).setIpStrategy(USE_IPV4_IPV6_RANDOM);
|
||||
}
|
||||
failedConnectionCount = 0;
|
||||
}
|
||||
}
|
||||
if (error == 0x68 || error == 0x71) {
|
||||
if (connectionType != ConnectionTypeProxy) {
|
||||
waitForReconnectTimer = true;
|
||||
reconnectTimer->setTimeout(lastReconnectTimeout, false);
|
||||
lastReconnectTimeout *= 2;
|
||||
if (lastReconnectTimeout > 400) {
|
||||
lastReconnectTimeout = 400;
|
||||
}
|
||||
reconnectTimer->start();
|
||||
}
|
||||
} else {
|
||||
waitForReconnectTimer = false;
|
||||
if (connectionType == ConnectionTypeGenericMedia && currentDatacenter->isHandshaking(true) || connectionType == ConnectionTypeGeneric && (currentDatacenter->isHandshaking(false) || datacenterId == ConnectionsManager::getInstance(currentDatacenter->instanceNum).currentDatacenterId || datacenterId == ConnectionsManager::getInstance(currentDatacenter->instanceNum).movingToDatacenterId)) {
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) reconnect %s:%hu", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, hostAddress.c_str(), hostPort);
|
||||
reconnectTimer->setTimeout(1000, false);
|
||||
reconnectTimer->start();
|
||||
}
|
||||
}
|
||||
}
|
||||
usefullData = false;
|
||||
}
|
||||
|
||||
void Connection::onDisconnected(int32_t reason, int32_t error) {
|
||||
if (connectionInProcess) {
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).scheduleTask([&, reason, error] {
|
||||
onDisconnectedInternal(reason, error);
|
||||
});
|
||||
} else {
|
||||
onDisconnectedInternal(reason, error);
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::onConnected() {
|
||||
connectionState = TcpConnectionStageConnected;
|
||||
connectionToken = lastConnectionToken++;
|
||||
wasConnected = true;
|
||||
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) connected to %s:%hu", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, hostAddress.c_str(), hostPort);
|
||||
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionConnected(this);
|
||||
}
|
||||
|
||||
bool Connection::hasPendingRequests() {
|
||||
return ConnectionsManager::getInstance(currentDatacenter->instanceNum).hasPendingRequestsForConnection(this);
|
||||
}
|
||||
|
||||
Datacenter *Connection::getDatacenter() {
|
||||
return currentDatacenter;
|
||||
}
|
||||
|
||||
ConnectionType Connection::getConnectionType() {
|
||||
return connectionType;
|
||||
}
|
||||
|
||||
int8_t Connection::getConnectionNum() {
|
||||
return connectionNum;
|
||||
}
|
||||
|
||||
uint32_t Connection::getConnectionToken() {
|
||||
return connectionToken;
|
||||
}
|
||||
121
TMessagesProj/jni/tgnet/Connection.h
Normal file
121
TMessagesProj/jni/tgnet/Connection.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_H
|
||||
#define CONNECTION_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <openssl/aes.h>
|
||||
#include "ConnectionSession.h"
|
||||
#include "ConnectionSocket.h"
|
||||
#include "Defines.h"
|
||||
|
||||
class Datacenter;
|
||||
class Timer;
|
||||
class ByteStream;
|
||||
class ByteArray;
|
||||
|
||||
class Connection : public ConnectionSession, public ConnectionSocket {
|
||||
|
||||
public:
|
||||
|
||||
Connection(Datacenter *datacenter, ConnectionType type, int8_t num);
|
||||
~Connection();
|
||||
|
||||
void connect();
|
||||
void suspendConnection();
|
||||
void suspendConnection(bool idle);
|
||||
void sendData(NativeByteBuffer *buffer, bool reportAck, bool encrypted);
|
||||
bool hasUsefullData();
|
||||
void setHasUsefullData();
|
||||
bool allowsCustomPadding();
|
||||
uint32_t getConnectionToken();
|
||||
ConnectionType getConnectionType();
|
||||
int8_t getConnectionNum();
|
||||
Datacenter *getDatacenter();
|
||||
bool isSuspended();
|
||||
static bool isMediaConnectionType(ConnectionType type);
|
||||
|
||||
protected:
|
||||
|
||||
void onReceivedData(NativeByteBuffer *buffer) override;
|
||||
void onDisconnected(int32_t reason, int32_t error) override;
|
||||
void onConnected() override;
|
||||
bool hasPendingRequests() override;
|
||||
void reconnect();
|
||||
|
||||
private:
|
||||
|
||||
enum TcpConnectionState {
|
||||
TcpConnectionStageIdle,
|
||||
TcpConnectionStageConnecting,
|
||||
TcpConnectionStageReconnecting,
|
||||
TcpConnectionStageConnected,
|
||||
TcpConnectionStageSuspended
|
||||
};
|
||||
|
||||
enum ProtocolType {
|
||||
ProtocolTypeEF,
|
||||
ProtocolTypeEE,
|
||||
ProtocolTypeDD,
|
||||
ProtocolTypeTLS
|
||||
};
|
||||
|
||||
inline void encryptKeyWithSecret(uint8_t *array, uint8_t secretType);
|
||||
inline std::string *getCurrentSecret(uint8_t secretType);
|
||||
void onDisconnectedInternal(int32_t reason, int32_t error);
|
||||
|
||||
ProtocolType currentProtocolType = ProtocolTypeEE;
|
||||
|
||||
TcpConnectionState connectionState = TcpConnectionStageIdle;
|
||||
uint32_t connectionToken = 0;
|
||||
std::string hostAddress;
|
||||
std::string secret;
|
||||
uint16_t hostPort;
|
||||
uint16_t failedConnectionCount;
|
||||
Datacenter *currentDatacenter;
|
||||
uint32_t currentAddressFlags;
|
||||
ConnectionType connectionType;
|
||||
int8_t connectionNum;
|
||||
bool firstPacketSent = false;
|
||||
NativeByteBuffer *restOfTheData = nullptr;
|
||||
uint32_t lastPacketLength = 0;
|
||||
bool hasSomeDataSinceLastConnect = false;
|
||||
bool isTryingNextPort = false;
|
||||
bool wasConnected = false;
|
||||
uint32_t willRetryConnectCount = 5;
|
||||
Timer *reconnectTimer;
|
||||
bool usefullData = false;
|
||||
bool forceNextPort = false;
|
||||
bool isMediaConnection = false;
|
||||
bool waitForReconnectTimer = false;
|
||||
bool connectionInProcess = false;
|
||||
uint32_t lastReconnectTimeout = 100;
|
||||
int64_t usefullDataReceiveTime;
|
||||
uint32_t currentTimeout = 4;
|
||||
uint32_t receivedDataAmount = 0;
|
||||
uint32_t generation = 0;
|
||||
|
||||
uint8_t temp[64];
|
||||
|
||||
AES_KEY encryptKey;
|
||||
uint8_t encryptIv[16];
|
||||
uint32_t encryptNum;
|
||||
uint8_t encryptCount[16];
|
||||
|
||||
AES_KEY decryptKey;
|
||||
uint8_t decryptIv[16];
|
||||
uint32_t decryptNum;
|
||||
uint8_t decryptCount[16];
|
||||
|
||||
friend class ConnectionsManager;
|
||||
};
|
||||
|
||||
#endif
|
||||
114
TMessagesProj/jni/tgnet/ConnectionSession.cpp
Normal file
114
TMessagesProj/jni/tgnet/ConnectionSession.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <openssl/rand.h>
|
||||
#include "ConnectionSession.h"
|
||||
#include "MTProtoScheme.h"
|
||||
#include "ConnectionsManager.h"
|
||||
#include "NativeByteBuffer.h"
|
||||
|
||||
ConnectionSession::ConnectionSession(int32_t instance) {
|
||||
instanceNum = instance;
|
||||
}
|
||||
|
||||
void ConnectionSession::recreateSession() {
|
||||
processedMessageIds.clear();
|
||||
messagesIdsForConfirmation.clear();
|
||||
processedSessionChanges.clear();
|
||||
nextSeqNo = 0;
|
||||
|
||||
genereateNewSessionId();
|
||||
}
|
||||
|
||||
void ConnectionSession::genereateNewSessionId() {
|
||||
int64_t newSessionId;
|
||||
RAND_bytes((uint8_t *) &newSessionId, 8);
|
||||
#if USE_DEBUG_SESSION
|
||||
sessionId = (0xabcd000000000000L | (newSessionId & 0x0000ffffffffffffL));
|
||||
#else
|
||||
sessionId = newSessionId;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConnectionSession::setSessionId(int64_t id) {
|
||||
sessionId = id;
|
||||
}
|
||||
|
||||
int64_t ConnectionSession::getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
uint32_t ConnectionSession::generateMessageSeqNo(bool increment) {
|
||||
uint32_t value = nextSeqNo;
|
||||
if (increment) {
|
||||
nextSeqNo++;
|
||||
}
|
||||
return value * 2 + (increment ? 1 : 0);
|
||||
}
|
||||
|
||||
int32_t ConnectionSession::isMessageIdProcessed(int64_t messageId) {
|
||||
if (!(messageId & 1)) {
|
||||
return 1;
|
||||
}
|
||||
if (minProcessedMessageId != 0 && messageId < minProcessedMessageId) {
|
||||
return 2;
|
||||
}
|
||||
if (std::find(processedMessageIds.begin(), processedMessageIds.end(), messageId) != processedMessageIds.end()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ConnectionSession::addProcessedMessageId(int64_t messageId) {
|
||||
if (processedMessageIds.size() > 300) {
|
||||
std::sort(processedMessageIds.begin(), processedMessageIds.end());
|
||||
processedMessageIds.erase(processedMessageIds.begin(), processedMessageIds.begin() + 100);
|
||||
minProcessedMessageId = *(processedMessageIds.begin());
|
||||
}
|
||||
processedMessageIds.push_back(messageId);
|
||||
}
|
||||
|
||||
bool ConnectionSession::hasMessagesToConfirm() {
|
||||
return !messagesIdsForConfirmation.empty();
|
||||
}
|
||||
|
||||
void ConnectionSession::addMessageToConfirm(int64_t messageId) {
|
||||
if (std::find(messagesIdsForConfirmation.begin(), messagesIdsForConfirmation.end(), messageId) != messagesIdsForConfirmation.end()) {
|
||||
return;
|
||||
}
|
||||
messagesIdsForConfirmation.push_back(messageId);
|
||||
}
|
||||
|
||||
NetworkMessage *ConnectionSession::generateConfirmationRequest() {
|
||||
NetworkMessage *networkMessage = nullptr;
|
||||
|
||||
if (!messagesIdsForConfirmation.empty()) {
|
||||
TL_msgs_ack *msgAck = new TL_msgs_ack();
|
||||
msgAck->msg_ids.insert(msgAck->msg_ids.begin(), messagesIdsForConfirmation.begin(), messagesIdsForConfirmation.end());
|
||||
NativeByteBuffer *os = new NativeByteBuffer(true);
|
||||
msgAck->serializeToStream(os);
|
||||
networkMessage = new NetworkMessage();
|
||||
networkMessage->message = std::unique_ptr<TL_message>(new TL_message);
|
||||
networkMessage->message->msg_id = ConnectionsManager::getInstance(instanceNum).generateMessageId();
|
||||
networkMessage->message->seqno = generateMessageSeqNo(false);
|
||||
networkMessage->message->bytes = os->capacity();
|
||||
networkMessage->message->body = std::unique_ptr<TLObject>(msgAck);
|
||||
messagesIdsForConfirmation.clear();
|
||||
}
|
||||
|
||||
return networkMessage;
|
||||
}
|
||||
|
||||
bool ConnectionSession::isSessionProcessed(int64_t sessionId) {
|
||||
return std::find(processedSessionChanges.begin(), processedSessionChanges.end(), sessionId) != processedSessionChanges.end();
|
||||
}
|
||||
|
||||
void ConnectionSession::addProcessedSession(int64_t sessionId) {
|
||||
processedSessionChanges.push_back(sessionId);
|
||||
}
|
||||
45
TMessagesProj/jni/tgnet/ConnectionSession.h
Normal file
45
TMessagesProj/jni/tgnet/ConnectionSession.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTIONSESSION_H
|
||||
#define CONNECTIONSESSION_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include "Defines.h"
|
||||
|
||||
class ConnectionSession {
|
||||
|
||||
public:
|
||||
ConnectionSession(int32_t instance);
|
||||
void recreateSession();
|
||||
void genereateNewSessionId();
|
||||
void setSessionId(int64_t id);
|
||||
int64_t getSessionId();
|
||||
uint32_t generateMessageSeqNo(bool increment);
|
||||
int32_t isMessageIdProcessed(int64_t messageId);
|
||||
void addProcessedMessageId(int64_t messageId);
|
||||
bool hasMessagesToConfirm();
|
||||
void addMessageToConfirm(int64_t messageId);
|
||||
NetworkMessage *generateConfirmationRequest();
|
||||
bool isSessionProcessed(int64_t sessionId);
|
||||
void addProcessedSession(int64_t sessionId);
|
||||
|
||||
private:
|
||||
int32_t instanceNum;
|
||||
int64_t sessionId;
|
||||
uint32_t nextSeqNo = 0;
|
||||
int64_t minProcessedMessageId = 0;
|
||||
|
||||
std::vector<int64_t> processedMessageIds;
|
||||
std::vector<int64_t> messagesIdsForConfirmation;
|
||||
std::vector<int64_t> processedSessionChanges;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
1257
TMessagesProj/jni/tgnet/ConnectionSocket.cpp
Normal file
1257
TMessagesProj/jni/tgnet/ConnectionSocket.cpp
Normal file
File diff suppressed because it is too large
Load diff
96
TMessagesProj/jni/tgnet/ConnectionSocket.h
Normal file
96
TMessagesProj/jni/tgnet/ConnectionSocket.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTIONSOCKET_H
|
||||
#define CONNECTIONSOCKET_H
|
||||
|
||||
#include <sys/epoll.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string>
|
||||
|
||||
class NativeByteBuffer;
|
||||
class ConnectionsManager;
|
||||
class ByteStream;
|
||||
class EventObject;
|
||||
class ByteArray;
|
||||
|
||||
class ConnectionSocket {
|
||||
|
||||
public:
|
||||
ConnectionSocket(int32_t instance);
|
||||
virtual ~ConnectionSocket();
|
||||
|
||||
void writeBuffer(uint8_t *data, uint32_t size);
|
||||
void writeBuffer(NativeByteBuffer *buffer);
|
||||
void openConnection(std::string address, uint16_t port, std::string secret, bool ipv6, int32_t networkType);
|
||||
void setTimeout(time_t timeout);
|
||||
time_t getTimeout();
|
||||
bool isDisconnected();
|
||||
void dropConnection();
|
||||
void setOverrideProxy(std::string address, uint16_t port, std::string username, std::string password, std::string secret);
|
||||
void onHostNameResolved(std::string host, std::string ip, bool ipv6);
|
||||
|
||||
protected:
|
||||
int32_t instanceNum;
|
||||
void onEvent(uint32_t events);
|
||||
bool checkTimeout(int64_t now);
|
||||
void resetLastEventTime();
|
||||
bool hasTlsHashMismatch();
|
||||
virtual void onReceivedData(NativeByteBuffer *buffer) = 0;
|
||||
virtual void onDisconnected(int32_t reason, int32_t error) = 0;
|
||||
virtual void onConnected() = 0;
|
||||
virtual bool hasPendingRequests() = 0;
|
||||
|
||||
std::string overrideProxyUser = "";
|
||||
std::string overrideProxyPassword = "";
|
||||
std::string overrideProxyAddress = "";
|
||||
std::string overrideProxySecret = "";
|
||||
uint16_t overrideProxyPort = 1080;
|
||||
|
||||
private:
|
||||
ByteStream *outgoingByteStream = nullptr;
|
||||
struct epoll_event eventMask;
|
||||
struct sockaddr_in socketAddress;
|
||||
struct sockaddr_in6 socketAddress6;
|
||||
int socketFd = -1;
|
||||
time_t timeout = 12;
|
||||
bool onConnectedSent = false;
|
||||
int64_t lastEventTime = 0;
|
||||
EventObject *eventObject;
|
||||
int32_t currentNetworkType;
|
||||
bool isIpv6;
|
||||
std::string currentAddress;
|
||||
uint16_t currentPort;
|
||||
|
||||
std::string waitingForHostResolve;
|
||||
bool adjustWriteOpAfterResolve;
|
||||
|
||||
std::string currentSecret;
|
||||
std::string currentSecretDomain;
|
||||
|
||||
bool tlsUseLegacy = false;
|
||||
bool tlsHashMismatch = false;
|
||||
bool tlsBufferSized = true;
|
||||
NativeByteBuffer *tlsBuffer = nullptr;
|
||||
ByteArray *tempBuffer = nullptr;
|
||||
size_t bytesRead = 0;
|
||||
int8_t tlsState = 0;
|
||||
|
||||
uint8_t proxyAuthState;
|
||||
|
||||
int32_t checkSocketError(int32_t *error);
|
||||
void closeSocket(int32_t reason, int32_t error);
|
||||
void openConnectionInternal(bool ipv6);
|
||||
void adjustWriteOp();
|
||||
|
||||
friend class EventObject;
|
||||
friend class ConnectionsManager;
|
||||
friend class Connection;
|
||||
};
|
||||
|
||||
#endif
|
||||
3966
TMessagesProj/jni/tgnet/ConnectionsManager.cpp
Normal file
3966
TMessagesProj/jni/tgnet/ConnectionsManager.cpp
Normal file
File diff suppressed because it is too large
Load diff
277
TMessagesProj/jni/tgnet/ConnectionsManager.h
Normal file
277
TMessagesProj/jni/tgnet/ConnectionsManager.h
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTIONSMANAGER_H
|
||||
#define CONNECTIONSMANAGER_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <queue>
|
||||
#include <functional>
|
||||
#include <sys/epoll.h>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <unordered_set>
|
||||
#include "Defines.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
class NativeByteBuffer;
|
||||
class Connection;
|
||||
class Datacenter;
|
||||
class Request;
|
||||
class DatacenterHandshake;
|
||||
class TLObject;
|
||||
class ConnectionSocket;
|
||||
class TL_auth_exportedAuthorization;
|
||||
class ByteArray;
|
||||
class TL_config;
|
||||
class EventObject;
|
||||
class Config;
|
||||
class ProxyCheckInfo;
|
||||
|
||||
class ConnectionsManager {
|
||||
|
||||
public:
|
||||
ConnectionsManager(int32_t instance);
|
||||
~ConnectionsManager();
|
||||
|
||||
static ConnectionsManager &getInstance(int32_t instanceNum);
|
||||
int64_t getCurrentTimeMillis();
|
||||
int64_t getCurrentTimeMonotonicMillis();
|
||||
int32_t getCurrentTime();
|
||||
int32_t getCurrentPingTime();
|
||||
uint32_t getCurrentDatacenterId();
|
||||
bool isTestBackend();
|
||||
int32_t getTimeDifference();
|
||||
int32_t sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, onRequestClearFunc onClear, uint32_t flags, uint32_t datacenterId, ConnectionType connectionType, bool immediate);
|
||||
int32_t sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, onRequestClearFunc onClear, uint32_t flags, uint32_t datacenterId, ConnectionType connectionType, bool immediate, int32_t requestToken);
|
||||
void cancelRequest(int32_t token, bool notifyServer, onRequestCancelDoneFunc onCancelled);
|
||||
void cleanUp(bool resetKeys, int32_t datacenterId);
|
||||
void cancelRequestsForGuid(int32_t guid);
|
||||
void bindRequestToGuid(int32_t requestToken, int32_t guid);
|
||||
void applyDatacenterAddress(uint32_t datacenterId, std::string ipAddress, uint32_t port);
|
||||
void setDelegate(ConnectiosManagerDelegate *connectiosManagerDelegate);
|
||||
ConnectionState getConnectionState();
|
||||
void setUserId(int64_t userId);
|
||||
void setUserPremium(bool premium);
|
||||
void switchBackend(bool restart);
|
||||
void resumeNetwork(bool partial);
|
||||
void pauseNetwork();
|
||||
void setNetworkAvailable(bool value, int32_t type, bool slow);
|
||||
void setIpStrategy(uint8_t value);
|
||||
void init(uint32_t version, int32_t layer, int32_t apiId, std::string deviceModel, std::string systemVersion, std::string appVersion, std::string langCode, std::string systemLangCode, std::string configPath, std::string logPath, std::string regId, std::string cFingerprint, std::string installerId, std::string packageId, int32_t timezoneOffset, int64_t userId, bool userPremium, bool isPaused, bool enablePushConnection, bool hasNetwork, int32_t networkType, int32_t performanceClass);
|
||||
void setProxySettings(std::string address, uint16_t port, std::string username, std::string password, std::string secret);
|
||||
void setLangCode(std::string langCode);
|
||||
void setRegId(std::string regId);
|
||||
void setSystemLangCode(std::string langCode);
|
||||
void updateDcSettings(uint32_t datacenterId, bool workaround, bool ifLoadingTryAgain);
|
||||
void setPushConnectionEnabled(bool value);
|
||||
void applyDnsConfig(NativeByteBuffer *buffer, std::string phone, int32_t date);
|
||||
int64_t checkProxy(std::string address, uint16_t port, std::string username, std::string password, std::string secret, onRequestTimeFunc requestTimeFunc, jobject ptr1);
|
||||
|
||||
#ifdef ANDROID
|
||||
void sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, onWriteToSocketFunc onWriteToSocket, onRequestClearFunc onClear, uint32_t flags, uint32_t datacenterId, ConnectionType connectionType, bool immediate, int32_t requestToken);
|
||||
static void useJavaVM(JavaVM *vm, bool useJavaByteBuffers);
|
||||
#endif
|
||||
|
||||
void reconnect(int32_t datacentrId, int32_t connectionType);
|
||||
void failNotRunningRequest(int32_t token);
|
||||
void receivedIntegrityCheckClassic(int32_t requestToken, std::string nonce, std::string token);
|
||||
void receivedCaptchaResult(int32_t requestTokensCount, int32_t* requestTokens, std::string token);
|
||||
|
||||
private:
|
||||
static void *ThreadProc(void *data);
|
||||
|
||||
void initDatacenters();
|
||||
void loadConfig();
|
||||
void saveConfig();
|
||||
void saveConfigInternal(NativeByteBuffer *buffer);
|
||||
void select();
|
||||
void wakeup();
|
||||
void processServerResponse(TLObject *message, int64_t messageId, int32_t messageSeqNo, int64_t messageSalt, Connection *connection, int64_t innerMsgId, int64_t containerMessageId);
|
||||
void sendPing(Datacenter *datacenter, bool usePushConnection);
|
||||
void sendMessagesToConnection(std::vector<std::unique_ptr<NetworkMessage>> &messages, Connection *connection, bool reportAck);
|
||||
void sendMessagesToConnectionWithConfirmation(std::vector<std::unique_ptr<NetworkMessage>> &messages, Connection *connection, bool reportAck);
|
||||
void requestSaltsForDatacenter(Datacenter *datacenter, bool media, bool useTempConnection);
|
||||
void clearRequestsForDatacenter(Datacenter *datacenter, HandshakeType type);
|
||||
void registerForInternalPushUpdates();
|
||||
void processRequestQueue(uint32_t connectionType, uint32_t datacenterId);
|
||||
void moveToDatacenter(uint32_t datacenterId);
|
||||
void authorizeOnMovingDatacenter();
|
||||
void authorizedOnMovingDatacenter();
|
||||
Datacenter *getDatacenterWithId(uint32_t datacenterId);
|
||||
std::unique_ptr<TLObject> wrapInLayer(TLObject *object, Datacenter *datacenter, Request *baseRequest);
|
||||
void removeRequestFromGuid(int32_t requestToken);
|
||||
bool cancelRequestInternal(int32_t token, int64_t messageId, bool notifyServer, bool removeFromClass, onRequestCancelDoneFunc onCancelled);
|
||||
int callEvents(int64_t now);
|
||||
int32_t sendRequestInternal(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, onRequestClearFunc onClear, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate);
|
||||
|
||||
void checkPendingTasks();
|
||||
void scheduleTask(std::function<void()> task);
|
||||
void scheduleEvent(EventObject *eventObject, uint32_t time);
|
||||
void removeEvent(EventObject *eventObject);
|
||||
void onConnectionClosed(Connection *connection, int reason);
|
||||
void onConnectionConnected(Connection *connection);
|
||||
void onConnectionQuickAckReceived(Connection *connection, int32_t ack);
|
||||
void onConnectionDataReceived(Connection *connection, NativeByteBuffer *data, uint32_t length);
|
||||
bool hasPendingRequestsForConnection(Connection *connection);
|
||||
void attachConnection(ConnectionSocket *connection);
|
||||
void detachConnection(ConnectionSocket *connection);
|
||||
TLObject *TLdeserialize(TLObject *request, uint32_t bytes, NativeByteBuffer *data);
|
||||
TLObject *getRequestWithMessageId(int64_t messageId);
|
||||
void onDatacenterHandshakeComplete(Datacenter *datacenter, HandshakeType type, int32_t timeDiff);
|
||||
void onDatacenterExportAuthorizationComplete(Datacenter *datacenter);
|
||||
int64_t generateMessageId();
|
||||
uint8_t getIpStratagy();
|
||||
bool isNetworkAvailable();
|
||||
|
||||
void scheduleCheckProxyInternal(ProxyCheckInfo *proxyCheckInfo);
|
||||
void checkProxyInternal(ProxyCheckInfo *proxyCheckInfo);
|
||||
|
||||
int32_t instanceNum = 0;
|
||||
uint32_t configVersion = 5;
|
||||
Config *config = nullptr;
|
||||
|
||||
std::list<EventObject *> events;
|
||||
|
||||
std::map<uint32_t, Datacenter *> datacenters;
|
||||
std::map<int32_t, std::vector<std::int32_t>> quickAckIdToRequestIds;
|
||||
int32_t pingTime;
|
||||
int64_t pingTimeMs;
|
||||
bool testBackend = false;
|
||||
bool clientBlocked = true;
|
||||
std::string lastInitSystemLangcode = "";
|
||||
std::atomic<uint32_t> lastRequestToken{50000000};
|
||||
uint32_t currentDatacenterId = 0;
|
||||
uint32_t movingToDatacenterId = DEFAULT_DATACENTER_ID;
|
||||
int64_t pushSessionId = 0;
|
||||
int32_t currentPingTime = 0;
|
||||
int32_t currentPingTimeLive = 0;
|
||||
bool registeringForPush = false;
|
||||
int64_t lastPushPingTime = 0;
|
||||
int32_t nextPingTimeOffset = 60000 * 3;
|
||||
int64_t sendingPushPingTime = 0;
|
||||
bool sendingPushPing = false;
|
||||
bool sendingPing = false;
|
||||
bool updatingDcSettings = false;
|
||||
bool updatingDcSettingsAgain = false;
|
||||
uint32_t updatingDcSettingsAgainDcNum = 0;
|
||||
bool updatingDcSettingsWorkaround = false;
|
||||
int32_t disconnectTimeoutAmount = 0;
|
||||
bool requestingSecondAddressByTlsHashMismatch = false;
|
||||
int32_t requestingSecondAddress = 0;
|
||||
int32_t updatingDcStartTime = 0;
|
||||
int32_t lastDcUpdateTime = 0;
|
||||
int64_t lastPingTime = getCurrentTimeMonotonicMillis();
|
||||
bool networkPaused = false;
|
||||
int32_t nextSleepTimeout = CONNECTION_BACKGROUND_KEEP_TIME;
|
||||
int64_t lastPauseTime = 0;
|
||||
int64_t lastMonotonicPauseTime = 0;
|
||||
int32_t lastSystemPauseTime = 0;
|
||||
ConnectionState connectionState = ConnectionStateConnecting;
|
||||
std::unique_ptr<ByteArray> movingAuthorization;
|
||||
std::vector<int64_t> sessionsToDestroy;
|
||||
int32_t lastDestroySessionRequestTime;
|
||||
std::map<int32_t, std::vector<int32_t>> requestsByGuids;
|
||||
std::map<int32_t, int32_t> guidsByRequests;
|
||||
std::map<int64_t, int64_t> resendRequests;
|
||||
Datacenter *deserializingDatacenter;
|
||||
|
||||
std::string proxyUser = "";
|
||||
std::string proxyPassword = "";
|
||||
std::string proxyAddress = "";
|
||||
std::string proxySecret = "";
|
||||
uint16_t proxyPort = 1080;
|
||||
int32_t lastPingProxyId = 2000000;
|
||||
std::vector<std::unique_ptr<ProxyCheckInfo>> proxyCheckQueue;
|
||||
std::vector<std::unique_ptr<ProxyCheckInfo>> proxyActiveChecks;
|
||||
|
||||
pthread_t networkThread;
|
||||
pthread_mutex_t mutex;
|
||||
std::queue<std::function<void()>> pendingTasks;
|
||||
struct epoll_event *epollEvents;
|
||||
timespec timeSpec;
|
||||
timespec timeSpecMonotonic;
|
||||
int32_t timeDifference = 0;
|
||||
int64_t lastOutgoingMessageId = 0;
|
||||
bool networkAvailable = true;
|
||||
bool networkSlow = false;
|
||||
uint8_t ipStrategy = USE_IPV4_ONLY;
|
||||
bool lastProtocolIsIpv6 = false;
|
||||
bool lastProtocolUsefullData = false;
|
||||
std::vector<ConnectionSocket *> activeConnections;
|
||||
std::vector<ConnectionSocket *> activeConnectionsCopy;
|
||||
int epolFd;
|
||||
int eventFd;
|
||||
int *pipeFd = nullptr;
|
||||
NativeByteBuffer *networkBuffer;
|
||||
|
||||
requestsList waitingLoginRequests;
|
||||
requestsList requestsQueue;
|
||||
requestsList runningRequests;
|
||||
std::vector<uint32_t> requestingSaltsForDc;
|
||||
std::unordered_set<int32_t> tokensToBeCancelled;
|
||||
int32_t lastPingId = 0;
|
||||
int64_t lastInvokeAfterMessageId = 0;
|
||||
|
||||
int32_t currentNetworkType = NETWORK_TYPE_WIFI;
|
||||
uint32_t currentVersion = 1;
|
||||
int32_t currentLayer = 34;
|
||||
int32_t currentApiId = 6;
|
||||
std::string currentDeviceModel;
|
||||
std::string currentSystemVersion;
|
||||
std::string currentAppVersion;
|
||||
std::string currentLangCode;
|
||||
std::string currentRegId;
|
||||
std::string certFingerprint;
|
||||
std::string installer;
|
||||
std::string package;
|
||||
int32_t currentDeviceTimezone = 0;
|
||||
std::string currentSystemLangCode;
|
||||
std::string currentConfigPath;
|
||||
std::string currentLogPath;
|
||||
int64_t currentUserId = 0;
|
||||
bool currentUserPremium = false;
|
||||
bool registeredForInternalPush = false;
|
||||
bool pushConnectionEnabled = true;
|
||||
int32_t currentPerformanceClass = -1;
|
||||
|
||||
std::map<uint32_t, std::vector<std::unique_ptr<NetworkMessage>>> genericMessagesToDatacenters;
|
||||
std::map<uint32_t, std::vector<std::unique_ptr<NetworkMessage>>> genericMediaMessagesToDatacenters;
|
||||
std::map<uint32_t, std::vector<std::unique_ptr<NetworkMessage>>> tempMessagesToDatacenters;
|
||||
std::vector<uint32_t> unknownDatacenterIds;
|
||||
std::vector<std::pair<Datacenter *, ConnectionType>> neededDatacenters;
|
||||
std::map<uint32_t, uint32_t> downloadRunningRequestCount;
|
||||
std::map<uint32_t, uint32_t> downloadCancelRunningRequestCount;
|
||||
std::vector<Datacenter *> unauthorizedDatacenters;
|
||||
NativeByteBuffer *sizeCalculator;
|
||||
|
||||
ConnectiosManagerDelegate *delegate;
|
||||
|
||||
friend class ConnectionSocket;
|
||||
friend class ConnectionSession;
|
||||
friend class Connection;
|
||||
friend class Timer;
|
||||
friend class Datacenter;
|
||||
friend class TL_message;
|
||||
friend class TL_rpc_result;
|
||||
friend class Config;
|
||||
friend class FileLog;
|
||||
friend class Handshake;
|
||||
};
|
||||
|
||||
#ifdef ANDROID
|
||||
extern JavaVM *javaVm;
|
||||
extern JNIEnv *jniEnv[MAX_ACCOUNT_COUNT];
|
||||
extern jclass jclass_ByteBuffer;
|
||||
extern jmethodID jclass_ByteBuffer_allocateDirect;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1584
TMessagesProj/jni/tgnet/Datacenter.cpp
Normal file
1584
TMessagesProj/jni/tgnet/Datacenter.cpp
Normal file
File diff suppressed because it is too large
Load diff
154
TMessagesProj/jni/tgnet/Datacenter.h
Normal file
154
TMessagesProj/jni/tgnet/Datacenter.h
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef DATACENTER_H
|
||||
#define DATACENTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "Defines.h"
|
||||
|
||||
class TL_future_salt;
|
||||
class Connection;
|
||||
class NativeByteBuffer;
|
||||
class TL_future_salt;
|
||||
class TL_future_salts;
|
||||
class TL_help_configSimple;
|
||||
class ByteArray;
|
||||
class TLObject;
|
||||
class Config;
|
||||
class Handshake;
|
||||
|
||||
class Datacenter : public HandshakeDelegate {
|
||||
|
||||
public:
|
||||
Datacenter(int32_t instance, uint32_t id);
|
||||
Datacenter(int32_t instance, NativeByteBuffer *data);
|
||||
uint32_t getDatacenterId();
|
||||
TcpAddress *getCurrentAddress(uint32_t flags);
|
||||
int32_t getCurrentPort(uint32_t flags);
|
||||
void addAddressAndPort(std::string address, uint32_t port, uint32_t flags, std::string secret);
|
||||
void nextAddressOrPort(uint32_t flags);
|
||||
bool isCustomPort(uint32_t flags);
|
||||
void storeCurrentAddressAndPortNum();
|
||||
void replaceAddresses(std::vector<TcpAddress> &newAddresses, uint32_t flags);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
void clearAuthKey(HandshakeType type);
|
||||
void clearServerSalts(bool media);
|
||||
int64_t getServerSalt(bool media);
|
||||
void mergeServerSalts(TL_future_salts *newSalts, bool media);
|
||||
void addServerSalt(std::unique_ptr<TL_future_salt> &serverSalt, bool media);
|
||||
bool containsServerSalt(int64_t value, bool media);
|
||||
void suspendConnections(bool suspendPush);
|
||||
void getSessions(std::vector<int64_t> &sessions);
|
||||
void recreateSessions(HandshakeType type);
|
||||
void resetAddressAndPortNum();
|
||||
bool isHandshakingAny();
|
||||
bool isHandshaking(bool media);
|
||||
bool isHandshaking(HandshakeType type);
|
||||
bool hasAuthKey(ConnectionType connectionTyoe, int32_t allowPendingKey);
|
||||
bool hasPermanentAuthKey();
|
||||
int64_t getPermanentAuthKeyId();
|
||||
bool isExportingAuthorization();
|
||||
bool hasMediaAddress();
|
||||
void resetInitVersion();
|
||||
bool isRepeatCheckingAddresses();
|
||||
|
||||
Connection *getDownloadConnection(uint8_t num, bool create);
|
||||
Connection *getProxyConnection(uint8_t num, bool create, bool connect);
|
||||
Connection *getUploadConnection(uint8_t num, bool create);
|
||||
Connection *getGenericConnection(bool create, int32_t allowPendingKey);
|
||||
Connection *getGenericMediaConnection(bool create, int32_t allowPendingKey);
|
||||
Connection *getPushConnection(bool create);
|
||||
Connection *getTempConnection(bool create);
|
||||
Connection *getConnectionByType(uint32_t connectionType, bool create, int32_t allowPendingKey);
|
||||
|
||||
static void aesIgeEncryption(uint8_t *buffer, uint8_t *key, uint8_t *iv, bool encrypt, bool changeIv, uint32_t length);
|
||||
|
||||
private:
|
||||
void onHandshakeConnectionClosed(Connection *connection);
|
||||
void onHandshakeConnectionConnected(Connection *connection);
|
||||
void onHandshakeComplete(Handshake *handshake, int64_t keyId, ByteArray *authKey, int32_t timeDifference);
|
||||
void processHandshakeResponse(bool media, TLObject *message, int64_t messageId);
|
||||
NativeByteBuffer *createRequestsData(std::vector<std::unique_ptr<NetworkMessage>> &requests, int32_t *quickAckId, Connection *connection, bool pfsInit);
|
||||
bool decryptServerResponse(int64_t keyId, uint8_t *key, uint8_t *data, uint32_t length, Connection *connection);
|
||||
TLObject *getCurrentHandshakeRequest(bool media);
|
||||
ByteArray *getAuthKey(ConnectionType connectionType, bool perm, int64_t *authKeyId, int32_t allowPendingKey);
|
||||
|
||||
const int32_t *defaultPorts = new int32_t[4] {-1, 443, 5222, -1};
|
||||
|
||||
int32_t instanceNum;
|
||||
uint32_t datacenterId;
|
||||
Connection *genericConnection = nullptr;
|
||||
Connection *genericMediaConnection = nullptr;
|
||||
Connection *tempConnection = nullptr;
|
||||
Connection *proxyConnection[PROXY_CONNECTIONS_COUNT];
|
||||
Connection *downloadConnection[DOWNLOAD_CONNECTIONS_COUNT];
|
||||
Connection *uploadConnection[UPLOAD_CONNECTIONS_COUNT];
|
||||
Connection *pushConnection = nullptr;
|
||||
|
||||
uint32_t lastInitVersion = 0;
|
||||
uint32_t lastInitMediaVersion = 0;
|
||||
bool authorized = false;
|
||||
|
||||
std::vector<TcpAddress> addressesIpv4;
|
||||
std::vector<TcpAddress> addressesIpv6;
|
||||
std::vector<TcpAddress> addressesIpv4Download;
|
||||
std::vector<TcpAddress> addressesIpv6Download;
|
||||
std::vector<TcpAddress> addressesIpv4Temp;
|
||||
std::vector<std::unique_ptr<TL_future_salt>> serverSalts;
|
||||
std::vector<std::unique_ptr<TL_future_salt>> mediaServerSalts;
|
||||
uint32_t currentPortNumIpv4 = 0;
|
||||
uint32_t currentAddressNumIpv4 = 0;
|
||||
uint32_t currentPortNumIpv4Temp = 0;
|
||||
uint32_t currentAddressNumIpv4Temp = 0;
|
||||
uint32_t currentPortNumIpv6 = 0;
|
||||
uint32_t currentAddressNumIpv6 = 0;
|
||||
uint32_t currentPortNumIpv4Download = 0;
|
||||
uint32_t currentAddressNumIpv4Download = 0;
|
||||
uint32_t currentPortNumIpv6Download = 0;
|
||||
uint32_t currentAddressNumIpv6Download = 0;
|
||||
ByteArray *authKeyPerm = nullptr;
|
||||
int64_t authKeyPermId = 0;
|
||||
ByteArray *authKeyTemp = nullptr;
|
||||
int64_t authKeyTempId = 0;
|
||||
ByteArray *authKeyMediaTemp = nullptr;
|
||||
int64_t authKeyMediaTempId = 0;
|
||||
Config *config = nullptr;
|
||||
bool isCdnDatacenter = false;
|
||||
bool repeatCheckingAddresses = false;
|
||||
|
||||
std::vector<std::unique_ptr<Handshake>> handshakes;
|
||||
|
||||
const uint32_t configVersion = 13;
|
||||
const uint32_t paramsConfigVersion = 1;
|
||||
|
||||
Connection *createProxyConnection(uint8_t num);
|
||||
Connection *createDownloadConnection(uint8_t num);
|
||||
Connection *createUploadConnection(uint8_t num);
|
||||
Connection *createGenericConnection();
|
||||
Connection *createGenericMediaConnection();
|
||||
Connection *createTempConnection();
|
||||
Connection *createPushConnection();
|
||||
Connection *createConnectionByType(uint32_t connectionType);
|
||||
|
||||
void beginHandshake(HandshakeType handshakeType, bool reconnect);
|
||||
|
||||
bool exportingAuthorization = false;
|
||||
void exportAuthorization();
|
||||
|
||||
static TL_help_configSimple *decodeSimpleConfig(NativeByteBuffer *buffer);
|
||||
|
||||
friend class ConnectionsManager;
|
||||
friend class Connection;
|
||||
friend class Handshake;
|
||||
friend class Request;
|
||||
};
|
||||
|
||||
#endif
|
||||
207
TMessagesProj/jni/tgnet/Defines.h
Normal file
207
TMessagesProj/jni/tgnet/Defines.h
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef DEFINES_H
|
||||
#define DEFINES_H
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <limits.h>
|
||||
#include <sstream>
|
||||
#include <inttypes.h>
|
||||
#include "ByteArray.h"
|
||||
|
||||
#define USE_DEBUG_SESSION false
|
||||
#define READ_BUFFER_SIZE 1024 * 1024 * 2
|
||||
//#define DEBUG_VERSION
|
||||
#define PFS_ENABLED 1
|
||||
#define DEFAULT_DATACENTER_ID INT_MAX
|
||||
#define DC_UPDATE_TIME 60 * 60
|
||||
#define TEMP_AUTH_KEY_EXPIRE_TIME 24 * 60 * 60
|
||||
#define PROXY_CONNECTIONS_COUNT 4
|
||||
#define DOWNLOAD_CONNECTIONS_COUNT 2
|
||||
#define UPLOAD_CONNECTIONS_COUNT 4
|
||||
#define CONNECTION_BACKGROUND_KEEP_TIME 10000
|
||||
#define MAX_ACCOUNT_COUNT 5
|
||||
#define USE_DELEGATE_HOST_RESOLVE
|
||||
|
||||
#define USE_IPV4_ONLY 0
|
||||
#define USE_IPV6_ONLY 1
|
||||
#define USE_IPV4_IPV6_RANDOM 2
|
||||
|
||||
#define NETWORK_TYPE_MOBILE 0
|
||||
#define NETWORK_TYPE_WIFI 1
|
||||
#define NETWORK_TYPE_ROAMING 2
|
||||
|
||||
class TLObject;
|
||||
class TL_error;
|
||||
class Request;
|
||||
class TL_message;
|
||||
class TL_config;
|
||||
class NativeByteBuffer;
|
||||
class Handshake;
|
||||
class ConnectionSocket;
|
||||
|
||||
typedef std::function<void(TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId)> onCompleteFunc;
|
||||
typedef std::function<void()> onQuickAckFunc;
|
||||
typedef std::function<void()> onWriteToSocketFunc;
|
||||
typedef std::function<void()> onRequestClearFunc;
|
||||
typedef std::function<void()> onRequestCancelDoneFunc;
|
||||
typedef std::function<void(int64_t messageId)> fillParamsFunc;
|
||||
typedef std::function<void(int64_t requestTime)> onRequestTimeFunc;
|
||||
typedef std::list<std::unique_ptr<Request>> requestsList;
|
||||
typedef requestsList::iterator requestsIter;
|
||||
|
||||
typedef struct NetworkMessage {
|
||||
std::unique_ptr<TL_message> message;
|
||||
bool invokeAfter = false;
|
||||
bool needQuickAck = false;
|
||||
bool forceContainer = false;
|
||||
int32_t requestId;
|
||||
} NetworkMessage;
|
||||
|
||||
enum ConnectionType {
|
||||
ConnectionTypeGeneric = 1,
|
||||
ConnectionTypeDownload = 2,
|
||||
ConnectionTypeUpload = 4,
|
||||
ConnectionTypePush = 8,
|
||||
ConnectionTypeTemp = 16,
|
||||
ConnectionTypeProxy = 32,
|
||||
ConnectionTypeGenericMedia = 64
|
||||
};
|
||||
|
||||
enum TcpAddressFlag {
|
||||
TcpAddressFlagIpv6 = 1,
|
||||
TcpAddressFlagDownload = 2,
|
||||
TcpAddressFlagO = 4,
|
||||
TcpAddressFlagCdn = 8,
|
||||
TcpAddressFlagStatic = 16,
|
||||
TcpAddressFlagTemp = 2048
|
||||
};
|
||||
|
||||
enum ConnectionState {
|
||||
ConnectionStateConnecting = 1,
|
||||
ConnectionStateWaitingForNetwork = 2,
|
||||
ConnectionStateConnected = 3,
|
||||
ConnectionStateConnectingViaProxy = 4
|
||||
};
|
||||
|
||||
enum EventObjectType {
|
||||
EventObjectTypeConnection,
|
||||
EventObjectTypeTimer,
|
||||
EventObjectTypePipe,
|
||||
EventObjectTypeEvent
|
||||
};
|
||||
|
||||
enum FileLoadState {
|
||||
FileLoadStateIdle,
|
||||
FileLoadStateDownloading,
|
||||
FileLoadStateFailed,
|
||||
FileLoadStateFinished
|
||||
};
|
||||
|
||||
enum FileLoadFailReason {
|
||||
FileLoadFailReasonError,
|
||||
FileLoadFailReasonCanceled,
|
||||
FileLoadFailReasonRetryLimit
|
||||
};
|
||||
|
||||
enum HandshakeType {
|
||||
HandshakeTypePerm,
|
||||
HandshakeTypeTemp,
|
||||
HandshakeTypeMediaTemp,
|
||||
HandshakeTypeCurrent,
|
||||
HandshakeTypeAll
|
||||
};
|
||||
|
||||
class TcpAddress {
|
||||
|
||||
public:
|
||||
std::string address;
|
||||
int32_t flags;
|
||||
int32_t port;
|
||||
std::string secret;
|
||||
|
||||
TcpAddress(std::string addr, int32_t p, int32_t f, std::string s) {
|
||||
address = addr;
|
||||
port = p;
|
||||
flags = f;
|
||||
secret = s;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<void(std::string path)> onFinishedFunc;
|
||||
typedef std::function<void(FileLoadFailReason reason)> onFailedFunc;
|
||||
typedef std::function<void(float progress)> onProgressChangedFunc;
|
||||
|
||||
typedef struct ConnectiosManagerDelegate {
|
||||
virtual void onUpdate(int32_t instanceNum) = 0;
|
||||
virtual void onSessionCreated(int32_t instanceNum) = 0;
|
||||
virtual void onConnectionStateChanged(ConnectionState state, int32_t instanceNum) = 0;
|
||||
virtual void onUnparsedMessageReceived(int64_t reqMessageId, NativeByteBuffer *buffer, ConnectionType connectionType, int32_t instanceNum) = 0;
|
||||
virtual void onLogout(int32_t instanceNum) = 0;
|
||||
virtual void onUpdateConfig(TL_config *config, int32_t instanceNum) = 0;
|
||||
virtual void onInternalPushReceived(int32_t instanceNum) = 0;
|
||||
virtual void onBytesSent(int32_t amount, int32_t networkType, int32_t instanceNum) = 0;
|
||||
virtual void onBytesReceived(int32_t amount, int32_t networkType, int32_t instanceNum) = 0;
|
||||
virtual void onRequestNewServerIpAndPort(int32_t second, int32_t instanceNum) = 0;
|
||||
virtual void onProxyError(int32_t instanceNum) = 0;
|
||||
virtual void getHostByName(std::string domain, int32_t instanceNum, ConnectionSocket *socket) = 0;
|
||||
virtual int32_t getInitFlags(int32_t instanceNum) = 0;
|
||||
virtual void onPremiumFloodWait(int32_t instanceNum, int32_t requestToken, bool isUpload) = 0;
|
||||
virtual void onIntegrityCheckClassic(int32_t instanceNum, int32_t requestToken, std::string project, std::string nonce) = 0;
|
||||
virtual void onCaptchaCheck(int32_t instanceNum, int32_t requestToken, std::string action, std::string key_id) = 0;
|
||||
} ConnectiosManagerDelegate;
|
||||
|
||||
typedef struct HandshakeDelegate {
|
||||
virtual void onHandshakeComplete(Handshake *handshake, int64_t keyId, ByteArray *authKey, int32_t timeDifference) = 0;
|
||||
} HandshakeDelegate;
|
||||
|
||||
#define AllConnectionTypes ConnectionTypeGeneric | ConnectionTypeDownload | ConnectionTypeUpload
|
||||
|
||||
enum RequestFlag {
|
||||
RequestFlagEnableUnauthorized = 1,
|
||||
RequestFlagFailOnServerErrors = 2,
|
||||
RequestFlagCanCompress = 4,
|
||||
RequestFlagWithoutLogin = 8,
|
||||
RequestFlagTryDifferentDc = 16,
|
||||
RequestFlagForceDownload = 32,
|
||||
RequestFlagInvokeAfter = 64,
|
||||
RequestFlagNeedQuickAck = 128,
|
||||
RequestFlagUseUnboundKey = 256,
|
||||
RequestFlagResendAfter = 512,
|
||||
RequestFlagIgnoreFloodWait = 1024,
|
||||
RequestFlagListenAfterCancel = 2048,
|
||||
RequestFlagIsCancel = 32768,
|
||||
RequestFlagFailOnServerErrorsExceptFloodWait = 65536
|
||||
};
|
||||
|
||||
inline std::string to_string_int32(int32_t value) {
|
||||
char buf[30];
|
||||
int len = sprintf(buf, "%d", value);
|
||||
return std::string(buf, (uint32_t) len);
|
||||
}
|
||||
|
||||
inline std::string to_string_uint64(uint64_t value) {
|
||||
char buf[30];
|
||||
int len = sprintf(buf, "%" PRIu64, value);
|
||||
return std::string(buf, (uint32_t) len);
|
||||
}
|
||||
|
||||
inline int32_t char2int(char input) {
|
||||
if (input >= '0' && input <= '9') {
|
||||
return input - '0';
|
||||
} else if (input >= 'A' && input <= 'F') {
|
||||
return (char) (input - 'A' + 10);
|
||||
} else if (input >= 'a' && input <= 'f') {
|
||||
return (char) (input - 'a' + 10);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
50
TMessagesProj/jni/tgnet/EventObject.cpp
Normal file
50
TMessagesProj/jni/tgnet/EventObject.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include "EventObject.h"
|
||||
#include "Connection.h"
|
||||
#include "Timer.h"
|
||||
|
||||
EventObject::EventObject(void *object, EventObjectType type) {
|
||||
eventObject = object;
|
||||
eventType = type;
|
||||
}
|
||||
|
||||
void EventObject::onEvent(uint32_t events) {
|
||||
switch (eventType) {
|
||||
case EventObjectTypeConnection: {
|
||||
Connection *connection = (Connection *) eventObject;
|
||||
connection->onEvent(events);
|
||||
break;
|
||||
}
|
||||
case EventObjectTypeTimer: {
|
||||
Timer *timer = (Timer *) eventObject;
|
||||
timer->onEvent();
|
||||
break;
|
||||
}
|
||||
case EventObjectTypePipe: {
|
||||
int *pipe = (int *) eventObject;
|
||||
char ch;
|
||||
ssize_t size = 1;
|
||||
while (size > 0) {
|
||||
size = read(pipe[0], &ch, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EventObjectTypeEvent: {
|
||||
int *eventFd = (int *) eventObject;
|
||||
uint64_t count;
|
||||
eventfd_read(eventFd[0], &count);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
26
TMessagesProj/jni/tgnet/EventObject.h
Normal file
26
TMessagesProj/jni/tgnet/EventObject.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef EVENTOBJECT_H
|
||||
#define EVENTOBJECT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "Defines.h"
|
||||
|
||||
class EventObject {
|
||||
|
||||
public:
|
||||
EventObject(void *object, EventObjectType type);
|
||||
void onEvent(uint32_t events);
|
||||
|
||||
int64_t time;
|
||||
void *eventObject;
|
||||
EventObjectType eventType;
|
||||
};
|
||||
|
||||
#endif
|
||||
212
TMessagesProj/jni/tgnet/FileLog.cpp
Normal file
212
TMessagesProj/jni/tgnet/FileLog.cpp
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include "FileLog.h"
|
||||
#include "ConnectionsManager.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_VERSION
|
||||
bool LOGS_ENABLED = true;
|
||||
#else
|
||||
bool LOGS_ENABLED = false;
|
||||
#endif
|
||||
|
||||
bool REF_LOGS_ENABLED = false;
|
||||
|
||||
FileLog &FileLog::getInstance() {
|
||||
static FileLog instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
FileLog::FileLog() {
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
}
|
||||
|
||||
void FileLog::init(std::string path) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
if (path.size() > 0 && logFile == nullptr) {
|
||||
logFile = fopen(path.c_str(), "w");
|
||||
}
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
void FileLog::fatal(const char *message, ...) {
|
||||
if (!LOGS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
va_list argptr;
|
||||
va_start(argptr, message);
|
||||
|
||||
struct timeval time_now;
|
||||
gettimeofday(&time_now, NULL);
|
||||
struct tm *now = localtime(&time_now.tv_sec);
|
||||
#ifdef ANDROID
|
||||
__android_log_vprint(ANDROID_LOG_FATAL, "tgnet", message, argptr);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#else
|
||||
printf("%d-%d %02d:%02d:%02d FATAL ERROR: ", now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
|
||||
vprintf(message, argptr);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#endif
|
||||
FILE *logFile = getInstance().logFile;
|
||||
if (logFile) {
|
||||
fprintf(logFile, "%d-%d %02d:%02d:%02d.%03d FATAL ERROR: ", now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, (int) (time_now.tv_usec / 1000));
|
||||
vfprintf(logFile, message, argptr);
|
||||
fprintf(logFile, "\n");
|
||||
fflush(logFile);
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
#ifdef DEBUG_VERSION
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FileLog::e(const char *message, ...) {
|
||||
if (!LOGS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
va_list argptr;
|
||||
va_start(argptr, message);
|
||||
struct timeval time_now;
|
||||
gettimeofday(&time_now, NULL);
|
||||
struct tm *now = localtime(&time_now.tv_sec);
|
||||
#ifdef ANDROID
|
||||
__android_log_vprint(ANDROID_LOG_ERROR, "tgnet", message, argptr);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#else
|
||||
printf("%d-%d %02d:%02d:%02d error: ", now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
|
||||
vprintf(message, argptr);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#endif
|
||||
FILE *logFile = getInstance().logFile;
|
||||
if (logFile) {
|
||||
fprintf(logFile, "%d-%d %02d:%02d:%02d.%03d error: ", now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, (int) (time_now.tv_usec / 1000));
|
||||
vfprintf(logFile, message, argptr);
|
||||
fprintf(logFile, "\n");
|
||||
fflush(logFile);
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void FileLog::w(const char *message, ...) {
|
||||
if (!LOGS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
va_list argptr;
|
||||
va_start(argptr, message);
|
||||
struct timeval time_now;
|
||||
gettimeofday(&time_now, NULL);
|
||||
struct tm *now = localtime(&time_now.tv_sec);
|
||||
#ifdef ANDROID
|
||||
__android_log_vprint(ANDROID_LOG_WARN, "tgnet", message, argptr);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#else
|
||||
printf("%d-%d %02d:%02d:%02d warning: ", now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
|
||||
vprintf(message, argptr);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#endif
|
||||
FILE *logFile = getInstance().logFile;
|
||||
if (logFile) {
|
||||
fprintf(logFile, "%d-%d %02d:%02d:%02d.%03d warning: ", now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, (int) (time_now.tv_usec / 1000));
|
||||
vfprintf(logFile, message, argptr);
|
||||
fprintf(logFile, "\n");
|
||||
fflush(logFile);
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void FileLog::d(const char *message, ...) {
|
||||
if (!LOGS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
va_list argptr;
|
||||
va_start(argptr, message);
|
||||
|
||||
struct timeval time_now;
|
||||
gettimeofday(&time_now, NULL);
|
||||
struct tm *now = localtime(&time_now.tv_sec);
|
||||
#ifdef ANDROID
|
||||
__android_log_vprint(ANDROID_LOG_DEBUG, "tgnet", message, argptr);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#else
|
||||
printf("%d-%d %02d:%02d:%02d debug: ", now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
|
||||
vprintf(message, argptr);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#endif
|
||||
FILE *logFile = getInstance().logFile;
|
||||
if (logFile) {
|
||||
fprintf(logFile, "%d-%d %02d:%02d:%02d.%03d debug: ", now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, (int) (time_now.tv_usec / 1000));
|
||||
vfprintf(logFile, message, argptr);
|
||||
fprintf(logFile, "\n");
|
||||
fflush(logFile);
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
static int refsCount = 0;
|
||||
|
||||
void FileLog::ref(const char *message, ...) {
|
||||
if (!REF_LOGS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
va_list argptr;
|
||||
va_start(argptr, message);
|
||||
refsCount++;
|
||||
#ifdef ANDROID
|
||||
std::ostringstream s;
|
||||
s << refsCount << " refs (+ref): " << message;
|
||||
__android_log_vprint(ANDROID_LOG_VERBOSE, "tgnetREF", s.str().c_str(), argptr);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#endif
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void FileLog::delref(const char *message, ...) {
|
||||
if (!REF_LOGS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
va_list argptr;
|
||||
va_start(argptr, message);
|
||||
refsCount--;
|
||||
#ifdef ANDROID
|
||||
std::ostringstream s;
|
||||
s << refsCount << " refs (-ref): " << message;
|
||||
__android_log_vprint(ANDROID_LOG_VERBOSE, "tgnetREF", s.str().c_str(), argptr);
|
||||
va_end(argptr);
|
||||
va_start(argptr, message);
|
||||
#endif
|
||||
va_end(argptr);
|
||||
}
|
||||
42
TMessagesProj/jni/tgnet/FileLog.h
Normal file
42
TMessagesProj/jni/tgnet/FileLog.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef FILELOG_H
|
||||
#define FILELOG_H
|
||||
|
||||
#include "Defines.h"
|
||||
|
||||
class FileLog {
|
||||
public:
|
||||
FileLog();
|
||||
void init(std::string path);
|
||||
static void fatal(const char *message, ...) __attribute__((format (printf, 1, 2)));
|
||||
static void e(const char *message, ...) __attribute__((format (printf, 1, 2)));
|
||||
static void w(const char *message, ...) __attribute__((format (printf, 1, 2)));
|
||||
static void d(const char *message, ...) __attribute__((format (printf, 1, 2)));
|
||||
static void ref(const char *message, ...) __attribute__((format (printf, 1, 2)));
|
||||
static void delref(const char *message, ...) __attribute__((format (printf, 1, 2)));
|
||||
|
||||
static FileLog &getInstance();
|
||||
|
||||
private:
|
||||
FILE *logFile = nullptr;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
extern bool LOGS_ENABLED;
|
||||
|
||||
#define DEBUG_FATAL FileLog::getInstance().fatal
|
||||
#define DEBUG_E FileLog::getInstance().e
|
||||
#define DEBUG_W FileLog::getInstance().w
|
||||
#define DEBUG_D FileLog::getInstance().d
|
||||
|
||||
#define DEBUG_REF FileLog::getInstance().ref
|
||||
#define DEBUG_DELREF FileLog::getInstance().delref
|
||||
|
||||
#endif
|
||||
1074
TMessagesProj/jni/tgnet/Handshake.cpp
Normal file
1074
TMessagesProj/jni/tgnet/Handshake.cpp
Normal file
File diff suppressed because it is too large
Load diff
73
TMessagesProj/jni/tgnet/Handshake.h
Normal file
73
TMessagesProj/jni/tgnet/Handshake.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef HANDSHAKE_H
|
||||
#define HANDSHAKE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "Defines.h"
|
||||
#include <openssl/bn.h>
|
||||
|
||||
class Datacenter;
|
||||
class ByteArray;
|
||||
class TLObject;
|
||||
class TL_future_salt;
|
||||
class Connection;
|
||||
|
||||
class Handshake {
|
||||
|
||||
public:
|
||||
|
||||
Handshake(Datacenter *datacenter, HandshakeType type, HandshakeDelegate *handshakeDelegate);
|
||||
~Handshake();
|
||||
void beginHandshake(bool reconnect);
|
||||
void cleanupHandshake();
|
||||
void processHandshakeResponse(TLObject *message, int64_t messageId);
|
||||
void processHandshakeResponse_resPQ(TLObject *message, int64_t messageId);
|
||||
void processHandshakeResponse_serverDHParams(TLObject *message, int64_t messageId);
|
||||
void processHandshakeResponse_serverDHParamsAnswer(TLObject *message, int64_t messageId);
|
||||
void onHandshakeConnectionConnected();
|
||||
void onHandshakeConnectionClosed();
|
||||
static void cleanupServerKeys();
|
||||
HandshakeType getType();
|
||||
ByteArray *getPendingAuthKey();
|
||||
int64_t getPendingAuthKeyId();
|
||||
TLObject *getCurrentHandshakeRequest();
|
||||
static bool isGoodPrime(BIGNUM *p, uint32_t g);
|
||||
|
||||
private:
|
||||
|
||||
Datacenter *currentDatacenter;
|
||||
HandshakeType handshakeType;
|
||||
HandshakeDelegate *delegate;
|
||||
|
||||
uint8_t handshakeState = 0;
|
||||
TLObject *handshakeRequest = nullptr;
|
||||
ByteArray *authNonce = nullptr;
|
||||
ByteArray *authServerNonce = nullptr;
|
||||
ByteArray *authNewNonce = nullptr;
|
||||
ByteArray *handshakeAuthKey = nullptr;
|
||||
TL_future_salt *handshakeServerSalt = nullptr;
|
||||
int32_t timeDifference = 0;
|
||||
ByteArray *authKeyTempPending = nullptr;
|
||||
int64_t authKeyTempPendingId = 0;
|
||||
int32_t authKeyPendingRequestId = 0;
|
||||
int64_t authKeyPendingMessageId = 0;
|
||||
bool needResendData = false;
|
||||
|
||||
void sendRequestData(TLObject *object, bool important);
|
||||
void sendAckRequest(int64_t messageId);
|
||||
|
||||
static void saveCdnConfig(Datacenter *datacenter);
|
||||
static void saveCdnConfigInternal(NativeByteBuffer *buffer);
|
||||
static void loadCdnConfig(Datacenter *datacenter);
|
||||
|
||||
inline Connection *getConnection();
|
||||
};
|
||||
|
||||
#endif
|
||||
1191
TMessagesProj/jni/tgnet/MTProtoScheme.cpp
Normal file
1191
TMessagesProj/jni/tgnet/MTProtoScheme.cpp
Normal file
File diff suppressed because it is too large
Load diff
923
TMessagesProj/jni/tgnet/MTProtoScheme.h
Normal file
923
TMessagesProj/jni/tgnet/MTProtoScheme.h
Normal file
|
|
@ -0,0 +1,923 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef MTPROTOSCHEME_H
|
||||
#define MTPROTOSCHEME_H
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include "TLObject.h"
|
||||
|
||||
class ByteArray;
|
||||
class NativeByteBuffer;
|
||||
|
||||
class TLClassStore {
|
||||
|
||||
public:
|
||||
static TLObject *TLdeserialize(NativeByteBuffer *stream, uint32_t bytes, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_api_request : public TLObject {
|
||||
|
||||
public:
|
||||
NativeByteBuffer *request = nullptr;
|
||||
|
||||
~TL_api_request();
|
||||
bool isNeedLayer();
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t bytes, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_api_response : public TLObject {
|
||||
|
||||
public:
|
||||
std::unique_ptr<NativeByteBuffer> response;
|
||||
|
||||
void readParamsEx(NativeByteBuffer *stream, uint32_t bytes, bool &error);
|
||||
};
|
||||
|
||||
class TL_future_salt : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x0949d9dc;
|
||||
|
||||
int32_t valid_since;
|
||||
int32_t valid_until;
|
||||
int64_t salt;
|
||||
|
||||
static TL_future_salt *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_msgs_state_info : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x04deb57d;
|
||||
|
||||
int64_t req_msg_id;
|
||||
std::unique_ptr<ByteArray> info;
|
||||
|
||||
static TL_msgs_state_info *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class Server_DH_Params : public TLObject {
|
||||
|
||||
public:
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
std::unique_ptr<ByteArray> new_nonce_hash;
|
||||
std::unique_ptr<ByteArray> encrypted_answer;
|
||||
|
||||
static Server_DH_Params *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_server_DH_params_fail : public Server_DH_Params {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x79cb045d;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_server_DH_params_ok : public Server_DH_Params {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xd0e8075c;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_resPQ : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x05162463;
|
||||
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
std::unique_ptr<ByteArray> pq;
|
||||
std::vector<int64_t> server_public_key_fingerprints;
|
||||
|
||||
static TL_resPQ *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
/*
|
||||
p_q_inner_data#83c95aec pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 = P_Q_inner_data;
|
||||
|
||||
p_q_inner_data_temp#3c6a84d4 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 expires_in:int = P_Q_inner_data;
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class TL_p_q_inner_data : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x83c95aec;
|
||||
|
||||
std::unique_ptr<ByteArray> pq;
|
||||
std::unique_ptr<ByteArray> p;
|
||||
std::unique_ptr<ByteArray> q;
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
std::unique_ptr<ByteArray> new_nonce;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_p_q_inner_data_dc : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xa9f55f95;
|
||||
|
||||
std::unique_ptr<ByteArray> pq;
|
||||
std::unique_ptr<ByteArray> p;
|
||||
std::unique_ptr<ByteArray> q;
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
std::unique_ptr<ByteArray> new_nonce;
|
||||
int32_t dc;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_p_q_inner_data_temp : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x3c6a84d4;
|
||||
|
||||
std::unique_ptr<ByteArray> pq;
|
||||
std::unique_ptr<ByteArray> p;
|
||||
std::unique_ptr<ByteArray> q;
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
std::unique_ptr<ByteArray> new_nonce;
|
||||
int32_t expires_in;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_p_q_inner_data_temp_dc : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x56fddf88;
|
||||
|
||||
std::unique_ptr<ByteArray> pq;
|
||||
std::unique_ptr<ByteArray> p;
|
||||
std::unique_ptr<ByteArray> q;
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
std::unique_ptr<ByteArray> new_nonce;
|
||||
int32_t dc;
|
||||
int32_t expires_in;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_bind_auth_key_inner : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x75a3f765;
|
||||
|
||||
int64_t nonce;
|
||||
int64_t temp_auth_key_id;
|
||||
int64_t perm_auth_key_id;
|
||||
int64_t temp_session_id;
|
||||
int32_t expires_at;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
|
||||
class TL_auth_bindTempAuthKey : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xcdd42a05;
|
||||
|
||||
int64_t perm_auth_key_id;
|
||||
int64_t nonce;
|
||||
int32_t expires_at;
|
||||
NativeByteBuffer *encrypted_message = nullptr;
|
||||
|
||||
~TL_auth_bindTempAuthKey();
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_auth_dropTempAuthKeys : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x8e48a188;
|
||||
|
||||
std::vector<int64_t> except_auth_keys;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_pong : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x347773c5;
|
||||
|
||||
int64_t msg_id;
|
||||
int64_t ping_id;
|
||||
|
||||
static TL_pong *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_future_salts : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xae500895;
|
||||
|
||||
int64_t req_msg_id;
|
||||
int32_t now;
|
||||
std::vector<std::unique_ptr<TL_future_salt>> salts;
|
||||
|
||||
static TL_future_salts *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class RpcDropAnswer : public TLObject {
|
||||
|
||||
public:
|
||||
int64_t msg_id;
|
||||
int32_t seq_no;
|
||||
int32_t bytes;
|
||||
|
||||
static RpcDropAnswer *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_rpc_answer_unknown : public RpcDropAnswer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x5e2ad36e;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_rpc_answer_dropped : public RpcDropAnswer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xa43ad8b7;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_rpc_answer_dropped_running : public RpcDropAnswer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xcd78e586;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class Set_client_DH_params_answer : public TLObject {
|
||||
|
||||
public:
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
std::unique_ptr<ByteArray> new_nonce_hash2;
|
||||
std::unique_ptr<ByteArray> new_nonce_hash3;
|
||||
std::unique_ptr<ByteArray> new_nonce_hash1;
|
||||
|
||||
static Set_client_DH_params_answer *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_message : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x5bb8e511;
|
||||
|
||||
int64_t msg_id;
|
||||
int32_t seqno;
|
||||
int32_t bytes;
|
||||
std::unique_ptr<TLObject> body;
|
||||
TLObject *outgoingBody = nullptr;
|
||||
std::unique_ptr<NativeByteBuffer> unparsedBody;
|
||||
|
||||
static TL_message *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_dh_gen_retry : public Set_client_DH_params_answer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x46dc1fb9;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_dh_gen_fail : public Set_client_DH_params_answer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xa69dae02;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_dh_gen_ok : public Set_client_DH_params_answer {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x3bcbf734;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class BadMsgNotification : public TLObject {
|
||||
|
||||
public:
|
||||
int64_t bad_msg_id;
|
||||
int32_t bad_msg_seqno;
|
||||
int32_t error_code;
|
||||
int64_t new_server_salt;
|
||||
|
||||
static BadMsgNotification *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_bad_msg_notification : public BadMsgNotification {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xa7eff811;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_bad_server_salt : public BadMsgNotification {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xedab447b;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_msgs_state_req : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xda69fb52;
|
||||
|
||||
std::vector<int64_t> msg_ids;
|
||||
|
||||
static TL_msgs_state_req *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class MsgDetailedInfo : public TLObject {
|
||||
|
||||
public:
|
||||
int64_t answer_msg_id;
|
||||
int32_t bytes;
|
||||
int32_t status;
|
||||
int64_t msg_id;
|
||||
|
||||
static MsgDetailedInfo *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_msg_new_detailed_info : public MsgDetailedInfo {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x809db6df;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_msg_detailed_info : public MsgDetailedInfo {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x276d3ec6;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_msg_copy : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xe06046b2;
|
||||
|
||||
std::unique_ptr<TL_message> orig_message;
|
||||
|
||||
static TL_msg_copy *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_msgs_all_info : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x8cc0d131;
|
||||
|
||||
std::vector<int64_t> msg_ids;
|
||||
std::unique_ptr<ByteArray> info;
|
||||
|
||||
static TL_msgs_all_info *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_rpc_result : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xf35c6d01;
|
||||
|
||||
int64_t req_msg_id;
|
||||
std::unique_ptr<TLObject> result;
|
||||
|
||||
void readParamsEx(NativeByteBuffer *stream, uint32_t bytes, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_new_session_created : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x9ec20908;
|
||||
|
||||
int64_t first_msg_id;
|
||||
int64_t unique_id;
|
||||
int64_t server_salt;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class DestroySessionRes : public TLObject {
|
||||
|
||||
public:
|
||||
int64_t session_id;
|
||||
|
||||
static DestroySessionRes *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_destroy_session_ok : public DestroySessionRes {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xe22045fc;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_destroy_session_none : public DestroySessionRes {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x62d350c9;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_msgs_ack : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x62d6b459;
|
||||
|
||||
std::vector<int64_t> msg_ids;
|
||||
|
||||
static TL_msgs_ack *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_msg_container : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x73f1f8dc;
|
||||
|
||||
std::vector<std::unique_ptr<TL_message>> messages;
|
||||
|
||||
static TL_msg_container *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_msg_resend_req : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x7d861a08;
|
||||
|
||||
std::vector<int64_t> msg_ids;
|
||||
|
||||
static TL_msg_resend_req *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class MsgsStateInfo : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x04deb57d;
|
||||
|
||||
int64_t req_msg_id;
|
||||
std::string info;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class RpcError : public TLObject {
|
||||
|
||||
public:
|
||||
int32_t error_code;
|
||||
std::string error_message;
|
||||
int64_t query_id;
|
||||
};
|
||||
|
||||
class TL_rpc_error : public RpcError {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x2144ca19;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_rpc_req_error : public RpcError {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x7ae432f5;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_client_DH_inner_data : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x6643b654;
|
||||
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
int64_t retry_id;
|
||||
std::unique_ptr<ByteArray> g_b;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_server_DH_inner_data : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xb5890dba;
|
||||
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
uint32_t g;
|
||||
std::unique_ptr<ByteArray> dh_prime;
|
||||
std::unique_ptr<ByteArray> g_a;
|
||||
int32_t server_time;
|
||||
|
||||
static TL_server_DH_inner_data *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_req_pq : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x60469778;
|
||||
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_req_pq_multi : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xbe7e8ef1;
|
||||
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_req_DH_params : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xd712e4be;
|
||||
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
std::unique_ptr<ByteArray> p;
|
||||
std::unique_ptr<ByteArray> q;
|
||||
int64_t public_key_fingerprint;
|
||||
std::unique_ptr<ByteArray> encrypted_data;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_set_client_DH_params : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xf5045f1f;
|
||||
|
||||
std::unique_ptr<ByteArray> nonce;
|
||||
std::unique_ptr<ByteArray> server_nonce;
|
||||
std::unique_ptr<ByteArray> encrypted_data;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_rpc_drop_answer : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x58e4a740;
|
||||
|
||||
int64_t req_msg_id;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_get_future_salts : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xb921bd04;
|
||||
|
||||
int32_t num;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_ping : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x7abe77ec;
|
||||
|
||||
int64_t ping_id;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_ping_delay_disconnect : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xf3427b8c;
|
||||
|
||||
int64_t ping_id;
|
||||
int32_t disconnect_delay;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_destroy_session : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xe7512126;
|
||||
|
||||
int64_t session_id;
|
||||
|
||||
TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_gzip_packed : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x3072cfa1;
|
||||
|
||||
NativeByteBuffer *packed_data_to_send = nullptr;
|
||||
std::unique_ptr<NativeByteBuffer> packed_data;
|
||||
std::unique_ptr<TLObject> originalRequest;
|
||||
|
||||
~TL_gzip_packed();
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_error : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xc4b9f9bb;
|
||||
|
||||
int32_t code;
|
||||
std::string text;
|
||||
|
||||
static TL_error *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_invokeAfterMsg : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xcb9f372d;
|
||||
|
||||
int64_t msg_id;
|
||||
TLObject *outgoingQuery = nullptr;
|
||||
std::unique_ptr<TLObject> query;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class invokeWithLayer : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xda9b0d0d;
|
||||
|
||||
int32_t layer;
|
||||
std::unique_ptr<TLObject> query;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class invokeWithGooglePlayIntegrity : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x1df92984;
|
||||
|
||||
std::string nonce;
|
||||
std::string token;
|
||||
std::unique_ptr<TLObject> query;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class invokeWithReCaptcha : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xadbb0f94;
|
||||
|
||||
std::string token;
|
||||
std::unique_ptr<TLObject> query;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_inputClientProxy : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x75588b3f;
|
||||
|
||||
std::string address;
|
||||
int32_t port;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class JSONValue : public TLObject {
|
||||
|
||||
public:
|
||||
static JSONValue *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_jsonObjectValue : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xc0de1bd9;
|
||||
|
||||
std::string key;
|
||||
std::unique_ptr<JSONValue> value;
|
||||
|
||||
static TL_jsonObjectValue *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_jsonBool : public JSONValue {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xc7345e6a;
|
||||
|
||||
bool value;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_jsonNull : public JSONValue {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x3f6d7b68;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_jsonString : public JSONValue {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xb71e767a;
|
||||
|
||||
std::string value;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_jsonArray : public JSONValue {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xf7444763;
|
||||
|
||||
std::vector<std::unique_ptr<JSONValue>> value;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_jsonObject : public JSONValue {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x99c1d49d;
|
||||
|
||||
std::vector<std::unique_ptr<TL_jsonObjectValue>> value;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class TL_jsonNumber : public JSONValue {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x2be0dfa4;
|
||||
|
||||
double value;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class initConnection : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0xc1cd5ea9;
|
||||
|
||||
int32_t flags;
|
||||
int32_t api_id;
|
||||
std::string device_model;
|
||||
std::string system_version;
|
||||
std::string app_version;
|
||||
std::string system_lang_code;
|
||||
std::string lang_pack;
|
||||
std::string lang_code;
|
||||
std::unique_ptr<TL_inputClientProxy> proxy;
|
||||
std::unique_ptr<JSONValue> params;
|
||||
std::unique_ptr<TLObject> query;
|
||||
|
||||
void serializeToStream(NativeByteBuffer *stream);
|
||||
};
|
||||
|
||||
class IpPort : public TLObject {
|
||||
|
||||
public:
|
||||
static IpPort *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_ipPort : public IpPort {
|
||||
|
||||
public:
|
||||
static const int32_t constructor = 0xd433ad73;
|
||||
|
||||
std::string ipv4;
|
||||
uint32_t port;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_ipPortSecret : public IpPort {
|
||||
|
||||
public:
|
||||
static const int32_t constructor = 0x37982646;
|
||||
|
||||
std::string ipv4;
|
||||
uint32_t port;
|
||||
std::unique_ptr<ByteArray> secret;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_accessPointRule : public TLObject {
|
||||
|
||||
public:
|
||||
static const int32_t constructor = 0x4679b65f;
|
||||
|
||||
std::string phone_prefix_rules;
|
||||
uint32_t dc_id;
|
||||
std::vector<std::unique_ptr<IpPort>> ips;
|
||||
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
class TL_help_configSimple : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x5a592a6c;
|
||||
|
||||
int32_t date;
|
||||
int32_t expires;
|
||||
std::vector<std::unique_ptr<TL_accessPointRule>> rules;
|
||||
|
||||
static TL_help_configSimple *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
};
|
||||
|
||||
#endif
|
||||
710
TMessagesProj/jni/tgnet/NativeByteBuffer.cpp
Normal file
710
TMessagesProj/jni/tgnet/NativeByteBuffer.cpp
Normal file
|
|
@ -0,0 +1,710 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include "NativeByteBuffer.h"
|
||||
#include "FileLog.h"
|
||||
#include "ByteArray.h"
|
||||
#include "ConnectionsManager.h"
|
||||
#include "BuffersStorage.h"
|
||||
|
||||
static int buffersCount = 0;
|
||||
|
||||
NativeByteBuffer::NativeByteBuffer(uint32_t size) {
|
||||
#ifdef ANDROID
|
||||
if (jclass_ByteBuffer != nullptr) {
|
||||
JNIEnv *env = 0;
|
||||
if (javaVm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
|
||||
if (LOGS_ENABLED) DEBUG_E("can't get jnienv");
|
||||
exit(1);
|
||||
}
|
||||
javaByteBuffer = env->CallStaticObjectMethod(jclass_ByteBuffer, jclass_ByteBuffer_allocateDirect, size);
|
||||
if (javaByteBuffer == nullptr) {
|
||||
if (LOGS_ENABLED) DEBUG_E("can't create javaByteBuffer");
|
||||
exit(1);
|
||||
}
|
||||
DEBUG_REF("nativebytebuffer");
|
||||
jobject globalRef = env->NewGlobalRef(javaByteBuffer);
|
||||
env->DeleteLocalRef(javaByteBuffer);
|
||||
javaByteBuffer = globalRef;
|
||||
buffer = (uint8_t *) env->GetDirectBufferAddress(javaByteBuffer);
|
||||
bufferOwner = false;
|
||||
} else {
|
||||
#endif
|
||||
buffer = new uint8_t[size];
|
||||
bufferOwner = true;
|
||||
#ifdef ANDROID
|
||||
}
|
||||
#endif
|
||||
if (buffer == nullptr) {
|
||||
if (LOGS_ENABLED) DEBUG_E("can't allocate NativeByteBuffer buffer");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_limit = _capacity = size;
|
||||
}
|
||||
|
||||
NativeByteBuffer::NativeByteBuffer(bool calculate) {
|
||||
calculateSizeOnly = calculate;
|
||||
}
|
||||
|
||||
NativeByteBuffer::NativeByteBuffer(uint8_t *buff, uint32_t length) {
|
||||
buffer = buff;
|
||||
sliced = true;
|
||||
_limit = _capacity = length;
|
||||
}
|
||||
|
||||
NativeByteBuffer::~NativeByteBuffer() {
|
||||
#ifdef ANDROID
|
||||
if (javaByteBuffer != nullptr) {
|
||||
JNIEnv *env = 0;
|
||||
if (javaVm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
|
||||
if (LOGS_ENABLED) DEBUG_E("can't get jnienv");
|
||||
exit(1);
|
||||
}
|
||||
DEBUG_DELREF("nativebytebuffer");
|
||||
env->DeleteGlobalRef(javaByteBuffer);
|
||||
javaByteBuffer = nullptr;
|
||||
}
|
||||
#endif
|
||||
if (bufferOwner && !sliced && buffer != nullptr) {
|
||||
delete[] buffer;
|
||||
buffer = nullptr;
|
||||
}
|
||||
_limit = _capacity = 0;
|
||||
}
|
||||
|
||||
uint32_t NativeByteBuffer::position() {
|
||||
return _position;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::position(uint32_t position) {
|
||||
if (position > _limit) {
|
||||
return;
|
||||
}
|
||||
_position = position;
|
||||
}
|
||||
|
||||
uint32_t NativeByteBuffer::capacity() {
|
||||
return _capacity;
|
||||
}
|
||||
|
||||
uint32_t NativeByteBuffer::limit() {
|
||||
return _limit;
|
||||
}
|
||||
|
||||
uint32_t NativeByteBuffer::remaining() {
|
||||
return _limit - _position;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::clearCapacity() {
|
||||
if (!calculateSizeOnly) {
|
||||
return;
|
||||
}
|
||||
_capacity = 0;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::limit(uint32_t limit) {
|
||||
if (limit > _capacity) {
|
||||
return;
|
||||
}
|
||||
if (_position > limit) {
|
||||
_position = limit;
|
||||
}
|
||||
_limit = limit;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::flip() {
|
||||
_limit = _position;
|
||||
_position = 0;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::clear() {
|
||||
_position = 0;
|
||||
_limit = _capacity;
|
||||
}
|
||||
|
||||
uint8_t *NativeByteBuffer::bytes() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::rewind() {
|
||||
_position = 0;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::compact() {
|
||||
if (_position == _limit) {
|
||||
return;
|
||||
}
|
||||
memmove(buffer, buffer + _position, sizeof(uint8_t) * (_limit - _position));
|
||||
_position = (_limit - _position);
|
||||
_limit = _capacity;
|
||||
}
|
||||
|
||||
bool NativeByteBuffer::hasRemaining() {
|
||||
return _position < _limit;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::skip(uint32_t length) {
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + length > _limit) {
|
||||
return;
|
||||
}
|
||||
_position += length;
|
||||
} else {
|
||||
_capacity += length;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeInt32(int32_t x, bool *error) {
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + 4 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write int32 error");
|
||||
return;
|
||||
}
|
||||
buffer[_position++] = (uint8_t) x;
|
||||
buffer[_position++] = (uint8_t) (x >> 8);
|
||||
buffer[_position++] = (uint8_t) (x >> 16);
|
||||
buffer[_position++] = (uint8_t) (x >> 24);
|
||||
} else {
|
||||
_capacity += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeInt64(int64_t x, bool *error) {
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + 8 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write int64 error");
|
||||
return;
|
||||
}
|
||||
buffer[_position++] = (uint8_t) x;
|
||||
buffer[_position++] = (uint8_t) (x >> 8);
|
||||
buffer[_position++] = (uint8_t) (x >> 16);
|
||||
buffer[_position++] = (uint8_t) (x >> 24);
|
||||
buffer[_position++] = (uint8_t) (x >> 32);
|
||||
buffer[_position++] = (uint8_t) (x >> 40);
|
||||
buffer[_position++] = (uint8_t) (x >> 48);
|
||||
buffer[_position++] = (uint8_t) (x >> 56);
|
||||
} else {
|
||||
_capacity += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBool(bool value, bool *error) {
|
||||
if (!calculateSizeOnly) {
|
||||
if (value) {
|
||||
writeInt32(0x997275b5, error);
|
||||
} else {
|
||||
writeInt32(0xbc799737, error);
|
||||
}
|
||||
} else {
|
||||
_capacity += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBytes(uint8_t *b, uint32_t length, bool *error) {
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + length > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write bytes error");
|
||||
return;
|
||||
}
|
||||
writeBytesInternal(b, 0, length);
|
||||
} else {
|
||||
_capacity += length;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBytes(uint8_t *b, uint32_t offset, uint32_t length, bool *error) {
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + length > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write bytes error");
|
||||
return;
|
||||
}
|
||||
writeBytesInternal(b, offset, length);
|
||||
} else {
|
||||
_capacity += length;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBytes(NativeByteBuffer *b, bool *error) {
|
||||
uint32_t length = b->_limit - b->_position;
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + length > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write bytes error");
|
||||
return;
|
||||
}
|
||||
writeBytesInternal(b->buffer + b->_position, 0, length);
|
||||
b->position(b->limit());
|
||||
} else {
|
||||
_capacity += length;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBytes(ByteArray *b, bool *error) {
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + b->length > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write bytes error");
|
||||
return;
|
||||
}
|
||||
writeBytesInternal(b->bytes, 0, b->length);
|
||||
} else {
|
||||
_capacity += b->length;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBytesInternal(uint8_t *b, uint32_t offset, uint32_t length) {
|
||||
memcpy(buffer + _position, b + offset, sizeof(uint8_t) * length);
|
||||
_position += length;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByte(uint8_t i, bool *error) {
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + 1 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write byte error");
|
||||
return;
|
||||
}
|
||||
buffer[_position++] = i;
|
||||
} else {
|
||||
_capacity += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeString(std::string s, bool *error) {
|
||||
writeByteArray((uint8_t *) s.c_str(), (uint32_t) s.length(), error);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByteArray(uint8_t *b, uint32_t offset, uint32_t length, bool *error) {
|
||||
if (length <= 253) {
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + 1 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write byte array error");
|
||||
return;
|
||||
}
|
||||
buffer[_position++] = (uint8_t) length;
|
||||
} else {
|
||||
_capacity += 1;
|
||||
}
|
||||
} else {
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + 4 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write byte array error");
|
||||
return;
|
||||
}
|
||||
buffer[_position++] = (uint8_t) 254;
|
||||
buffer[_position++] = (uint8_t) length;
|
||||
buffer[_position++] = (uint8_t) (length >> 8);
|
||||
buffer[_position++] = (uint8_t) (length >> 16);
|
||||
} else {
|
||||
_capacity += 4;
|
||||
}
|
||||
}
|
||||
if (!calculateSizeOnly) {
|
||||
if (_position + length > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write byte array error");
|
||||
return;
|
||||
}
|
||||
writeBytesInternal(b, offset, length);
|
||||
} else {
|
||||
_capacity += length;
|
||||
}
|
||||
uint32_t addition = (length + (length <= 253 ? 1 : 4)) % 4;
|
||||
if (addition != 0) {
|
||||
addition = 4 - addition;
|
||||
}
|
||||
if (!calculateSizeOnly && _position + addition > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("write byte array error");
|
||||
return;
|
||||
}
|
||||
for (uint32_t a = 0; a < addition; a++) {
|
||||
if (!calculateSizeOnly) {
|
||||
buffer[_position++] = (uint8_t) 0;
|
||||
} else {
|
||||
_capacity += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByteArray(uint8_t *b, uint32_t length, bool *error) {
|
||||
writeByteArray(b, 0, length, error);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByteArray(NativeByteBuffer *b, bool *error) {
|
||||
b->rewind();
|
||||
writeByteArray(b->buffer, 0, b->limit(), error);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByteArray(ByteArray *b, bool *error) {
|
||||
writeByteArray(b->bytes, 0, b->length, error);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeDouble(double d, bool *error) {
|
||||
int64_t value;
|
||||
memcpy(&value, &d, sizeof(int64_t));
|
||||
writeInt64(value, error);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeInt32(int32_t x) {
|
||||
writeInt32(x, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeInt64(int64_t x) {
|
||||
writeInt64(x, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBool(bool value) {
|
||||
writeBool(value, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBytes(uint8_t *b, uint32_t length) {
|
||||
writeBytes(b, length, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBytes(uint8_t *b, uint32_t offset, uint32_t length) {
|
||||
writeBytes(b, offset, length, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBytes(ByteArray *b) {
|
||||
writeBytes(b, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeBytes(NativeByteBuffer *b) {
|
||||
writeBytes(b, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByte(uint8_t i) {
|
||||
writeByte(i, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeString(std::string s) {
|
||||
writeString(s, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByteArray(uint8_t *b, uint32_t offset, uint32_t length) {
|
||||
writeByteArray(b, offset, length, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByteArray(uint8_t *b, uint32_t length) {
|
||||
writeByteArray(b, length, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByteArray(NativeByteBuffer *b) {
|
||||
writeByteArray(b, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeByteArray(ByteArray *b) {
|
||||
writeByteArray(b->bytes, b->length, nullptr);
|
||||
}
|
||||
|
||||
void NativeByteBuffer::writeDouble(double d) {
|
||||
writeDouble(d, nullptr);
|
||||
}
|
||||
|
||||
int32_t NativeByteBuffer::readInt32(bool *error) {
|
||||
if (_position + 4 > _limit || calculateSizeOnly) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read int32 error");
|
||||
return 0;
|
||||
}
|
||||
int32_t result = ((buffer[_position] & 0xff)) |
|
||||
((buffer[_position + 1] & 0xff) << 8) |
|
||||
((buffer[_position + 2] & 0xff) << 16) |
|
||||
((buffer[_position + 3] & 0xff) << 24);
|
||||
_position += 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t NativeByteBuffer::readUint32(bool *error) {
|
||||
return (uint32_t) readInt32(error);
|
||||
}
|
||||
|
||||
uint64_t NativeByteBuffer::readUint64(bool *error) {
|
||||
return (uint64_t) readInt64(error);
|
||||
}
|
||||
|
||||
int32_t NativeByteBuffer::readBigInt32(bool *error) {
|
||||
if (_position + 4 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read big int32 error");
|
||||
return 0;
|
||||
}
|
||||
int32_t result = ((buffer[_position] & 0xff) << 24) |
|
||||
((buffer[_position + 1] & 0xff) << 16) |
|
||||
((buffer[_position + 2] & 0xff) << 8) |
|
||||
((buffer[_position + 3] & 0xff));
|
||||
_position += 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t NativeByteBuffer::readInt64(bool *error) {
|
||||
if (_position + 8 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read int64 error");
|
||||
return 0;
|
||||
}
|
||||
int64_t result = ((int64_t) (buffer[_position] & 0xff)) |
|
||||
((int64_t) (buffer[_position + 1] & 0xff) << 8) |
|
||||
((int64_t) (buffer[_position + 2] & 0xff) << 16) |
|
||||
((int64_t) (buffer[_position + 3] & 0xff) << 24) |
|
||||
((int64_t) (buffer[_position + 4] & 0xff) << 32) |
|
||||
((int64_t) (buffer[_position + 5] & 0xff) << 40) |
|
||||
((int64_t) (buffer[_position + 6] & 0xff) << 48) |
|
||||
((int64_t) (buffer[_position + 7] & 0xff) << 56);
|
||||
_position += 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t NativeByteBuffer::readByte(bool *error) {
|
||||
if (_position + 1 > _limit || calculateSizeOnly) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read byte error");
|
||||
return 0;
|
||||
}
|
||||
return buffer[_position++];
|
||||
}
|
||||
|
||||
bool NativeByteBuffer::readBool(bool *error) {
|
||||
uint32_t consructor = readUint32(error);
|
||||
if (consructor == 0x997275b5) {
|
||||
return true;
|
||||
} else if (consructor == 0xbc799737) {
|
||||
return false;
|
||||
}
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
if (LOGS_ENABLED) DEBUG_E("read bool error");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::readBytes(uint8_t *b, uint32_t length, bool *error) {
|
||||
if (length > _limit - _position || calculateSizeOnly) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read bytes error");
|
||||
return;
|
||||
}
|
||||
memcpy(b, buffer + _position, length);
|
||||
_position += length;
|
||||
}
|
||||
|
||||
ByteArray *NativeByteBuffer::readBytes(uint32_t length, bool *error) {
|
||||
if (length > _limit - _position || calculateSizeOnly) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read bytes error");
|
||||
return nullptr;
|
||||
}
|
||||
ByteArray *byteArray = new ByteArray(length);
|
||||
memcpy(byteArray->bytes, buffer + _position, sizeof(uint8_t) * length);
|
||||
_position += length;
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
std::string NativeByteBuffer::readString(bool *error) {
|
||||
uint32_t sl = 1;
|
||||
if (_position + 1 > _limit || calculateSizeOnly) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read string error");
|
||||
return std::string("");
|
||||
}
|
||||
uint32_t l = buffer[_position++];
|
||||
if (l >= 254) {
|
||||
if (_position + 3 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read string error");
|
||||
return std::string("");
|
||||
}
|
||||
l = buffer[_position] | (buffer[_position + 1] << 8) | (buffer[_position + 2] << 16);
|
||||
_position += 3;
|
||||
sl = 4;
|
||||
}
|
||||
uint32_t addition = (l + sl) % 4;
|
||||
if (addition != 0) {
|
||||
addition = 4 - addition;
|
||||
}
|
||||
if (_position + l + addition > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read string error");
|
||||
return std::string("");
|
||||
}
|
||||
std::string result = std::string((const char *) (buffer + _position), l);
|
||||
_position += l + addition;
|
||||
return result;
|
||||
}
|
||||
|
||||
ByteArray *NativeByteBuffer::readByteArray(bool *error) {
|
||||
uint32_t sl = 1;
|
||||
if (_position + 1 > _limit || calculateSizeOnly) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read byte array error");
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t l = buffer[_position++];
|
||||
if (l >= 254) {
|
||||
if (_position + 3 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read byte array error");
|
||||
return nullptr;
|
||||
}
|
||||
l = buffer[_position] | (buffer[_position + 1] << 8) | (buffer[_position + 2] << 16);
|
||||
_position += 3;
|
||||
sl = 4;
|
||||
}
|
||||
uint32_t addition = (l + sl) % 4;
|
||||
if (addition != 0) {
|
||||
addition = 4 - addition;
|
||||
}
|
||||
if (_position + l + addition > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read byte array error");
|
||||
return nullptr;
|
||||
}
|
||||
ByteArray *result = new ByteArray(l);
|
||||
memcpy(result->bytes, buffer + _position, sizeof(uint8_t) * l);
|
||||
_position += l + addition;
|
||||
return result;
|
||||
}
|
||||
|
||||
NativeByteBuffer *NativeByteBuffer::readByteBuffer(bool copy, bool *error) {
|
||||
uint32_t sl = 1;
|
||||
if (_position + 1 > _limit || calculateSizeOnly) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read byte buffer error");
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t l = buffer[_position++];
|
||||
if (l >= 254) {
|
||||
if (_position + 3 > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read byte buffer error");
|
||||
return nullptr;
|
||||
}
|
||||
l = buffer[_position] | (buffer[_position + 1] << 8) | (buffer[_position + 2] << 16);
|
||||
_position += 3;
|
||||
sl = 4;
|
||||
}
|
||||
uint32_t addition = (l + sl) % 4;
|
||||
if (addition != 0) {
|
||||
addition = 4 - addition;
|
||||
}
|
||||
if (_position + l + addition > _limit) {
|
||||
if (error != nullptr) {
|
||||
*error = true;
|
||||
}
|
||||
if (LOGS_ENABLED) DEBUG_E("read byte buffer error");
|
||||
return nullptr;
|
||||
}
|
||||
NativeByteBuffer *result = nullptr;
|
||||
if (copy) {
|
||||
result = BuffersStorage::getInstance().getFreeBuffer(l);
|
||||
memcpy(result->buffer, buffer + _position, sizeof(uint8_t) * l);
|
||||
} else {
|
||||
result = new NativeByteBuffer(buffer + _position, l);
|
||||
}
|
||||
_position += l + addition;
|
||||
return result;
|
||||
}
|
||||
|
||||
double NativeByteBuffer::readDouble(bool *error) {
|
||||
double value;
|
||||
int64_t value2 = readInt64(error);
|
||||
memcpy(&value, &value2, sizeof(double));
|
||||
return value;
|
||||
}
|
||||
|
||||
void NativeByteBuffer::reuse() {
|
||||
if (sliced) {
|
||||
return;
|
||||
}
|
||||
BuffersStorage::getInstance().reuseFreeBuffer(this);
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
jobject NativeByteBuffer::getJavaByteBuffer() {
|
||||
if (javaByteBuffer == nullptr && javaVm != nullptr) {
|
||||
JNIEnv *env = 0;
|
||||
if (javaVm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
|
||||
if (LOGS_ENABLED) DEBUG_E("can't get jnienv");
|
||||
exit(1);
|
||||
}
|
||||
javaByteBuffer = env->NewDirectByteBuffer(buffer, _capacity);
|
||||
if (javaByteBuffer == nullptr) {
|
||||
if (LOGS_ENABLED) DEBUG_E("can't allocate NativeByteBuffer buffer");
|
||||
exit(1);
|
||||
}
|
||||
DEBUG_REF("nativebytebuffer");
|
||||
jobject globalRef = env->NewGlobalRef(javaByteBuffer);
|
||||
env->DeleteLocalRef(javaByteBuffer);
|
||||
javaByteBuffer = globalRef;
|
||||
}
|
||||
return javaByteBuffer;
|
||||
}
|
||||
#endif
|
||||
107
TMessagesProj/jni/tgnet/NativeByteBuffer.h
Normal file
107
TMessagesProj/jni/tgnet/NativeByteBuffer.h
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef NATIVEBYTEBUFFER_H
|
||||
#define NATIVEBYTEBUFFER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
class ByteArray;
|
||||
|
||||
class NativeByteBuffer {
|
||||
|
||||
public:
|
||||
NativeByteBuffer(uint32_t size);
|
||||
NativeByteBuffer(bool calculate);
|
||||
NativeByteBuffer(uint8_t *buff, uint32_t length);
|
||||
~NativeByteBuffer();
|
||||
|
||||
uint32_t position();
|
||||
void position(uint32_t position);
|
||||
uint32_t limit();
|
||||
void limit(uint32_t limit);
|
||||
uint32_t capacity();
|
||||
uint32_t remaining();
|
||||
bool hasRemaining();
|
||||
void rewind();
|
||||
void compact();
|
||||
void flip();
|
||||
void clear();
|
||||
void skip(uint32_t length);
|
||||
void clearCapacity();
|
||||
uint8_t *bytes();
|
||||
|
||||
void writeInt32(int32_t x, bool *error);
|
||||
void writeInt64(int64_t x, bool *error);
|
||||
void writeBool(bool value, bool *error);
|
||||
void writeBytes(uint8_t *b, uint32_t length, bool *error);
|
||||
void writeBytes(uint8_t *b, uint32_t offset, uint32_t length, bool *error);
|
||||
void writeBytes(ByteArray *b, bool *error);
|
||||
void writeBytes(NativeByteBuffer *b, bool *error);
|
||||
void writeByte(uint8_t i, bool *error);
|
||||
void writeString(std::string s, bool *error);
|
||||
void writeByteArray(uint8_t *b, uint32_t offset, uint32_t length, bool *error);
|
||||
void writeByteArray(uint8_t *b, uint32_t length, bool *error);
|
||||
void writeByteArray(NativeByteBuffer *b, bool *error);
|
||||
void writeByteArray(ByteArray *b, bool *error);
|
||||
void writeDouble(double d, bool *error);
|
||||
void writeInt32(int32_t x);
|
||||
void writeInt64(int64_t x);
|
||||
void writeBool(bool value);
|
||||
void writeBytes(uint8_t *b, uint32_t length);
|
||||
void writeBytes(uint8_t *b, uint32_t offset, uint32_t length);
|
||||
void writeBytes(ByteArray *b);
|
||||
void writeBytes(NativeByteBuffer *b);
|
||||
void writeByte(uint8_t i);
|
||||
void writeString(std::string s);
|
||||
void writeByteArray(uint8_t *b, uint32_t offset, uint32_t length);
|
||||
void writeByteArray(uint8_t *b, uint32_t length);
|
||||
void writeByteArray(NativeByteBuffer *b);
|
||||
void writeByteArray(ByteArray *b);
|
||||
void writeDouble(double d);
|
||||
|
||||
uint32_t readUint32(bool *error);
|
||||
uint64_t readUint64(bool *error);
|
||||
int32_t readInt32(bool *error);
|
||||
int32_t readBigInt32(bool *error);
|
||||
int64_t readInt64(bool *error);
|
||||
uint8_t readByte(bool *error);
|
||||
bool readBool(bool *error);
|
||||
void readBytes(uint8_t *b, uint32_t length, bool *error);
|
||||
ByteArray *readBytes(uint32_t length, bool *error);
|
||||
std::string readString(bool *error);
|
||||
ByteArray *readByteArray(bool *error);
|
||||
NativeByteBuffer *readByteBuffer(bool copy, bool *error);
|
||||
double readDouble(bool *error);
|
||||
|
||||
void reuse();
|
||||
#ifdef ANDROID
|
||||
jobject getJavaByteBuffer();
|
||||
#endif
|
||||
|
||||
private:
|
||||
void writeBytesInternal(uint8_t *b, uint32_t offset, uint32_t length);
|
||||
|
||||
uint8_t *buffer = nullptr;
|
||||
bool calculateSizeOnly = false;
|
||||
bool sliced = false;
|
||||
uint32_t _position = 0;
|
||||
uint32_t _limit = 0;
|
||||
uint32_t _capacity = 0;
|
||||
bool bufferOwner = true;
|
||||
#ifdef ANDROID
|
||||
jobject javaByteBuffer = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
21
TMessagesProj/jni/tgnet/ProxyCheckInfo.cpp
Normal file
21
TMessagesProj/jni/tgnet/ProxyCheckInfo.cpp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include "ProxyCheckInfo.h"
|
||||
#include "ConnectionsManager.h"
|
||||
#include "FileLog.h"
|
||||
|
||||
ProxyCheckInfo::~ProxyCheckInfo() {
|
||||
#ifdef ANDROID
|
||||
if (ptr1 != nullptr) {
|
||||
DEBUG_DELREF("tgnet (2) request ptr1");
|
||||
jniEnv[instanceNum]->DeleteGlobalRef(ptr1);
|
||||
ptr1 = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
41
TMessagesProj/jni/tgnet/ProxyCheckInfo.h
Normal file
41
TMessagesProj/jni/tgnet/ProxyCheckInfo.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef PROXYCHECKINFO_H
|
||||
#define PROXYCHECKINFO_H
|
||||
|
||||
#include <sstream>
|
||||
#include "Defines.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
class ProxyCheckInfo {
|
||||
|
||||
public:
|
||||
~ProxyCheckInfo();
|
||||
|
||||
int32_t connectionNum = 0;
|
||||
int32_t requestToken = 0;
|
||||
std::string address;
|
||||
uint16_t port = 1080;
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string secret;
|
||||
int64_t pingId = 0;
|
||||
onRequestTimeFunc onRequestTime;
|
||||
int32_t instanceNum = 0;
|
||||
|
||||
#ifdef ANDROID
|
||||
jobject ptr1 = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
93
TMessagesProj/jni/tgnet/Request.cpp
Normal file
93
TMessagesProj/jni/tgnet/Request.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include "Request.h"
|
||||
#include "TLObject.h"
|
||||
#include "MTProtoScheme.h"
|
||||
#include "ConnectionsManager.h"
|
||||
#include "Datacenter.h"
|
||||
#include "Connection.h"
|
||||
#include "FileLog.h"
|
||||
|
||||
Request::Request(int32_t instance, int32_t token, ConnectionType type, uint32_t flags, uint32_t datacenter, onCompleteFunc completeFunc, onQuickAckFunc quickAckFunc, onWriteToSocketFunc writeToSocketFunc, onRequestClearFunc onClearFunc) {
|
||||
requestToken = token;
|
||||
connectionType = type;
|
||||
requestFlags = flags;
|
||||
datacenterId = datacenter;
|
||||
onCompleteRequestCallback = completeFunc;
|
||||
onQuickAckCallback = quickAckFunc;
|
||||
onWriteToSocketCallback = writeToSocketFunc;
|
||||
onRequestClearCallback = onClearFunc;
|
||||
dataType = (uint8_t) (requestFlags >> 24);
|
||||
instanceNum = instance;
|
||||
}
|
||||
|
||||
Request::~Request() {
|
||||
if (!completedSent && !disableClearCallback && onRequestClearCallback != nullptr) {
|
||||
onRequestClearCallback();
|
||||
}
|
||||
}
|
||||
|
||||
void Request::addRespondMessageId(int64_t id) {
|
||||
respondsToMessageIds.push_back(messageId);
|
||||
}
|
||||
|
||||
bool Request::respondsToMessageId(int64_t id) {
|
||||
return messageId == id || std::find(respondsToMessageIds.begin(), respondsToMessageIds.end(), id) != respondsToMessageIds.end();
|
||||
}
|
||||
|
||||
void Request::clear(bool time) {
|
||||
messageId = 0;
|
||||
messageSeqNo = 0;
|
||||
connectionToken = 0;
|
||||
if (time) {
|
||||
startTime = 0;
|
||||
minStartTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Request::onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t requestMsgId, int32_t dcId) {
|
||||
if (onCompleteRequestCallback != nullptr && (result != nullptr || error != nullptr)) {
|
||||
completedSent = true;
|
||||
onCompleteRequestCallback(result, error, networkType, responseTime, requestMsgId, dcId);
|
||||
}
|
||||
}
|
||||
|
||||
void Request::onWriteToSocket() {
|
||||
if (onWriteToSocketCallback != nullptr) {
|
||||
onWriteToSocketCallback();
|
||||
}
|
||||
}
|
||||
|
||||
bool Request::hasInitFlag() {
|
||||
return isInitRequest || isInitMediaRequest;
|
||||
}
|
||||
|
||||
bool Request::isMediaRequest() {
|
||||
return Connection::isMediaConnectionType(connectionType);
|
||||
}
|
||||
|
||||
bool Request::isCancelRequest() {
|
||||
return (requestFlags & RequestFlagIsCancel) != 0;
|
||||
}
|
||||
|
||||
bool Request::needInitRequest(Datacenter *datacenter, uint32_t currentVersion) {
|
||||
bool media = PFS_ENABLED && datacenter != nullptr && isMediaRequest() && datacenter->hasMediaAddress();
|
||||
return !media && datacenter->lastInitVersion != currentVersion || media && datacenter->lastInitMediaVersion != currentVersion;
|
||||
}
|
||||
|
||||
void Request::onQuickAck() {
|
||||
if (onQuickAckCallback != nullptr) {
|
||||
onQuickAckCallback();
|
||||
}
|
||||
}
|
||||
|
||||
TLObject *Request::getRpcRequest() {
|
||||
return rpcRequest.get();
|
||||
}
|
||||
83
TMessagesProj/jni/tgnet/Request.h
Normal file
83
TMessagesProj/jni/tgnet/Request.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef REQUEST_H
|
||||
#define REQUEST_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include "Defines.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
class TLObject;
|
||||
class TL_error;
|
||||
class Datacenter;
|
||||
|
||||
class Request {
|
||||
|
||||
public:
|
||||
Request(int32_t instance, int32_t token, ConnectionType type, uint32_t flags, uint32_t datacenter, onCompleteFunc completeFunc, onQuickAckFunc quickAckFunc, onWriteToSocketFunc writeToSocketFunc, onRequestClearFunc onClearFunc);
|
||||
~Request();
|
||||
|
||||
int64_t messageId = 0;
|
||||
int32_t messageSeqNo = 0;
|
||||
uint32_t datacenterId = 0;
|
||||
uint32_t connectionToken = 0;
|
||||
int32_t requestToken = 0;
|
||||
uint32_t retryCount = 0;
|
||||
bool failedBySalt = false;
|
||||
int32_t failedByFloodWait = 0;
|
||||
bool awaitingIntegrityCheck = false;
|
||||
bool awaitingCaptchaCheck = false;
|
||||
bool premiumFloodWait = false;
|
||||
ConnectionType connectionType;
|
||||
uint32_t requestFlags;
|
||||
bool completedSent = false;
|
||||
bool completed = false;
|
||||
bool cancelled = false;
|
||||
bool isInitRequest = false;
|
||||
bool isInitMediaRequest = false;
|
||||
uint8_t dataType = 0;
|
||||
int32_t serializedLength = 0;
|
||||
int32_t startTime = 0;
|
||||
int64_t startTimeMillis = 0;
|
||||
int32_t minStartTime = 0;
|
||||
int32_t lastResendTime = 0;
|
||||
bool isResending = false;
|
||||
int32_t instanceNum = 0;
|
||||
uint32_t serverFailureCount = 0;
|
||||
TLObject *rawRequest;
|
||||
std::unique_ptr<TLObject> rpcRequest;
|
||||
onCompleteFunc onCompleteRequestCallback;
|
||||
onQuickAckFunc onQuickAckCallback;
|
||||
onWriteToSocketFunc onWriteToSocketCallback;
|
||||
bool disableClearCallback = false;
|
||||
bool doNotClearOnDrop = false;
|
||||
int32_t clearAfter = 0;
|
||||
onRequestClearFunc onRequestClearCallback;
|
||||
|
||||
void addRespondMessageId(int64_t id);
|
||||
bool respondsToMessageId(int64_t id);
|
||||
void clear(bool time);
|
||||
void onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msg_id, int32_t dcId);
|
||||
void onQuickAck();
|
||||
void onWriteToSocket();
|
||||
bool isMediaRequest();
|
||||
bool isCancelRequest();
|
||||
bool hasInitFlag();
|
||||
bool needInitRequest(Datacenter *datacenter, uint32_t currentVersion);
|
||||
TLObject *getRpcRequest();
|
||||
|
||||
private:
|
||||
std::vector<int64_t> respondsToMessageIds;
|
||||
};
|
||||
|
||||
#endif
|
||||
38
TMessagesProj/jni/tgnet/TLObject.cpp
Normal file
38
TMessagesProj/jni/tgnet/TLObject.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include "TLObject.h"
|
||||
#include "NativeByteBuffer.h"
|
||||
|
||||
thread_local NativeByteBuffer *sizeCalculatorBuffer = new NativeByteBuffer(true);
|
||||
|
||||
TLObject::~TLObject() {
|
||||
|
||||
}
|
||||
|
||||
void TLObject::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
|
||||
|
||||
}
|
||||
|
||||
void TLObject::serializeToStream(NativeByteBuffer *stream) {
|
||||
|
||||
}
|
||||
|
||||
TLObject *TLObject::deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t TLObject::getObjectSize() {
|
||||
sizeCalculatorBuffer->clearCapacity();
|
||||
serializeToStream(sizeCalculatorBuffer);
|
||||
return sizeCalculatorBuffer->capacity();
|
||||
}
|
||||
|
||||
bool TLObject::isNeedLayer() {
|
||||
return false;
|
||||
}
|
||||
30
TMessagesProj/jni/tgnet/TLObject.h
Normal file
30
TMessagesProj/jni/tgnet/TLObject.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef TLOBJECT_H
|
||||
#define TLOBJECT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "Defines.h"
|
||||
|
||||
class NativeByteBuffer;
|
||||
|
||||
class TLObject {
|
||||
|
||||
public:
|
||||
virtual ~TLObject();
|
||||
virtual void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
|
||||
virtual void serializeToStream(NativeByteBuffer *stream);
|
||||
virtual TLObject *deserializeResponse(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
|
||||
uint32_t getObjectSize();
|
||||
virtual bool isNeedLayer();
|
||||
|
||||
fillParamsFunc initFunc;
|
||||
};
|
||||
|
||||
#endif
|
||||
62
TMessagesProj/jni/tgnet/Timer.cpp
Normal file
62
TMessagesProj/jni/tgnet/Timer.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#include "Timer.h"
|
||||
#include "FileLog.h"
|
||||
#include "EventObject.h"
|
||||
#include "ConnectionsManager.h"
|
||||
|
||||
Timer::Timer(int32_t instance, std::function<void()> function) {
|
||||
eventObject = new EventObject(this, EventObjectTypeTimer);
|
||||
instanceNum = instance;
|
||||
callback = function;
|
||||
}
|
||||
|
||||
Timer::~Timer() {
|
||||
stop();
|
||||
if (eventObject != nullptr) {
|
||||
delete eventObject;
|
||||
eventObject = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::start() {
|
||||
if (started || timeout == 0) {
|
||||
return;
|
||||
}
|
||||
started = true;
|
||||
ConnectionsManager::getInstance(instanceNum).scheduleEvent(eventObject, timeout);
|
||||
}
|
||||
|
||||
void Timer::stop() {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
started = false;
|
||||
ConnectionsManager::getInstance(instanceNum).removeEvent(eventObject);
|
||||
}
|
||||
|
||||
void Timer::setTimeout(uint32_t ms, bool repeat) {
|
||||
if (ms == timeout) {
|
||||
return;
|
||||
}
|
||||
repeatable = repeat;
|
||||
timeout = ms;
|
||||
if (started) {
|
||||
ConnectionsManager::getInstance(instanceNum).removeEvent(eventObject);
|
||||
ConnectionsManager::getInstance(instanceNum).scheduleEvent(eventObject, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::onEvent() {
|
||||
callback();
|
||||
if (LOGS_ENABLED) DEBUG_D("timer(%p) call", this);
|
||||
if (started && repeatable && timeout != 0) {
|
||||
ConnectionsManager::getInstance(instanceNum).scheduleEvent(eventObject, timeout);
|
||||
}
|
||||
}
|
||||
41
TMessagesProj/jni/tgnet/Timer.h
Normal file
41
TMessagesProj/jni/tgnet/Timer.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* This is the source code of tgnet library v. 1.1
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2015-2018.
|
||||
*/
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <functional>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
class EventObject;
|
||||
|
||||
class Timer {
|
||||
|
||||
public:
|
||||
Timer(int32_t instance, std::function<void()> function);
|
||||
~Timer();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void setTimeout(uint32_t ms, bool repeat);
|
||||
|
||||
private:
|
||||
void onEvent();
|
||||
|
||||
bool started = false;
|
||||
bool repeatable = false;
|
||||
int32_t instanceNum;
|
||||
uint32_t timeout = 0;
|
||||
std::function<void()> callback;
|
||||
EventObject *eventObject;
|
||||
|
||||
friend class EventObject;
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue