From 9b0bfb26c29c003210dc9fdb568f06d9f9d659ad Mon Sep 17 00:00:00 2001 From: ewensun Date: Mon, 8 Sep 2008 08:44:37 +0000 Subject: [PATCH] add fileControl and fileCancel code in ftController git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@720 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/ft/ftcontroller.cc | 50 +++- libretroshare/src/ft/fttransfermodule.cc | 295 +++++++++++------------ libretroshare/src/ft/fttransfermodule.h | 211 +++++++++------- 3 files changed, 320 insertions(+), 236 deletions(-) diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc index 55ae87b94..7a5e671eb 100644 --- a/libretroshare/src/ft/ftcontroller.cc +++ b/libretroshare/src/ft/ftcontroller.cc @@ -280,13 +280,57 @@ bool ftController::FileRequest(std::string fname, std::string hash, bool ftController::FileCancel(std::string hash) { - /* TODO */ - return false; +#ifdef CONTROL_DEBUG + std::cerr << "ftController::FileCancel" << std::endl; +#endif + /*check if the file in the download map*/ + std::map::iterator mit; + mit=mDownloads.find(hash); + if (mit==mDownloads.end()) + { +#ifdef CONTROL_DEBUG + std::cerr<<"ftController::FileCancel file is not found in mDownloads"<second).mTransfer; + ft->cancelTransfer(); + return true; } bool ftController::FileControl(std::string hash, uint32_t flags) { - return false; +#ifdef CONTROL_DEBUG + std::cerr << "ftController::FileControl(" << hash << ","; + std::cerr << flags << ")"<::iterator mit; + mit=mDownloads.find(hash); + if (mit==mDownloads.end()) + { +#ifdef CONTROL_DEBUG + std::cerr<<"ftController::FileControl file is not found in mDownloads"<second).mTransfer; + switch (flags) + { + case RS_FILE_CTRL_PAUSE: + ft->stopTransfer(); + break; + case RS_FILE_CTRL_START: + ft->resumeTransfer(); + break; + default: + return false; + } + return true; } bool ftController::FileClearCompleted() diff --git a/libretroshare/src/ft/fttransfermodule.cc b/libretroshare/src/ft/fttransfermodule.cc index 977603887..3a46dab8e 100644 --- a/libretroshare/src/ft/fttransfermodule.cc +++ b/libretroshare/src/ft/fttransfermodule.cc @@ -21,32 +21,22 @@ * * Please report all bugs and problems to "retroshare@lunamutt.com". * - */ - -#include "fttransfermodule.h" - -const uint32_t PQIPEER_OFFLINE_CHECK = 120; /* check every 2 minutes */ -const uint32_t PQIPEER_DOWNLOAD_TIMEOUT = 60; /* time it out, -> offline after 60 secs */ -const uint32_t PQIPEER_DOWNLOAD_CHECK = 10; /* desired delta = 10 secs */ -const uint32_t PQIPEER_DOWNLOAD_TOO_FAST = 8; /* 8 secs */ -const uint32_t PQIPEER_DOWNLOAD_TOO_SLOW = 12; /* 12 secs */ -const uint32_t PQIPEER_DOWNLOAD_MIN_DELTA = 5; /* 5 secs */ - -const uint32_t TRANSFER_START_MIN = 10000; /* 10000 byte min limit */ -const uint32_t TRANSFER_START_MAX = 10000; /* 10000 byte max limit */ - -ftTransferModule::ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm) - :mFileCreator(fc), mMultiplexor(dm), mFlag(0) -{ - mHash = mFileCreator->getHash(); - mSize = mFileCreator->getFileSize(); - - // Dummy for Testing (should be handled independantly for - // each peer. - //mChunkSize = 10000; - return; -} - + */ + +#include "fttransfermodule.h" + +ftTransferModule::ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm) + :mFileCreator(fc), mMultiplexor(dm), mFlag(0) +{ + mHash = mFileCreator->getHash(); + mSize = mFileCreator->getFileSize(); + + // Dummy for Testing (should be handled independantly for + // each peer. + //mChunkSize = 10000; + return; +} + ftTransferModule::~ftTransferModule() {} @@ -76,21 +66,11 @@ bool ftTransferModule::setPeerState(std::string peerId,uint32_t state,uint32_t m if (!found) mFileSources.push_back(peerId); std::map::iterator mit; - mit = mOnlinePeers.find(peerId); - if (mit == mOnlinePeers.end()) - { - peerInfo pInfo; - /* Initialise it properly */ - pInfo.peerId = peerId; - pInfo.state = state; - pInfo.offset = 0; - pInfo.chunkSize = TRANSFER_START_MIN; - pInfo.receivedSize = 0; - pInfo.lastTS = 0; - pInfo.actualRate = 0; - pInfo.desiredRate = maxRate; - mOnlinePeers[peerId] = pInfo; - + mit = mOnlinePeers.find(peerId); + if (mit == mOnlinePeers.end()) + { + peerInfo pInfo(peerId,state,maxRate); + mOnlinePeers[peerId] = pInfo; } else { @@ -111,93 +91,98 @@ uint32_t ftTransferModule::getDataRate(std::string peerId) return (uint32_t) (mit->second).actualRate; } - - //interface to client module -bool ftTransferModule::recvFileData(std::string peerId, uint64_t offset, - uint32_t chunk_size, void *data) -{ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::recvFileData()"; - std::cerr << " peerId: " << peerId; - std::cerr << " offset: " << offset; - std::cerr << " chunksize: " << chunk_size; - std::cerr << std::endl; -#endif - std::map::iterator mit; - mit = mOnlinePeers.find(peerId); - if (mit == mOnlinePeers.end()) - return false; - if ((mit->second).state != PQIPEER_DOWNLOADING) - return false; - if (offset != ((mit->second).offset + (mit->second).receivedSize)) - return false; - (mit->second).receivedSize += chunk_size; - (mit->second).state = PQIPEER_IDLE; - - return storeData(offset, chunk_size, data); -} - -void ftTransferModule::requestData(std::string peerId, uint64_t offset, uint32_t chunk_size) -{ - std::cerr << "ftTransferModule::requestData()"; - std::cerr << " peerId: " << peerId; - std::cerr << " offset: " << offset; - std::cerr << " chunk_size: " << chunk_size; - std::cerr << std::endl; - - mMultiplexor->sendDataRequest(peerId, mHash, mSize, offset,chunk_size); -} - -bool ftTransferModule::getChunk(uint64_t &offset, uint32_t &chunk_size) -{ - std::cerr << "ftTransferModule::getChunk()"; - std::cerr << " Request: offset: " << offset; - std::cerr << " chunk_size: " << chunk_size; - std::cerr << std::endl; - - bool val = mFileCreator->getMissingChunk(offset, chunk_size); - - if (val) - { - std::cerr << "ftTransferModule::getChunk()"; - std::cerr << " Answer: offset: " << offset; - std::cerr << " chunk_size: " << chunk_size; - std::cerr << std::endl; - } - else - { - std::cerr << "ftTransferModule::getChunk()"; - std::cerr << " Answer: No Chunk Available"; - std::cerr << std::endl; - } - - return val; -} - -bool ftTransferModule::storeData(uint64_t offset, uint32_t chunk_size,void *data) -{ - std::cerr << "ftTransferModule::storeData()"; - std::cerr << " offset: " << offset; - std::cerr << " chunk_size: " << chunk_size; - std::cerr << std::endl; - - return mFileCreator -> addFileData(offset, chunk_size, data); -} - + + //interface to client module +bool ftTransferModule::recvFileData(std::string peerId, uint64_t offset, + uint32_t chunk_size, void *data) +{ +#ifdef FT_DEBUG + std::cerr << "ftTransferModule::recvFileData()"; + std::cerr << " peerId: " << peerId; + std::cerr << " offset: " << offset; + std::cerr << " chunksize: " << chunk_size; + std::cerr << std::endl; +#endif + std::map::iterator mit; + mit = mOnlinePeers.find(peerId); + if (mit == mOnlinePeers.end()) + return false; + if ((mit->second).state != PQIPEER_DOWNLOADING) + return false; + if (offset != ((mit->second).offset + (mit->second).receivedSize)) + return false; + (mit->second).receivedSize += chunk_size; + (mit->second).state = PQIPEER_IDLE; + + return storeData(offset, chunk_size, data); +} + +void ftTransferModule::requestData(std::string peerId, uint64_t offset, uint32_t chunk_size) +{ + std::cerr << "ftTransferModule::requestData()"; + std::cerr << " peerId: " << peerId; + std::cerr << " offset: " << offset; + std::cerr << " chunk_size: " << chunk_size; + std::cerr << std::endl; + + mMultiplexor->sendDataRequest(peerId, mHash, mSize, offset,chunk_size); +} + +bool ftTransferModule::getChunk(uint64_t &offset, uint32_t &chunk_size) +{ + std::cerr << "ftTransferModule::getChunk()"; + std::cerr << " Request: offset: " << offset; + std::cerr << " chunk_size: " << chunk_size; + std::cerr << std::endl; + + bool val = mFileCreator->getMissingChunk(offset, chunk_size); + + if (val) + { + std::cerr << "ftTransferModule::getChunk()"; + std::cerr << " Answer: offset: " << offset; + std::cerr << " chunk_size: " << chunk_size; + std::cerr << std::endl; + } + else + { + std::cerr << "ftTransferModule::getChunk()"; + std::cerr << " Answer: No Chunk Available"; + std::cerr << std::endl; + } + + return val; +} + +bool ftTransferModule::storeData(uint64_t offset, uint32_t chunk_size,void *data) +{ + std::cerr << "ftTransferModule::storeData()"; + std::cerr << " offset: " << offset; + std::cerr << " chunk_size: " << chunk_size; + std::cerr << std::endl; + + return mFileCreator -> addFileData(offset, chunk_size, data); +} + void ftTransferModule::queryInactive() { #ifdef FT_DEBUG std::ostringstream out; out<<"ftTransferModule::queryInactive()"; out<::iterator mit; for(mit = mOnlinePeers.begin(); mit != mOnlinePeers.end(); mit++) { @@ -263,33 +248,43 @@ void ftTransferModule::queryInactive() } -bool ftTransferModule::stopTransfer() +bool ftTransferModule::pauseTransfer() { +/* std::map::iterator mit; for(mit = mOnlinePeers.begin(); mit != mOnlinePeers.end(); mit++) { (mit->second).state = PQIPEER_SUSPEND; } - +*/ + mFileStatus.stat=ftFileStatus::PQIFILE_PAUSE; + return 1; } bool ftTransferModule::resumeTransfer() { +/* std::map::iterator mit; for(mit = mOnlinePeers.begin(); mit != mOnlinePeers.end(); mit++) { (mit->second).state = PQIPEER_IDLE; } +*/ + mFileStatus.stat=ftFileStatus::PQIFILE_DOWNLOADING; return 1; } -bool ftTransferModule::completeFileTransfer() -{ - return true; -} - +bool ftTransferModule::cancelTransfer() +{ +} + +bool ftTransferModule::completeFileTransfer() +{ + return true; +} + int ftTransferModule::tick() { queryInactive(); @@ -299,28 +294,28 @@ int ftTransferModule::tick() return 0; } - - -void ftTransferModule::adjustSpeed() -{ + + +void ftTransferModule::adjustSpeed() +{ std::map::iterator mit; for(mit = mOnlinePeers.begin(); mit != mOnlinePeers.end(); mit++) - { - if (((mit->second).state == PQIPEER_DOWNLOADING) - || ((mit->second).state == PQIPEER_IDLE)) - { - if ((actualRate < desiredRate) && ((mit->second).actualRate >= (mit->second).desiredRate)) - { - (mit->second).desiredRate *= 1.1; - } - - if ((actualRate > desiredRate) && ((mit->second).actualRate < (mit->second).desiredRate)) - { - (mit->second).desiredRate *= 0.9; - } - } - } - return; -} - - + { + if (((mit->second).state == PQIPEER_DOWNLOADING) + || ((mit->second).state == PQIPEER_IDLE)) + { + if ((actualRate < desiredRate) && ((mit->second).actualRate >= (mit->second).desiredRate)) + { + (mit->second).desiredRate *= 1.1; + } + + if ((actualRate > desiredRate) && ((mit->second).actualRate < (mit->second).desiredRate)) + { + (mit->second).desiredRate *= 0.9; + } + } + } + return; +} + + diff --git a/libretroshare/src/ft/fttransfermodule.h b/libretroshare/src/ft/fttransfermodule.h index af93784c7..c570c999c 100644 --- a/libretroshare/src/ft/fttransfermodule.h +++ b/libretroshare/src/ft/fttransfermodule.h @@ -34,96 +34,141 @@ * It must be able to cope with varying data rates and dropped peers without flooding the system with too many requests. * */ - -#include -#include -#include - -#include "ft/ftfilecreator.h" -#include "ft/ftdatamultiplex.h" - -#include "util/rsthreads.h" - + +#include +#include +#include + +#include "ft/ftfilecreator.h" +#include "ft/ftdatamultiplex.h" + +#include "util/rsthreads.h" + const int PQIPEER_INIT = 0x0000; const int PQIPEER_NOT_ONLINE = 0x0001; const int PQIPEER_DOWNLOADING = 0x0002; const int PQIPEER_IDLE = 0x0004; const int PQIPEER_SUSPEND = 0x0010; +const uint32_t PQIPEER_OFFLINE_CHECK = 120; /* check every 2 minutes */ +const uint32_t PQIPEER_DOWNLOAD_TIMEOUT = 60; /* time it out, -> offline after 60 secs */ +const uint32_t PQIPEER_DOWNLOAD_CHECK = 10; /* desired delta = 10 secs */ +const uint32_t PQIPEER_DOWNLOAD_TOO_FAST = 8; /* 8 secs */ +const uint32_t PQIPEER_DOWNLOAD_TOO_SLOW = 12; /* 12 secs */ +const uint32_t PQIPEER_DOWNLOAD_MIN_DELTA = 5; /* 5 secs */ + +const uint32_t TRANSFER_START_MIN = 10000; /* 10000 byte min limit */ +const uint32_t TRANSFER_START_MAX = 10000; /* 10000 byte max limit */ +/* class Request { - public: - uint64_t offset; - uint32_t chunkSize; +public: + uint64_t offset; + uint32_t chunkSize; +}; +*/ +class peerInfo +{ +public: + peerInfo(std::string peerId_in,uint32_t state_in,uint32_t maxRate_in): + peerId(peerId_in),state(state_in),desiredRate(maxRate_in),actualRate(0), + offset(0),chunkSize(TRANSFER_START_MIN),receivedSize(0),lastTS(0) + { + return; + } + std::string peerId; + uint32_t state; + double desiredRate; + double actualRate; + + //current file data request + uint64_t offset; + uint32_t chunkSize; + + //already received data size + uint32_t receivedSize; + + time_t lastTS; }; -class peerInfo -{ - public: - std::string peerId; - uint32_t state; - double desiredRate; - double actualRate; - - //current file data request - uint64_t offset; - uint32_t chunkSize; - - //already received data size - uint32_t receivedSize; - - time_t lastTS; -}; - -class ftTransferModule -{ -public: - ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm); - ~ftTransferModule(); - - //interface to download controller - bool setFileSources(std::list peerIds); - bool setPeerState(std::string peerId,uint32_t state,uint32_t maxRate); //state = ONLINE/OFFLINE - uint32_t getDataRate(std::string peerId); - bool stopTransfer(); - bool resumeTransfer(); - bool completeFileTransfer(); - - //interface to multiplex module - bool recvFileData(std::string peerId, uint64_t offset, - uint32_t chunk_size, void *data); - void requestData(std::string peerId, uint64_t offset, uint32_t chunk_size); - - //interface to file creator - bool getChunk(uint64_t &offset, uint32_t &chunk_size); - bool storeData(uint64_t offset, uint32_t chunk_size, void *data); - - int tick(); - - std::string hash() { return mHash; } - uint64_t size() { return mSize; } - - //internal used functions - void queryInactive(); - void adjustSpeed(); - -private: - - /* These have independent Mutexes / are const locally (no Mutex protection)*/ - ftFileCreator *mFileCreator; - ftDataMultiplex *mMultiplexor; - - std::string mHash; - uint64_t mSize; - - RsMutex tfMtx; /* below is mutex protected */ - - std::list mFileSources; - std::map mOnlinePeers; - - bool mFlag; //1:transfer complete, 0: not complete - double desiredRate; - double actualRate; -}; - -#endif //FT_TRANSFER_MODULE_HEADER +class ftFileStatus +{ + enum Status { + PQIFILE_INIT, + PQIFILE_NOT_ONLINE, + PQIFILE_DOWNLOADING, + PQIFILE_PAUSE, + PQIFILE_COMPLETE, + PQIFILE_FAIL, + PQIFILE_FAIL_CANCEL, + PQIFILE_FAIL_NOT_AVAIL, + PQIFILE_FAIL_NOT_OPEN, + PQIFILE_FAIL_NOT_SEEK, + PQIFILE_FAIL_NOT_WRITE, + PQIFILE_FAIL_NOT_READ, + PQIFILE_FAIL_BAD_PATH + }; +public: + ftFileStatus(std::string hash_in):hash(hash_in),stat(PQIFILE_INIT) + { + return; + } + std::string hash; + Status stat; +}; + +class ftTransferModule +{ +public: + ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm); + ~ftTransferModule(); + + //interface to download controller + bool setFileSources(std::list peerIds); + bool setPeerState(std::string peerId,uint32_t state,uint32_t maxRate); //state = ONLINE/OFFLINE + uint32_t getDataRate(std::string peerId); + bool pauseTransfer(); + bool resumeTransfer(); + bool cancelTransfer(); + bool completeFileTransfer(); + + //interface to multiplex module + bool recvFileData(std::string peerId, uint64_t offset, + uint32_t chunk_size, void *data); + void requestData(std::string peerId, uint64_t offset, uint32_t chunk_size); + + //interface to file creator + bool getChunk(uint64_t &offset, uint32_t &chunk_size); + bool storeData(uint64_t offset, uint32_t chunk_size, void *data); + + int tick(); + + std::string hash() { return mHash; } + uint64_t size() { return mSize; } + + //internal used functions + void queryInactive(); + void adjustSpeed(); + +private: + + /* These have independent Mutexes / are const locally (no Mutex protection)*/ + ftFileCreator *mFileCreator; + ftDataMultiplex *mMultiplexor; + + std::string mHash; + uint64_t mSize; + + RsMutex tfMtx; /* below is mutex protected */ + + std::list mFileSources; + std::map mOnlinePeers; + + bool mFlag; //1:transfer complete, 0: not complete + double desiredRate; + double actualRate; + + ftFileStatus mFileStatus; //used for pause/resume file transfer +}; + +#endif //FT_TRANSFER_MODULE_HEADER