From 2d0cbc078494bbf8f70e68fe629710bbaa30b2e8 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Tue, 3 Feb 2015 21:39:16 +0000 Subject: Tox: rewrited file sending git-svn-id: http://svn.miranda-ng.org/main/trunk@11998 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/src/tox_account.cpp | 3 +- protocols/Tox/src/tox_contacts.cpp | 11 ++- protocols/Tox/src/tox_transfer.cpp | 144 +++++++++++++++++++------------------ protocols/Tox/src/tox_transfer.h | 23 ++++-- 4 files changed, 96 insertions(+), 85 deletions(-) (limited to 'protocols/Tox') diff --git a/protocols/Tox/src/tox_account.cpp b/protocols/Tox/src/tox_account.cpp index 49eb5fa146..7a4d4515ab 100644 --- a/protocols/Tox/src/tox_account.cpp +++ b/protocols/Tox/src/tox_account.cpp @@ -121,7 +121,8 @@ void CToxProto::UninitToxCore() { mir_cslock(transfer->fileLock); - transfer->Cancel(tox); + transfer->status = CANCELED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0); } transfers->Remove(transfer); diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index 0808837727..5fb359100e 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -257,15 +257,12 @@ void CToxProto::OnConnectionStatusChanged(Tox *tox, const int friendNumber, cons FileTransferParam *transfer = proto->transfers->GetAt(i); if (transfer->friendNumber == friendNumber && transfer->GetDirection() == 1) { - if (transfer->Resume(tox) == TOX_ERROR) + proto->debugLogA("CToxProto::OnConnectionStatusChanged: sending ask to resume the transfer of file (%d)", transfer->fileNumber); + transfer->status = STARTED; + if (tox_file_send_control(tox, friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_RESUME_BROKEN, (uint8_t*)&transfer->pfts.currentFileProgress, sizeof(transfer->pfts.currentFileProgress)) == TOX_ERROR) { - transfer->Cancel(tox); - proto->debugLogA("CToxProto::OnConnectionStatusChanged: failed to resuming of file (%d)", - transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber); - continue; + tox_file_send_control(tox, friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); } - proto->debugLogA("CToxProto::OnConnectionStatusChanged: ask to resume the receiving at %llu of %llu of file (%d)", - transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber); } } } diff --git a/protocols/Tox/src/tox_transfer.cpp b/protocols/Tox/src/tox_transfer.cpp index 43656ce349..65a00899ab 100644 --- a/protocols/Tox/src/tox_transfer.cpp +++ b/protocols/Tox/src/tox_transfer.cpp @@ -51,13 +51,19 @@ HANDLE __cdecl CToxProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const P if (!transfer->OpenFile(_T("wb"))) { debugLogA("CToxProto::FileAllow: cannot to open file (%d)", transfer->fileNumber); - transfer->Fail(tox); + transfer->status = FAILED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); transfers->Remove(transfer); return NULL; } debugLogA("CToxProto::FileAllow: start receiving file (%d)", transfer->fileNumber); - transfer->Start(tox); + transfer->status = STARTED; + if (tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0) == TOX_ERROR) + { + debugLogA("CToxProto::FileAllow: failed to start the transfer of file (%d)", transfer->fileNumber); + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); + } } return hTransfer; @@ -91,12 +97,18 @@ int __cdecl CToxProto::FileResume(HANDLE hTransfer, int *action, const PROTOCHAR if (result) { - transfer->Start(tox); debugLogA("CToxProto::FileResume: start receiving file (%d)", transfer->fileNumber); + transfer->status = STARTED; + if (tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0) == TOX_ERROR) + { + debugLogA("CToxProto::FileResume: failed to start the transfer of file (%d)", transfer->fileNumber); + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); + } } else { - transfer->Cancel(tox); + transfer->status = CANCELED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); transfers->Remove(transfer); } ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, result ? ACKRESULT_CONNECTED : ACKRESULT_DENIED, (HANDLE)transfer, 0); @@ -121,7 +133,8 @@ void CToxProto::OnFileData(Tox *tox, int32_t friendNumber, uint8_t fileNumber, c if (transfer == NULL) { proto->debugLogA("CToxProto::OnFileData: cannot find transfer by number (%d)", fileNumber); - transfer->Fail(tox); + transfer->status = FAILED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); return; } @@ -129,7 +142,8 @@ void CToxProto::OnFileData(Tox *tox, int32_t friendNumber, uint8_t fileNumber, c { 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); + transfer->status = FAILED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); return; } @@ -192,45 +206,31 @@ void CToxProto::SendFileAsync(void *arg) FileTransferParam *transfer = (FileTransferParam*)arg; transfer->status = STARTED; - 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 dataSize = 0; + size_t fileProgress = transfer->pfts.currentFileProgress; size_t fileSize = transfer->pfts.currentFileSize; 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 && transfer->hFile != NULL && fileProgress < fileSize) + while (transfer->status == STARTED && transfer->hFile != NULL && fileProgress < fileSize) { mir_cslockfull locker(transfer->fileLock); - if (transfer->status == PAUSED || transfer->status == BROKEN) - { - if (transfer->status == BROKEN) - { - dataSize = 0; - } - locker.unlock(); - Sleep(100); - continue; - } - if (dataSize == 0) { 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); + transfer->status = FAILED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); return; } } if (tox_file_send_data(tox, transfer->friendNumber, transfer->fileNumber, data, dataSize) == TOX_ERROR) { - //fseek(transfer->hFile, -(long)size, SEEK_CUR); locker.unlock(); //Sleep(100); continue; @@ -243,9 +243,14 @@ void CToxProto::SendFileAsync(void *arg) mir_free(data); - if (transfer->status == STARTED) + if (transfer->status == STARTED && fileProgress == fileSize) { - transfer->Finish(tox); + transfer->status = FINISHED; + if (tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0) == TOX_ERROR) + { + debugLogA("CToxProto::SendFileAsync: failed to finish the transfer of file (%d)", transfer->fileNumber); + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); + } } } @@ -255,7 +260,8 @@ void CToxProto::SendFileAsync(void *arg) int __cdecl CToxProto::FileCancel(MCONTACT hContact, HANDLE hTransfer) { FileTransferParam *transfer = (FileTransferParam*)hTransfer; - transfer->Cancel(tox); + transfer->status = CANCELED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); transfers->Remove(transfer); return 0; @@ -284,87 +290,85 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_se switch (type) { case TOX_FILECONTROL_ACCEPT: - // if friend allow file request + // receiver allowed the transfer if (receive_send == 1) { - if (transfer->status == NONE) - { - proto->ForkThread(&CToxProto::SendFileAsync, transfer); - } - else - { - mir_cslock locker(transfer->fileLock); - - // unpause file transfer - transfer->status = STARTED; - } + proto->debugLogA("CToxProto::OnFileRequest: start the transfer of file (%d)", transfer->fileNumber); + // start file sending + proto->ForkThread(&CToxProto::SendFileAsync, transfer); } break; case TOX_FILECONTROL_PAUSE: - { - mir_cslock locker(transfer->fileLock); + { + mir_cslock locker(transfer->fileLock); - transfer->status = PAUSED; - } - break; + transfer->status = PAUSED; + } + break; case TOX_FILECONTROL_RESUME_BROKEN: + // receiver asked to resume transfer if (receive_send == 1) { mir_cslock locker(transfer->fileLock); - // if receiver ask to resume transfer uint64_t progress = *(uint64_t*)data; if (progress >= transfer->pfts.currentFileSize || length != sizeof(uint64_t)) { - transfer->Fail(tox); + transfer->status = FAILED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); } 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->debugLogA("CToxProto::OnFileRequest: failed to resume the transfer of file (%d)", transfer->fileNumber); proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); - transfer->Fail(tox); + transfer->status = FAILED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); 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); + if (_fseeki64(transfer->hFile, progress, SEEK_SET)) + { + proto->debugLogA("CToxProto::OnFileRequest: failed to change file position from %llu to %llu of file (%d)", + transfer->pfts.currentFileProgress, progress, transfer->fileNumber); + transfer->status = FAILED; + tox_file_send_control(tox, transfer->friendNumber, transfer->GetDirection(), transfer->fileNumber, TOX_FILECONTROL_KILL, NULL, 0); + } } - 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; + proto->debugLogA("CToxProto::SendFileAsync: resume the transfer of file (%d)", transfer->fileNumber); + // resume file sending + proto->ForkThread(&CToxProto::SendFileAsync, transfer); } break; case TOX_FILECONTROL_KILL: { mir_cslock locker(transfer->fileLock); - transfer->status = CANCELED; - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0); - proto->transfers->Remove(transfer); } + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0); + proto->transfers->Remove(transfer); break; case TOX_FILECONTROL_FINISHED: - if (receive_send == 0) { - transfer->Finish(tox); - proto->debugLogA("CToxProto::OnFileRequest: finished receiving file (%d)", fileNumber); - } - else - { - proto->debugLogA("CToxProto::OnFileRequest: finished sending file (%d)", fileNumber); + proto->debugLogA("CToxProto::SendFileAsync: finish the transfer of file (%d)", transfer->fileNumber); + bool isFileFullyTransfered = transfer->pfts.currentFileProgress == transfer->pfts.currentFileSize; + { + mir_cslock locker(transfer->fileLock); + transfer->status = isFileFullyTransfered ? FINISHED : FAILED; + } + if (!isFileFullyTransfered) + { + proto->debugLogA("CToxProto::SendFileAsync: file (%d) is transferred not completely", transfer->fileNumber); + } + tox_file_send_control(tox, friendNumber, transfer->GetDirection(), fileNumber, isFileFullyTransfered ? TOX_FILECONTROL_FINISHED : TOX_FILECONTROL_KILL, NULL, 0); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, isFileFullyTransfered ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)transfer, 0); + proto->transfers->Remove(transfer); } - 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 8bc1987bea..13120756fb 100644 --- a/protocols/Tox/src/tox_transfer.h +++ b/protocols/Tox/src/tox_transfer.h @@ -47,16 +47,22 @@ struct FileTransferParam return hFile != NULL; } - int Start(Tox *tox) + /*void Start(Tox *tox) { status = STARTED; - return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0); + if (tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0)) + { + Fail(tox); + } } - int Resume(Tox *tox) + void Resume(Tox *tox) { status = STARTED; - return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_RESUME_BROKEN, (uint8_t*)&pfts.currentFileProgress, sizeof(pfts.currentFileProgress)); + if (tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_RESUME_BROKEN, (uint8_t*)&pfts.currentFileProgress, sizeof(pfts.currentFileProgress)) == -1) + { + Fail(tox); + } } int Fail(Tox *tox) @@ -71,11 +77,14 @@ struct FileTransferParam return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0); } - int Finish(Tox *tox) + void Finish(Tox *tox) { status = FINISHED; - return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0); - } + if (tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0)) + { + Fail(tox); + } + }*/ void Rename(const TCHAR* fileName) { -- cgit v1.2.3