summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorAlexander Lantsev <aunsane@gmail.com>2015-02-01 09:23:58 +0000
committerAlexander Lantsev <aunsane@gmail.com>2015-02-01 09:23:58 +0000
commit09fa77d73829e76123ac7a9b73bc90def12e9d9c (patch)
tree20c5e5a4fc83c672e0505db662e88c16635c5d9d /protocols
parenta76b0175b2cb203f4a0cc68c99588f23ef945eb6 (diff)
Tox:
- refactoring - updated tox core git-svn-id: http://svn.miranda-ng.org/main/trunk@11970 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Tox/Tox_12.vcxproj1
-rw-r--r--protocols/Tox/Tox_12.vcxproj.filters3
-rw-r--r--protocols/Tox/bin/x64/libtox.dllbin3959506 -> 3959539 bytes
-rw-r--r--protocols/Tox/bin/x86/libtox.dllbin3301258 -> 3301804 bytes
-rw-r--r--protocols/Tox/include/tox.h25
-rw-r--r--protocols/Tox/src/common.h3
-rw-r--r--protocols/Tox/src/tox_account.cpp19
-rw-r--r--protocols/Tox/src/tox_address.h150
-rw-r--r--protocols/Tox/src/tox_avatars.cpp4
-rw-r--r--protocols/Tox/src/tox_contacts.cpp122
-rw-r--r--protocols/Tox/src/tox_messages.cpp20
-rw-r--r--protocols/Tox/src/tox_profile.cpp9
-rw-r--r--protocols/Tox/src/tox_proto.cpp47
-rw-r--r--protocols/Tox/src/tox_proto.h20
-rw-r--r--protocols/Tox/src/tox_search.cpp42
-rw-r--r--protocols/Tox/src/tox_transfer.cpp178
-rw-r--r--protocols/Tox/src/tox_transfer.h35
-rw-r--r--protocols/Tox/src/tox_utils.cpp37
18 files changed, 425 insertions, 290 deletions
diff --git a/protocols/Tox/Tox_12.vcxproj b/protocols/Tox/Tox_12.vcxproj
index c1e0ab8b2e..c29ce07566 100644
--- a/protocols/Tox/Tox_12.vcxproj
+++ b/protocols/Tox/Tox_12.vcxproj
@@ -199,6 +199,7 @@
<ItemGroup>
<ClInclude Include="src\common.h" />
<ClInclude Include="src\resource.h" />
+ <ClInclude Include="src\tox_address.h" />
<ClInclude Include="src\tox_bootstrap.h" />
<ClInclude Include="src\tox_dns.h" />
<ClInclude Include="src\tox_proto.h" />
diff --git a/protocols/Tox/Tox_12.vcxproj.filters b/protocols/Tox/Tox_12.vcxproj.filters
index fee1c08363..0a3ec927ab 100644
--- a/protocols/Tox/Tox_12.vcxproj.filters
+++ b/protocols/Tox/Tox_12.vcxproj.filters
@@ -36,6 +36,9 @@
<ClInclude Include="src\tox_transfer.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\tox_address.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\tox_proto.cpp">
diff --git a/protocols/Tox/bin/x64/libtox.dll b/protocols/Tox/bin/x64/libtox.dll
index 6c68460b7c..dfe99f697f 100644
--- a/protocols/Tox/bin/x64/libtox.dll
+++ b/protocols/Tox/bin/x64/libtox.dll
Binary files differ
diff --git a/protocols/Tox/bin/x86/libtox.dll b/protocols/Tox/bin/x86/libtox.dll
index 39f1a65585..dca28deeaa 100644
--- a/protocols/Tox/bin/x86/libtox.dll
+++ b/protocols/Tox/bin/x86/libtox.dll
Binary files differ
diff --git a/protocols/Tox/include/tox.h b/protocols/Tox/include/tox.h
index db1b10331c..ee678cc1f5 100644
--- a/protocols/Tox/include/tox.h
+++ b/protocols/Tox/include/tox.h
@@ -38,11 +38,14 @@ extern "C" {
#define TOX_MAX_STATUSMESSAGE_LENGTH 1007
#define TOX_MAX_FRIENDREQUEST_LENGTH 1016
-#define TOX_CLIENT_ID_SIZE 32
+#define TOX_PUBLIC_KEY_SIZE 32
+/* TODO: remove */
+#define TOX_CLIENT_ID_SIZE TOX_PUBLIC_KEY_SIZE
+
#define TOX_AVATAR_MAX_DATA_LENGTH 16384
#define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32
-#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
+#define TOX_FRIEND_ADDRESS_SIZE (TOX_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
#define TOX_ENABLE_IPV6_DEFAULT 1
@@ -97,7 +100,7 @@ typedef struct Tox Tox;
*/
/* return TOX_FRIEND_ADDRESS_SIZE byte address to give to others.
- * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
+ * format: [public_key (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
*/
void tox_get_address(const Tox *tox, uint8_t *address);
@@ -124,18 +127,18 @@ int32_t tox_add_friend(Tox *tox, const uint8_t *address, const uint8_t *data, ui
* return the friend number if success.
* return -1 if failure.
*/
-int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *client_id);
+int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *public_key);
/* return the friend number associated to that client id.
return -1 if no such friend */
-int32_t tox_get_friend_number(const Tox *tox, const uint8_t *client_id);
+int32_t tox_get_friend_number(const Tox *tox, const uint8_t *public_key);
-/* Copies the public key associated to that friend id into client_id buffer.
- * Make sure that client_id is of size CLIENT_ID_SIZE.
+/* Copies the public key associated to that friend id into public_key buffer.
+ * Make sure that public_key is of size TOX_PUBLIC_KEY_SIZE.
* return 0 if success.
* return -1 if failure.
*/
-int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *client_id);
+int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *public_key);
/* Remove a friend.
*
@@ -500,13 +503,13 @@ int tox_del_groupchat(Tox *tox, int groupnumber);
*/
int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t *name);
-/* Copy the public key of peernumber who is in groupnumber to pk.
- * pk must be TOX_CLIENT_ID_SIZE long.
+/* Copy the public key of peernumber who is in groupnumber to public_key.
+ * public_key must be TOX_PUBLIC_KEY_SIZE long.
*
* returns 0 on success
* returns -1 on failure
*/
-int tox_group_peer_pubkey(const Tox *tox, int groupnumber, int peernumber, uint8_t *pk);
+int tox_group_peer_pubkey(const Tox *tox, int groupnumber, int peernumber, uint8_t *public_key);
/* invite friendnumber to groupnumber
* return 0 on success
diff --git a/protocols/Tox/src/common.h b/protocols/Tox/src/common.h
index 1250b10fd7..93b22b718e 100644
--- a/protocols/Tox/src/common.h
+++ b/protocols/Tox/src/common.h
@@ -9,7 +9,7 @@
#include <string>
#include <sstream>
#include <iomanip>
-#include <vector>
+//#include <vector>
#include <regex>
#include <map>
@@ -37,6 +37,7 @@
#include "version.h"
#include "resource.h"
+#include "tox_address.h"
#include "tox_transfer.h"
#include "tox_proto.h"
diff --git a/protocols/Tox/src/tox_account.cpp b/protocols/Tox/src/tox_account.cpp
index 3b4f61b32b..2aa3081442 100644
--- a/protocols/Tox/src/tox_account.cpp
+++ b/protocols/Tox/src/tox_account.cpp
@@ -84,15 +84,14 @@ bool CToxProto::InitToxCore()
tox_callback_avatar_info(tox, OnGotFriendAvatarInfo, this);
tox_callback_avatar_data(tox, OnGotFriendAvatarData, this);
- std::vector<uint8_t> pubKey(TOX_FRIEND_ADDRESS_SIZE);
- tox_get_address(tox, &pubKey[0]);
- std::string address = DataToHexString(pubKey);
- setString(NULL, TOX_SETTINGS_ID, address.c_str());
+ uint8_t data[TOX_FRIEND_ADDRESS_SIZE];
+ tox_get_address(tox, data);
+ ToxHexAddress address(data, TOX_FRIEND_ADDRESS_SIZE);
+ setString(NULL, TOX_SETTINGS_ID, address);
int size = tox_get_self_name_size(tox);
- std::vector<uint8_t> username(size);
- tox_get_self_name(tox, &username[0]);
- std::string nick(username.begin(), username.end());
+ std::string nick(size, 0);
+ tox_get_self_name(tox, (uint8_t*)nick.data());
setWString("Nick", ptrW(Utf8DecodeW(nick.c_str())));
std::tstring avatarPath = GetAvatarFilePath();
@@ -117,7 +116,7 @@ bool CToxProto::InitToxCore()
void CToxProto::UninitToxCore()
{
ptrA nickname(mir_utf8encodeW(ptrT(getTStringA("Nick"))));
- tox_set_name(tox, (uint8_t*)(char*)nickname, (uint16_t)strlen(nickname));
+ tox_set_name(tox, (uint8_t*)(char*)nickname, mir_strlen(nickname));
SaveToxProfile();
if (password != NULL)
@@ -143,8 +142,6 @@ void CToxProto::DoBootstrap()
void CToxProto::DoTox()
{
tox_do(tox);
-
- //PulseEvent(hToxEvent);
uint32_t interval = tox_do_interval(tox);
Sleep(interval);
}
@@ -178,7 +175,7 @@ void CToxProto::PollingThread(void*)
isConnected = true;
debugLogA("CToxProto::PollingThread: successfuly connected to DHT");
- LoadFriendList();
+ ForkThread(&CToxProto::LoadFriendList, NULL);
debugLogA("CToxProto::PollingThread: changing status from %i to %i", ID_STATUS_CONNECTING, m_iDesiredStatus);
m_iStatus = m_iDesiredStatus;
diff --git a/protocols/Tox/src/tox_address.h b/protocols/Tox/src/tox_address.h
new file mode 100644
index 0000000000..b8ceccefae
--- /dev/null
+++ b/protocols/Tox/src/tox_address.h
@@ -0,0 +1,150 @@
+#ifndef _TOX_ADDRESS_H_
+#define _TOX_ADDRESS_H_
+
+class ToxHexAddress;
+class ToxBinAddress;
+
+class ToxHexAddress
+{
+private:
+ std::string hexData;
+public:
+ ToxHexAddress(const char *hex) : hexData(hex) { }
+ ToxHexAddress(const std::string &hex) : hexData(hex) { }
+ ToxHexAddress(const ToxHexAddress &address) : hexData(address.hexData) { }
+ ToxHexAddress(const std::vector<uint8_t> &bin)
+ {
+ this->ToxHexAddress::ToxHexAddress(bin.data(), bin.size());
+ }
+ ToxHexAddress(const uint8_t *bin, int size = TOX_FRIEND_ADDRESS_SIZE)
+ {
+ char *hex = (char*)mir_alloc(size * 2 + 1);
+ hexData = bin2hex(bin, size, hex);
+ std::transform(hexData.begin(), hexData.end(), hexData.begin(), ::toupper);
+ mir_free(hex);
+ }
+ const size_t GetLength() const
+ {
+ return hexData.length();
+ }
+ const ToxHexAddress GetPubKey() const
+ {
+ ToxHexAddress pubKey = hexData.substr(0, TOX_PUBLIC_KEY_SIZE * 2).c_str();
+ return pubKey;
+ }
+ operator const char*() const
+ {
+ return hexData.c_str();
+ }
+ ToxBinAddress ToBin() const;
+};
+
+class ToxBinAddress
+{
+private:
+ std::vector<uint8_t> binData;
+public:
+ ToxBinAddress(const ToxBinAddress &address) : binData(address.binData) { }
+ ToxBinAddress(const std::vector<uint8_t> &bin) : binData(bin) { }
+ ToxBinAddress(const uint8_t *bin, int size = TOX_FRIEND_ADDRESS_SIZE) : binData(bin, bin + size) { }
+ ToxBinAddress(const std::string &hex)
+ {
+ this->ToxBinAddress::ToxBinAddress(hex.c_str());
+ }
+ ToxBinAddress(const char *hex)
+ {
+ char *endptr;
+ const char *pos = hex;
+ int size = mir_strlen(hex) / 2;
+ uint8_t *result = (uint8_t*)mir_alloc(size);
+ for (int i = 0; i < size; i++)
+ {
+ char buf[5] = { '0', 'x', pos[0], pos[1], 0 };
+ binData.push_back((uint8_t)strtol(buf, &endptr, 0));
+ pos += 2;
+ }
+ }
+ const ToxBinAddress GetPubKey() const
+ {
+ ToxBinAddress pubKey(binData.data(), TOX_PUBLIC_KEY_SIZE);
+ return pubKey;
+ }
+ operator const uint8_t*() const
+ {
+ return binData.data();
+ }
+ ToxHexAddress ToHex() const
+ {
+ ToxHexAddress hex(binData.data(), binData.size());
+ return hex;
+ }
+};
+
+ToxBinAddress ToxHexAddress::ToBin() const
+{
+ ToxBinAddress bin(hexData.c_str());
+ return bin;
+}
+
+/*class ToxAddress
+{
+private:
+ std::string hexData;
+
+ class ToxBytes
+ {
+ private:
+ uint8_t *bytes;
+
+ public:
+ ToxBytes(uint8_t *bytes) : bytes(bytes) { }
+ ~ToxBytes() { if (bytes) mir_free(bytes); }
+
+ operator const uint8_t*() { return bytes; }
+ };
+
+public:
+ ToxAddress(const char *hex) : hexData(hex) { }
+ ToxAddress(const std::string &hex) : hexData(hex) { }
+ ToxAddress(const ToxAddress &address) : hexData(address.hexData) { }
+ ToxAddress(const uint8_t *bin, int size = TOX_FRIEND_ADDRESS_SIZE)
+ //: binData(bin, bin + size)
+ {
+ char *hex = (char*)mir_alloc(size * 2 + 1);
+ std::string hexData = bin2hex(bin, size, hex);
+ std::transform(hexData.begin(), hexData.end(), hexData.begin(), ::toupper);
+ //mir_free(hex);
+ }
+
+ ~ToxAddress()
+ {
+ int i = 0;
+ }
+
+ operator const char*() const
+ {
+ return hexData.c_str();
+ }
+
+ ToxBytes AsBytes() const
+ {
+ char *endptr;
+ const char *pos = hexData.c_str();
+ int size = hexData.length() / 2;
+ uint8_t *result = (uint8_t*)mir_alloc(size);
+ for (int i = 0; i < size; i++)
+ {
+ char buf[5] = { '0', 'x', pos[0], pos[1], 0 };
+ result[i] = (uint8_t)strtol(buf, &endptr, 0);
+ pos += 2;
+ }
+ return ToxBytes(result);
+ }
+
+ std::string AsPubKey() const
+ {
+ return hexData.substr(0, TOX_PUBLIC_KEY_SIZE * 2).c_str();
+ }
+};*/
+
+#endif //_TOX_ADDRESS_H_ \ No newline at end of file
diff --git a/protocols/Tox/src/tox_avatars.cpp b/protocols/Tox/src/tox_avatars.cpp
index b69c462559..8f4410c5f3 100644
--- a/protocols/Tox/src/tox_avatars.cpp
+++ b/protocols/Tox/src/tox_avatars.cpp
@@ -196,7 +196,7 @@ void CToxProto::OnGotFriendAvatarInfo(Tox *tox, int32_t number, uint8_t format,
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->GetContact(number);
if (hContact)
{
std::tstring path = proto->GetAvatarFilePath(hContact);
@@ -232,7 +232,7 @@ void CToxProto::OnGotFriendAvatarData(Tox *tox, int32_t number, uint8_t format,
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->GetContact(number);
if (hContact)
{
db_set_blob(hContact, proto->m_szModuleName, TOX_SETTINGS_AVATAR_HASH, hash, TOX_HASH_LENGTH);
diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp
index 30c9fcc486..0808837727 100644
--- a/protocols/Tox/src/tox_contacts.cpp
+++ b/protocols/Tox/src/tox_contacts.cpp
@@ -41,14 +41,15 @@ MCONTACT CToxProto::GetContactFromAuthEvent(MEVENT hEvent)
return DbGetAuthEventContact(&dbei);
}
-bool CToxProto::IsMe(const std::string &id)
+MCONTACT CToxProto::GetContact(const int friendNumber)
{
- std::string ownId = getStringA(NULL, TOX_SETTINGS_ID);
-
- return strnicmp(id.c_str(), ownId.c_str(), TOX_CLIENT_ID_SIZE) == 0;
+ uint8_t data[TOX_PUBLIC_KEY_SIZE];
+ tox_get_client_id(tox, friendNumber, data);
+ ToxHexAddress pubKey(data, TOX_PUBLIC_KEY_SIZE);
+ return GetContact(pubKey);
}
-MCONTACT CToxProto::FindContact(const std::string &id)
+MCONTACT CToxProto::GetContact(const char *pubKey)
{
MCONTACT hContact = NULL;
for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName))
@@ -56,24 +57,14 @@ MCONTACT CToxProto::FindContact(const std::string &id)
DBVARIANT dbv;
if (!db_get(hContact, m_szModuleName, TOX_SETTINGS_ID, &dbv))
{
- std::string clientId;
-
- // temporary code for contact id conversion
- if (dbv.type == DBVT_BLOB)
+ std::string contactPubKey;
+ if (dbv.type == DBVT_ASCIIZ)
{
- std::vector<uint8_t> pubKey(dbv.cpbVal);
- memcpy(&pubKey[0], dbv.pbVal, dbv.cpbVal);
- clientId = DataToHexString(pubKey);
- delSetting(hContact, TOX_SETTINGS_ID);
- setString(hContact, TOX_SETTINGS_ID, clientId.c_str());
- }
- else if (dbv.type == DBVT_ASCIIZ)
- {
- clientId = dbv.pszVal;
+ contactPubKey = dbv.pszVal;
}
db_free(&dbv);
-
- if (mir_strcmpi(id.c_str(), clientId.c_str()) == 0)
+ // check only public key part of address
+ if (strnicmp(pubKey, contactPubKey.c_str(), TOX_PUBLIC_KEY_SIZE) == 0)
{
break;
}
@@ -82,25 +73,16 @@ MCONTACT CToxProto::FindContact(const std::string &id)
return hContact;
}
-MCONTACT CToxProto::FindContact(const int friendNumber)
+MCONTACT CToxProto::AddContact(const char *address, const std::tstring &dnsId, bool isTemporary)
{
- std::vector<uint8_t> clientId(TOX_CLIENT_ID_SIZE);
- tox_get_client_id(tox, friendNumber, clientId.data());
-
- std::string id = DataToHexString(clientId);
-
- return FindContact(id);
-}
-
-MCONTACT CToxProto::AddContact(const std::string &id, const std::tstring &dnsId, bool isTemporary)
-{
- MCONTACT hContact = FindContact(id);
+ MCONTACT hContact = GetContact(address);
if (!hContact)
{
hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)m_szModuleName);
- setString(hContact, TOX_SETTINGS_ID, id.c_str());
+ setString(hContact, TOX_SETTINGS_ID, address);
+
if (!dnsId.empty())
{
setTString(hContact, TOX_SETTINGS_DNS, dnsId.c_str());
@@ -124,7 +106,7 @@ MCONTACT CToxProto::AddContact(const std::string &id, const std::tstring &dnsId,
return hContact;
}
-void CToxProto::LoadFriendList()
+void CToxProto::LoadFriendList(void*)
{
uint32_t count = tox_count_friendlist(tox);
if (count > 0)
@@ -132,21 +114,24 @@ void CToxProto::LoadFriendList()
int32_t *friends = (int32_t*)mir_alloc(count * sizeof(int32_t));
tox_get_friendlist(tox, friends, count);
- std::vector<uint8_t> id(TOX_CLIENT_ID_SIZE);
+ uint8_t data[TOX_PUBLIC_KEY_SIZE];
for (uint32_t i = 0; i < count; ++i)
{
- tox_get_client_id(tox, friends[i], id.data());
- MCONTACT hContact = AddContact(DataToHexString(id), _T(""));
+ tox_get_client_id(tox, friends[i], data);
+ ToxHexAddress pubKey(data, TOX_PUBLIC_KEY_SIZE);
+ MCONTACT hContact = AddContact(pubKey, _T(""));
if (hContact)
{
delSetting(hContact, "Auth");
delSetting(hContact, "Grant");
int size = tox_get_name_size(tox, friends[i]);
- std::vector<uint8_t> username(size);
- tox_get_name(tox, friends[i], &username[0]);
- std::string nick(username.begin(), username.end());
- setWString(hContact, "Nick", ptrW(Utf8DecodeW(nick.c_str())));
+ if (size != TOX_ERROR)
+ {
+ std::string nick(size, 0);
+ tox_get_name(tox, friends[i], (uint8_t*)nick.data());
+ setWString(hContact, "Nick", ptrW(Utf8DecodeW(nick.c_str())));
+ }
uint64_t timestamp = tox_get_last_online(tox, friends[i]);
if (timestamp)
@@ -171,10 +156,8 @@ int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM lParam)
return 1;
}
- std::string id = getStringA(hContact, TOX_SETTINGS_ID);
- std::vector<uint8_t> clientId = HexStringToData(id);
-
- uint32_t number = tox_get_friend_number(tox, clientId.data());
+ ToxBinAddress pubKey = ptrA(getStringA(hContact, TOX_SETTINGS_ID));
+ int32_t number = tox_get_friend_number(tox, pubKey);
if (number == TOX_ERROR || tox_del_friend(tox, number) == TOX_ERROR)
{
return 1;
@@ -183,15 +166,12 @@ int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM lParam)
return 0;
}
-void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t *message, const uint16_t messageSize, void *arg)
+void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *data, const uint8_t *message, const uint16_t messageSize, void *arg)
{
CToxProto *proto = (CToxProto*)arg;
- // trim tox address to tox id
- std::vector<uint8_t> clientId(address, address + TOX_CLIENT_ID_SIZE);
- std::string id = proto->DataToHexString(clientId);
-
- MCONTACT hContact = proto->AddContact(id, _T(""));
+ ToxHexAddress address(data, TOX_FRIEND_ADDRESS_SIZE);
+ MCONTACT hContact = proto->AddContact(address, _T(""));
if (!hContact)
{
return;
@@ -202,7 +182,7 @@ void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t
PROTORECVEVENT pre = { 0 };
pre.flags = PREF_UTF;
pre.timestamp = time(NULL);
- pre.lParam = (DWORD)(sizeof(DWORD)* 2 + id.length() + messageSize + 5);
+ pre.lParam = (DWORD)(sizeof(DWORD) * 2 + address.GetLength() + messageSize + 5);
/*blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), firstName(ASCIIZ), lastName(ASCIIZ), id(ASCIIZ), reason(ASCIIZ)*/
PBYTE pBlob, pCurBlob;
@@ -213,9 +193,9 @@ void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t
*((PDWORD)pCurBlob) = (DWORD)hContact;
pCurBlob += sizeof(DWORD);
pCurBlob += 3;
- strcpy((char *)pCurBlob, id.c_str());
- pCurBlob += id.length() + 1;
- strcpy((char *)pCurBlob, (char*)message);
+ mir_strcpy((char *)pCurBlob, address);
+ pCurBlob += address.GetLength() + 1;
+ mir_strcpy((char *)pCurBlob, (char*)message);
pre.szMessage = (char*)pBlob;
ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre);
@@ -225,7 +205,7 @@ void CToxProto::OnFriendNameChange(Tox *tox, const int friendNumber, const uint8
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(friendNumber);
+ MCONTACT hContact = proto->GetContact(friendNumber);
if (hContact)
{
proto->setString(hContact, "Nick", (char*)name);
@@ -236,7 +216,7 @@ void CToxProto::OnStatusMessageChanged(Tox *tox, const int friendNumber, const u
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(friendNumber);
+ MCONTACT hContact = proto->GetContact(friendNumber);
if (hContact)
{
ptrW statusMessage(mir_utf8decodeW((char*)message));
@@ -248,7 +228,7 @@ void CToxProto::OnUserStatusChanged(Tox *tox, int32_t friendNumber, uint8_t user
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(friendNumber);
+ MCONTACT hContact = proto->GetContact(friendNumber);
if (hContact)
{
TOX_USERSTATUS userstatus = (TOX_USERSTATUS)usertatus;
@@ -261,9 +241,7 @@ void CToxProto::OnConnectionStatusChanged(Tox *tox, const int friendNumber, cons
{
CToxProto *proto = (CToxProto*)arg;
- //mir_cslock lock(proto->toxLock);
-
- MCONTACT hContact = proto->FindContact(friendNumber);
+ MCONTACT hContact = proto->GetContact(friendNumber);
if (hContact)
{
int newStatus = status ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
@@ -273,24 +251,34 @@ void CToxProto::OnConnectionStatusChanged(Tox *tox, const int friendNumber, cons
tox_send_avatar_info(proto->tox, friendNumber);
proto->delSetting(hContact, "Auth");
- for (int i = 0; i < proto->transfers->Count(); i++)
+ for (size_t i = 0; i < proto->transfers->Count(); i++)
{
// only for receiving
- FileTransferParam *transfer = proto->transfers->At(i);
+ FileTransferParam *transfer = proto->transfers->GetAt(i);
if (transfer->friendNumber == friendNumber && transfer->GetDirection() == 1)
{
- transfer->Resume(tox);
+ if (transfer->Resume(tox) == TOX_ERROR)
+ {
+ transfer->Cancel(tox);
+ proto->debugLogA("CToxProto::OnConnectionStatusChanged: failed to resuming of file (%d)",
+ transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
+ continue;
+ }
+ proto->debugLogA("CToxProto::OnConnectionStatusChanged: ask to resume the receiving at %llu of %llu of file (%d)",
+ transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
}
}
}
else
{
- for (int i = 0; i < proto->transfers->Count(); i++)
+ for (size_t i = 0; i < proto->transfers->Count(); i++)
{
- FileTransferParam *transfer = proto->transfers->At(i);
+ FileTransferParam *transfer = proto->transfers->GetAt(i);
if (transfer->friendNumber == friendNumber)
{
- transfer->status = PAUSED;
+ mir_cslock(transfer->fileLock);
+
+ transfer->status = BROKEN;
}
}
}
diff --git a/protocols/Tox/src/tox_messages.cpp b/protocols/Tox/src/tox_messages.cpp
index 51f255b546..a050b7f962 100644
--- a/protocols/Tox/src/tox_messages.cpp
+++ b/protocols/Tox/src/tox_messages.cpp
@@ -4,7 +4,7 @@ void CToxProto::OnFriendMessage(Tox *tox, const int number, const uint8_t *messa
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->GetContact(number);
if (hContact)
{
PROTORECVEVENT recv = { 0 };
@@ -20,7 +20,7 @@ void CToxProto::OnFriendAction(Tox *tox, const int number, const uint8_t *action
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->GetContact(number);
if (hContact)
{
proto->AddDbEvent(
@@ -35,9 +35,7 @@ void CToxProto::OnFriendAction(Tox *tox, const int number, const uint8_t *action
int __cdecl CToxProto::SendMsg(MCONTACT hContact, int flags, const char* msg)
{
- std::string id = getStringA(hContact, TOX_SETTINGS_ID);
- std::vector<uint8_t> clientId = HexStringToData(id);
- uint32_t number = tox_get_friend_number(tox, clientId.data());
+ uint32_t number = 0;// getDword(hContact, TOX_SETTINGS_NUMBER, TOX_ERROR);
if (number == TOX_ERROR)
{
debugLogA("CToxProto::SendMsg: failed to get friend number");
@@ -48,11 +46,11 @@ int __cdecl CToxProto::SendMsg(MCONTACT hContact, int flags, const char* msg)
{
if (strncmp(msg, "/me ", 4) != 0)
{
- result = tox_send_message(tox, number, (uint8_t*)msg, (uint16_t)strlen(msg));
+ result = tox_send_message(tox, number, (uint8_t*)msg, mir_strlen(msg));
}
else
{
- result = tox_send_action(tox, number, (uint8_t*)&msg[4], (uint16_t)(strlen(msg) - 4));
+ result = tox_send_action(tox, number, (uint8_t*)&msg[4], mir_strlen(msg) - 4);
}
}
@@ -68,7 +66,7 @@ void CToxProto::OnReadReceipt(Tox *tox, int32_t number, uint32_t receipt, void *
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->GetContact(number);
if (hContact)
{
proto->ProtoBroadcastAck(
@@ -106,7 +104,7 @@ void CToxProto::OnTypingChanged(Tox *tox, const int number, uint8_t isTyping, vo
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->GetContact(number);
if (hContact)
{
CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)isTyping);
@@ -117,9 +115,7 @@ int __cdecl CToxProto::UserIsTyping(MCONTACT hContact, int type)
{
if (hContact && IsOnline())
{
- std::string id = getStringA(hContact, TOX_SETTINGS_ID);
- std::vector<uint8_t> clientId = HexStringToData(id);
- uint32_t number = tox_get_friend_number(tox, clientId.data());
+ uint32_t number = 0;//getDword(hContact, TOX_SETTINGS_NUMBER, TOX_ERROR);
if (number >= 0)
{
tox_set_user_is_typing(tox, number, type);
diff --git a/protocols/Tox/src/tox_profile.cpp b/protocols/Tox/src/tox_profile.cpp
index 898899bff1..d169b21f78 100644
--- a/protocols/Tox/src/tox_profile.cpp
+++ b/protocols/Tox/src/tox_profile.cpp
@@ -31,8 +31,8 @@ bool CToxProto::LoadToxProfile()
}
fseek(profile, 0, SEEK_END);
- size_t size = ftell(profile);
- fseek(profile, 0, SEEK_SET);
+ size_t size = _ftelli64(profile);
+ rewind(profile);
if (size == 0)
{
fclose(profile);
@@ -41,8 +41,7 @@ bool CToxProto::LoadToxProfile()
}
uint8_t *data = (uint8_t*)mir_calloc(size);
- size_t read = fread((char*)data, sizeof(char), size, profile);
- if (size != read)
+ if (fread((char*)data, sizeof(char), size, profile) != size)
{
fclose(profile);
debugLogA("CToxProto::LoadToxData: could not read tox profile");
@@ -66,7 +65,7 @@ bool CToxProto::LoadToxProfile()
}
}
- if (tox_encrypted_load(tox, data, size, (uint8_t*)password, strlen(password)) == TOX_ERROR)
+ if (tox_encrypted_load(tox, data, size, (uint8_t*)password, mir_strlen(password)) == TOX_ERROR)
{
debugLogA("CToxProto::LoadToxData: could not decrypt tox profile");
mir_free(data);
diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp
index 36dba649ea..bf122b72e7 100644
--- a/protocols/Tox/src/tox_proto.cpp
+++ b/protocols/Tox/src/tox_proto.cpp
@@ -48,8 +48,6 @@ CToxProto::CToxProto(const char* protoName, const TCHAR* userName) :
// transfers
transfers = new CTransferList();
-
- hToxEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
CToxProto::~CToxProto()
@@ -83,22 +81,26 @@ DWORD_PTR __cdecl CToxProto::GetCaps(int type, MCONTACT hContact)
return 0;
}
-MCONTACT __cdecl CToxProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
+MCONTACT __cdecl CToxProto::AddToList(int flags, PROTOSEARCHRESULT *psr)
{
- std::string address(mir_t2a(psr->id));
- if (IsMe(address))
+ std::string address(ptrA(mir_t2a(psr->id)));
+ ptrA myAddress(getStringA(NULL, TOX_SETTINGS_ID));
+ if (strnicmp(address.c_str(), myAddress, TOX_PUBLIC_KEY_SIZE) == 0)
+ {
+ ShowNotification(TranslateT("You cannot add yourself to your contact list"), 0);
+ return NULL;
+ }
+ MCONTACT hContact = GetContact(address.c_str());
+ if (hContact)
{
- debugLogA("CToxProto::AddToList: you cannot add yourself to friend list");
+ ShowNotification(TranslateT("Contact already in your contact list"), 0, hContact);
return NULL;
}
- // set tox address as contact id
- return AddContact(address, _T(""), flags & PALF_TEMPORARY);
+ // set tox address as contact public key
+ return AddContact(address.c_str(), _T(""), flags & PALF_TEMPORARY);
}
-MCONTACT __cdecl CToxProto::AddToListByEvent(int flags, int iContact, MEVENT hDbEvent)
-{
- return 0;
-}
+MCONTACT __cdecl CToxProto::AddToListByEvent(int flags, int iContact, MEVENT hDbEvent) { return 0; }
int __cdecl CToxProto::Authorize(MEVENT hDbEvent)
{
@@ -108,13 +110,16 @@ int __cdecl CToxProto::Authorize(MEVENT hDbEvent)
return 1;
}
- std::string id = getStringA(hContact, TOX_SETTINGS_ID);
- std::vector<uint8_t> clientId = HexStringToData(id);
- if (tox_add_friend_norequest(tox, clientId.data()) != TOX_ERROR)
+ ToxBinAddress address = ptrA(getStringA(hContact, TOX_SETTINGS_ID));
+ ToxBinAddress pubKey = address.GetPubKey();
+ if (tox_add_friend_norequest(tox, pubKey) == TOX_ERROR)
{
return 1;
}
+ // trim address to public key
+ setString(hContact, TOX_SETTINGS_ID, pubKey.ToHex());
+
db_unset(hContact, "CList", "NotOnList");
delSetting(hContact, "Grant");
@@ -132,14 +137,12 @@ int __cdecl CToxProto::AuthRequest(MCONTACT hContact, const PROTOCHAR *szMessage
{
ptrA reason(mir_utf8encodeW(szMessage));
- std::string address = getStringA(hContact, TOX_SETTINGS_ID);
- std::vector<uint8_t> pubKey = HexStringToData(address);
- int32_t number = tox_add_friend(tox, pubKey.data(), (uint8_t*)(char*)reason, (uint16_t)strlen(reason));
+ ToxBinAddress address = ptrA(getStringA(hContact, TOX_SETTINGS_ID));
+ int32_t number = tox_add_friend(tox, address, (uint8_t*)(char*)reason, mir_strlen(reason));
if (number > TOX_ERROR)
{
- // change tox address in contact id by tox id
- std::string id = ToxAddressToId(address);
- setString(hContact, TOX_SETTINGS_ID, id.c_str());
+ // trim address to public key
+ setString(hContact, TOX_SETTINGS_ID, address.ToHex().GetPubKey());
db_unset(hContact, "CList", "NotOnList");
delSetting(hContact, "Grant");
@@ -260,7 +263,7 @@ int __cdecl CToxProto::SetAwayMsg(int iStatus, const PROTOCHAR *msg)
//WaitForSingleObject(hToxEvent, INFINITE);
ptrA statusMessage(msg == NULL ? mir_strdup("") : mir_utf8encodeT(msg));
- if (tox_set_status_message(tox, (uint8_t*)(char*)statusMessage, min(TOX_MAX_STATUSMESSAGE_LENGTH, strlen(statusMessage))) == TOX_ERROR)
+ if (tox_set_status_message(tox, (uint8_t*)(char*)statusMessage, min(TOX_MAX_STATUSMESSAGE_LENGTH, mir_strlen(statusMessage))) == TOX_ERROR)
{
debugLogA("CToxProto::SetAwayMsg: failed to set status status message %s", msg);
}
diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h
index eab3eb509b..03fdfa1a78 100644
--- a/protocols/Tox/src/tox_proto.h
+++ b/protocols/Tox/src/tox_proto.h
@@ -68,7 +68,7 @@ private:
char *password;
mir_cs toxLock;
TCHAR *accountName;
- HANDLE hNetlib, hPollingThread, hToxEvent;
+ HANDLE hNetlib, hPollingThread;
bool isTerminated, isConnected;
CTransferList *transfers;
@@ -119,18 +119,19 @@ private:
WORD GetContactStatus(MCONTACT hContact);
void SetContactStatus(MCONTACT hContact, WORD status);
void SetAllContactsStatus(WORD status);
- bool IsMe(const std::string &id);
- MCONTACT FindContact(const std::string &id);
- MCONTACT FindContact(const int friendNumber);
- MCONTACT AddContact(const std::string &id, const std::tstring &dnsId, bool isTemporary = false);
+
+ MCONTACT GetContact(const int friendNumber);
+ MCONTACT GetContact(const char *pubKey);
+
+ MCONTACT AddContact(const char *address, const std::tstring &dnsId, bool isTemporary = false);
MCONTACT GetContactFromAuthEvent(MEVENT hEvent);
- void LoadFriendList();
+ void __cdecl LoadFriendList(void*);
int __cdecl OnContactDeleted(MCONTACT, LPARAM);
- static void OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t *message, const uint16_t messageSize, void *arg);
+ static void OnFriendRequest(Tox *tox, const uint8_t *pubKey, const uint8_t *message, const uint16_t messageSize, void *arg);
static void OnFriendNameChange(Tox *tox, const int friendNumber, const uint8_t *name, const uint16_t nameSize, void *arg);
static void OnStatusMessageChanged(Tox *tox, const int friendNumber, const uint8_t* message, const uint16_t messageSize, void *arg);
static void OnUserStatusChanged(Tox *tox, int32_t friendNumber, uint8_t usertatus, void *arg);
@@ -178,11 +179,6 @@ private:
static void ShowNotification(const TCHAR *caption, const TCHAR *message, int flags = 0, MCONTACT hContact = NULL);
MEVENT AddDbEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob);
-
- std::vector<uint8_t> HexStringToData(std::string hex);
- std::string DataToHexString(std::vector<uint8_t>);
-
- std::string ToxAddressToId(std::string);
static bool IsFileExists(std::tstring path);
};
diff --git a/protocols/Tox/src/tox_search.cpp b/protocols/Tox/src/tox_search.cpp
index 8e1df68786..d62eccd593 100644
--- a/protocols/Tox/src/tox_search.cpp
+++ b/protocols/Tox/src/tox_search.cpp
@@ -23,7 +23,7 @@ void CToxProto::SearchByNameAsync(void *arg)
uint8_t dnsString[256];
uint32_t requestId = 0;
- int length = tox_generate_dns3_string(dns, dnsString, sizeof(dnsString), &requestId, (uint8_t*)name, strlen(name));
+ int length = tox_generate_dns3_string(dns, dnsString, sizeof(dnsString), &requestId, (uint8_t*)name, mir_strlen(name));
if (length != TOX_ERROR)
{
dnsString[length] = 0;
@@ -40,14 +40,14 @@ void CToxProto::SearchByNameAsync(void *arg)
if (record->wType == DNS_TYPE_TEXT && txt->dwStringCount)
{
char *recordId = &txt->pStringArray[0][10];
- std::vector<uint8_t> address(TOX_FRIEND_ADDRESS_SIZE);
- if (tox_decrypt_dns3_TXT(dns, &address[0], (uint8_t*)recordId, strlen(recordId), requestId) != TOX_ERROR)
+ uint8_t data[TOX_FRIEND_ADDRESS_SIZE];
+ if (tox_decrypt_dns3_TXT(dns, data, (uint8_t*)recordId, mir_strlen(recordId), requestId) != TOX_ERROR)
{
- std::string id = DataToHexString(address);
+ ToxHexAddress address(data, TOX_FRIEND_ADDRESS_SIZE);
PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) };
psr.flags = PSR_TCHAR;
- psr.id = mir_a2t(id.c_str());
+ psr.id = mir_a2t(address);
psr.nick = mir_utf8decodeT(name);
TCHAR email[MAX_PATH];
@@ -115,30 +115,18 @@ HWND __cdecl CToxProto::SearchAdvanced(HWND owner)
if (std::regex_search(query, match, regex))
{
std::string address = match[1];
- if (IsMe(address))
- {
- ShowNotification(TranslateT("You cannot add yourself to friend list"), 0);
- }
- else
- {
- MCONTACT hContact = FindContact(address);
- if (!hContact)
- {
- PROTOSEARCHRESULT psr = { sizeof(psr) };
- psr.flags = PSR_TCHAR;
- psr.id = mir_a2t(query.c_str());
+ MCONTACT hContact = GetContact(address.c_str());
- ADDCONTACTSTRUCT acs = { HANDLE_SEARCHRESULT };
- acs.szProto = m_szModuleName;
- acs.psr = &psr;
+ PROTOSEARCHRESULT psr = { sizeof(psr) };
+ psr.flags = PSR_TCHAR;
+ psr.id = mir_a2t(query.c_str());
+
+ ADDCONTACTSTRUCT acs = { HANDLE_SEARCHRESULT };
+ acs.szProto = m_szModuleName;
+ acs.psr = &psr;
+
+ CallService(MS_ADDCONTACT_SHOW, (WPARAM)owner, (LPARAM)&acs);
- CallService(MS_ADDCONTACT_SHOW, (WPARAM)owner, (LPARAM)&acs);
- }
- else
- {
- ShowNotification(TranslateT("Contact already in your contact list"), 0, hContact);
- }
- }
ForkThread(&CToxProto::SearchFailedAsync, NULL);
}
else
diff --git a/protocols/Tox/src/tox_transfer.cpp b/protocols/Tox/src/tox_transfer.cpp
index ce8488438b..a56799f971 100644
--- a/protocols/Tox/src/tox_transfer.cpp
+++ b/protocols/Tox/src/tox_transfer.cpp
@@ -3,12 +3,11 @@
/* FILE RECEIVING */
// incoming file flow
-// send it through miranda
void CToxProto::OnFriendFile(Tox *tox, int32_t friendNumber, uint8_t fileNumber, uint64_t fileSize, const uint8_t *fileName, uint16_t length, void *arg)
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(friendNumber);
+ MCONTACT hContact = proto->GetContact(friendNumber);
if (hContact)
{
TCHAR *name = mir_utf8decodeT((char*)fileName);
@@ -45,7 +44,7 @@ HANDLE __cdecl CToxProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const P
// stupid fix
TCHAR fullPath[MAX_PATH];
mir_sntprintf(fullPath, SIZEOF(fullPath), _T("%s\\%s"), transfer->pfts.tszWorkingDir, transfer->pfts.tszCurrentFile);
- transfer->RenameName(fullPath);
+ transfer->Rename(fullPath);
if (!ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, (HANDLE)transfer, (LPARAM)&transfer->pfts))
{
@@ -73,7 +72,7 @@ int __cdecl CToxProto::FileResume(HANDLE hTransfer, int *action, const PROTOCHAR
switch (*action)
{
case FILERESUME_RENAME:
- transfer->RenameName(*szFilename);
+ transfer->Rename(*szFilename);
result = transfer->OpenFile(_T("wb"));
break;
@@ -83,7 +82,7 @@ int __cdecl CToxProto::FileResume(HANDLE hTransfer, int *action, const PROTOCHAR
case FILERESUME_SKIP:
result = false;
- return 0;
+ break;
case FILERESUME_RESUME:
result = transfer->OpenFile(_T("ab"));
@@ -93,6 +92,7 @@ int __cdecl CToxProto::FileResume(HANDLE hTransfer, int *action, const PROTOCHAR
if (result)
{
transfer->Start(tox);
+ debugLogA("CToxProto::FileResume: start receiving file (%d)", transfer->fileNumber);
}
else
{
@@ -109,37 +109,40 @@ void CToxProto::OnFileData(Tox *tox, int32_t friendNumber, uint8_t fileNumber, c
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(friendNumber);
- if (hContact)
+ MCONTACT hContact = proto->GetContact(friendNumber);
+ if (hContact == NULL)
{
- FileTransferParam *transfer = proto->transfers->Get(fileNumber);
- if (transfer == NULL)
- {
- tox_file_send_control(tox, friendNumber, 1, fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
- return;
- }
+ proto->debugLogA("CToxProto::OnFileData: cannot find contact by number (%d)", friendNumber);
+ tox_file_send_control(tox, friendNumber, 1, fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
+ return;
+ }
- if (fwrite(data, sizeof(uint8_t), size, transfer->hFile) != size)
- {
- proto->debugLogA("CToxProto::OnFileData: cannot write to file (%d)", fileNumber);
- proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
- transfer->Fail(tox);
- }
+ FileTransferParam *transfer = proto->transfers->Get(fileNumber);
+ if (transfer == NULL)
+ {
+ proto->debugLogA("CToxProto::OnFileData: cannot find transfer by number (%d)", fileNumber);
+ transfer->Fail(tox);
+ return;
+ }
- transfer->pfts.totalProgress = transfer->pfts.currentFileProgress += size;
- proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
+ if (fwrite(data, sizeof(uint8_t), size, transfer->hFile) != size)
+ {
+ proto->debugLogA("CToxProto::OnFileData: cannot write to file (%d)", fileNumber);
+ proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
+ transfer->Fail(tox);
+ return;
}
+
+ transfer->pfts.totalProgress = transfer->pfts.currentFileProgress += size;
+ proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
}
/* FILE SENDING */
// outcoming file flow
-// send request through tox
-HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR *szDescription, PROTOCHAR **ppszFiles)
+HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR*, PROTOCHAR **ppszFiles)
{
- std::string id = getStringA(hContact, TOX_SETTINGS_ID);
- std::vector<uint8_t> clientId = HexStringToData(id);
- uint32_t friendNumber = tox_get_friend_number(tox, clientId.data());
+ uint32_t friendNumber = 0;// getDword(hContact, TOX_SETTINGS_NUMBER, TOX_ERROR);
TCHAR *fileName = _tcsrchr(ppszFiles[0], '\\') + 1;
@@ -148,19 +151,19 @@ HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR *szDescrip
_tcsncpy(fileDir, ppszFiles[0], fileDirLength);
fileDir[fileDirLength] = '\0';
- size_t fileSize = 0;
FILE *hFile = _tfopen(ppszFiles[0], _T("rb"));
if (hFile == NULL)
{
debugLogA("CToxProto::SendFilesAsync: cannot open file");
return NULL;
}
+
fseek(hFile, 0, SEEK_END);
- fileSize = ftell(hFile);
- fseek(hFile, 0, SEEK_SET);
+ size_t fileSize = _ftelli64(hFile);
+ rewind(hFile);
char *name = mir_utf8encodeW(fileName);
- int fileNumber = tox_new_file_sender(tox, friendNumber, fileSize, (uint8_t*)name, strlen(name));
+ int fileNumber = tox_new_file_sender(tox, friendNumber, fileSize, (uint8_t*)name, mir_strlen(name));
if (fileNumber < 0)
{
debugLogA("CToxProto::SendFilesAsync: cannot send file");
@@ -186,51 +189,62 @@ void CToxProto::SendFileAsync(void *arg)
debugLogA("CToxProto::SendFileAsync: start sending file (%d)", transfer->fileNumber);
ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)transfer, 0);
+ size_t dataSize = 0, fileProgress = 0;
size_t fileSize = transfer->pfts.currentFileSize;
- size_t fileProgress = 0;
- TCHAR filePath[MAX_PATH];
- mir_sntprintf(filePath, SIZEOF(filePath), _T("%s%s"), transfer->pfts.tszWorkingDir, transfer->pfts.tszCurrentFile);
-
- uint16_t chunkSize = min(fileSize, (size_t)tox_file_data_size(tox, transfer->friendNumber));
+ size_t chunkSize = min(fileSize, (size_t)tox_file_data_size(tox, transfer->friendNumber));
uint8_t *data = (uint8_t*)mir_alloc(chunkSize);
- while (transfer->status < FAILED && !feof(transfer->hFile) && fileProgress < fileSize)
+
+ while (transfer->status < FAILED && transfer->hFile != NULL && fileProgress < fileSize)
{
- if (transfer->status == PAUSED)
+ mir_cslockfull locker(transfer->fileLock);
+
+ if (transfer->status == PAUSED || transfer->status == BROKEN)
{
- Sleep(1000);
+ if (transfer->status == BROKEN)
+ {
+ dataSize = 0;
+ }
+ locker.unlock();
+ Sleep(100);
continue;
}
- //mir_cslock lock(toxLock);
-
- uint16_t size = min(chunkSize, fileSize - fileProgress);
- if (fread(data, sizeof(uint8_t), size, transfer->hFile) != size)
+ if (dataSize == 0)
{
- transfer->Fail(tox);
- debugLogA("CToxProto::SendFileAsync: failed to read from file (%d)", transfer->fileNumber);
- ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
- return;
+ dataSize = min(chunkSize, fileSize - fileProgress);
+ if (fread(data, sizeof(uint8_t), dataSize, transfer->hFile) != dataSize)
+ {
+ debugLogA("CToxProto::SendFileAsync: failed to read from file (%d)", transfer->fileNumber);
+ debugLogA("CToxProto::OnFileRequest: failure of sending at %llu of %llu of file (%d)", fileProgress, fileSize, transfer->fileNumber);
+ ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
+ transfer->Fail(tox);
+ return;
+ }
}
- if (tox_file_send_data(tox, transfer->friendNumber, transfer->fileNumber, data, size) == TOX_ERROR)
+ if (tox_file_send_data(tox, transfer->friendNumber, transfer->fileNumber, data, dataSize) == TOX_ERROR)
{
- fseek(transfer->hFile, -size, SEEK_CUR);
+ //fseek(transfer->hFile, -(long)size, SEEK_CUR);
+ locker.unlock();
+ //Sleep(100);
continue;
}
- transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = fileProgress += size;
+ transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = fileProgress += dataSize;
ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
+ dataSize = 0;
}
+
mir_free(data);
- if (transfer->status == STARTED)
+ if (transfer->status != STARTED)
{
- //mir_cslock lock(toxLock);
- transfer->Finish(tox);
+ transfer->Fail(tox);
}
+ transfer->Finish(tox);
}
-/* GENERAL */
+/* COMMON */
// file request is cancelled
int __cdecl CToxProto::FileCancel(MCONTACT hContact, HANDLE hTransfer)
@@ -252,12 +266,9 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_se
{
CToxProto *proto = (CToxProto*)arg;
- //mir_cslock lock(proto->toxLock);
-
- MCONTACT hContact = proto->FindContact(friendNumber);
+ MCONTACT hContact = proto->GetContact(friendNumber);
if (hContact)
{
-
FileTransferParam *transfer = proto->transfers->Get(fileNumber);
if (transfer == NULL)
{
@@ -268,15 +279,17 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_se
switch (type)
{
case TOX_FILECONTROL_ACCEPT:
+ // if friend allow file request
if (receive_send == 1)
{
- // if friend allow file request
if (transfer->status == NONE)
{
proto->ForkThread(&CToxProto::SendFileAsync, transfer);
}
else
{
+ mir_cslock locker(transfer->fileLock);
+
// unpause file transfer
transfer->status = STARTED;
}
@@ -284,24 +297,53 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_se
break;
case TOX_FILECONTROL_PAUSE:
- transfer->status = PAUSED;
+ {
+ mir_cslock locker(transfer->fileLock);
+
+ transfer->status = PAUSED;
+ }
break;
case TOX_FILECONTROL_RESUME_BROKEN:
- // only for sending
- if (receive_send == 0)
+ if (receive_send == 1)
{
+ mir_cslock locker(transfer->fileLock);
+
+ // if receiver ask to resume transfer
uint64_t progress = *(uint64_t*)data;
- transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = progress;
- fseek(transfer->hFile, progress, SEEK_SET);
- transfer->Start(tox);
+ if (progress >= transfer->pfts.currentFileSize || length != sizeof(uint64_t))
+ {
+ transfer->Fail(tox);
+ }
+ if (tox_file_send_control(tox, friendNumber, transfer->GetDirection(), fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0) == TOX_ERROR)
+ {
+ proto->debugLogA("CToxProto::OnFileRequest: failed to resume sending file (%d)",
+ transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
+ proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
+ transfer->Fail(tox);
+ break;
+ }
+ if (transfer->pfts.currentFileProgress != progress)
+ {
+ proto->debugLogA("CToxProto::OnFileRequest: change file position from %llu to %llu of file (%d)",
+ transfer->pfts.currentFileProgress, progress, transfer->fileNumber);
+ transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = progress;
+ _fseeki64(transfer->hFile, progress, SEEK_SET);
+ }
+ proto->debugLogA("CToxProto::OnFileRequest: resumption of sending at %llu of %llu of file (%d)",
+ transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
+ transfer->status = STARTED;
}
break;
case TOX_FILECONTROL_KILL:
- transfer->status = CANCELED;
- proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0);
- proto->transfers->Remove(transfer);
+ {
+ mir_cslock locker(transfer->fileLock);
+
+ transfer->status = CANCELED;
+ proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0);
+ proto->transfers->Remove(transfer);
+ }
break;
case TOX_FILECONTROL_FINISHED:
@@ -314,6 +356,8 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_se
{
proto->debugLogA("CToxProto::OnFileRequest: finished sending file (%d)", fileNumber);
}
+ proto->debugLogA("CToxProto::OnFileRequest: %llu of %llu of file(%d) was transferred successfully",
+ transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)transfer, 0);
proto->transfers->Remove(transfer);
break;
diff --git a/protocols/Tox/src/tox_transfer.h b/protocols/Tox/src/tox_transfer.h
index f0732ca3b0..7cbbffe3ee 100644
--- a/protocols/Tox/src/tox_transfer.h
+++ b/protocols/Tox/src/tox_transfer.h
@@ -6,6 +6,7 @@ enum FILE_TRANSFER_STATUS
NONE,
STARTED,
PAUSED,
+ BROKEN,
FAILED,
CANCELED,
FINISHED,
@@ -17,6 +18,7 @@ struct FileTransferParam
PROTOFILETRANSFERSTATUS pfts;
FILE_TRANSFER_STATUS status;
FILE *hFile;
+ mir_cs fileLock;
int friendNumber;
int fileNumber;
@@ -45,37 +47,37 @@ struct FileTransferParam
return hFile != NULL;
}
- void Start(Tox *tox)
+ int Start(Tox *tox)
{
status = STARTED;
- tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0);
+ return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0);
}
- void Resume(Tox *tox)
+ int Resume(Tox *tox)
{
status = STARTED;
- tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_RESUME_BROKEN, (uint8_t*)&pfts.currentFileProgress, sizeof(uint64_t));
+ return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_RESUME_BROKEN, (uint8_t*)&pfts.currentFileProgress, sizeof(pfts.currentFileProgress));
}
- void Fail(Tox *tox)
+ int Fail(Tox *tox)
{
status = FAILED;
- tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
+ return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
}
- void Cancel(Tox *tox)
+ int Cancel(Tox *tox)
{
status = FINISHED;
- tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
+ return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
}
- void Finish(Tox *tox)
+ int Finish(Tox *tox)
{
status = FINISHED;
- tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0);
+ return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0);
}
- void RenameName(const TCHAR* fileName)
+ void Rename(const TCHAR* fileName)
{
pfts.ptszFiles[0] = replaceStrT(pfts.tszCurrentFile, fileName);
}
@@ -94,9 +96,10 @@ struct FileTransferParam
}
mir_free(pfts.pszFiles[0]);
mir_free(pfts.pszFiles);
- if (hFile)
+ if (hFile != NULL)
{
fclose(hFile);
+ hFile = NULL;
}
}
};
@@ -107,7 +110,7 @@ private:
std::map<uint8_t, FileTransferParam*> transfers;
public:
- int Count() const
+ size_t Count() const
{
return transfers.size();
}
@@ -120,7 +123,7 @@ public:
}
}
- FileTransferParam * Get(uint8_t fileNumber)
+ FileTransferParam* Get(uint8_t fileNumber)
{
if (transfers.find(fileNumber) != transfers.end())
{
@@ -129,9 +132,9 @@ public:
return NULL;
}
- FileTransferParam * At(int index)
+ FileTransferParam* GetAt(size_t index)
{
- if (Count() < index)
+ if (index < Count())
{
std::map<uint8_t, FileTransferParam*>::iterator it = transfers.begin();
std::advance(it, index);
diff --git a/protocols/Tox/src/tox_utils.cpp b/protocols/Tox/src/tox_utils.cpp
index e3bf7d9707..14caa84026 100644
--- a/protocols/Tox/src/tox_utils.cpp
+++ b/protocols/Tox/src/tox_utils.cpp
@@ -73,43 +73,6 @@ MEVENT CToxProto::AddDbEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWOR
return db_event_add(hContact, &dbei);
}
-std::vector<uint8_t> CToxProto::HexStringToData(std::string hex)
-{
- std::stringstream ss;
- std::vector<uint8_t> data;
-
- size_t count = hex.length() / 2;
- for (size_t i = 0; i < count; i++)
- {
- unsigned byte;
- std::istringstream hex_byte(hex.substr(i * 2, 2));
- hex_byte >> std::hex >> byte;
- data.push_back(static_cast<unsigned char>(byte));
- }
-
- return data;
-}
-
-std::string CToxProto::DataToHexString(std::vector<uint8_t> data)
-{
- std::ostringstream oss;
- oss << std::hex << std::uppercase << std::setfill('0');
- for (size_t i = 0; i < data.size(); i++)
- {
- oss << std::setw(2) << static_cast<int>(data[i]);
- }
- return oss.str();
-}
-
-std::string CToxProto::ToxAddressToId(std::string address)
-{
- if (address.length() > TOX_CLIENT_ID_SIZE * 2)
- {
- address.erase(address.begin() + TOX_CLIENT_ID_SIZE * 2, address.end());
- }
- return address;
-}
-
bool CToxProto::IsFileExists(std::tstring path)
{
//return ::GetFileAttributes(fileName) != DWORD(-1)