diff options
-rw-r--r-- | protocols/Tox/bin/x64/libtox.dll | bin | 3955846 -> 3959506 bytes | |||
-rw-r--r-- | protocols/Tox/bin/x86/libtox.dll | bin | 3301072 -> 3301258 bytes | |||
-rw-r--r-- | protocols/Tox/src/tox_account.cpp | 8 | ||||
-rw-r--r-- | protocols/Tox/src/tox_contacts.cpp | 41 | ||||
-rw-r--r-- | protocols/Tox/src/tox_messages.cpp | 4 | ||||
-rw-r--r-- | protocols/Tox/src/tox_proto.cpp | 2 | ||||
-rw-r--r-- | protocols/Tox/src/tox_proto.h | 83 | ||||
-rw-r--r-- | protocols/Tox/src/tox_transfer.cpp | 231 |
8 files changed, 225 insertions, 144 deletions
diff --git a/protocols/Tox/bin/x64/libtox.dll b/protocols/Tox/bin/x64/libtox.dll Binary files differindex 385a6d3177..6c68460b7c 100644 --- a/protocols/Tox/bin/x64/libtox.dll +++ b/protocols/Tox/bin/x64/libtox.dll diff --git a/protocols/Tox/bin/x86/libtox.dll b/protocols/Tox/bin/x86/libtox.dll Binary files differindex 8d29046034..39f1a65585 100644 --- a/protocols/Tox/bin/x86/libtox.dll +++ b/protocols/Tox/bin/x86/libtox.dll diff --git a/protocols/Tox/src/tox_account.cpp b/protocols/Tox/src/tox_account.cpp index 5c4154af29..3b4f61b32b 100644 --- a/protocols/Tox/src/tox_account.cpp +++ b/protocols/Tox/src/tox_account.cpp @@ -142,11 +142,9 @@ void CToxProto::DoBootstrap() void CToxProto::DoTox()
{
- {
- mir_cslock lock(toxLock);
- tox_do(tox);
- }
- PulseEvent(hToxEvent);
+ tox_do(tox);
+
+ //PulseEvent(hToxEvent);
uint32_t interval = tox_do_interval(tox);
Sleep(interval);
}
diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index 6a7321546f..5cd56e099d 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -73,7 +73,7 @@ MCONTACT CToxProto::FindContact(const std::string &id) }
db_free(&dbv);
- if (_strnicmp(id.c_str(), clientId.c_str(), TOX_CLIENT_ID_SIZE) == 0)
+ if (mir_strcmpi(id.c_str(), clientId.c_str()) == 0)
{
break;
}
@@ -221,22 +221,22 @@ void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre);
}
-void CToxProto::OnFriendNameChange(Tox *tox, const int number, const uint8_t *name, const uint16_t nameSize, void *arg)
+void CToxProto::OnFriendNameChange(Tox *tox, const int friendNumber, const uint8_t *name, const uint16_t nameSize, void *arg)
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->FindContact(friendNumber);
if (hContact)
{
proto->setString(hContact, "Nick", (char*)name);
}
}
-void CToxProto::OnStatusMessageChanged(Tox *tox, const int number, const uint8_t* message, const uint16_t messageSize, void *arg)
+void CToxProto::OnStatusMessageChanged(Tox *tox, const int friendNumber, const uint8_t* message, const uint16_t messageSize, void *arg)
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->FindContact(friendNumber);
if (hContact)
{
ptrW statusMessage(mir_utf8decodeW((char*)message));
@@ -244,11 +244,11 @@ void CToxProto::OnStatusMessageChanged(Tox *tox, const int number, const uint8_t }
}
-void CToxProto::OnUserStatusChanged(Tox *tox, int32_t number, uint8_t usertatus, void *arg)
+void CToxProto::OnUserStatusChanged(Tox *tox, int32_t friendNumber, uint8_t usertatus, void *arg)
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->FindContact(friendNumber);
if (hContact)
{
TOX_USERSTATUS userstatus = (TOX_USERSTATUS)usertatus;
@@ -257,19 +257,40 @@ void CToxProto::OnUserStatusChanged(Tox *tox, int32_t number, uint8_t usertatus, }
}
-void CToxProto::OnConnectionStatusChanged(Tox *tox, const int number, const uint8_t status, void *arg)
+void CToxProto::OnConnectionStatusChanged(Tox *tox, const int friendNumber, const uint8_t status, void *arg)
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ //mir_cslock lock(proto->toxLock);
+
+ MCONTACT hContact = proto->FindContact(friendNumber);
if (hContact)
{
int newStatus = status ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
proto->SetContactStatus(hContact, newStatus);
if (status)
{
- tox_send_avatar_info(proto->tox, number);
+ tox_send_avatar_info(proto->tox, friendNumber);
proto->delSetting(hContact, "Auth");
+
+ for (std::map<uint8_t, FileTransferParam*>::iterator it = proto->transfers.begin(); it != proto->transfers.end(); it++)
+ {
+ // only for receiving
+ if (it->second->friendNumber == friendNumber && it->second->GetDirection() == 1)
+ {
+ it->second->Broken(tox);
+ }
+ }
+ }
+ else
+ {
+ for (std::map<uint8_t, FileTransferParam*>::iterator it = proto->transfers.begin(); it != proto->transfers.end(); it++)
+ {
+ if (it->second->friendNumber == friendNumber)
+ {
+ it->second->status = PAUSED;
+ }
+ }
}
}
}
diff --git a/protocols/Tox/src/tox_messages.cpp b/protocols/Tox/src/tox_messages.cpp index 9926068014..51f255b546 100644 --- a/protocols/Tox/src/tox_messages.cpp +++ b/protocols/Tox/src/tox_messages.cpp @@ -52,13 +52,13 @@ int __cdecl CToxProto::SendMsg(MCONTACT hContact, int flags, const char* 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], (uint16_t)(strlen(msg) - 4));
}
}
if (result == 0)
{
- debugLogA("CToxProto::SendMsg: could not to send message");
+ debugLogA("CToxProto::SendMsg: failed to send message");
}
return result;
diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp index e9d93dac78..b5be241c0f 100644 --- a/protocols/Tox/src/tox_proto.cpp +++ b/protocols/Tox/src/tox_proto.cpp @@ -253,7 +253,7 @@ int __cdecl CToxProto::SetAwayMsg(int iStatus, const PROTOCHAR *msg) {
if (IsOnline())
{
- WaitForSingleObject(hToxEvent, INFINITE);
+ //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)
diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index 962af5b609..92ba5ba49d 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -1,18 +1,31 @@ #ifndef _TOX_PROTO_H_
#define _TOX_PROTO_H_
+enum FILE_TRANSFER_STATUS
+{
+ NONE,
+ STARTED,
+ PAUSED,
+ FAILED,
+ CANCELED,
+ FINISHED,
+ DESTROYED
+};
+
struct FileTransferParam
{
PROTOFILETRANSFERSTATUS pfts;
- bool isTerminated;
+ FILE_TRANSFER_STATUS status;
FILE *hFile;
- int number;
+ int friendNumber;
+ int fileNumber;
- FileTransferParam(int fileNumber, const TCHAR* fileName, size_t fileSize)
+ FileTransferParam(int friendNumber, int fileNumber, const TCHAR* fileName, size_t fileSize)
{
- isTerminated = false;
- number = fileNumber;
+ status = NONE;
hFile = NULL;
+ this->friendNumber = friendNumber;
+ this->fileNumber = fileNumber;
pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
pfts.flags = PFTS_TCHAR;
@@ -26,19 +39,55 @@ struct FileTransferParam pfts.tszWorkingDir = NULL;
}
- void ChangeFileName(const TCHAR* fileName)
+ bool OpenFile(const TCHAR *mode)
+ {
+ hFile = _tfopen(pfts.tszCurrentFile, mode);
+ return hFile != NULL;
+ }
+
+ void Start(Tox *tox)
+ {
+ status = STARTED;
+ tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0);
+ }
+
+ void Broken(Tox *tox)
+ {
+ status = PAUSED;
+ tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_RESUME_BROKEN, (uint8_t*)&pfts.currentFileProgress, sizeof(uint64_t));
+ }
+
+ void Fail(Tox *tox)
+ {
+ status = FAILED;
+ tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
+ }
+
+ void Cancel(Tox *tox)
+ {
+ status = FINISHED;
+ tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
+ }
+
+ void Finish(Tox *tox)
+ {
+ status = FINISHED;
+ tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0);
+ }
+
+ void RenameName(const TCHAR* fileName)
{
pfts.ptszFiles[0] = replaceStrT(pfts.tszCurrentFile, fileName);
}
- uint8_t GetTransferStatus() const
+ uint8_t GetDirection() const
{
return pfts.flags & PFTS_SENDING ? 0 : 1;
}
~FileTransferParam()
{
- isTerminated = true;
+ status = DESTROYED;
if (pfts.tszWorkingDir != NULL)
{
mir_free(pfts.tszWorkingDir);
@@ -94,8 +143,8 @@ public: virtual int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT*);
virtual int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT*);
- virtual int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT* hContactsList);
- virtual HANDLE __cdecl SendFile(MCONTACT hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles);
+ virtual int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList);
+ virtual HANDLE __cdecl SendFile(MCONTACT hContact, const PROTOCHAR *szDescription, PROTOCHAR **ppszFiles);
virtual int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg);
virtual int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url);
@@ -182,10 +231,10 @@ private: 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 OnFriendNameChange(Tox *tox, const int number, const uint8_t *name, const uint16_t nameSize, void *arg);
- static void OnStatusMessageChanged(Tox *tox, const int number, const uint8_t* message, const uint16_t messageSize, void *arg);
- static void OnUserStatusChanged(Tox *tox, int32_t number, uint8_t usertatus, void *arg);
- static void OnConnectionStatusChanged(Tox *tox, const int number, const uint8_t status, 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);
+ static void OnConnectionStatusChanged(Tox *tox, const int friendNumber, const uint8_t status, void *arg);
// contacts search
void __cdecl SearchFailedAsync(void* arg);
@@ -208,9 +257,9 @@ private: void __cdecl SendFileAsync(void* arg);
//static void OnFileControlCallback(Tox *tox, int32_t number, uint8_t hFile, uint64_t fileSize, uint8_t *name, uint16_t nameSize, void *arg);
- static void OnFileRequest(Tox *tox, int32_t number, uint8_t receive_send, uint8_t fileNumber, uint8_t type, const uint8_t *data, uint16_t length, void *arg);
- static void OnFriendFile(Tox *tox, int32_t number, uint8_t fileNumber, uint64_t fileSize, const uint8_t *fileName, uint16_t length, void *arg);
- static void OnFileData(Tox *tox, int32_t number, uint8_t fileNumber, const uint8_t *data, uint16_t length, void *arg);
+ static void OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_send, uint8_t fileNumber, uint8_t type, const uint8_t *data, uint16_t length, void *arg);
+ static void OnFriendFile(Tox *tox, int32_t friendNumber, uint8_t fileNumber, uint64_t fileSize, const uint8_t *fileName, uint16_t length, void *arg);
+ static void OnFileData(Tox *tox, int32_t friendNumber, uint8_t fileNumber, const uint8_t *data, uint16_t length, void *arg);
// avatars
std::tstring GetAvatarFilePath(MCONTACT hContact = NULL);
diff --git a/protocols/Tox/src/tox_transfer.cpp b/protocols/Tox/src/tox_transfer.cpp index 22af0bb711..3ff4a9a0e1 100644 --- a/protocols/Tox/src/tox_transfer.cpp +++ b/protocols/Tox/src/tox_transfer.cpp @@ -2,17 +2,17 @@ void CToxProto::AddToTransferList(FileTransferParam *transfer)
{
- if (transfers.find(transfer->number) == transfers.end())
+ if (transfers.find(transfer->fileNumber) == transfers.end())
{
- transfers[transfer->number] = transfer;
+ transfers[transfer->fileNumber] = transfer;
}
}
void CToxProto::RemoveFromTransferList(FileTransferParam *transfer)
{
- if (transfers.find(transfer->number) != transfers.end())
+ if (transfers.find(transfer->fileNumber) != transfers.end())
{
- transfers.erase(transfer->number);
+ transfers.erase(transfer->fileNumber);
delete transfer;
}
}
@@ -21,11 +21,11 @@ void CToxProto::RemoveFromTransferList(FileTransferParam *transfer) // incoming file flow
// send it through miranda
-void CToxProto::OnFriendFile(Tox *tox, int32_t number, uint8_t fileNumber, uint64_t fileSize, const uint8_t *fileName, uint16_t length, void *arg)
+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(number);
+ MCONTACT hContact = proto->FindContact(friendNumber);
if (hContact)
{
TCHAR *name = mir_utf8decodeT((char*)fileName);
@@ -35,7 +35,7 @@ void CToxProto::OnFriendFile(Tox *tox, int32_t number, uint8_t fileNumber, uint6 name = mir_a2u((char*)fileName);
}
- FileTransferParam *transfer = new FileTransferParam(fileNumber, name, fileSize);
+ FileTransferParam *transfer = new FileTransferParam(friendNumber, fileNumber, name, fileSize);
transfer->pfts.hContact = hContact;
transfer->pfts.flags |= PFTS_RECEIVING;
proto->AddToTransferList(transfer);
@@ -45,7 +45,7 @@ void CToxProto::OnFriendFile(Tox *tox, int32_t number, uint8_t fileNumber, uint6 pre.fileCount = 1;
pre.timestamp = time(NULL);
pre.tszDescription = _T("");
- pre.ptszFiles = (TCHAR**)mir_alloc(sizeof(TCHAR*) * 2);
+ pre.ptszFiles = (TCHAR**)mir_alloc(sizeof(TCHAR*)*2);
pre.ptszFiles[0] = name;
pre.ptszFiles[1] = NULL;
pre.lParam = (LPARAM)transfer;
@@ -56,9 +56,9 @@ void CToxProto::OnFriendFile(Tox *tox, int32_t number, uint8_t fileNumber, uint6 // file request is allowed
HANDLE __cdecl CToxProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR *tszPath)
{
- std::string id = getStringA(hContact, TOX_SETTINGS_ID);
+ /*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 = tox_get_friend_number(tox, clientId.data());*/
FileTransferParam *transfer = (FileTransferParam*)hTransfer;
transfer->pfts.tszWorkingDir = mir_tstrdup(tszPath);
@@ -66,12 +66,20 @@ 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->ChangeFileName(fullPath);
+ transfer->RenameName(fullPath);
if (!ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, (HANDLE)transfer, (LPARAM)&transfer->pfts))
{
- transfer->hFile = _tfopen(transfer->pfts.tszCurrentFile, _T("wb"));
- tox_file_send_control(tox, number, 1, transfer->number, TOX_FILECONTROL_ACCEPT, NULL, 0);
+ if (!transfer->OpenFile(_T("wb")))
+ {
+ debugLogA("CToxProto::FileAllow: cannot to open file (%d)", transfer->fileNumber);
+ transfer->Fail(tox);
+ RemoveFromTransferList(transfer);
+ return NULL;
+ }
+
+ debugLogA("CToxProto::FileAllow: start receiving file (%d)", transfer->fileNumber);
+ transfer->Start(tox);
}
return hTransfer;
@@ -80,67 +88,62 @@ HANDLE __cdecl CToxProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const P // if file is exists
int __cdecl CToxProto::FileResume(HANDLE hTransfer, int *action, const PROTOCHAR **szFilename)
{
+ bool result = false;
FileTransferParam *transfer = (FileTransferParam*)hTransfer;
- std::string id = getStringA(transfer->pfts.hContact, TOX_SETTINGS_ID);
- std::vector<uint8_t> clientId = HexStringToData(id);
- uint32_t number = tox_get_friend_number(tox, clientId.data());
-
switch (*action)
{
case FILERESUME_RENAME:
- // rename file
- transfer->ChangeFileName(*szFilename);
- transfer->hFile = _tfopen(transfer->pfts.tszCurrentFile, _T("wb"));
- ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)transfer, 0);
- tox_file_send_control(tox, number, transfer->GetTransferStatus(), transfer->number, TOX_FILECONTROL_ACCEPT, NULL, 0);
+ transfer->RenameName(*szFilename);
+ result = transfer->OpenFile(_T("wb"));
break;
case FILERESUME_OVERWRITE:
- // truncate file to zero
- transfer->hFile = _tfopen(transfer->pfts.tszCurrentFile, _T("wb"));
- ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)transfer, 0);
- tox_file_send_control(tox, number, transfer->GetTransferStatus(), transfer->number, TOX_FILECONTROL_ACCEPT, NULL, 0);
+ result = transfer->OpenFile(_T("wb"));
break;
case FILERESUME_SKIP:
- // deny file request
- ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0);
- tox_file_send_control(tox, number, transfer->GetTransferStatus(), transfer->number, TOX_FILECONTROL_KILL, NULL, 0);
- RemoveFromTransferList(transfer);
- break;
+ result = false;
+ return 0;
case FILERESUME_RESUME:
- transfer->hFile = _tfopen(transfer->pfts.tszCurrentFile, _T("ab"));
- ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)transfer, 0);
- tox_file_send_control(tox, number, transfer->GetTransferStatus(), transfer->number, TOX_FILECONTROL_ACCEPT, NULL, 0);
+ result = transfer->OpenFile(_T("ab"));
break;
}
+ if (result)
+ {
+ transfer->Start(tox);
+ }
+ else
+ {
+ transfer->Cancel(tox);
+ RemoveFromTransferList(transfer);
+ }
+ ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, result ? ACKRESULT_CONNECTED : ACKRESULT_DENIED, (HANDLE)transfer, 0);
+
return 0;
}
// getting the file data
-void CToxProto::OnFileData(Tox *tox, int32_t number, uint8_t fileNumber, const uint8_t *data, uint16_t size, void *arg)
+void CToxProto::OnFileData(Tox *tox, int32_t friendNumber, uint8_t fileNumber, const uint8_t *data, uint16_t size, void *arg)
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ MCONTACT hContact = proto->FindContact(friendNumber);
if (hContact)
{
FileTransferParam *transfer = proto->transfers.at(fileNumber);
- if (transfer->hFile == NULL)
+ if (fwrite(data, sizeof(uint8_t), size, transfer->hFile) != size)
{
- tox_file_send_control(tox, number, transfer->GetTransferStatus(), transfer->number, TOX_FILECONTROL_KILL, NULL, 0);
+ 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);
}
- if (fwrite(data, sizeof(uint8_t), size, transfer->hFile) == size)
- {
- transfer->pfts.totalProgress = transfer->pfts.currentFileProgress += size;
- proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
- }
+ transfer->pfts.totalProgress = transfer->pfts.currentFileProgress += size;
+ proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
}
}
@@ -148,11 +151,11 @@ void CToxProto::OnFileData(Tox *tox, int32_t number, uint8_t fileNumber, const u // 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 *szDescription, PROTOCHAR **ppszFiles)
{
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 friendNumber = tox_get_friend_number(tox, clientId.data());
TCHAR *fileName = _tcsrchr(ppszFiles[0], '\\') + 1;
@@ -173,14 +176,14 @@ HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR* szDescrip fseek(hFile, 0, SEEK_SET);
char *name = mir_utf8encodeW(fileName);
- int fileNumber = tox_new_file_sender(tox, number, fileSize, (uint8_t*)name, strlen(name));
+ int fileNumber = tox_new_file_sender(tox, friendNumber, fileSize, (uint8_t*)name, strlen(name));
if (fileNumber < 0)
{
debugLogA("CToxProto::SendFilesAsync: cannot send file");
return NULL;
}
- FileTransferParam *transfer = new FileTransferParam(fileNumber, fileName, fileSize);
+ FileTransferParam *transfer = new FileTransferParam(friendNumber, fileNumber, fileName, fileSize);
transfer->pfts.hContact = hContact;
transfer->pfts.flags |= PFTS_SENDING;
transfer->pfts.tszWorkingDir = fileDir;
@@ -191,65 +194,55 @@ HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR* szDescrip }
// start sending
-void CToxProto::SendFileAsync(void* arg)
+void CToxProto::SendFileAsync(void *arg)
{
FileTransferParam *transfer = (FileTransferParam*)arg;
+ transfer->status = STARTED;
- std::string id = getStringA(transfer->pfts.hContact, TOX_SETTINGS_ID);
- std::vector<uint8_t> clientId = HexStringToData(id);
- int32_t number = tox_get_friend_number(tox, clientId.data());
- if (number > TOX_ERROR)
- {
- ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)transfer, 0);
+ debugLogA("CToxProto::SendFileAsync: start sending file (%d)", transfer->fileNumber);
+ ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)transfer, 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);
+ 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);
- size_t chunkSize = min(fileSize, (size_t)tox_file_data_size(tox, number));
- uint8_t *data = (uint8_t*)mir_alloc(TOX_FILE_BLOCK_SIZE);
- while (!feof(transfer->hFile) && fileProgress < fileSize && !transfer->isTerminated)
+ uint16_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)
+ {
+ if (transfer->status == PAUSED)
{
- // read file by block of TOX_FILE_BLOCK_SIZE
- size_t blockSize = min(chunkSize * (TOX_FILE_BLOCK_SIZE / chunkSize), fileSize - fileProgress);
- if (fread(data, sizeof(uint8_t), blockSize, transfer->hFile) != blockSize)
- {
- ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
- tox_file_send_control(tox, number, transfer->GetTransferStatus(), transfer->number, TOX_FILECONTROL_KILL, NULL, 0);
- return;
- }
+ Sleep(1000);
+ continue;
+ }
- // send block by chunk of chunkSize
- size_t blockProgress = 0;
- while (blockProgress < blockSize && !transfer->isTerminated)
- {
- size_t size = min(chunkSize, blockSize - blockProgress);
- do
- {
- {
- //mir_cslock lck(toxLock);
-
- if (tox_file_send_data(tox, number, transfer->number, &data[blockProgress], size) != TOX_ERROR)
- {
- break;
- }
- }
- WaitForSingleObject(hToxEvent, INFINITE);
- } while (!transfer->isTerminated);
-
- blockProgress += size;
- transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = fileProgress += size;
- ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
- }
+ //mir_cslock lock(toxLock);
+
+ uint16_t size = min(chunkSize, fileSize - fileProgress);
+ if (fread(data, sizeof(uint8_t), size, transfer->hFile) != size)
+ {
+ 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;
}
- mir_free(data);
- if (!transfer->isTerminated)
+ if (tox_file_send_data(tox, transfer->friendNumber, transfer->fileNumber, data, size) == TOX_ERROR)
{
- uint8_t receive_send = transfer->GetTransferStatus();
- tox_file_send_control(tox, number, receive_send, transfer->number, TOX_FILECONTROL_FINISHED, NULL, 0);
+ fseek(transfer->hFile, -size, SEEK_CUR);
+ continue;
}
+
+ transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = fileProgress += size;
+ ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
+ }
+ mir_free(data);
+
+ if (transfer->status == STARTED)
+ {
+ //mir_cslock lock(toxLock);
+ transfer->Finish(tox);
}
}
@@ -258,14 +251,8 @@ void CToxProto::SendFileAsync(void* arg) // file request is cancelled
int __cdecl CToxProto::FileCancel(MCONTACT hContact, HANDLE hTransfer)
{
- 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());
-
FileTransferParam *transfer = (FileTransferParam*)hTransfer;
-
- transfer->isTerminated = true;
- tox_file_send_control(tox, number, transfer->GetTransferStatus(), transfer->number, TOX_FILECONTROL_KILL, NULL, 0);
+ transfer->Cancel(tox);
RemoveFromTransferList(transfer);
return 0;
@@ -277,11 +264,13 @@ int __cdecl CToxProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const PROTO return FileCancel(hContact, hTransfer);
}
-void CToxProto::OnFileRequest(Tox *tox, int32_t number, uint8_t receive_send, uint8_t fileNumber, uint8_t type, const uint8_t *data, uint16_t length, void *arg)
+void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_send, uint8_t fileNumber, uint8_t type, const uint8_t *data, uint16_t length, void *arg)
{
CToxProto *proto = (CToxProto*)arg;
- MCONTACT hContact = proto->FindContact(number);
+ //mir_cslock lock(proto->toxLock);
+
+ MCONTACT hContact = proto->FindContact(friendNumber);
if (hContact)
{
FileTransferParam *transfer = proto->transfers.at(fileNumber);
@@ -292,22 +281,46 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t number, uint8_t receive_send, ui if (receive_send == 1)
{
// if friend allow file request
- proto->ForkThread(&CToxProto::SendFileAsync, transfer);
+ if (transfer->status == NONE)
+ {
+ proto->ForkThread(&CToxProto::SendFileAsync, transfer);
+ }
+ else
+ {
+ // unpause file transfer
+ transfer->status = STARTED;
+ }
+ }
+ break;
+
+ case TOX_FILECONTROL_PAUSE:
+ transfer->status = PAUSED;
+ break;
+
+ case TOX_FILECONTROL_RESUME_BROKEN:
+ // only for sending
+ if (receive_send == 0)
+ {
+ //uint64_t progress = *(uint64_t*)data;
+ transfer->Start(tox);
}
break;
- // if file transfer is cancelled
case TOX_FILECONTROL_KILL:
- transfer->isTerminated = true;
+ transfer->status = CANCELED;
proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0);
proto->RemoveFromTransferList(transfer);
break;
- // if file transfer is finished
case TOX_FILECONTROL_FINISHED:
if (receive_send == 0)
{
- tox_file_send_control(proto->tox, number, 1, fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0);
+ transfer->Finish(tox);
+ proto->debugLogA("CToxProto::OnFileRequest: finished receiving file (%d)", fileNumber);
+ }
+ else
+ {
+ proto->debugLogA("CToxProto::OnFileRequest: finished sending file (%d)", fileNumber);
}
proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)transfer, 0);
proto->RemoveFromTransferList(transfer);
|