mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
- implemented a visualisation for currently handled chunks, availability maps, and transfer info
- implemented transfer protocol for chunk availability maps between peers (not enabled yet though) - suppressed rsiface directory from retroshare-gui - moved notifyqt.{h,cpp} to gui/ next moves: - send availability maps to clients; - connect turtle search to unfinished files; - test multisource download with unfinished files. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1939 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
1a86871556
commit
f4a2eaecce
@ -212,16 +212,28 @@ bool ChunkMap::getDataChunk(const std::string& peer_id,uint32_t size_hint,ftChun
|
||||
return true ;
|
||||
}
|
||||
|
||||
#ifdef A_FAIRE
|
||||
void setPeerAvailabilityMap(const std::string& peer_id,const std::vector<uint32_t>& peer_map)
|
||||
void ChunkMap::setPeerAvailabilityMap(const std::string& peer_id,uint32_t chunk_size,uint32_t nb_chunks,const std::vector<uint32_t>& compressed_peer_map)
|
||||
{
|
||||
#ifdef DEBUG_FTCHUNK
|
||||
std::cout << "Receiving new availability map for peer " << peer_id << std::endl ;
|
||||
std::cout << "ChunkMap::Receiving new availability map for peer " << peer_id << std::endl ;
|
||||
#endif
|
||||
// Check that the parameters are the same. Otherwise we should convert the info into the local format.
|
||||
// If all RS instances have the same policy for deciding the sizes of chunks, this should not happen.
|
||||
|
||||
_peers_chunks_availability[peer_id] = peer_map ;
|
||||
}
|
||||
if(chunk_size != _chunk_size || nb_chunks != _map.size())
|
||||
{
|
||||
std::cerr << "ChunkMap::setPeerAvailabilityMap: chunk size / number of chunks is not correct. Dropping the info." << std::endl ;
|
||||
return ;
|
||||
}
|
||||
|
||||
// sets the map.
|
||||
//
|
||||
_peers_chunks_availability[peer_id] = compressed_peer_map ;
|
||||
|
||||
#ifdef DEBUG_FTCHUNK
|
||||
std::cerr << "ChunkMap::setPeerAvailabilityMap: Setting chunk availability info for peer " << peer_id << std::endl ;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t ChunkMap::sizeOfChunk(uint32_t cid) const
|
||||
{
|
||||
@ -231,11 +243,10 @@ uint32_t ChunkMap::sizeOfChunk(uint32_t cid) const
|
||||
return _chunk_size ;
|
||||
}
|
||||
|
||||
uint32_t ChunkMap::getAvailableChunk(uint32_t start_location,const std::string& peer_id) const
|
||||
uint32_t ChunkMap::getAvailableChunk(uint32_t start_location,const std::string& peer_id)
|
||||
{
|
||||
// Very bold algorithm: checks for 1st availabe chunk for this peer starting
|
||||
// from the given start location.
|
||||
#ifdef A_FAIRE
|
||||
std::map<std::string,std::vector<uint32_t> >::const_iterator it(_peers_chunks_availability.find(peer_id)) ;
|
||||
|
||||
// Do we have records for this file source ?
|
||||
@ -243,18 +254,21 @@ uint32_t ChunkMap::getAvailableChunk(uint32_t start_location,const std::string&
|
||||
if(it == _peers_chunks_availability.end())
|
||||
{
|
||||
#ifdef DEBUG_FTCHUNK
|
||||
std::cout << "No chunk map for peer " << peer_id << ": returning false" << endl ;
|
||||
std::cout << "No chunk map for peer " << peer_id << ": supposing full data." << std::endl ;
|
||||
#endif
|
||||
return _map.size() ;
|
||||
std::vector<uint32_t>& pchunks(_peers_chunks_availability[peer_id]) ;
|
||||
|
||||
pchunks.resize( (_map.size() >> 5)+!!(_map.size() & 0x11111),~(uint32_t)0 ) ;
|
||||
|
||||
it = _peers_chunks_availability.find(peer_id) ;
|
||||
}
|
||||
const std::vector<uint32_t> peer_chunks(it->second) ;
|
||||
#endif
|
||||
const std::vector<uint32_t>& peer_chunks(it->second) ;
|
||||
|
||||
for(unsigned int i=0;i<_map.size();++i)
|
||||
{
|
||||
uint32_t j = (start_location+i)%_map.size() ;
|
||||
uint32_t j = (start_location+i)%(int)_map.size() ; // index of the chunk
|
||||
|
||||
if(_map[j] == FileChunksInfo::CHUNK_OUTSTANDING /*&& peers_chunks[j] == CHUNK_DONE*/)
|
||||
if(_map[j] == FileChunksInfo::CHUNK_OUTSTANDING && COMPRESSED_MAP_READ(peer_chunks,j))
|
||||
{
|
||||
#ifdef DEBUG_FTCHUNK
|
||||
std::cerr << "ChunkMap::getAvailableChunk: returning chunk " << j << " for peer " << peer_id << std::endl;
|
||||
@ -274,6 +288,16 @@ void ChunkMap::getChunksInfo(FileChunksInfo& info) const
|
||||
info.file_size = _file_size ;
|
||||
info.chunk_size = _chunk_size ;
|
||||
info.chunks = _map ;
|
||||
|
||||
info.active_chunks.clear() ;
|
||||
|
||||
for(std::map<ChunkNumber,ChunkDownloadInfo>::const_iterator it(_slices_to_download.begin());it!=_slices_to_download.end();++it)
|
||||
info.active_chunks.push_back(std::pair<uint32_t,uint32_t>(it->first,it->second._remains)) ;
|
||||
|
||||
info.compressed_peer_availability_maps.clear() ;
|
||||
|
||||
for(std::map<std::string,std::vector<uint32_t> >::const_iterator it(_peers_chunks_availability.begin());it!= _peers_chunks_availability.end();++it)
|
||||
info.compressed_peer_availability_maps.push_back(std::pair<std::string,std::vector<uint32_t> >(it->first,it->second)) ;
|
||||
}
|
||||
|
||||
void ChunkMap::buildAvailabilityMap(std::vector<uint32_t>& map,uint32_t& chunk_size,uint32_t& chunk_number,FileChunksInfo::ChunkStrategy& strategy) const
|
||||
|
@ -24,7 +24,8 @@
|
||||
// corresponding acive slice. When asked a slice, ftChunkMap cuts out a slice from the remaining part of the chunk
|
||||
// to download, sends the slice's coordinates and gives a unique slice id (such as the slice offset).
|
||||
|
||||
// This class handles a slice of a chunk, at the level of ftFileCreator
|
||||
|
||||
// This class handles a slice of a chunk of arbitrary uint32_t size, at the level of ftFileCreator
|
||||
|
||||
class ftChunk
|
||||
{
|
||||
@ -41,10 +42,10 @@ class ftChunk
|
||||
time_t ts;
|
||||
};
|
||||
|
||||
// This class handles a single chunk. Although each chunk is requested at once,
|
||||
// This class handles a single fixed-sized chunk. Although each chunk is requested at once,
|
||||
// it may be sent back into sub-chunks because of file transfer rate constraints.
|
||||
// So the dataReceived function should be called to progressively complete the chunk,
|
||||
// and the getChunk method should ask for a sub0chunk of a given size.
|
||||
// and the getChunk method should ask for a sub-chunk of a given size.
|
||||
//
|
||||
class Chunk
|
||||
{
|
||||
@ -118,11 +119,9 @@ class ChunkMap
|
||||
void buildAvailabilityMap(std::vector<uint32_t>& map,uint32_t& chunk_size,uint32_t& chunk_number,FileChunksInfo::ChunkStrategy& s) const ;
|
||||
void loadAvailabilityMap(const std::vector<uint32_t>& map,uint32_t chunk_size,uint32_t chunk_number,FileChunksInfo::ChunkStrategy s) ;
|
||||
|
||||
#ifdef TO_DO
|
||||
// Updates the peer's availablility map
|
||||
//
|
||||
void setPeerAvailabilityMap(const std::string& peer_id,const std::vector<uint32_t>& peer_map) ;
|
||||
#endif
|
||||
void setPeerAvailabilityMap(const std::string& peer_id,uint32_t chunk_size,uint32_t nb_chunks,const std::vector<uint32_t>& peer_map) ;
|
||||
|
||||
// Returns the total size of downloaded data in the file.
|
||||
uint64_t getTotalReceived() const { return _total_downloaded ; }
|
||||
@ -134,7 +133,7 @@ class ChunkMap
|
||||
|
||||
// Returns the first chunk available starting from start_location for this peer_id.
|
||||
//
|
||||
uint32_t getAvailableChunk(uint32_t start_location,const std::string& peer_id) const ;
|
||||
uint32_t getAvailableChunk(uint32_t start_location,const std::string& peer_id) ;
|
||||
|
||||
private:
|
||||
uint64_t _file_size ; // total size of the file in bytes.
|
||||
@ -145,7 +144,7 @@ class ChunkMap
|
||||
|
||||
std::vector<FileChunksInfo::ChunkState> _map ; // vector of chunk state over the whole file
|
||||
|
||||
std::map<std::string,std::vector<uint32_t> > _peers_chunks_availability ; // what does each source peer have.
|
||||
std::map<std::string,std::vector<uint32_t> > _peers_chunks_availability ; // what does each source peer have, stored in compressed format.
|
||||
|
||||
uint64_t _total_downloaded ;
|
||||
};
|
||||
|
@ -599,6 +599,8 @@ bool ftController::handleAPendingRequest()
|
||||
mPendingChunkMaps.erase(it) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
@ -750,7 +752,7 @@ bool ftController::FileRequest(std::string fname, std::string hash,
|
||||
/* do a source search - for any extra sources */
|
||||
if (mSearch->search(hash, size,
|
||||
RS_FILE_HINTS_REMOTE |
|
||||
RS_FILE_HINTS_TURTLE |
|
||||
// RS_FILE_HINTS_TURTLE |
|
||||
RS_FILE_HINTS_SPEC_ONLY, info))
|
||||
{
|
||||
/* do something with results */
|
||||
|
@ -328,6 +328,31 @@ bool ftDataMultiplex::doWork()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ftDataMultiplex::recvFileMap(const std::string& peerId, const std::string& hash, uint32_t chunk_size, uint32_t nb_chunks, const std::vector<uint32_t>& compressed_map)
|
||||
{
|
||||
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
|
||||
std::map<std::string, ftClient>::iterator it;
|
||||
|
||||
if (mClients.end() == (it = mClients.find(hash)))
|
||||
{
|
||||
#ifdef MPLEX_DEBUG
|
||||
std::cerr << "ftDataMultiplex::handleRecvMap() ERROR: No matching Client!";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* error */
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef MPLEX_DEBUG
|
||||
std::cerr << "ftDataMultiplex::handleRecvMap() Passing map to FT Module";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
(it->second).mCreator->setSourceMap(peerId, chunk_size, nb_chunks,compressed_map);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ftDataMultiplex::handleRecvData(std::string peerId,
|
||||
std::string hash, uint64_t size,
|
||||
|
@ -84,81 +84,72 @@ class ftDataMultiplex: public ftDataRecv, public RsQueueThread
|
||||
|
||||
public:
|
||||
|
||||
ftDataMultiplex(std::string ownId, ftDataSend *server, ftSearch *search);
|
||||
ftDataMultiplex(std::string ownId, ftDataSend *server, ftSearch *search);
|
||||
|
||||
/* ftController Interface */
|
||||
bool addTransferModule(ftTransferModule *mod, ftFileCreator *f);
|
||||
bool removeTransferModule(std::string hash);
|
||||
/* ftController Interface */
|
||||
bool addTransferModule(ftTransferModule *mod, ftFileCreator *f);
|
||||
bool removeTransferModule(std::string hash);
|
||||
|
||||
/* data interface */
|
||||
/* get Details of File Transfers */
|
||||
bool FileUploads(std::list<std::string> &hashs);
|
||||
bool FileDownloads(std::list<std::string> &hashs);
|
||||
bool FileDetails(std::string hash, uint32_t hintsflag, FileInfo &info);
|
||||
/* data interface */
|
||||
/* get Details of File Transfers */
|
||||
bool FileUploads(std::list<std::string> &hashs);
|
||||
bool FileDownloads(std::list<std::string> &hashs);
|
||||
bool FileDetails(std::string hash, uint32_t hintsflag, FileInfo &info);
|
||||
|
||||
void deleteServers(const std::list<std::string>& serv_hash) ;
|
||||
void deleteServers(const std::list<std::string>& serv_hash) ;
|
||||
|
||||
|
||||
/*************** SEND INTERFACE (calls ftDataSend) *******************/
|
||||
/*************** SEND INTERFACE (calls ftDataSend) *******************/
|
||||
|
||||
/* Client Send */
|
||||
bool sendDataRequest(std::string peerId, std::string hash, uint64_t size,
|
||||
uint64_t offset, uint32_t chunksize);
|
||||
/* Client Send */
|
||||
bool sendDataRequest(std::string peerId, std::string hash, uint64_t size,
|
||||
uint64_t offset, uint32_t chunksize);
|
||||
|
||||
/* Server Send */
|
||||
bool sendData(std::string peerId, std::string hash, uint64_t size,
|
||||
uint64_t offset, uint32_t chunksize, void *data);
|
||||
/* Server Send */
|
||||
bool sendData(std::string peerId, std::string hash, uint64_t size,
|
||||
uint64_t offset, uint32_t chunksize, void *data);
|
||||
|
||||
|
||||
/*************** RECV INTERFACE (provides ftDataRecv) ****************/
|
||||
/*************** RECV INTERFACE (provides ftDataRecv) ****************/
|
||||
|
||||
/* Client Recv */
|
||||
virtual bool recvData(std::string peerId, std::string hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data);
|
||||
/* Client Recv */
|
||||
virtual bool recvData(std::string peerId, std::string hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data);
|
||||
virtual bool recvFileMap(const std::string& peerId, const std::string& hash, uint32_t chunk_size, uint32_t nb_chunks, const std::vector<uint32_t>& compressed_map) ;
|
||||
|
||||
/* Server Recv */
|
||||
virtual bool recvDataRequest(std::string peerId, std::string hash, uint64_t size, uint64_t offset, uint32_t chunksize);
|
||||
/* Server Recv */
|
||||
virtual bool recvDataRequest(std::string peerId, std::string hash, uint64_t size, uint64_t offset, uint32_t chunksize);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/* Overloaded from RsQueueThread */
|
||||
virtual bool workQueued();
|
||||
virtual bool doWork();
|
||||
/* Overloaded from RsQueueThread */
|
||||
virtual bool workQueued();
|
||||
virtual bool doWork();
|
||||
|
||||
private:
|
||||
|
||||
/* Handling Job Queues */
|
||||
bool handleRecvData(std::string peerId,
|
||||
std::string hash, uint64_t size,
|
||||
uint64_t offset, uint32_t chunksize, void *data);
|
||||
/* Handling Job Queues */
|
||||
bool handleRecvData(std::string peerId, std::string hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data);
|
||||
bool handleRecvDataRequest(std::string peerId, std::string hash, uint64_t size, uint64_t offset, uint32_t chunksize);
|
||||
bool handleSearchRequest(std::string peerId, std::string hash, uint64_t size, uint64_t offset, uint32_t chunksize);
|
||||
|
||||
bool handleRecvDataRequest(std::string peerId,
|
||||
std::string hash, uint64_t size,
|
||||
uint64_t offset, uint32_t chunksize);
|
||||
/* We end up doing the actual server job here */
|
||||
bool locked_handleServerRequest(ftFileProvider *provider, std::string peerId, std::string hash, uint64_t size, uint64_t offset, uint32_t chunksize);
|
||||
|
||||
bool handleSearchRequest(std::string peerId,
|
||||
std::string hash, uint64_t size,
|
||||
uint64_t offset, uint32_t chunksize);
|
||||
RsMutex dataMtx;
|
||||
|
||||
/* We end up doing the actual server job here */
|
||||
bool locked_handleServerRequest(ftFileProvider *provider,
|
||||
std::string peerId, std::string hash, uint64_t size,
|
||||
uint64_t offset, uint32_t chunksize);
|
||||
std::map<std::string, ftClient> mClients;
|
||||
std::map<std::string, ftFileProvider *> mServers;
|
||||
|
||||
RsMutex dataMtx;
|
||||
std::list<ftRequest> mRequestQueue;
|
||||
std::list<ftRequest> mSearchQueue;
|
||||
std::map<std::string, time_t> mUnknownHashs;
|
||||
|
||||
std::map<std::string, ftClient> mClients;
|
||||
std::map<std::string, ftFileProvider *> mServers;
|
||||
ftDataSend *mDataSend;
|
||||
ftSearch *mSearch;
|
||||
std::string mOwnId;
|
||||
|
||||
std::list<ftRequest> mRequestQueue;
|
||||
std::list<ftRequest> mSearchQueue;
|
||||
std::map<std::string, time_t> mUnknownHashs;
|
||||
|
||||
ftDataSend *mDataSend;
|
||||
ftSearch *mSearch;
|
||||
std::string mOwnId;
|
||||
|
||||
friend class ftServer;
|
||||
friend class ftServer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -409,6 +409,7 @@ void ftFileCreator::loadAvailabilityMap(const std::vector<uint32_t>& map,uint32_
|
||||
|
||||
chunkMap = ChunkMap(mSize,map,chunk_size,chunk_number,FileChunksInfo::ChunkStrategy(strategy)) ;
|
||||
}
|
||||
|
||||
void ftFileCreator::storeAvailabilityMap(std::vector<uint32_t>& map,uint32_t& chunk_size,uint32_t& chunk_number,uint32_t& strategy)
|
||||
{
|
||||
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||
@ -418,4 +419,11 @@ void ftFileCreator::storeAvailabilityMap(std::vector<uint32_t>& map,uint32_t& ch
|
||||
strategy = (uint32_t)strat ;
|
||||
}
|
||||
|
||||
void ftFileCreator::setSourceMap(const std::string& peer_id,uint32_t chunk_size,uint32_t nb_chunks,const std::vector<uint32_t>& compressed_map)
|
||||
{
|
||||
RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/
|
||||
|
||||
chunkMap.setPeerAvailabilityMap(peer_id,chunk_size,nb_chunks,compressed_map) ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,48 +38,64 @@
|
||||
|
||||
class ftFileCreator: public ftFileProvider
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
ftFileCreator(std::string savepath, uint64_t size, std::string hash, uint64_t recvd);
|
||||
|
||||
~ftFileCreator();
|
||||
ftFileCreator(std::string savepath, uint64_t size, std::string hash, uint64_t recvd);
|
||||
|
||||
/* overloaded from FileProvider */
|
||||
virtual bool getFileData(uint64_t offset, uint32_t &chunk_size, void *data);
|
||||
bool finished() { return getRecvd() == getFileSize(); }
|
||||
uint64_t getRecvd();
|
||||
|
||||
void getChunkMap(FileChunksInfo& info) ;
|
||||
void setChunkStrategy(FileChunksInfo::ChunkStrategy s) ;
|
||||
~ftFileCreator();
|
||||
|
||||
/*
|
||||
* creation functions for FileCreator
|
||||
*/
|
||||
/* overloaded from FileProvider */
|
||||
virtual bool getFileData(uint64_t offset, uint32_t &chunk_size, void *data);
|
||||
bool finished() { return getRecvd() == getFileSize(); }
|
||||
uint64_t getRecvd();
|
||||
|
||||
bool getMissingChunk(const std::string& peer_id,uint32_t size_hint,uint64_t& offset, uint32_t& size);
|
||||
bool addFileData(uint64_t offset, uint32_t chunk_size, void *data);
|
||||
void getChunkMap(FileChunksInfo& info) ;
|
||||
void setChunkStrategy(FileChunksInfo::ChunkStrategy s) ;
|
||||
|
||||
void loadAvailabilityMap(const std::vector<uint32_t>& map,uint32_t chunk_size,uint32_t chunk_number,uint32_t chunk_strategy) ;
|
||||
void storeAvailabilityMap(std::vector<uint32_t>& map,uint32_t& chunk_size,uint32_t& chunk_number,uint32_t& chunk_strategy) ;
|
||||
/*
|
||||
* creation functions for FileCreator
|
||||
*/
|
||||
|
||||
protected:
|
||||
// Gets a new variable-sized chunk of size "size_hint" from the given peer id. The returned size, "size" is
|
||||
// at most equal to size_hint.
|
||||
//
|
||||
bool getMissingChunk(const std::string& peer_id,uint32_t size_hint,uint64_t& offset, uint32_t& size);
|
||||
|
||||
virtual int initializeFileAttrs();
|
||||
// actually store data in the file, and update chunks info
|
||||
//
|
||||
bool addFileData(uint64_t offset, uint32_t chunk_size, void *data);
|
||||
|
||||
private:
|
||||
// Load/save the availability map for the file being downloaded, in a compact/compressed form.
|
||||
// This is used for
|
||||
// - loading and saving info about the current transfers
|
||||
// - getting info about current chunks for the GUI
|
||||
// - sending availability info to the peers for which we also are a source
|
||||
//
|
||||
void loadAvailabilityMap(const std::vector<uint32_t>& map,uint32_t chunk_size,uint32_t chunk_number,uint32_t chunk_strategy) ;
|
||||
void storeAvailabilityMap(std::vector<uint32_t>& map,uint32_t& chunk_size,uint32_t& chunk_number,uint32_t& chunk_strategy) ;
|
||||
|
||||
bool locked_printChunkMap();
|
||||
int locked_notifyReceived(uint64_t offset, uint32_t chunk_size);
|
||||
/*
|
||||
* structure to track missing chunks
|
||||
*/
|
||||
|
||||
uint64_t mStart;
|
||||
uint64_t mEnd;
|
||||
// This is called when receiving the availability map from a source peer, for the file being handled.
|
||||
//
|
||||
void setSourceMap(const std::string& peer_id,uint32_t chunk_size,uint32_t nb_chunks,const std::vector<uint32_t>& map) ;
|
||||
|
||||
std::map<uint64_t, ftChunk> mChunks;
|
||||
protected:
|
||||
|
||||
ChunkMap chunkMap ;
|
||||
virtual int initializeFileAttrs();
|
||||
|
||||
private:
|
||||
|
||||
bool locked_printChunkMap();
|
||||
int locked_notifyReceived(uint64_t offset, uint32_t chunk_size);
|
||||
/*
|
||||
* structure to track missing chunks
|
||||
*/
|
||||
|
||||
uint64_t mStart;
|
||||
uint64_t mEnd;
|
||||
|
||||
std::map<uint64_t, ftChunk> mChunks;
|
||||
|
||||
ChunkMap chunkMap ;
|
||||
};
|
||||
|
||||
#endif // FT_FILE_CREATOR_HEADER
|
||||
|
@ -156,7 +156,7 @@ void ftServer::connectToTurtleRouter(p3turtle *fts)
|
||||
{
|
||||
mTurtleRouter = fts ;
|
||||
|
||||
mFtSearch->addSearchMode(fts, RS_FILE_HINTS_TURTLE);
|
||||
// mFtSearch->addSearchMode(fts, RS_FILE_HINTS_TURTLE);
|
||||
mFtController->setTurtleRouter(fts) ;
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ const uint32_t RS_FILE_HINTS_LOCAL = 0x00000004;
|
||||
const uint32_t RS_FILE_HINTS_REMOTE = 0x00000008;
|
||||
const uint32_t RS_FILE_HINTS_DOWNLOAD = 0x00000010;
|
||||
const uint32_t RS_FILE_HINTS_UPLOAD = 0x00000020;
|
||||
const uint32_t RS_FILE_HINTS_TURTLE = 0x00000040;
|
||||
//const uint32_t RS_FILE_HINTS_TURTLE = 0x00000040; // unused
|
||||
const uint32_t RS_FILE_HINTS_NETWORK_WIDE = 0x00000080; // anonymously shared over network
|
||||
const uint32_t RS_FILE_HINTS_BROWSABLE = 0x00000100; // browsable by friends
|
||||
|
||||
|
@ -62,45 +62,45 @@ class FileInfo
|
||||
/* old BaseInfo Entries */
|
||||
public:
|
||||
|
||||
FileInfo() :flags(0), mId(0) { return; }
|
||||
RsCertId id; /* key for matching everything */
|
||||
int flags; /* INFO_TAG above */
|
||||
FileInfo() :flags(0), mId(0) { return; }
|
||||
RsCertId id; /* key for matching everything */
|
||||
int flags; /* INFO_TAG above */
|
||||
|
||||
/* allow this to be tweaked by the GUI Model */
|
||||
mutable unsigned int mId; /* (GUI) Model Id -> unique number */
|
||||
/* allow this to be tweaked by the GUI Model */
|
||||
mutable unsigned int mId; /* (GUI) Model Id -> unique number */
|
||||
|
||||
/* Old FileInfo Entries */
|
||||
/* Old FileInfo Entries */
|
||||
public:
|
||||
|
||||
static const int kRsFiStatusNone = 0;
|
||||
static const int kRsFiStatusStall = 1;
|
||||
static const int kRsFiStatusProgress = 2;
|
||||
static const int kRsFiStatusDone = 2;
|
||||
static const int kRsFiStatusNone = 0;
|
||||
static const int kRsFiStatusStall = 1;
|
||||
static const int kRsFiStatusProgress = 2;
|
||||
static const int kRsFiStatusDone = 2;
|
||||
|
||||
/* FileInfo(); */
|
||||
/* FileInfo(); */
|
||||
|
||||
int searchId; /* 0 if none */
|
||||
std::string path;
|
||||
std::string fname;
|
||||
std::string hash;
|
||||
std::string ext;
|
||||
int searchId; /* 0 if none */
|
||||
std::string path;
|
||||
std::string fname;
|
||||
std::string hash;
|
||||
std::string ext;
|
||||
|
||||
uint64_t size;
|
||||
uint64_t avail; /* how much we have */
|
||||
int status;
|
||||
uint64_t size;
|
||||
uint64_t avail; /* how much we have */
|
||||
int status;
|
||||
|
||||
bool inRecommend;
|
||||
bool inRecommend;
|
||||
|
||||
double rank;
|
||||
int age;
|
||||
double rank;
|
||||
int age;
|
||||
|
||||
/* Transfer Stuff */
|
||||
uint64_t transfered;
|
||||
double tfRate; /* in kbytes */
|
||||
uint32_t downloadStatus; /* 0 = Err, 1 = Ok, 2 = Done */
|
||||
std::list<TransferInfo> peers;
|
||||
/* Transfer Stuff */
|
||||
uint64_t transfered;
|
||||
double tfRate; /* in kbytes */
|
||||
uint32_t downloadStatus; /* 0 = Err, 1 = Ok, 2 = Done */
|
||||
std::list<TransferInfo> peers;
|
||||
|
||||
time_t lastTS;
|
||||
time_t lastTS;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const FileInfo &info);
|
||||
@ -248,15 +248,29 @@ class FileDetail
|
||||
|
||||
enum DwlPriority { Low = 0, Normal, High, Auto };
|
||||
|
||||
// Macro to read a bits array for compressed chunk maps
|
||||
//
|
||||
#define COMPRESSED_MAP_READ(A,j) (A[j >> 5] & (1 << (j & 0x11111)))
|
||||
|
||||
class FileChunksInfo
|
||||
{
|
||||
public:
|
||||
enum ChunkState { CHUNK_DONE, CHUNK_ACTIVE, CHUNK_OUTSTANDING } ;
|
||||
enum ChunkStrategy { CHUNK_STRATEGY_STREAMING, CHUNK_STRATEGY_RANDOM } ;
|
||||
enum ChunkState { CHUNK_DONE, CHUNK_ACTIVE, CHUNK_OUTSTANDING } ;
|
||||
enum ChunkStrategy { CHUNK_STRATEGY_STREAMING, CHUNK_STRATEGY_RANDOM } ;
|
||||
|
||||
uint64_t file_size ; // real size of the file
|
||||
uint32_t chunk_size ; // size of chunks
|
||||
|
||||
// dl state of chunks. Only the last chunk may have size < chunk_size
|
||||
std::vector<ChunkState> chunks ;
|
||||
|
||||
// For each source peer, gives the compressed bit map of have/don't have sate
|
||||
std::vector<std::pair<std::string, std::vector<uint32_t> > > compressed_peer_availability_maps ;
|
||||
|
||||
// For each chunk (by chunk number), gives the completion of the chunk.
|
||||
//
|
||||
std::vector<std::pair<uint32_t,uint32_t> > active_chunks ;
|
||||
|
||||
uint64_t file_size ; // real size of the file
|
||||
uint32_t chunk_size ; // size of chunks
|
||||
std::vector<ChunkState> chunks ; // dl state of chunks. Only the last chunk may have size < chunk_size
|
||||
};
|
||||
|
||||
/* class which encapsulates download details */
|
||||
|
@ -205,7 +205,7 @@ void p3turtle::manageTunnels()
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
bool tunnel_campain = false ;
|
||||
if(now > _last_tunnel_campaign_time+REGULAR_TUNNEL_DIGGING_TIME)
|
||||
if(now > _last_tunnel_campaign_time + REGULAR_TUNNEL_DIGGING_TIME)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " Tunnel management: flaging all hashes for tunnels digging." << std::endl ;
|
||||
@ -819,14 +819,12 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item)
|
||||
|
||||
// Only file data transfer updates tunnels time_stamp field, to avoid maintaining tunnel that are incomplete.
|
||||
tunnel.time_stamp = time(NULL) ;
|
||||
// also update the hash time stamp to show that it's actually being downloaded.
|
||||
_incoming_file_hashes[tunnel.hash].time_stamp = time(NULL) ;
|
||||
|
||||
// Let's figure out whether this reuqest is for us or not.
|
||||
|
||||
if(tunnel.local_src == mConnMgr->getOwnId()) // Yes, we have to pass on the data to the multiplexer
|
||||
{
|
||||
std::map<TurtleFileHash,TurtleFileHashInfo>::const_iterator it( _incoming_file_hashes.find(tunnel.hash) ) ;
|
||||
std::map<TurtleFileHash,TurtleFileHashInfo>::iterator it( _incoming_file_hashes.find(tunnel.hash) ) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
assert(!tunnel.hash.empty()) ;
|
||||
#endif
|
||||
@ -848,6 +846,9 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item)
|
||||
vpid = tunnel.vpid ;
|
||||
hash = tunnel.hash ;
|
||||
size = hash_info.size ;
|
||||
|
||||
// also update the hash time stamp to show that it's actually being downloaded.
|
||||
it->second.time_stamp = time(NULL) ;
|
||||
}
|
||||
else // No, it's a request we should forward down the pipe.
|
||||
{
|
||||
@ -876,6 +877,73 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item)
|
||||
// down _ft_server->getMultiplexer()->recvData()...in ftTransferModule::recvFileData
|
||||
}
|
||||
|
||||
void p3turtle::handleRecvFileMap(RsTurtleFileMapItem *item)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "p3Turtle: received file Map item:" << std::endl ;
|
||||
item->print(std::cerr,1) ;
|
||||
#endif
|
||||
{
|
||||
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<TurtleTunnelId,TurtleTunnel>::iterator it(_local_tunnels.find(item->tunnel_id)) ;
|
||||
|
||||
if(it == _local_tunnels.end())
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "p3turtle: got file map with unknown tunnel id " << (void*)item->tunnel_id << std::endl ;
|
||||
#endif
|
||||
return ;
|
||||
}
|
||||
|
||||
TurtleTunnel& tunnel(it->second) ;
|
||||
|
||||
// Only file data transfer updates tunnels time_stamp field, to avoid maintaining tunnel that are incomplete.
|
||||
tunnel.time_stamp = time(NULL) ;
|
||||
|
||||
// Let's figure out whether this reuqest is for us or not.
|
||||
|
||||
if(tunnel.local_src == mConnMgr->getOwnId()) // Yes, we have to pass on the data to the multiplexer
|
||||
{
|
||||
std::map<TurtleFileHash,TurtleFileHashInfo>::iterator it( _incoming_file_hashes.find(tunnel.hash) ) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
assert(!tunnel.hash.empty()) ;
|
||||
#endif
|
||||
if(it==_incoming_file_hashes.end())
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "No tunnel for incoming data. Maybe the tunnel is being closed." << std::endl ;
|
||||
#endif
|
||||
return ;
|
||||
}
|
||||
|
||||
const TurtleFileHashInfo& hash_info(it->second) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " This is an endpoint for this file map." << std::endl ;
|
||||
std::cerr << " Forwarding data to the multiplexer." << std::endl ;
|
||||
std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ;
|
||||
#endif
|
||||
// also update the hash time stamp to show that it's actually being downloaded.
|
||||
it->second.time_stamp = time(NULL) ;
|
||||
|
||||
// we should check that there is no backward call to the turtle router!
|
||||
//
|
||||
_ft_server->getMultiplexer()->recvFileMap(tunnel.vpid,tunnel.hash,item->chunk_size,item->nb_chunks,item->compressed_map) ;
|
||||
}
|
||||
else // No, it's a request we should forward down the pipe.
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " Forwarding file map to peer " << tunnel.local_src << std::endl ;
|
||||
#endif
|
||||
RsTurtleFileMapItem *res_item = new RsTurtleFileMapItem(*item) ;
|
||||
res_item->PeerId(tunnel.local_src) ;
|
||||
|
||||
sendItem(res_item) ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send a data request into the correct tunnel for the given file hash
|
||||
void p3turtle::sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t, uint64_t offset, uint32_t chunksize)
|
||||
{
|
||||
@ -953,61 +1021,61 @@ void p3turtle::sendFileData(const std::string& peerId, const std::string& hash,
|
||||
sendItem(item) ;
|
||||
}
|
||||
|
||||
bool p3turtle::search(std::string hash, uint64_t, uint32_t hintflags, FileInfo &info) const
|
||||
{
|
||||
if(! (hintflags & RS_FILE_HINTS_TURTLE)) // this should not happen, but it's a security.
|
||||
return false;
|
||||
|
||||
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "p3turtle: received file search request for hash " << hash << "." << std::endl ;
|
||||
#endif
|
||||
|
||||
std::map<TurtleFileHash,TurtleFileHashInfo>::const_iterator it = _incoming_file_hashes.find(hash) ;
|
||||
|
||||
if(_incoming_file_hashes.end() != it)
|
||||
{
|
||||
info.fname = it->second.name;
|
||||
info.size = it->second.size;
|
||||
info.hash = it->first;
|
||||
|
||||
for(unsigned int i=0;i<it->second.tunnels.size();++i)
|
||||
{
|
||||
TransferInfo ti;
|
||||
ti.peerId = getTurtlePeerId(it->second.tunnels[i]);
|
||||
ti.name = "Distant peer for hash=" + hash ;
|
||||
ti.tfRate = 0;
|
||||
info.peers.push_back(ti);
|
||||
}
|
||||
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " Found these tunnels for that hash:. "<< std::endl ;
|
||||
for(unsigned int i=0;i<it->second.tunnels.size();++i)
|
||||
std::cerr << " " << (void*)it->second.tunnels[i] << std::endl ;
|
||||
|
||||
std::cerr << " answered yes. "<< std::endl ;
|
||||
#endif
|
||||
return true ;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " responding false." << std::endl ;
|
||||
#endif
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// This function is actually not needed: Search request to the turtle router are:
|
||||
// - distant search requests, handled by the router
|
||||
// - search requests over files being downloaded, handled by rsFiles !!
|
||||
//
|
||||
//bool p3turtle::search(std::string hash, uint64_t, uint32_t hintflags, FileInfo &info) const
|
||||
//{
|
||||
// if(! (hintflags & RS_FILE_HINTS_TURTLE)) // this should not happen, but it's a security.
|
||||
// return false;
|
||||
//
|
||||
// RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
|
||||
//
|
||||
//#ifdef P3TURTLE_DEBUG
|
||||
// std::cerr << "p3turtle: received file search request for hash " << hash << "." << std::endl ;
|
||||
//#endif
|
||||
//
|
||||
// std::map<TurtleFileHash,TurtleFileHashInfo>::const_iterator it = _incoming_file_hashes.find(hash) ;
|
||||
//
|
||||
// if(_incoming_file_hashes.end() != it)
|
||||
// {
|
||||
// info.fname = it->second.name;
|
||||
// info.size = it->second.size;
|
||||
// info.hash = it->first;
|
||||
//
|
||||
// for(unsigned int i=0;i<it->second.tunnels.size();++i)
|
||||
// {
|
||||
// TransferInfo ti;
|
||||
// ti.peerId = getTurtlePeerId(it->second.tunnels[i]);
|
||||
// ti.name = "Distant peer for hash=" + hash ;
|
||||
// ti.tfRate = 0;
|
||||
// info.peers.push_back(ti);
|
||||
// }
|
||||
//
|
||||
//#ifdef P3TURTLE_DEBUG
|
||||
// std::cerr << " Found these tunnels for that hash:. "<< std::endl ;
|
||||
// for(unsigned int i=0;i<it->second.tunnels.size();++i)
|
||||
// std::cerr << " " << (void*)it->second.tunnels[i] << std::endl ;
|
||||
//
|
||||
// std::cerr << " answered yes. "<< std::endl ;
|
||||
//#endif
|
||||
// return true ;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
//#ifdef P3TURTLE_DEBUG
|
||||
// std::cerr << " responding false." << std::endl ;
|
||||
//#endif
|
||||
// return false ;
|
||||
// }
|
||||
//}
|
||||
|
||||
bool p3turtle::isTurtlePeer(const std::string& peer_id) const
|
||||
{
|
||||
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
return _virtual_peers.find(peer_id) != _virtual_peers.end() ;
|
||||
|
||||
// if(it->second.tunnels.empty())
|
||||
// return false ;
|
||||
//
|
||||
}
|
||||
|
||||
std::string p3turtle::getTurtlePeerId(TurtleTunnelId tid) const
|
||||
@ -1472,7 +1540,7 @@ void p3turtle::returnSearchResult(RsTurtleSearchResultItem *item)
|
||||
|
||||
bool p3turtle::performLocalHashSearch(const TurtleFileHash& hash,FileInfo& info)
|
||||
{
|
||||
return rsFiles->FileDetails(hash, RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SPEC_ONLY, info);
|
||||
return rsFiles->FileDetails(hash, RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SPEC_ONLY | RS_FILE_HINTS_DOWNLOAD, info);
|
||||
}
|
||||
|
||||
static std::string printNumber(uint64_t num,bool hex=false)
|
||||
@ -1480,7 +1548,7 @@ static std::string printNumber(uint64_t num,bool hex=false)
|
||||
if(hex)
|
||||
{
|
||||
char tmp[100] ;
|
||||
sprintf(tmp,"0x%08lx",num) ;
|
||||
sprintf(tmp,"0x%08x%08x", uint32_t(num >> 32),uint32_t(num & ( (1<<32)-1 ))) ;
|
||||
return std::string(tmp) ;
|
||||
}
|
||||
else
|
||||
|
@ -131,6 +131,11 @@
|
||||
//
|
||||
// Questions:
|
||||
// - should tunnels be re-used ? nope. The only useful case would be when two peers are exchanging files, which happens quite rarely.
|
||||
//
|
||||
// TODO:
|
||||
// - derive most packets from RsTurtleTunnelPacketItem, that can be handled
|
||||
// as raw data through a tunnel. This will avoid replicating most of the
|
||||
// tunnel handling code.
|
||||
|
||||
|
||||
#ifndef MRK_PQI_TURTLE_H
|
||||
@ -152,6 +157,7 @@ class p3AuthMgr;
|
||||
class p3ConnectMgr;
|
||||
class ftDataMultiplex;
|
||||
class RsSerialiser;
|
||||
|
||||
static const int TURTLE_MAX_SEARCH_DEPTH = 6 ;
|
||||
|
||||
// This class is used to keep trace of requests (searches and tunnels).
|
||||
@ -197,7 +203,7 @@ class TurtleFileHashInfo
|
||||
// p3Config | ConfigChanged() | used to load/save .cfg file for turtle variales.
|
||||
// -----------+------------------+------------------------------------------------------
|
||||
//
|
||||
class p3turtle: public p3Service, public pqiMonitor, public RsTurtle, public ftSearch, public p3Config
|
||||
class p3turtle: public p3Service, public pqiMonitor, public RsTurtle,/* public ftSearch */ public p3Config
|
||||
{
|
||||
public:
|
||||
p3turtle(p3ConnectMgr *cm,ftServer *m);
|
||||
@ -250,10 +256,10 @@ class p3turtle: public p3Service, public pqiMonitor, public RsTurtle, public ftS
|
||||
//
|
||||
virtual int tick();
|
||||
|
||||
/************* from ftSearch *******************/
|
||||
// Search function. This function looks into the file hashes currently handled , and sends back info.
|
||||
//
|
||||
virtual bool search(std::string hash, uint64_t size, uint32_t hintflags, FileInfo &info) const ;
|
||||
// /************* from ftSearch *******************/
|
||||
// // Search function. This function looks into the file hashes currently handled , and sends back info.
|
||||
// //
|
||||
// virtual bool search(std::string hash, uint64_t size, uint32_t hintflags, FileInfo &info) const ;
|
||||
|
||||
/************* from p3Config *******************/
|
||||
virtual RsSerialiser *setupSerialiser() ;
|
||||
@ -304,6 +310,7 @@ class p3turtle: public p3Service, public pqiMonitor, public RsTurtle, public ftS
|
||||
void handleTunnelResult(RsTurtleTunnelOkItem *item);
|
||||
void handleRecvFileRequest(RsTurtleFileRequestItem *item);
|
||||
void handleRecvFileData(RsTurtleFileDataItem *item);
|
||||
void handleRecvFileMap(RsTurtleFileMapItem*);
|
||||
|
||||
//------ Functions connecting the turtle router to other components.----------//
|
||||
|
||||
|
@ -113,6 +113,22 @@ uint32_t RsTurtleFileDataItem::serial_size()
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileMapItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 4 ; // chunk_size
|
||||
s += 4 ; // nb_chunks
|
||||
s += 4 ; // compressed_map.size()
|
||||
|
||||
s += 4 * compressed_map.size() ;
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
//
|
||||
// ---------------------------------- Serialization ----------------------------------//
|
||||
//
|
||||
@ -146,6 +162,7 @@ RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
|
||||
case RS_TURTLE_SUBTYPE_TUNNEL_OK : return new RsTurtleTunnelOkItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem(data,*size) ;
|
||||
|
||||
default:
|
||||
std::cerr << "Unknown packet type in RsTurtle!" << std::endl ;
|
||||
@ -162,6 +179,44 @@ RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
|
||||
|
||||
}
|
||||
|
||||
bool RsTurtleFileMapItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chunk_size);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, nb_chunks);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map.size());
|
||||
|
||||
for(uint32_t i=0;i<compressed_map.size() && ok;++i)
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map[i]);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsTurtleStringSearchRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
@ -350,6 +405,30 @@ bool RsTurtleSearchResultItem::serialize(void *data,uint32_t& pktsize)
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsTurtleFileMapItem::RsTurtleFileMapItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleItem(RS_TURTLE_SUBTYPE_FILE_MAP)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = search result" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
uint32_t s ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &chunk_size);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &nb_chunks) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &s) ;
|
||||
|
||||
compressed_map.resize(s) ;
|
||||
|
||||
for(uint32_t i=0;i<s && ok;++i)
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &(compressed_map[i])) ;
|
||||
}
|
||||
|
||||
RsTurtleSearchResultItem::RsTurtleSearchResultItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_RESULT)
|
||||
{
|
||||
@ -742,3 +821,18 @@ std::ostream& RsTurtleFileDataItem::print(std::ostream& o, uint16_t)
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileMapItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File map item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << (void*)tunnel_id << std::endl ;
|
||||
o << " chunk size: " << chunk_size << std::endl ;
|
||||
o << " nb chunks : " << nb_chunks << std::endl ;
|
||||
o << " map : " ;
|
||||
|
||||
for(uint32_t i=0;i<compressed_map.size();++i)
|
||||
o << (void*)compressed_map[i] << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ const uint8_t RS_TURTLE_SUBTYPE_TUNNEL_CLOSED = 0x06 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_REQUEST = 0x07 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_DATA = 0x08 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST = 0x09 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP = 0x10 ;
|
||||
|
||||
/***********************************************************************************/
|
||||
/* Basic Turtle Item Class */
|
||||
@ -142,36 +143,6 @@ class RsTurtleTunnelOkItem: public RsTurtleItem
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
#ifdef A_VIRER
|
||||
class RsTurtleCloseTunnelItem: public RsTurtleItem
|
||||
{
|
||||
public:
|
||||
RsTurtleCloseTunnelItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_CLOSE_TUNNEL) {}
|
||||
RsTurtleCloseTunnelItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
uint32_t tunnel_id ; // id of the tunnel to close.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
protected:
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleTunnelClosedItem: public RsTurtleItem
|
||||
{
|
||||
public:
|
||||
RsTurtleTunnelClosedItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_TUNNEL_CLOSED) {}
|
||||
RsTurtleTunnelClosedItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
uint32_t tunnel_id ; // id of the tunnel to close.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
protected:
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
#endif
|
||||
|
||||
/***********************************************************************************/
|
||||
/* Turtle File Transfer item classes */
|
||||
/***********************************************************************************/
|
||||
@ -210,6 +181,27 @@ class RsTurtleFileDataItem: public RsTurtleItem
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileMapItem: public RsTurtleItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileMapItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_FILE_MAP) {}
|
||||
RsTurtleFileMapItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
|
||||
uint32_t chunk_size ; // fixed size of chunks, as seen from the source, for the given map.
|
||||
uint32_t nb_chunks ; // number of chunks in the file. The last two infos are redundant, as we can recompute
|
||||
// this info from the file size, but this allows a security check.
|
||||
|
||||
std::vector<uint32_t> compressed_map ; // Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have"
|
||||
// by default, we suppose the peer has all the chunks. This info will thus be and-ed
|
||||
// with the default file map for this source.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
/***********************************************************************************/
|
||||
/* Turtle Serialiser class */
|
||||
/***********************************************************************************/
|
||||
|
@ -32,18 +32,57 @@
|
||||
|
||||
/* RsIface Thread Wrappers */
|
||||
|
||||
#undef RSTHREAD_SELF_LOCKING_GUARD
|
||||
|
||||
class RsMutex
|
||||
{
|
||||
public:
|
||||
|
||||
RsMutex() { pthread_mutex_init(&realMutex, NULL); }
|
||||
~RsMutex() { pthread_mutex_destroy(&realMutex); }
|
||||
void lock() { pthread_mutex_lock(&realMutex); }
|
||||
void unlock() { pthread_mutex_unlock(&realMutex); }
|
||||
bool trylock() { return (0 == pthread_mutex_trylock(&realMutex)); }
|
||||
RsMutex()
|
||||
{
|
||||
pthread_mutex_init(&realMutex, NULL);
|
||||
#ifdef RSTHREAD_SELF_LOCKING_GUARD
|
||||
_thread_id = 0 ;
|
||||
#endif
|
||||
}
|
||||
~RsMutex()
|
||||
{
|
||||
pthread_mutex_destroy(&realMutex);
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
#ifdef RSTHREAD_SELF_LOCKING_GUARD
|
||||
if(!trylock())
|
||||
if(!pthread_equal(_thread_id,pthread_self()))
|
||||
#endif
|
||||
pthread_mutex_lock(&realMutex);
|
||||
|
||||
#ifdef RSTHREAD_SELF_LOCKING_GUARD
|
||||
_thread_id = pthread_self() ;
|
||||
++_cnt ;
|
||||
#endif
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
#ifdef RSTHREAD_SELF_LOCKING_GUARD
|
||||
if(--_cnt == 0)
|
||||
{
|
||||
#endif
|
||||
pthread_mutex_unlock(&realMutex);
|
||||
#ifdef RSTHREAD_SELF_LOCKING_GUARD
|
||||
_thread_id = 0 ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
bool trylock() { return (0 == pthread_mutex_trylock(&realMutex)); }
|
||||
|
||||
private:
|
||||
pthread_mutex_t realMutex;
|
||||
pthread_mutex_t realMutex;
|
||||
#ifdef RSTHREAD_SELF_LOCKING_GUARD
|
||||
pthread_t _thread_id ;
|
||||
uint32_t _cnt ;
|
||||
#endif
|
||||
};
|
||||
|
||||
class RsStackMutex
|
||||
|
@ -115,7 +115,7 @@ INCLUDEPATH += ../../libretroshare/src/
|
||||
|
||||
# Input
|
||||
HEADERS += rshare.h \
|
||||
rsiface/notifyqt.h \
|
||||
gui/notifyqt.h \
|
||||
control/bandwidthevent.h \
|
||||
control/eventtype.h \
|
||||
gui/DLListDelegate.h \
|
||||
@ -289,7 +289,7 @@ FORMS += gui/StartDialog.ui \
|
||||
|
||||
SOURCES += main.cpp \
|
||||
rshare.cpp \
|
||||
rsiface/notifyqt.cpp \
|
||||
gui/notifyqt.cpp \
|
||||
gui/DLListDelegate.cpp \
|
||||
gui/ULListDelegate.cpp \
|
||||
gui/StartDialog.cpp \
|
||||
|
@ -20,11 +20,23 @@
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
#include <QStylePainter>
|
||||
#include <QDebug>
|
||||
#include <rsiface/rsfiles.h>
|
||||
#include <rsiface/rstypes.h>
|
||||
#include "FileTransferInfoWidget.h"
|
||||
|
||||
// Variables to decide of display behaviour. Should be adapted to window size.
|
||||
//
|
||||
static const int chunk_square_size = 13 ;
|
||||
static const int text_height = 10 ; // should be set according to the font size
|
||||
static const int block_sep = 3 ; // separator between blocks
|
||||
static const int ch_num_size = 50 ; // size of field for chunk number
|
||||
static const int availability_map_size_X = 400 ;// length of availability bar
|
||||
static const int availability_map_size_Y = 20 ; // height of availability bar
|
||||
static const int tab_size = 200 ;// size between tabulated entries
|
||||
|
||||
FileTransferInfoWidget::FileTransferInfoWidget(QWidget * parent, Qt::WFlags f )
|
||||
{
|
||||
QRect TaskGraphRect = geometry();
|
||||
@ -63,10 +75,10 @@ void FileTransferInfoWidget::updateDisplay()
|
||||
uint32_t blockSize = info.chunk_size ;
|
||||
int blocks = info.chunks.size() ;
|
||||
|
||||
int columns = maxWidth/13;
|
||||
y = blocks/columns*13;
|
||||
x = blocks%columns*13;
|
||||
maxHeight = y+15;
|
||||
int columns = maxWidth/chunk_square_size;
|
||||
y = blocks/columns*chunk_square_size;
|
||||
x = blocks%columns*chunk_square_size;
|
||||
maxHeight = y+150+info.active_chunks.size()*(block_sep+text_height); // warning: this should be computed from the different size parameter and the number of objects drawn, otherwise the last objects to be displayed will be truncated.
|
||||
pixmap = QPixmap(size());
|
||||
pixmap.fill(this, 0, 0);
|
||||
pixmap = QPixmap(maxWidth, maxHeight);
|
||||
@ -101,12 +113,19 @@ void FileTransferInfoWidget::draw(const FileChunksInfo& info,QPainter *painter)
|
||||
if (fileSize%blockSize == 0) blocks--;
|
||||
QRectF source(0.0, 0.0, 12.0, 12.0);
|
||||
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
y += text_height ;
|
||||
painter->drawText(0,y,tr("Chunk map:")) ;
|
||||
y += block_sep ;
|
||||
|
||||
// draw the chunk map
|
||||
//
|
||||
for (int i=0;i<blocks;i++)
|
||||
{
|
||||
if (x > maxWidth - 13)
|
||||
if (x > maxWidth - chunk_square_size)
|
||||
{
|
||||
x = 0;
|
||||
y += 13;
|
||||
y += chunk_square_size;
|
||||
}
|
||||
QRectF target(x, y, 12.0, 12.0);
|
||||
|
||||
@ -122,8 +141,88 @@ void FileTransferInfoWidget::draw(const FileChunksInfo& info,QPainter *painter)
|
||||
break ;
|
||||
default: ;
|
||||
}
|
||||
x += 13;
|
||||
x += chunk_square_size;
|
||||
}
|
||||
y += chunk_square_size ;
|
||||
|
||||
// draw the currently downloaded chunks
|
||||
//
|
||||
painter->setPen(QColor::fromRgb(70,70,70)) ;
|
||||
painter->drawLine(0,y,maxWidth,y) ;
|
||||
|
||||
uint32_t sizeX = 100 ;
|
||||
uint32_t sizeY = 10 ;
|
||||
y += block_sep ;
|
||||
y += text_height ;
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawText(0,y,tr("Active chunks:")) ;
|
||||
y += block_sep ;
|
||||
|
||||
for(uint i=0;i<info.active_chunks.size();++i)
|
||||
{
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawText(5,y+text_height,QString::number(info.active_chunks[i].first)) ;
|
||||
|
||||
uint32_t s = (uint32_t)rint(sizeX*(info.chunk_size - info.active_chunks[i].second)/(float)info.chunk_size) ;
|
||||
|
||||
painter->fillRect(ch_num_size,y,s,sizeY,QColor::fromHsv(200,200,255)) ;
|
||||
painter->fillRect(ch_num_size+s,y,sizeX-s,sizeY,QColor::fromHsv(200,50,255)) ;
|
||||
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
float percent = (info.chunk_size - info.active_chunks[i].second)*100.0/info.chunk_size ;
|
||||
|
||||
painter->drawText(sizeX+55,y+text_height,QString::number(percent,'g',2) + " %") ;
|
||||
|
||||
y += sizeY+block_sep ;
|
||||
}
|
||||
|
||||
// draw the availability map
|
||||
//
|
||||
painter->setPen(QColor::fromRgb(70,70,70)) ;
|
||||
painter->drawLine(0,y,maxWidth,y) ;
|
||||
|
||||
y += block_sep ;
|
||||
y += text_height ;
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawText(0,y,tr("Availability map (")+QString::number(info.compressed_peer_availability_maps.size())+ tr(" sources")+")") ;
|
||||
y += block_sep ;
|
||||
|
||||
int nb_chunks = info.file_size/info.chunk_size + !(info.file_size % info.chunk_size);
|
||||
|
||||
for(uint i=0;i<availability_map_size_X;++i)
|
||||
{
|
||||
int nb_src = 0 ;
|
||||
int chunk_num = (int)floor(i/float(availability_map_size_X)*(nb_chunks-1)) ;
|
||||
|
||||
for(uint j=0;j<info.compressed_peer_availability_maps.size();++j)
|
||||
nb_src += (bool)(COMPRESSED_MAP_READ(info.compressed_peer_availability_maps[j].second, chunk_num)) ;
|
||||
|
||||
painter->setPen(QColor::fromHsv(200,50*nb_src,200)) ; // the more sources, the more saturated
|
||||
painter->drawLine(i,y,i,y+availability_map_size_Y) ;
|
||||
}
|
||||
|
||||
y += block_sep + availability_map_size_Y ;
|
||||
painter->setPen(QColor::fromRgb(70,70,70)) ;
|
||||
painter->drawLine(0,y,maxWidth,y) ;
|
||||
y += block_sep ;
|
||||
|
||||
// various info:
|
||||
//
|
||||
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
y += text_height ; painter->drawText(0,y,tr("File info:")) ;
|
||||
y += block_sep ;
|
||||
y += text_height ; painter->drawText(20,y,tr("File size: ")) ; painter->drawText(tab_size,y,QString::number(info.file_size)) ;
|
||||
y += block_sep ;
|
||||
y += text_height ; painter->drawText(20,y,tr("Chunk size: ")) ; painter->drawText(tab_size,y,QString::number(info.chunk_size)) ;
|
||||
y += block_sep ;
|
||||
y += text_height ; painter->drawText(20,y,tr("Number of chunks: ")) ; painter->drawText(tab_size,y,QString::number(info.chunks.size())) ;
|
||||
y += block_sep ;
|
||||
y += text_height ; painter->drawText(20,y,tr("Number of sources: ")) ; painter->drawText(tab_size,y,QString::number(info.compressed_peer_availability_maps.size())) ;
|
||||
y += text_height ;
|
||||
y += block_sep ;
|
||||
|
||||
maxHeight = y+15;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,402 +0,0 @@
|
||||
|
||||
#include "rsiface/notifyqt.h"
|
||||
#include "rsiface/rsnotify.h"
|
||||
#include "rsiface/rspeers.h"
|
||||
#include "rsiface/rsphoto.h"
|
||||
#ifdef TURTLE_HOPPING
|
||||
#include <rsiface/rsturtle.h>
|
||||
#endif
|
||||
|
||||
#include "gui/NetworkDialog.h"
|
||||
#include "gui/PeersDialog.h"
|
||||
#include "gui/SharedFilesDialog.h"
|
||||
#include "gui/TransfersDialog.h"
|
||||
#include "gui/MessagesDialog.h"
|
||||
#include "gui/MessengerWindow.h"
|
||||
|
||||
#include "gui/toaster/OnlineToaster.h"
|
||||
#include "gui/toaster/MessageToaster.h"
|
||||
#include "gui/toaster/ChatToaster.h"
|
||||
#include "gui/toaster/CallToaster.h"
|
||||
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
/*****
|
||||
* #define NOTIFY_DEBUG
|
||||
****/
|
||||
|
||||
void NotifyQt::notifyErrorMsg(int list, int type, std::string msg)
|
||||
{
|
||||
(void) list;
|
||||
(void) type;
|
||||
(void) msg;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void NotifyQt::notifyOwnAvatarChanged()
|
||||
{
|
||||
std::cerr << "Notifyqt:: notified that own avatar changed" << std::endl ;
|
||||
emit ownAvatarChanged() ;
|
||||
}
|
||||
|
||||
std::string NotifyQt::askForPassword(const std::string& window_title,const std::string& text)
|
||||
{
|
||||
return QInputDialog::getText(NULL, QString::fromStdString(window_title),
|
||||
QString::fromStdString(text), QLineEdit::Password,
|
||||
NULL, NULL).toStdString();
|
||||
}
|
||||
|
||||
void NotifyQt::notifyOwnStatusMessageChanged()
|
||||
{
|
||||
std::cerr << "Notifyqt:: notified that own avatar changed" << std::endl ;
|
||||
emit ownStatusMessageChanged() ;
|
||||
}
|
||||
|
||||
void NotifyQt::notifyPeerHasNewAvatar(std::string peer_id)
|
||||
{
|
||||
std::cerr << "notifyQt: notification of new avatar." << std::endl ;
|
||||
emit peerHasNewAvatar(QString::fromStdString(peer_id)) ;
|
||||
}
|
||||
|
||||
void NotifyQt::notifyCustomState(const std::string& peer_id)
|
||||
{
|
||||
std::cerr << "notifyQt: Received custom status string notification" << std::endl ;
|
||||
emit peerHasNewCustomStateString(QString::fromStdString(peer_id)) ;
|
||||
}
|
||||
|
||||
void NotifyQt::notifyChatStatus(const std::string& peer_id,const std::string& status_string,bool is_private)
|
||||
{
|
||||
std::cerr << "notifyQt: Received chat status string: " << status_string << std::endl ;
|
||||
emit chatStatusChanged(QString::fromStdString(peer_id),QString::fromStdString(status_string),is_private) ;
|
||||
}
|
||||
|
||||
void NotifyQt::notifyTurtleSearchResult(uint32_t search_id,const std::list<TurtleFileInfo>& files)
|
||||
{
|
||||
std::cerr << "in notify search result..." << std::endl ;
|
||||
|
||||
for(std::list<TurtleFileInfo>::const_iterator it(files.begin());it!=files.end();++it)
|
||||
{
|
||||
FileDetail det ;
|
||||
det.rank = 0 ;
|
||||
det.age = 0 ;
|
||||
det.name = (*it).name ;
|
||||
det.hash = (*it).hash ;
|
||||
det.size = (*it).size ;
|
||||
det.id = "Anonymous" ;
|
||||
|
||||
emit gotTurtleSearchResult(search_id,det) ;
|
||||
}
|
||||
}
|
||||
|
||||
void NotifyQt::notifyHashingInfo(std::string fileinfo)
|
||||
{
|
||||
emit hashingInfoChanged(QString::fromStdString(fileinfo)) ;
|
||||
}
|
||||
|
||||
//void NotifyQt::notifyChat()
|
||||
//{
|
||||
// std::cerr << "Received chat notification" << std::endl ;
|
||||
// return;
|
||||
//}
|
||||
|
||||
void NotifyQt::notifyListChange(int list, int type)
|
||||
{
|
||||
#ifdef NOTIFY_DEBUG
|
||||
std::cerr << "NotifyQt::notifyListChange()" << std::endl;
|
||||
#endif
|
||||
switch(list)
|
||||
{
|
||||
case NOTIFY_LIST_NEIGHBOURS:
|
||||
#ifdef DEBUG
|
||||
std::cerr << "received neighbrs changed" << std::endl ;
|
||||
#endif
|
||||
emit neighborsChanged();
|
||||
break;
|
||||
case NOTIFY_LIST_FRIENDS:
|
||||
#ifdef DEBUG
|
||||
std::cerr << "received friends changed" << std::endl ;
|
||||
#endif
|
||||
emit friendsChanged() ;
|
||||
break;
|
||||
case NOTIFY_LIST_DIRLIST_LOCAL:
|
||||
#ifdef DEBUG
|
||||
std::cerr << "received files changed" << std::endl ;
|
||||
#endif
|
||||
emit filesPostModChanged(true) ; /* Local */
|
||||
break;
|
||||
case NOTIFY_LIST_DIRLIST_FRIENDS:
|
||||
#ifdef DEBUG
|
||||
std::cerr << "received files changed" << std::endl ;
|
||||
#endif
|
||||
emit filesPostModChanged(false) ; /* Local */
|
||||
break;
|
||||
case NOTIFY_LIST_SEARCHLIST:
|
||||
break;
|
||||
case NOTIFY_LIST_MESSAGELIST:
|
||||
#ifdef DEBUG
|
||||
std::cerr << "received msg changed" << std::endl ;
|
||||
#endif
|
||||
emit messagesChanged() ;
|
||||
break;
|
||||
case NOTIFY_LIST_CHANNELLIST:
|
||||
break;
|
||||
case NOTIFY_LIST_TRANSFERLIST:
|
||||
#ifdef DEBUG
|
||||
std::cerr << "received transfer changed" << std::endl ;
|
||||
#endif
|
||||
emit transfersChanged() ;
|
||||
break;
|
||||
case NOTIFY_LIST_CONFIG:
|
||||
#ifdef DEBUG
|
||||
std::cerr << "received config changed" << std::endl ;
|
||||
#endif
|
||||
emit configChanged() ;
|
||||
break ;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void NotifyQt::notifyListPreChange(int list, int type)
|
||||
{
|
||||
#ifdef NOTIFY_DEBUG
|
||||
std::cerr << "NotifyQt::notifyListPreChange()" << std::endl;
|
||||
#endif
|
||||
switch(list)
|
||||
{
|
||||
case NOTIFY_LIST_NEIGHBOURS:
|
||||
break;
|
||||
case NOTIFY_LIST_FRIENDS:
|
||||
emit friendsChanged() ;
|
||||
break;
|
||||
case NOTIFY_LIST_DIRLIST_FRIENDS:
|
||||
emit filesPreModChanged(false) ; /* remote */
|
||||
break ;
|
||||
case NOTIFY_LIST_DIRLIST_LOCAL:
|
||||
emit filesPreModChanged(true) ; /* local */
|
||||
break;
|
||||
case NOTIFY_LIST_SEARCHLIST:
|
||||
break;
|
||||
case NOTIFY_LIST_MESSAGELIST:
|
||||
break;
|
||||
case NOTIFY_LIST_CHANNELLIST:
|
||||
break;
|
||||
case NOTIFY_LIST_TRANSFERLIST:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* New Timer Based Update scheme ...
|
||||
* means correct thread seperation
|
||||
*
|
||||
* uses Flags, to detect changes
|
||||
*/
|
||||
|
||||
void NotifyQt::UpdateGUI()
|
||||
{
|
||||
/* hack to force updates until we've fixed that part */
|
||||
static time_t lastTs = 0;
|
||||
|
||||
// std::cerr << "Got update signal t=" << lastTs << std::endl ;
|
||||
|
||||
lastTs = time(NULL) ;
|
||||
|
||||
static bool already_updated = false ; // these only update once at start because they may already have been set before
|
||||
// the gui is running, then they get updated by callbacks.
|
||||
if(!already_updated)
|
||||
{
|
||||
emit messagesChanged() ;
|
||||
emit neighborsChanged();
|
||||
emit configChanged();
|
||||
|
||||
already_updated = true ;
|
||||
}
|
||||
|
||||
/* Finally Check for PopupMessages / System Error Messages */
|
||||
|
||||
if (rsNotify)
|
||||
{
|
||||
uint32_t sysid;
|
||||
uint32_t type;
|
||||
std::string title, id, msg;
|
||||
|
||||
if (rsNotify->NotifyPopupMessage(type, id, msg))
|
||||
{
|
||||
RshareSettings settings;
|
||||
uint popupflags = settings.getNotifyFlags();
|
||||
|
||||
/* id the name */
|
||||
std::string name = rsPeers->getPeerName(id);
|
||||
std::string realmsg = "<strong>" + name + "</strong>";
|
||||
switch(type)
|
||||
{
|
||||
case RS_POPUP_MSG:
|
||||
if (popupflags & RS_POPUP_MSG)
|
||||
{
|
||||
MessageToaster * msgToaster = new MessageToaster();
|
||||
//msgToaster->setMessage(QString::fromStdString(title));
|
||||
msgToaster->setName(QString::fromStdString(realmsg));
|
||||
msgToaster->displayPopup();
|
||||
}
|
||||
break;
|
||||
case RS_POPUP_CHAT:
|
||||
if (popupflags & RS_POPUP_CHAT)
|
||||
{
|
||||
ChatToaster * chatToaster = new ChatToaster();
|
||||
chatToaster->setMessage(QString::fromStdString(realmsg));
|
||||
chatToaster->show();
|
||||
}
|
||||
break;
|
||||
case RS_POPUP_CALL:
|
||||
if (popupflags & RS_POPUP_CALL)
|
||||
{
|
||||
CallToaster * callToaster = new CallToaster();
|
||||
callToaster->setMessage(QString::fromStdString(realmsg));
|
||||
callToaster->show();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case RS_POPUP_CONNECT:
|
||||
if (popupflags & RS_POPUP_CONNECT)
|
||||
{
|
||||
OnlineToaster * onlineToaster = new OnlineToaster();
|
||||
onlineToaster->setMessage(QString::fromStdString(realmsg));
|
||||
onlineToaster->show();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (rsNotify->NotifySysMessage(sysid, type, title, msg))
|
||||
{
|
||||
/* make a warning message */
|
||||
switch(type)
|
||||
{
|
||||
case RS_SYS_ERROR:
|
||||
QMessageBox::critical(0,
|
||||
QString::fromStdString(title),
|
||||
QString::fromStdString(msg));
|
||||
break;
|
||||
case RS_SYS_WARNING:
|
||||
QMessageBox::warning(0,
|
||||
QString::fromStdString(title),
|
||||
QString::fromStdString(msg));
|
||||
break;
|
||||
default:
|
||||
case RS_SYS_INFO:
|
||||
QMessageBox::information(0,
|
||||
QString::fromStdString(title),
|
||||
QString::fromStdString(msg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rsNotify->NotifyLogMessage(sysid, type, title, msg))
|
||||
{
|
||||
/* make a log message */
|
||||
std::string logMesString = title + " " + msg;
|
||||
switch(type)
|
||||
{
|
||||
case RS_SYS_ERROR:
|
||||
case RS_SYS_WARNING:
|
||||
case RS_SYS_INFO: emit logInfoChanged(QString(logMesString.c_str()));
|
||||
default:;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//void NotifyQt::displaySearch()
|
||||
//{
|
||||
// iface->lockData(); /* Lock Interface */
|
||||
//
|
||||
//#ifdef NOTIFY_DEBUG
|
||||
// std::ostringstream out;
|
||||
// std::cerr << out.str();
|
||||
//#endif
|
||||
//
|
||||
// iface->unlockData(); /* UnLock Interface */
|
||||
//}
|
||||
|
||||
// void NotifyQt::displayChat()
|
||||
// {
|
||||
// iface->lockData(); /* Lock Interface */
|
||||
//
|
||||
// #ifdef NOTIFY_DEBUG
|
||||
// std::ostringstream out;
|
||||
// std::cerr << out.str();
|
||||
// #endif
|
||||
//
|
||||
// iface->unlockData(); /* UnLock Interface */
|
||||
//
|
||||
// if (hDialog)
|
||||
// hDialog -> insertChat();
|
||||
// }
|
||||
//
|
||||
//
|
||||
//void NotifyQt::displayChannels()
|
||||
//{
|
||||
// iface->lockData(); /* Lock Interface */
|
||||
//
|
||||
//#ifdef NOTIFY_DEBUG
|
||||
// std::ostringstream out;
|
||||
// std::cerr << out.str();
|
||||
//#endif
|
||||
//
|
||||
// iface->unlockData(); /* UnLock Interface */
|
||||
//
|
||||
// if (sDialog)
|
||||
// sDialog -> insertChannels();
|
||||
//}
|
||||
//
|
||||
//
|
||||
//void NotifyQt::displayTransfers()
|
||||
//{
|
||||
// /* Do the GUI */
|
||||
// if (tDialog)
|
||||
// tDialog->insertTransfers();
|
||||
//}
|
||||
//
|
||||
//
|
||||
//void NotifyQt::preDisplayNeighbours()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void NotifyQt::preDisplayFriends()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
|
||||
//void NotifyQt::preDisplaySearch()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void NotifyQt::preDisplayMessages()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void NotifyQt::preDisplayChannels()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void NotifyQt::preDisplayTransfers()
|
||||
//{
|
||||
//
|
||||
//
|
||||
//}
|
||||
|
||||
|
||||
|
@ -1,101 +0,0 @@
|
||||
#ifndef RSIFACE_NOTIFY_TXT_H
|
||||
#define RSIFACE_NOTIFY_TXT_H
|
||||
|
||||
#include "rsiface/rsiface.h"
|
||||
#include "rsiface/rsturtle.h"
|
||||
#include <QObject>
|
||||
|
||||
#include <string>
|
||||
|
||||
class NetworkDialog;
|
||||
class PeersDialog;
|
||||
class SharedFilesDialog;
|
||||
class TransfersDialog;
|
||||
class ChatDialog;
|
||||
class MessagesDialog;
|
||||
class ChannelsDialog;
|
||||
class MessengerWindow;
|
||||
struct TurtleFileInfo ;
|
||||
|
||||
//class NotifyQt: public NotifyBase, public QObject
|
||||
class NotifyQt: public QObject, public NotifyBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NotifyQt()
|
||||
: cDialog(NULL)
|
||||
{ return; }
|
||||
|
||||
virtual ~NotifyQt() { return; }
|
||||
|
||||
void setNetworkDialog(NetworkDialog *c) { cDialog = c; }
|
||||
|
||||
virtual void notifyListPreChange(int list, int type);
|
||||
virtual void notifyListChange(int list, int type);
|
||||
virtual void notifyErrorMsg(int list, int sev, std::string msg);
|
||||
virtual void notifyChatStatus(const std::string& peer_id,const std::string& status_string,bool is_private);
|
||||
virtual void notifyCustomState(const std::string& peer_id);
|
||||
virtual void notifyHashingInfo(std::string fileinfo);
|
||||
virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list<TurtleFileInfo>& found_files);
|
||||
virtual void notifyPeerHasNewAvatar(std::string peer_id) ;
|
||||
virtual void notifyOwnAvatarChanged() ;
|
||||
virtual void notifyOwnStatusMessageChanged() ;
|
||||
virtual std::string askForPassword(const std::string& window_title,const std::string& text) ;
|
||||
|
||||
signals:
|
||||
// It's beneficial to send info to the GUI using signals, because signals are thread-safe
|
||||
// as they get queued by Qt.
|
||||
//
|
||||
void hashingInfoChanged(const QString&) const ;
|
||||
void filesPreModChanged(bool) const ;
|
||||
void filesPostModChanged(bool) const ;
|
||||
void transfersChanged() const ;
|
||||
void friendsChanged() const ;
|
||||
void neighborsChanged() const ;
|
||||
void messagesChanged() const ;
|
||||
void configChanged() const ;
|
||||
void logInfoChanged(const QString&) const ;
|
||||
void chatStatusChanged(const QString&,const QString&,bool) const ;
|
||||
void peerHasNewCustomStateString(const QString&) const ;
|
||||
void gotTurtleSearchResult(qulonglong search_id,FileDetail file) const ;
|
||||
void peerHasNewAvatar(const QString& peer_id) const ;
|
||||
void ownAvatarChanged() const ;
|
||||
void ownStatusMessageChanged() const ;
|
||||
|
||||
public slots:
|
||||
|
||||
void UpdateGUI(); /* called by timer */
|
||||
|
||||
private:
|
||||
|
||||
// void displayNeighbours();
|
||||
// void displayFriends();
|
||||
// void displayDirectories();
|
||||
// void displaySearch();
|
||||
// void displayChat();
|
||||
// void displayMessages();
|
||||
// void displayChannels();
|
||||
// void displayTransfers();
|
||||
|
||||
// void preDisplayNeighbours();
|
||||
// void preDisplayFriends();
|
||||
// void preDisplayDirectories();
|
||||
// void preDisplaySearch();
|
||||
// void preDisplayMessages();
|
||||
// void preDisplayChannels();
|
||||
// void preDisplayTransfers();
|
||||
|
||||
/* so we can update windows */
|
||||
NetworkDialog *cDialog;
|
||||
// PeersDialog *pDialog;
|
||||
// SharedFilesDialog *dDialog;
|
||||
// TransfersDialog *tDialog;
|
||||
// ChatDialog *hDialog;
|
||||
// MessagesDialog *mDialog;
|
||||
// ChannelsDialog *sDialog;
|
||||
// MessengerWindow *mWindow;
|
||||
|
||||
// RsIface *iface;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user