fixed merged with upstream/master

This commit is contained in:
csoler 2018-08-28 23:42:24 +02:00
commit c9b30f5a72
No known key found for this signature in database
GPG key ID: 7BCA522266C0804C
88 changed files with 3867 additions and 977 deletions

View file

@ -71,7 +71,8 @@ ftServer::ftServer(p3PeerMgr *pm, p3ServiceControl *sc)
mPeerMgr(pm), mServiceCtrl(sc),
mFileDatabase(NULL),
mFtController(NULL), mFtExtra(NULL),
mFtDataplex(NULL), mFtSearch(NULL), srvMutex("ftServer")
mFtDataplex(NULL), mFtSearch(NULL), srvMutex("ftServer"),
mSearchCallbacksMapMutex("ftServer callbacks map")
{
addSerialType(new RsFileTransferSerialiser()) ;
}
@ -425,7 +426,7 @@ void ftServer::requestDirUpdate(void *ref)
}
/* Directory Handling */
bool ftServer::setDownloadDirectory(std::string path)
bool ftServer::setDownloadDirectory(const std::string& path)
{
return mFtController->setDownloadDirectory(path);
}
@ -435,7 +436,7 @@ std::string ftServer::getDownloadDirectory()
return mFtController->getDownloadDirectory();
}
bool ftServer::setPartialsDirectory(std::string path)
bool ftServer::setPartialsDirectory(const std::string& path)
{
return mFtController->setPartialsDirectory(path);
}
@ -1630,6 +1631,7 @@ int ftServer::tick()
mFtDataplex->deleteUnusedServers() ;
mFtDataplex->handlePendingCrcRequests() ;
mFtDataplex->dispatchReceivedChunkCheckSum() ;
cleanTimedOutSearches();
}
return moreToTick;
@ -1820,6 +1822,24 @@ int ftServer::handleIncoming()
**********************************
*********************************/
void ftServer::receiveSearchResult(RsTurtleFTSearchResultItem *item)
{
bool hasCallback = false;
{
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
auto cbpt = mSearchCallbacksMap.find(item->request_id);
if(cbpt != mSearchCallbacksMap.end())
{
hasCallback = true;
cbpt->second.first(item->result);
}
} // end RS_STACK_MUTEX(mSearchCallbacksMapMutex);
if(!hasCallback)
RsServer::notify()->notifyTurtleSearchResult(item->PeerId(),item->request_id, item->result );
}
/***************************** CONFIG ****************************/
bool ftServer::addConfiguration(p3ConfigMgr *cfgmgr)
@ -1832,6 +1852,42 @@ bool ftServer::addConfiguration(p3ConfigMgr *cfgmgr)
return true;
}
bool ftServer::turtleSearchRequest(
const std::string& matchString,
const std::function<void (const std::list<TurtleFileInfo>& results)>& multiCallback,
std::time_t maxWait )
{
if(matchString.empty())
{
std::cerr << __PRETTY_FUNCTION__ << " match string can't be empty!"
<< std::endl;
return false;
}
TurtleRequestId sId = turtleSearch(matchString);
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
mSearchCallbacksMap.emplace(
sId,
std::make_pair(
multiCallback,
std::chrono::system_clock::now() +
std::chrono::seconds(maxWait) ) );
return true;
}
void ftServer::cleanTimedOutSearches()
{
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
auto now = std::chrono::system_clock::now();
for( auto cbpt = mSearchCallbacksMap.begin();
cbpt != mSearchCallbacksMap.end(); )
if(cbpt->second.second <= now)
cbpt = mSearchCallbacksMap.erase(cbpt);
else ++cbpt;
}
// Offensive content file filtering
int ftServer::banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size)
@ -1851,3 +1907,5 @@ bool ftServer::isHashBanned(const RsFileHash& hash)
{
return mFileDatabase->isFileBanned(hash);
}

View file

@ -39,6 +39,8 @@
#include <map>
#include <list>
#include <iostream>
#include <functional>
#include <chrono>
#include "ft/ftdata.h"
#include "turtle/turtleclientservice.h"
@ -96,7 +98,7 @@ public:
uint16_t serviceId() const { return RS_SERVICE_TYPE_FILE_TRANSFER ; }
virtual bool handleTunnelRequest(const RsFileHash& hash,const RsPeerId& peer_id) ;
virtual void receiveTurtleData(const RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
//virtual void receiveSearchResult(RsTurtleSearchResultItem *item);// TODO
virtual void receiveSearchResult(RsTurtleFTSearchResultItem *item);
virtual RsItem *create_item(uint16_t service,uint8_t item_type) const ;
virtual RsServiceSerializer *serializer() { return this ; }
@ -143,6 +145,12 @@ public:
virtual void setFilePermDirectDL(uint32_t perm) ;
virtual uint32_t filePermDirectDL() ;
/// @see RsFiles
virtual bool turtleSearchRequest(
const std::string& matchString,
const std::function<void (const std::list<TurtleFileInfo>& results)>& multiCallback,
std::time_t maxWait = 300 );
virtual TurtleSearchRequestId turtleSearch(const std::string& string_to_match) ;
virtual TurtleSearchRequestId turtleSearch(const RsRegularExpression::LinearizedExpression& expr) ;
@ -210,8 +218,8 @@ public:
* Directory Handling
***/
virtual void requestDirUpdate(void *ref) ; // triggers the update of the given reference. Used when browsing.
virtual bool setDownloadDirectory(std::string path);
virtual bool setPartialsDirectory(std::string path);
virtual bool setDownloadDirectory(const std::string& path);
virtual bool setPartialsDirectory(const std::string& path);
virtual std::string getDownloadDirectory();
virtual std::string getPartialsDirectory();
@ -319,6 +327,18 @@ private:
std::map<RsFileHash,RsFileHash> mEncryptedHashes ; // This map is such that sha1(it->second) = it->first
std::map<RsPeerId,RsFileHash> mEncryptedPeerIds ; // This map holds the hash to be used with each peer id
std::map<RsPeerId,std::map<RsFileHash,time_t> > mUploadLimitMap ;
/** Store search callbacks with timeout*/
std::map<
TurtleRequestId,
std::pair<
std::function<void (const std::list<TurtleFileInfo>& results)>,
std::chrono::system_clock::time_point >
> mSearchCallbacksMap;
RsMutex mSearchCallbacksMapMutex;
/// Cleanup mSearchCallbacksMap
void cleanTimedOutSearches();
};

View file

@ -55,7 +55,7 @@ void GxsTokenQueue::checkRequests()
uint32_t token = it->mToken;
uint32_t status = mGenExchange->getTokenService()->requestStatus(token);
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
if (status == RsTokenService::COMPLETE)
{
toload.push_back(*it);
it = mQueue.erase(it);
@ -67,7 +67,7 @@ void GxsTokenQueue::checkRequests()
#endif
++it;
}
else if (status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
else if (status == RsTokenService::FAILED)
{
// maybe we should do alternative callback?
std::cerr << "GxsTokenQueue::checkRequests() ERROR Request Failed: " << token;

View file

@ -1999,7 +1999,7 @@ void RsGenExchange::processMsgMetaChanges()
if(ok)
{
mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
mDataAccess->updatePublicRequestStatus(token, RsTokenService::COMPLETE);
if (changed)
{
msgIds[m.msgId.first].insert(m.msgId.second);
@ -2007,7 +2007,7 @@ void RsGenExchange::processMsgMetaChanges()
}
else
{
mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
mDataAccess->updatePublicRequestStatus(token, RsTokenService::FAILED);
}
{
@ -2053,11 +2053,11 @@ void RsGenExchange::processGrpMetaChanges()
if(ok)
{
mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
mDataAccess->updatePublicRequestStatus(token, RsTokenService::COMPLETE);
grpChanged.push_back(g.grpId);
}else
{
mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
mDataAccess->updatePublicRequestStatus(token, RsTokenService::FAILED);
}
{
@ -2290,7 +2290,7 @@ void RsGenExchange::publishMsgs()
// add to published to allow acknowledgement
mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(grpId, msgId)));
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::COMPLETE);
}
else
@ -2300,7 +2300,7 @@ void RsGenExchange::publishMsgs()
if(!tryLater)
mDataAccess->updatePublicRequestStatus(mit->first,
RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
RsTokenService::FAILED);
std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl;
}
@ -2377,7 +2377,7 @@ void RsGenExchange::processGroupUpdatePublish()
if(mit == grpMeta.end() || mit->second == NULL)
{
std::cerr << "Error! could not find meta of old group to update!" << std::endl;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::FAILED);
delete gup.grpItem;
continue;
}
@ -2405,7 +2405,7 @@ void RsGenExchange::processGroupUpdatePublish()
std::cerr << "(EE) publish group fails because RS cannot find the private publish and author keys" << std::endl;
delete gup.grpItem;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::FAILED);
}
}
@ -2426,7 +2426,7 @@ void RsGenExchange::processRoutingClues()
void RsGenExchange::processGroupDelete()
{
RS_STACK_MUTEX(mGenMtx) ;
RS_STACK_MUTEX(mGenMtx);
// get keys for group delete publish
typedef std::pair<bool, RsGxsGroupId> GrpNote;
@ -2447,8 +2447,9 @@ void RsGenExchange::processGroupDelete()
for(; mit != toNotify.end(); ++mit)
{
GrpNote& note = mit->second;
uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
: RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
RsTokenService::GxsRequestStatus status =
note.first ? RsTokenService::COMPLETE
: RsTokenService::FAILED;
mGrpNotify.insert(std::make_pair(mit->first, note.second));
mDataAccess->updatePublicRequestStatus(mit->first, status);
@ -2756,8 +2757,9 @@ void RsGenExchange::publishGrps()
for(; mit != toNotify.end(); ++mit)
{
GrpNote& note = mit->second;
uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
: RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
RsTokenService::GxsRequestStatus status =
note.first ? RsTokenService::COMPLETE
: RsTokenService::FAILED;
mGrpNotify.insert(std::make_pair(mit->first, note.second));
mDataAccess->updatePublicRequestStatus(mit->first, status);
@ -2793,7 +2795,8 @@ uint32_t RsGenExchange::generatePublicToken()
return mDataAccess->generatePublicToken();
}
bool RsGenExchange::updatePublicRequestStatus(const uint32_t &token, const uint32_t &status)
bool RsGenExchange::updatePublicRequestStatus(
uint32_t token, RsTokenService::GxsRequestStatus status )
{
return mDataAccess->updatePublicRequestStatus(token, status);
}

View file

@ -479,7 +479,8 @@ public:
* @param status
* @return false if token could not be found, true if token disposed of
*/
bool updatePublicRequestStatus(const uint32_t &token, const uint32_t &status);
bool updatePublicRequestStatus(
uint32_t token, RsTokenService::GxsRequestStatus status);
/*!
* This gets rid of a publicly issued token

View file

@ -26,15 +26,6 @@
#include "rsgxsdataaccess.h"
#include "retroshare/rsgxsflags.h"
// TODO CLEANUP: This should be an enum defined in rstokenservice.h
const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_FAILED = 0;
const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_PENDING = 1;
const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_PARTIAL = 2;
const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_FINISHED_INCOMPLETE = 3;
const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE = 4;
const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_DONE = 5; // ONCE ALL DATA RETRIEVED.
const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_CANCELLED = 6;
/***********
* #define DATA_DEBUG 1
**********/
@ -314,22 +305,22 @@ void RsGxsDataAccess::storeRequest(GxsRequest* req)
{
RsStackMutex stack(mDataMutex); /****** LOCKED *****/
req->status = GXS_REQUEST_V2_STATUS_PENDING;
req->status = PENDING;
req->reqTime = time(NULL);
mRequests[req->token] = req;
return;
}
uint32_t RsGxsDataAccess::requestStatus(uint32_t token)
RsTokenService::GxsRequestStatus RsGxsDataAccess::requestStatus(uint32_t token)
{
uint32_t status;
RsTokenService::GxsRequestStatus status;
uint32_t reqtype;
uint32_t anstype;
time_t ts;
{
RsStackMutex stack(mDataMutex);
RS_STACK_MUTEX(mDataMutex);
// first check public tokens
if(mPublicToken.find(token) != mPublicToken.end())
@ -337,7 +328,7 @@ uint32_t RsGxsDataAccess::requestStatus(uint32_t token)
}
if (!checkRequestStatus(token, status, reqtype, anstype, ts))
return RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
return RsTokenService::FAILED;
return status;
}
@ -352,7 +343,7 @@ bool RsGxsDataAccess::cancelRequest(const uint32_t& token)
return false;
}
req->status = GXS_REQUEST_V2_STATUS_CANCELLED;
req->status = CANCELLED;
return true;
}
@ -388,7 +379,7 @@ bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list<const RsG
<< "group summary" << std::endl;
return false;
}
else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE)
else if(req->status == COMPLETE)
{
GroupMetaReq* gmreq = dynamic_cast<GroupMetaReq*>(req);
@ -396,7 +387,7 @@ bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list<const RsG
{
groupInfo = gmreq->mGroupMetaData;
gmreq->mGroupMetaData.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else
{
@ -427,7 +418,7 @@ bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list<RsNxsGrp*>&
<< "data" << std::endl;
return false;
}
else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE)
else if(req->status == COMPLETE)
{
GroupDataReq* gmreq = dynamic_cast<GroupDataReq*>(req);
GroupSerializedDataReq* gsreq = dynamic_cast<GroupSerializedDataReq*>(req);
@ -437,13 +428,13 @@ bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list<RsNxsGrp*>&
grpData.swap(gsreq->mGroupData);
gsreq->mGroupData.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else if(gmreq)
{
grpData.swap(gmreq->mGroupData);
gmreq->mGroupData.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else
{
@ -472,7 +463,7 @@ bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgDat
std::cerr << "RsGxsDataAccess::getMsgData() Unable to retrieve group data" << std::endl;
return false;
}else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){
}else if(req->status == COMPLETE){
MsgDataReq* mdreq = dynamic_cast<MsgDataReq*>(req);
@ -480,7 +471,7 @@ bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgDat
{
msgData.swap(mdreq->mMsgData);
mdreq->mMsgData.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else
{
@ -506,7 +497,7 @@ bool RsGxsDataAccess::getMsgRelatedData(const uint32_t &token, NxsMsgRelatedData
std::cerr << "RsGxsDataAccess::getMsgRelatedData() Unable to retrieve group data" << std::endl;
return false;
}else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){
}else if(req->status == COMPLETE){
MsgRelatedInfoReq* mrireq = dynamic_cast<MsgRelatedInfoReq*>(req);
@ -517,7 +508,7 @@ bool RsGxsDataAccess::getMsgRelatedData(const uint32_t &token, NxsMsgRelatedData
{
msgData.swap(mrireq->mMsgDataResult);
mrireq->mMsgDataResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else
{
@ -543,7 +534,7 @@ bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msg
std::cerr << "RsGxsDataAccess::getMsgSummary() Unable to retrieve group data" << std::endl;
return false;
}else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){
}else if(req->status == COMPLETE){
MsgMetaReq* mmreq = dynamic_cast<MsgMetaReq*>(req);
@ -551,7 +542,7 @@ bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msg
{
msgInfo.swap(mmreq->mMsgMetaData);
mmreq->mMsgMetaData.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else
@ -580,7 +571,7 @@ bool RsGxsDataAccess::getMsgRelatedSummary(const uint32_t &token, MsgRelatedMeta
std::cerr << "RsGxsDataAccess::getMsgRelatedSummary() Unable to retrieve message summary" << std::endl;
return false;
}else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){
}else if(req->status == COMPLETE){
if(req->Options.mReqType != GXS_REQUEST_TYPE_MSG_RELATED_META)
return false;
@ -591,7 +582,7 @@ bool RsGxsDataAccess::getMsgRelatedSummary(const uint32_t &token, MsgRelatedMeta
{
msgMeta.swap(mrireq->mMsgMetaResult);
mrireq->mMsgMetaResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else
{
@ -619,7 +610,7 @@ bool RsGxsDataAccess::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResul
std::cerr << "RsGxsDataAccess::getMsgRelatedList() Unable to retrieve message data" << std::endl;
return false;
}else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){
}else if(req->status == COMPLETE){
if(req->Options.mReqType != GXS_REQUEST_TYPE_MSG_RELATED_IDS)
return false;
@ -630,7 +621,7 @@ bool RsGxsDataAccess::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResul
{
msgIds.swap(mrireq->mMsgIdResult);
mrireq->mMsgIdResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else{
std::cerr << "RsGxsDataAccess::getMsgRelatedList() Req found, failed caste" << std::endl;
@ -656,7 +647,7 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds)
std::cerr << "RsGxsDataAccess::getMsgList() Unable to retrieve msg Ids" << std::endl;
return false;
}else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){
}else if(req->status == COMPLETE){
MsgIdReq* mireq = dynamic_cast<MsgIdReq*>(req);
@ -664,7 +655,7 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds)
{
msgIds.swap(mireq->mMsgIdResult);
mireq->mMsgIdResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else{
std::cerr << "RsGxsDataAccess::getMsgList() Req found, failed caste" << std::endl;
@ -689,7 +680,7 @@ bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list<RsGxsGroupId
std::cerr << "RsGxsDataAccess::getGroupList() Unable to retrieve group Ids,"
"\nRequest does not exist" << std::endl;
return false;
}else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){
}else if(req->status == COMPLETE){
GroupIdReq* gireq = dynamic_cast<GroupIdReq*>(req);
@ -697,7 +688,7 @@ bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list<RsGxsGroupId
{
groupIds.swap(gireq->mGroupIdResult);
gireq->mGroupIdResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}else{
std::cerr << "RsGxsDataAccess::getGroupList() Req found, failed caste" << std::endl;
@ -739,21 +730,21 @@ void RsGxsDataAccess::processRequests()
switch (req->status)
{
case GXS_REQUEST_V2_STATUS_PENDING:
case PENDING:
// process request later
break;
case GXS_REQUEST_V2_STATUS_PARTIAL:
case PARTIAL:
// should not happen
req->status = GXS_REQUEST_V2_STATUS_COMPLETE;
req->status = COMPLETE;
break;
case GXS_REQUEST_V2_STATUS_DONE:
case DONE:
#ifdef DATA_DEBUG
std::cerr << "RsGxsDataAccess::processrequests() Clearing Done Request Token: " << req->token;
std::cerr << std::endl;
#endif
toClear.push_back(req->token);
break;
case GXS_REQUEST_V2_STATUS_CANCELLED:
case CANCELLED:
#ifdef DATA_DEBUG
std::cerr << "RsGxsDataAccess::processrequests() Clearing Cancelled Request Token: " << req->token;
std::cerr << std::endl;
@ -791,10 +782,10 @@ void RsGxsDataAccess::processRequests()
for (it = mRequests.begin(); it != mRequests.end(); ++it)
{
GxsRequest* reqCheck = it->second;
if (reqCheck->status == GXS_REQUEST_V2_STATUS_PENDING)
if (reqCheck->status == PENDING)
{
req = reqCheck;
req->status = GXS_REQUEST_V2_STATUS_PARTIAL;
req->status = PARTIAL;
break;
}
}
@ -874,9 +865,9 @@ void RsGxsDataAccess::processRequests()
{
RsStackMutex stack(mDataMutex); /******* LOCKED *******/
if (req->status == GXS_REQUEST_V2_STATUS_PARTIAL)
if (req->status == PARTIAL)
{
req->status = ok ? GXS_REQUEST_V2_STATUS_COMPLETE : GXS_REQUEST_V2_STATUS_FAILED;
req->status = ok ? COMPLETE : FAILED;
}
} // END OF MUTEX.
}
@ -892,14 +883,14 @@ bool RsGxsDataAccess::getGroupStatistic(const uint32_t &token, GxsGroupStatistic
std::cerr << "RsGxsDataAccess::getGroupStatistic() Unable to retrieve grp stats" << std::endl;
return false;
}else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){
}else if(req->status == COMPLETE){
GroupStatisticRequest* gsreq = dynamic_cast<GroupStatisticRequest*>(req);
if(gsreq)
{
grpStatistic = gsreq->mGroupStatistic;
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else{
std::cerr << "RsGxsDataAccess::getGroupStatistic() Req found, failed caste" << std::endl;
@ -923,14 +914,14 @@ bool RsGxsDataAccess::getServiceStatistic(const uint32_t &token, GxsServiceStati
std::cerr << "RsGxsDataAccess::getServiceStatistic() Unable to retrieve service stats" << std::endl;
return false;
}else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){
}else if(req->status == COMPLETE){
ServiceStatisticRequest* ssreq = dynamic_cast<ServiceStatisticRequest*>(req);
if(ssreq)
{
servStatistic = ssreq->mServiceStatistic;
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
locked_updateRequestStatus(token, DONE);
}
else{
std::cerr << "RsGxsDataAccess::getServiceStatistic() Req found, failed caste" << std::endl;
@ -1767,15 +1758,15 @@ void RsGxsDataAccess::filterGrpList(std::list<RsGxsGroupId> &grpIds, const RsTok
}
bool RsGxsDataAccess::checkRequestStatus(const uint32_t& token,
uint32_t& status, uint32_t& reqtype, uint32_t& anstype, time_t& ts)
bool RsGxsDataAccess::checkRequestStatus(
uint32_t token, GxsRequestStatus& status, uint32_t& reqtype,
uint32_t& anstype, time_t& ts )
{
RsStackMutex stack(mDataMutex);
RS_STACK_MUTEX(mDataMutex);
GxsRequest* req = locked_retrieveRequest(token);
if (req == NULL || req->status == GXS_REQUEST_V2_STATUS_CANCELLED)
if (req == NULL || req->status == CANCELLED)
return false;
anstype = req->ansType;
@ -1845,70 +1836,52 @@ void RsGxsDataAccess::tokenList(std::list<uint32_t>& tokens)
}
}
bool RsGxsDataAccess::locked_updateRequestStatus(const uint32_t& token,
const uint32_t& status)
bool RsGxsDataAccess::locked_updateRequestStatus(
uint32_t token, RsTokenService::GxsRequestStatus status )
{
GxsRequest* req = locked_retrieveRequest(token);
if(req)
req->status = status;
else
return false;
if(req) req->status = status;
else return false;
return true;
}
uint32_t RsGxsDataAccess::generatePublicToken()
{
uint32_t token;
generateToken(token);
{
RsStackMutex stack(mDataMutex);
mPublicToken[token] = RsTokenService::GXS_REQUEST_V2_STATUS_PENDING;
}
{
RS_STACK_MUTEX(mDataMutex);
mPublicToken[token] = RsTokenService::PENDING;
}
return token;
}
bool RsGxsDataAccess::updatePublicRequestStatus(const uint32_t& token,
const uint32_t& status)
bool RsGxsDataAccess::updatePublicRequestStatus(
uint32_t token, RsTokenService::GxsRequestStatus status )
{
RsStackMutex stack(mDataMutex);
std::map<uint32_t, uint32_t>::iterator mit = mPublicToken.find(token);
if(mit != mPublicToken.end())
{
mit->second = status;
}
else
{
return false;
}
RS_STACK_MUTEX(mDataMutex);
std::map<uint32_t, RsTokenService::GxsRequestStatus>::iterator mit =
mPublicToken.find(token);
if(mit != mPublicToken.end()) mit->second = status;
else return false;
return true;
}
bool RsGxsDataAccess::disposeOfPublicToken(const uint32_t& token)
bool RsGxsDataAccess::disposeOfPublicToken(uint32_t token)
{
RsStackMutex stack(mDataMutex);
std::map<uint32_t, uint32_t>::iterator mit = mPublicToken.find(token);
if(mit != mPublicToken.end())
{
mPublicToken.erase(mit);
}
else
{
return false;
}
RS_STACK_MUTEX(mDataMutex);
std::map<uint32_t, RsTokenService::GxsRequestStatus>::iterator mit =
mPublicToken.find(token);
if(mit != mPublicToken.end()) mPublicToken.erase(mit);
else return false;
return true;
}

View file

@ -44,6 +44,8 @@ public:
* deprecated and should be removed as soon as possible as it is cause of
* many confusions, instead use const RsTokReqOptions::mReqType &opts to
* specify the kind of data you are interested in.
* Most of the methods use const uint32_t &token as param type change it to
* uint32_t
*/
/*!
@ -117,7 +119,7 @@ public:
/* Poll */
uint32_t requestStatus(const uint32_t token);
GxsRequestStatus requestStatus(const uint32_t token);
/* Cancel Request */
bool cancelRequest(const uint32_t &token);
@ -300,7 +302,7 @@ private:
* @param status the status to set
* @return
*/
bool locked_updateRequestStatus(const uint32_t &token, const uint32_t &status);
bool locked_updateRequestStatus(uint32_t token, GxsRequestStatus status);
/*!
* Use to query the status and other values of a given token
@ -311,7 +313,8 @@ private:
* @param ts time stamp
* @return false if token does not exist, true otherwise
*/
bool checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, uint32_t &anstype, time_t &ts);
bool checkRequestStatus( uint32_t token, GxsRequestStatus &status,
uint32_t &reqtype, uint32_t &anstype, time_t &ts);
// special ones for testing (not in final design)
/*!
@ -341,14 +344,14 @@ public:
* @param status
* @return false if token could not be found, true if token disposed of
*/
bool updatePublicRequestStatus(const uint32_t &token, const uint32_t &status);
bool updatePublicRequestStatus(uint32_t token, GxsRequestStatus status);
/*!
* This gets rid of a publicly issued token
* @param token
* @return false if token could not found, true if token disposed of
*/
bool disposeOfPublicToken(const uint32_t &token);
bool disposeOfPublicToken(uint32_t token);
private:
@ -488,7 +491,7 @@ private:
RsMutex mDataMutex; /* protecting below */
uint32_t mNextToken;
std::map<uint32_t, uint32_t> mPublicToken;
std::map<uint32_t, GxsRequestStatus> mPublicToken;
std::map<uint32_t, GxsRequest*> mRequests;

View file

@ -5181,43 +5181,51 @@ bool RsGxsNetService::clearDistantSearchResults(const TurtleRequestId& id)
}
void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req, const std::list<RsGxsGroupSummary>& group_infos)
{
RS_STACK_MUTEX(mNxsMutex) ;
std::set<RsGxsGroupId> groupsToNotifyResults;
RsGxsGrpMetaTemporaryMap grpMeta;
std::map<RsGxsGroupId,RsGxsGroupSummary>& search_results_map(mDistantSearchResults[req]) ;
{
RS_STACK_MUTEX(mNxsMutex);
for(auto it(group_infos.begin());it!=group_infos.end();++it)
if(search_results_map.find((*it).mGroupId) == search_results_map.end())
grpMeta[(*it).mGroupId] = NULL;
RsGxsGrpMetaTemporaryMap grpMeta;
std::map<RsGxsGroupId,RsGxsGroupSummary>&
search_results_map(mDistantSearchResults[req]);
mDataStore->retrieveGxsGrpMetaData(grpMeta);
for(auto it(group_infos.begin());it!=group_infos.end();++it)
if(search_results_map.find((*it).mGroupId) == search_results_map.end())
grpMeta[(*it).mGroupId] = NULL;
std::list<RsGxsGroupSummary> filtered_results ;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
// only keep groups that are not locally known, and groups that are not already in the mDistantSearchResults structure
// only keep groups that are not locally known, and groups that are not already in the mDistantSearchResults structure
for(auto it(group_infos.begin());it!=group_infos.end();++it)
if(grpMeta[(*it).mGroupId] == NULL)
{
filtered_results.push_back(*it) ;
for(auto it(group_infos.begin());it!=group_infos.end();++it)
if(grpMeta[(*it).mGroupId] == NULL)
{
const RsGxsGroupId& grpId((*it).mGroupId);
auto it2 = search_results_map.find((*it).mGroupId) ;
groupsToNotifyResults.insert(grpId);
if(it2 != search_results_map.end())
{
// update existing data
auto it2 = search_results_map.find(grpId);
it2->second.mPopularity++ ;
it2->second.mNumberOfMessages = std::max(it2->second.mNumberOfMessages,(*it).mNumberOfMessages) ;
}
else
{
search_results_map[(*it).mGroupId] = *it;
search_results_map[(*it).mGroupId].mPopularity = 1; // number of results so far
}
if(it2 != search_results_map.end())
{
// update existing data
mObserver->receiveDistantSearchResults(req,(*it).mGroupId) ;
}
it2->second.mPopularity++;
it2->second.mNumberOfMessages = std::max(
it2->second.mNumberOfMessages,
(*it).mNumberOfMessages );
}
else
{
search_results_map[grpId] = *it;
search_results_map[grpId].mPopularity = 1; // number of results so far
}
}
} // end RS_STACK_MUTEX(mNxsMutex);
for(const RsGxsGroupId& grpId : groupsToNotifyResults)
mObserver->receiveDistantSearchResults(req, grpId);
}
void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len)

View file

@ -28,7 +28,9 @@
struct GxsRequest
{
GxsRequest() : token(0), reqTime(0), ansType(0), reqType(0), status(0) {}
GxsRequest() :
token(0), reqTime(0), ansType(0), reqType(0),
status(RsTokenService::FAILED) {}
virtual ~GxsRequest() {}
uint32_t token;
@ -38,7 +40,7 @@ struct GxsRequest
uint32_t reqType;
RsTokReqOptions Options;
uint32_t status;
RsTokenService::GxsRequestStatus status;
};
class GroupMetaReq : public GxsRequest

View file

@ -89,7 +89,7 @@ struct MsgSizeCount
* @see GxsTransClient::receiveGxsTransMail(...),
* @see GxsTransClient::notifyGxsTransSendStatus(...).
*/
class p3GxsTrans : public RsGenExchange, public GxsTokenQueue, public p3Config, public RsGxsTrans
struct p3GxsTrans : RsGenExchange, GxsTokenQueue, p3Config, RsGxsTrans
{
public:
p3GxsTrans( RsGeneralDataService* gds, RsNetworkExchangeService* nes,
@ -98,17 +98,16 @@ public:
RS_SERVICE_TYPE_GXS_TRANS, &identities,
AuthenPolicy()),
GxsTokenQueue(this),
RsGxsTrans(this),
mIdService(identities),
RsGxsTrans(static_cast<RsGxsIface&>(*this)),
// always check 30 secs after start)
mLastMsgCleanup(time(NULL) - MAX_DELAY_BETWEEN_CLEANUPS + 30),
mIdService(identities),
mServClientsMutex("p3GxsTrans client services map mutex"),
mOutgoingMutex("p3GxsTrans outgoing queue map mutex"),
mIngoingMutex("p3GxsTrans ingoing queue map mutex"),
mCleanupThread(nullptr),
mPerUserStatsMutex("p3GxsTrans user stats mutex"),
mDataMutex("p3GxsTrans data mutex")
{
mLastMsgCleanup = time(NULL) - MAX_DELAY_BETWEEN_CLEANUPS + 30; // always check 30 secs after start
mCleanupThread = NULL ;
}
mDataMutex("p3GxsTrans data mutex") {}
virtual ~p3GxsTrans();

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <stdexcept>
#include <time.h>

View file

@ -0,0 +1,145 @@
/*
* RetroShare JSON API
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jsonapi.h"
#include <sstream>
#include <memory>
#include <restbed>
#include <vector>
#include "util/rsjson.h"
#include "retroshare/rsfiles.h"
#include "util/radix64.h"
// Generated at compile time
#include "jsonapi-includes.inl"
JsonApiServer::JsonApiServer(
uint16_t port, const std::function<void(int)> shutdownCallback) :
mPort(port), mShutdownCallback(shutdownCallback)
{
registerHandler("/jsonApiServer/shutdown",
[this](const std::shared_ptr<rb::Session>)
{
shutdown();
});
registerHandler("/rsFiles/getFileData",
[](const std::shared_ptr<rb::Session> session)
{
size_t reqSize = session->get_request()->get_header("Content-Length", 0);
session->fetch( reqSize, [](
const std::shared_ptr<rb::Session> session,
const rb::Bytes& body )
{
RsGenericSerializer::SerializeContext cReq(
nullptr, 0,
RsGenericSerializer::SERIALIZATION_FLAG_YIELDING );
RsJson& jReq(cReq.mJson);
jReq.Parse(reinterpret_cast<const char*>(body.data()), body.size());
RsGenericSerializer::SerializeContext cAns;
RsJson& jAns(cAns.mJson);
// if caller specified caller_data put it back in the answhere
const char kcd[] = "caller_data";
if(jReq.HasMember(kcd))
jAns.AddMember(kcd, jReq[kcd], jAns.GetAllocator());
RsFileHash hash;
uint64_t offset;
uint32_t requested_size;
bool retval = false;
std::string errorMessage;
std::string base64data;
// deserialize input parameters from JSON
{
RsGenericSerializer::SerializeContext& ctx(cReq);
RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON);
RS_SERIAL_PROCESS(hash);
RS_SERIAL_PROCESS(offset);
RS_SERIAL_PROCESS(requested_size);
}
if(requested_size > 10485760)
errorMessage = "requested_size is too big! Better less then 1M";
else
{
std::vector<uint8_t> buffer(requested_size);
// call retroshare C++ API
retval = rsFiles->getFileData(
hash, offset, requested_size, buffer.data());
Radix64::encode(buffer.data(), requested_size, base64data);
}
// serialize out parameters and return value to JSON
{
RsGenericSerializer::SerializeContext& ctx(cAns);
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
RS_SERIAL_PROCESS(retval);
RS_SERIAL_PROCESS(requested_size);
RS_SERIAL_PROCESS(base64data);
if(!errorMessage.empty()) RS_SERIAL_PROCESS(errorMessage);
}
// return them to the API caller
std::stringstream ss;
ss << jAns;
std::string&& ans(ss.str());
const std::multimap<std::string, std::string> headers
{
{ "Content-Type", "text/json" },
{ "Content-Length", std::to_string(ans.length()) }
};
session->close(rb::OK, ans, headers);
} );
});
// Generated at compile time
#include "jsonapi-wrappers.inl"
}
void JsonApiServer::run()
{
std::shared_ptr<rb::Settings> settings(new rb::Settings);
settings->set_port(mPort);
// settings->set_default_header("Connection", "close");
settings->set_default_header("Cache-Control", "no-cache");
mService.start(settings);
}
void JsonApiServer::registerHandler(
const std::string& path,
const std::function<void (const std::shared_ptr<restbed::Session>)>& handler)
{
std::shared_ptr<restbed::Resource> resource(new rb::Resource);
resource->set_path(path);
resource->set_method_handler("GET", handler);
resource->set_method_handler("POST", handler);
mService.publish(resource);
}
void JsonApiServer::shutdown(int exitCode)
{
mService.stop();
mShutdownCallback(exitCode);
}

View file

@ -0,0 +1,73 @@
/*
* RetroShare JSON API
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string>
#include <memory>
#include <restbed>
#include "util/rsthreads.h"
namespace rb = restbed;
/**
* Simple usage
* \code{.cpp}
* JsonApiServer jas(9092);
* jas.start("JsonApiServer");
* \endcode
*/
struct JsonApiServer : RsSingleJobThread
{
JsonApiServer(
uint16_t port,
const std::function<void(int)> shutdownCallback = [](int){} );
/// @see RsSingleJobThread
virtual void run();
/**
* @param[in] path Path itno which publish the API call
* @param[in] handler function which will be called to handle the requested
* path, the function must be declared like:
* \code{.cpp}
* void functionName(const shared_ptr<restbed::Session> session)
* \endcode
*/
void registerHandler(
const std::string& path,
const std::function<void(const std::shared_ptr<rb::Session>)>& handler );
/**
* @brief Shutdown the JSON API server and call shutdownCallback
* @jsonapi{development}
* Beware that this method shout down only the JSON API server instance not
* the whole RetroShare instance, this behaviour can be altered via
* shutdownCallback paramether of @see JsonApiServer::JsonApiServer
* This method is made available also via JSON API with path
* /jsonApiServer/shutdown
* @param exitCode just passed down to the shutdownCallback
*/
void shutdown(int exitCode = 0);
private:
uint16_t mPort;
rb::Service mService;
const std::function<void(int)> mShutdownCallback;
};

View file

@ -776,10 +776,12 @@ SOURCES += gxstunnel/p3gxstunnel.cc \
# new serialization code
HEADERS += serialiser/rsserializable.h \
serialiser/rsserializer.h \
serialiser/rstypeserializer.h
serialiser/rstypeserializer.h \
util/rsjson.h
SOURCES += serialiser/rsserializer.cc \
serialiser/rstypeserializer.cc
serialiser/rstypeserializer.cc \
util/rsjson.cc
# Identity Service
HEADERS += retroshare/rsidentity.h \
@ -867,11 +869,64 @@ rs_gxs_trans {
SOURCES += gxstrans/p3gxstransitems.cc gxstrans/p3gxstrans.cc
}
rs_jsonapi {
JSONAPI_GENERATOR_SRC=$$system_path($$clean_path($${RS_SRC_PATH}/jsonapi-generator/src/))
JSONAPI_GENERATOR_OUT=$$system_path($$clean_path($${RS_BUILD_PATH}/jsonapi-generator/src/))
JSONAPI_GENERATOR_EXE=$$system_path($$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-generator))
DOXIGEN_INPUT_DIRECTORY=$$system_path($$clean_path($${PWD}))
DOXIGEN_CONFIG_SRC=$$system_path($$clean_path($${RS_SRC_PATH}/jsonapi-generator/src/jsonapi-generator-doxygen.conf))
DOXIGEN_CONFIG_OUT=$$system_path($$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-generator-doxygen.conf))
WRAPPERS_INCL_FILE=$$system_path($$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-includes.inl))
WRAPPERS_REG_FILE=$$system_path($$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-wrappers.inl))
restbed.target = $$system_path($$clean_path($${RESTBED_BUILD_PATH}/library/librestbed.a))
restbed.commands = \
cd $${RS_SRC_PATH};\
git submodule update --init --recommend-shallow supportlibs/restbed;\
cd $${RESTBED_SRC_PATH};\
git submodule update --init --recommend-shallow dependency/asio;\
git submodule update --init --recommend-shallow dependency/catch;\
git submodule update --init --recommend-shallow dependency/kashmir;\
mkdir -p $${RESTBED_BUILD_PATH}; cd $${RESTBED_BUILD_PATH};\
cmake -DBUILD_SSL=OFF -DCMAKE_INSTALL_PREFIX=. -B. -H$${RESTBED_SRC_PATH};\
make; make install
QMAKE_EXTRA_TARGETS += restbed
libretroshare.depends += restbed
PRE_TARGETDEPS *= $${restbed.target}
PRE_TARGETDEPS *= $${JSONAPI_GENERATOR_EXE}
INCLUDEPATH *= $${JSONAPI_GENERATOR_OUT}
GENERATED_HEADERS += $${WRAPPERS_INCL_FILE}
jsonwrappersincl.target = $${WRAPPERS_INCL_FILE}
jsonwrappersincl.commands = \
cp $${DOXIGEN_CONFIG_SRC} $${DOXIGEN_CONFIG_OUT}; \
echo OUTPUT_DIRECTORY=$${JSONAPI_GENERATOR_OUT} >> $${DOXIGEN_CONFIG_OUT};\
echo INPUT=$${DOXIGEN_INPUT_DIRECTORY} >> $${DOXIGEN_CONFIG_OUT}; \
doxygen $${DOXIGEN_CONFIG_OUT}; \
$${JSONAPI_GENERATOR_EXE} $${JSONAPI_GENERATOR_SRC} $${JSONAPI_GENERATOR_OUT};
QMAKE_EXTRA_TARGETS += jsonwrappersincl
libretroshare.depends += jsonwrappersincl
PRE_TARGETDEPS *= $${WRAPPERS_INCL_FILE}
jsonwrappersreg.target = $${WRAPPERS_REG_FILE}
jsonwrappersreg.commands = touch $${WRAPPERS_REG_FILE}
jsonwrappersreg.depends = jsonwrappersincl
QMAKE_EXTRA_TARGETS += jsonwrappersreg
libretroshare.depends += jsonwrappersreg
PRE_TARGETDEPS *= $${WRAPPERS_REG_FILE}
# Force recalculation of libretroshare dependencies see https://stackoverflow.com/a/47884045
QMAKE_EXTRA_TARGETS += libretroshare
HEADERS += jsonapi/jsonapi.h
SOURCES += jsonapi/jsonapi.cpp
}
rs_deep_search {
HEADERS += deep_search/deep_search.h
}
###########################################################################################################
# OLD CONFIG OPTIONS.
# Not used much - but might be useful one day.

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#ifdef WINDOWS_SYS

View file

@ -95,7 +95,11 @@ std::string pgp_pwd_callback(void * /*hook*/, const char *uid_title, const char
return password ;
}
void AuthGPG::init(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file)
void AuthGPG::init(
const std::string& path_to_public_keyring,
const std::string& path_to_secret_keyring,
const std::string& path_to_trustdb,
const std::string& pgp_lock_file)
{
if(_instance != NULL)
{
@ -103,8 +107,11 @@ void AuthGPG::init(const std::string& path_to_public_keyring,const std::string&
std::cerr << "AuthGPG::init() called twice!" << std::endl ;
}
PGPHandler::setPassphraseCallback(pgp_pwd_callback) ;
_instance = new AuthGPG(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file) ;
// if(cb) PGPHandler::setPassphraseCallback(cb);else
PGPHandler::setPassphraseCallback(pgp_pwd_callback);
_instance = new AuthGPG( path_to_public_keyring,
path_to_secret_keyring,
path_to_trustdb, pgp_lock_file );
}
void AuthGPG::exit()

View file

@ -82,8 +82,8 @@ public:
class AuthGPGService
{
public:
AuthGPGService() {};
~AuthGPGService() {};
AuthGPGService() {}
~AuthGPGService() {}
virtual AuthGPGOperation *getGPGOperation() = 0;
virtual void setGPGOperation(AuthGPGOperation *operation) = 0;
@ -91,12 +91,11 @@ public:
class AuthGPG: public p3Config, public RsTickingThread, public PGPHandler
{
public:
static void init( const std::string& path_to_pubring,
const std::string& path_to_secring,
const std::string& path_to_trustdb,
const std::string& pgp_lock_file);
public:
static void init(const std::string& path_to_pubring,
const std::string& path_to_secring,
const std::string& path_to_trustdb,
const std::string& pgp_lock_file);
static void exit();
static AuthGPG *getAuthGPG() { return _instance ; }

View file

@ -19,18 +19,25 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RS_FILES_GUI_INTERFACE_H
#define RS_FILES_GUI_INTERFACE_H
#pragma once
#include <list>
#include <iostream>
#include <string>
#include <functional>
#include <chrono>
#include "rstypes.h"
#include "serialiser/rsserializable.h"
#include "rsturtle.h"
class RsFiles;
extern RsFiles *rsFiles;
/**
* Pointer to global instance of RsFiles service implementation
* @jsonapi{development}
*/
extern RsFiles* rsFiles;
namespace RsRegularExpression { class Expression; }
@ -104,7 +111,7 @@ const TransferRequestFlags RS_FILE_REQ_NO_SEARCH ( 0x02000000 ); // di
const uint32_t RS_FILE_EXTRA_DELETE = 0x0010;
struct SharedDirInfo
struct SharedDirInfo : RsSerializable
{
static bool sameLists(const std::list<RsNodeGroupId>& l1,const std::list<RsNodeGroupId>& l2)
{
@ -118,10 +125,22 @@ struct SharedDirInfo
return it1 == l1.end() && it2 == l2.end() ;
}
std::string filename ;
std::string virtualname ;
FileStorageFlags shareflags ; // combnation of DIR_FLAGS_ANONYMOUS_DOWNLOAD | DIR_FLAGS_BROWSABLE | ...
std::list<RsNodeGroupId> parent_groups ;
std::string filename;
std::string virtualname;
/// combnation of DIR_FLAGS_ANONYMOUS_DOWNLOAD | DIR_FLAGS_BROWSABLE | ...
FileStorageFlags shareflags;
std::list<RsNodeGroupId> parent_groups;
/// @see RsSerializable::serial_process
virtual void serial_process(RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx)
{
RS_SERIAL_PROCESS(filename);
RS_SERIAL_PROCESS(virtualname);
RS_SERIAL_PROCESS(shareflags);
RS_SERIAL_PROCESS(parent_groups);
}
};
struct SharedDirStats
@ -177,38 +196,128 @@ public:
RsFiles() {}
virtual ~RsFiles() {}
/**
* Provides file data for the gui: media streaming or rpc clients.
* It may return unverified chunks. This allows streaming without having to wait for hashes or completion of the file.
* This function returns an unspecified amount of bytes. Either as much data as available or a sensible maximum. Expect a block size of around 1MiB.
* To get more data, call this function repeatedly with different offsets.
* Returns false in case
* - the files is not available on the local node
* - not downloading
* - the requested data was not downloaded yet
* - end of file was reached
* @param hash hash of a file. The file has to be available on this node or it has to be in downloading state.
* @param offset where the desired block starts
* @param requested_size size of pre-allocated data. Will be updated by the function.
* @param data pre-allocated memory chunk of size 'requested_size' by the client
*/
virtual bool getFileData(const RsFileHash& hash, uint64_t offset, uint32_t& requested_size,uint8_t *data)=0;
/**
* Provides file data for the gui, media streaming or rpc clients.
* It may return unverified chunks. This allows streaming without having to
* wait for hashes or completion of the file.
* This function returns an unspecified amount of bytes. Either as much data
* as available or a sensible maximum. Expect a block size of around 1MiB.
* To get more data, call this function repeatedly with different offsets.
*
* jsonapi{development}
* note the missing @ the wrapper for this is written manually not
* autogenerated @see JsonApiServer.
*
* @param[in] hash hash of the file. The file has to be available on this node
* or it has to be in downloading state.
* @param[in] offset where the desired block starts
* @param[inout] requested_size size of pre-allocated data. Will be updated
* by the function.
* @param data pre-allocated memory chunk of size 'requested_size' by the
* client
* @return Returns false in case
* - the files is not available on the local node
* - not downloading
* - the requested data was not downloaded yet
* - end of file was reached
*/
virtual bool getFileData( const RsFileHash& hash, uint64_t offset,
uint32_t& requested_size, uint8_t* data ) = 0;
/***
* Control of Downloads.
***/
/**
* @brief Check if we already have a file
* @jsonapi{development}
* @param[in] hash file identifier
* @param[out] info storage for the possibly found file information
* @return true if the file is already present, false otherwise
*/
virtual bool alreadyHaveFile(const RsFileHash& hash, FileInfo &info) = 0;
/**
* @brief Initiate downloading of a file
* @jsonapi{development}
* @param[in] fileName
* @param[in] hash
* @param[in] size
* @param[in] destPath in not empty specify a destination path
* @param[in] flags you usually want RS_FILE_REQ_ANONYMOUS_ROUTING
* @param[in] srcIds eventually specify known sources
* @return false if we already have the file, true otherwhise
*/
virtual bool FileRequest(
const std::string& fileName, const RsFileHash& hash, uint64_t size,
const std::string& destPath, TransferRequestFlags flags,
const std::list<RsPeerId>& srcIds ) = 0;
/**
* @brief Cancel file downloading
* @jsonapi{development}
* @param[in] hash
* @return false if the file is not in the download queue, true otherwhise
*/
virtual bool FileCancel(const RsFileHash& hash) = 0;
/**
* @brief Set destination directory for given file
* @jsonapi{development}
* @param[in] hash file identifier
* @param[in] newPath
* @return false if some error occurred, true otherwise
*/
virtual bool setDestinationDirectory(
const RsFileHash& hash, const std::string& newPath ) = 0;
/**
* @brief Set name for dowloaded file
* @jsonapi{development}
* @param[in] hash file identifier
* @param[in] newName
* @return false if some error occurred, true otherwise
*/
virtual bool setDestinationName(
const RsFileHash& hash, const std::string& newName ) = 0;
/**
* @brief Set chunk strategy for file, useful to set streaming mode to be
* able of see video or other media preview while it is still downloading
* @jsonapi{development}
* @param[in] hash file identifier
* @param[in] newStrategy
* @return false if some error occurred, true otherwise
*/
virtual bool setChunkStrategy(
const RsFileHash& hash,
FileChunksInfo::ChunkStrategy newStrategy ) = 0;
/**
* @brief Set default chunk strategy
* @jsonapi{development}
* @param[in] strategy
*/
virtual void setDefaultChunkStrategy(
FileChunksInfo::ChunkStrategy strategy ) = 0;
/**
* @brief Get default chunk strategy
* @jsonapi{development}
* @return current default chunck strategy
*/
virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() = 0;
/**
* @brief Get free disk space limit
* @jsonapi{development}
* @return current current minimum free space on disk in MB
*/
virtual uint32_t freeDiskSpaceLimit() const = 0;
/**
* @brief Set minimum free disk space limit
* @jsonapi{development}
* @param[in] minimumFreeMB minimum free space in MB
*/
virtual void setFreeDiskSpaceLimit(uint32_t minimumFreeMB) = 0;
virtual bool alreadyHaveFile(const RsFileHash& hash, FileInfo &info) = 0;
/// Returns false is we already have the file. Otherwise, initiates the dl and returns true.
virtual bool FileRequest(const std::string& fname, const RsFileHash& hash, uint64_t size, const std::string& dest, TransferRequestFlags flags, const std::list<RsPeerId>& srcIds) = 0;
virtual bool FileCancel(const RsFileHash& hash) = 0;
virtual bool setDestinationDirectory(const RsFileHash& hash,const std::string& new_path) = 0;
virtual bool setDestinationName(const RsFileHash& hash,const std::string& new_name) = 0;
virtual bool setChunkStrategy(const RsFileHash& hash,FileChunksInfo::ChunkStrategy) = 0;
virtual void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy) = 0;
virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() = 0;
virtual uint32_t freeDiskSpaceLimit() const =0;
virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) =0;
virtual bool FileControl(const RsFileHash& hash, uint32_t flags) = 0;
virtual bool FileClearCompleted() = 0;
virtual void setDefaultEncryptionPolicy(uint32_t policy)=0; // RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT/PERMISSIVE
@ -217,8 +326,24 @@ public:
virtual uint32_t getMaxUploadSlotsPerFriend()=0;
virtual void setFilePermDirectDL(uint32_t perm)=0;
virtual uint32_t filePermDirectDL()=0;
virtual TurtleRequestId turtleSearch(const std::string& string_to_match) =0;
virtual TurtleRequestId turtleSearch(const RsRegularExpression::LinearizedExpression& expr) =0;
/**
* @brief Request remote files search
* @jsonapi{development}
* @param[in] matchString string to look for in the search
* @param multiCallback function that will be called each time a search
* result is received
* @param[in] maxWait maximum wait time in seconds for search results
* @return false on error, true otherwise
*/
virtual bool turtleSearchRequest(
const std::string& matchString,
const std::function<void (const std::list<TurtleFileInfo>& results)>& multiCallback,
std::time_t maxWait = 300 ) = 0;
virtual TurtleRequestId turtleSearch(const std::string& string_to_match) = 0;
virtual TurtleRequestId turtleSearch(
const RsRegularExpression::LinearizedExpression& expr) = 0;
/***
* Control of Downloads Priority.
@ -229,21 +354,56 @@ public:
virtual bool changeDownloadSpeed(const RsFileHash& hash, int speed) = 0;
virtual bool getDownloadSpeed(const RsFileHash& hash, int & speed) = 0;
virtual bool clearDownload(const RsFileHash& hash) = 0;
// virtual void getDwlDetails(std::list<DwlDetails> & details) = 0;
/***
* Download / Upload Details.
***/
virtual void FileDownloads(std::list<RsFileHash> &hashs) = 0;
virtual bool FileUploads(std::list<RsFileHash> &hashs) = 0;
virtual bool FileDetails(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) = 0;
/**
* @brief Get incoming files list
* @jsonapi{development}
* @param[out] hashs storage for files identifiers list
*/
virtual void FileDownloads(std::list<RsFileHash>& hashs) = 0;
/**
* @brief Get outgoing files list
* @jsonapi{development}
* @param[out] hashs storage for files identifiers list
* @return false if some error occurred, true otherwise
*/
virtual bool FileUploads(std::list<RsFileHash>& hashs) = 0;
/**
* @brief Get file details
* @jsonapi{development}
* @param[in] hash file identifier
* @param[in] hintflags filtering hint (RS_FILE_HINTS_EXTRA|...|RS_FILE_HINTS_LOCAL)
* @param[out] info storage for file information
* @return true if file found, false otherwise
*/
virtual bool FileDetails(
const RsFileHash &hash, FileSearchFlags hintflags, FileInfo& info ) = 0;
virtual bool isEncryptedSource(const RsPeerId& virtual_peer_id) =0;
/// Gives chunk details about the downloaded file with given hash.
virtual bool FileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info) = 0 ;
/**
* @brief Get chunk details about the downloaded file with given hash.
* @jsonapi{development}
* @param[in] hash file identifier
* @param[out] info storage for file information
* @return true if file found, false otherwise
*/
virtual bool FileDownloadChunksDetails(
const RsFileHash& hash, FileChunksInfo& info) = 0;
/// details about the upload with given hash
virtual bool FileUploadChunksDetails(const RsFileHash& hash,const RsPeerId& peer_id,CompressedChunkMap& map) = 0 ;
/**
* @brief Get details about the upload with given hash
* @jsonapi{development}
* @param[in] hash file identifier
* @param[in] peer_id peer identifier
* @param[out] map storage for chunk info
* @return true if file found, false otherwise
*/
virtual bool FileUploadChunksDetails(
const RsFileHash& hash, const RsPeerId& peer_id,
CompressedChunkMap& map ) = 0;
/***
* Extra List Access
@ -289,16 +449,76 @@ public:
***/
virtual void requestDirUpdate(void *ref) =0 ; // triggers the update of the given reference. Used when browsing.
virtual bool setDownloadDirectory(std::string path) = 0;
virtual bool setPartialsDirectory(std::string path) = 0;
virtual std::string getDownloadDirectory() = 0;
virtual std::string getPartialsDirectory() = 0;
/**
* @brief Set default complete downloads directory
* @jsonapi{development}
* @param[in] path directory path
* @return false if something failed, true otherwhise
*/
virtual bool setDownloadDirectory(const std::string& path) = 0;
virtual bool getSharedDirectories(std::list<SharedDirInfo>& dirs) = 0;
virtual bool setSharedDirectories(const std::list<SharedDirInfo>& dirs) = 0;
virtual bool addSharedDirectory(const SharedDirInfo& dir) = 0;
virtual bool updateShareFlags(const SharedDirInfo& dir) = 0; // updates the flags. The directory should already exist !
virtual bool removeSharedDirectory(std::string dir) = 0;
/**
* @brief Set partial downloads directory
* @jsonapi{development}
* @param[in] path directory path
* @return false if something failed, true otherwhise
*/
virtual bool setPartialsDirectory(const std::string& path) = 0;
/**
* @brief Get default complete downloads directory
* @jsonapi{development}
* @return default completed downloads directory path
*/
virtual std::string getDownloadDirectory() = 0;
/**
* @brief Get partial downloads directory
* @jsonapi{development}
* @return partials downloads directory path
*/
virtual std::string getPartialsDirectory() = 0;
/**
* @brief Get list of current shared directories
* @jsonapi{development}
* @param[out] dirs storage for the list of share directories
* @return false if something failed, true otherwhise
*/
virtual bool getSharedDirectories(std::list<SharedDirInfo>& dirs) = 0;
/**
* @brief Set shared directories
* @jsonapi{development}
* @param[in] dirs list of shared directories with share options
* @return false if something failed, true otherwhise
*/
virtual bool setSharedDirectories(const std::list<SharedDirInfo>& dirs) = 0;
/**
* @brief Add shared directory
* @jsonapi{development}
* @param[in] dir directory to share with sharing options
* @return false if something failed, true otherwhise
*/
virtual bool addSharedDirectory(const SharedDirInfo& dir) = 0;
/**
* @brief Updates shared directory sharing flags.
* The directory should be already shared!
* @jsonapi{development}
* @param[in] dir Shared directory with updated sharing options
* @return false if something failed, true otherwhise
*/
virtual bool updateShareFlags(const SharedDirInfo& dir) = 0;
/**
* @brief Remove directory from shared list
* @jsonapi{development}
* @param[in] dir Path of the directory to remove from shared list
* @return false if something failed, true otherwhise
*/
virtual bool removeSharedDirectory(std::string dir) = 0;
virtual bool getIgnoreLists(std::list<std::string>& ignored_prefixes, std::list<std::string>& ignored_suffixes,uint32_t& flags) =0;
virtual void setIgnoreLists(const std::list<std::string>& ignored_prefixes, const std::list<std::string>& ignored_suffixes,uint32_t flags) =0;
@ -320,8 +540,4 @@ public:
virtual bool ignoreDuplicates() = 0;
virtual void setIgnoreDuplicates(bool ignore) = 0;
};
#endif

View file

@ -1,9 +1,11 @@
#pragma once
/*******************************************************************************
* libretroshare/src/retroshare: rsgxschannels.h *
* *
* libretroshare: retroshare core library *
* *
* Copyright 2012-2012 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,44 +21,56 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RETROSHARE_GXS_CHANNEL_GUI_INTERFACE_H
#define RETROSHARE_GXS_CHANNEL_GUI_INTERFACE_H
#include <inttypes.h>
#include <string>
#include <list>
#include <functional>
#include "retroshare/rstokenservice.h"
#include "retroshare/rsgxsifacehelper.h"
#include "retroshare/rsgxscommon.h"
#include "serialiser/rsserializable.h"
#include "retroshare/rsturtle.h"
/* The Main Interface Class - for information about your Peers */
class RsGxsChannels;
extern RsGxsChannels *rsGxsChannels;
/**
* Pointer to global instance of RsGxsChannels service implementation
* @jsonapi{development}
*/
extern RsGxsChannels* rsGxsChannels;
// These should be in rsgxscommon.h
class RsGxsChannelGroup
struct RsGxsChannelGroup : RsSerializable
{
public:
RsGroupMetaData mMeta;
std::string mDescription;
RsGxsImage mImage;
bool mAutoDownload;
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(mDescription);
RS_SERIAL_PROCESS(mImage);
RS_SERIAL_PROCESS(mAutoDownload);
}
};
class RsGxsChannelPost
std::ostream &operator<<(std::ostream& out, const RsGxsChannelGroup& group);
struct RsGxsChannelPost : RsSerializable
{
public:
RsGxsChannelPost() : mCount(0), mSize(0) {}
public:
RsMsgMetaData mMeta;
std::set<RsGxsMessageId> mOlderVersions ;
std::set<RsGxsMessageId> mOlderVersions;
std::string mMsg; // UTF8 encoded.
std::list<RsGxsFile> mFiles;
@ -64,26 +78,217 @@ public:
uint64_t mSize; // auto calced.
RsGxsImage mThumbnail;
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(mOlderVersions);
RS_SERIAL_PROCESS(mMsg);
RS_SERIAL_PROCESS(mFiles);
RS_SERIAL_PROCESS(mCount);
RS_SERIAL_PROCESS(mSize);
RS_SERIAL_PROCESS(mThumbnail);
}
};
std::ostream &operator<<(std::ostream& out, const RsGxsChannelPost& post);
std::ostream &operator<<(std::ostream &out, const RsGxsChannelGroup &group);
std::ostream &operator<<(std::ostream &out, const RsGxsChannelPost &post);
class RsGxsChannels: public RsGxsIfaceHelper, public RsGxsCommentService
{
public:
explicit RsGxsChannels(RsGxsIface *gxs)
:RsGxsIfaceHelper(gxs) {}
explicit RsGxsChannels(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
virtual ~RsGxsChannels() {}
/* Specific Service Data */
/**
* @brief Get channels summaries list. Blocking API.
* @jsonapi{development}
* @param[out] channels list where to store the channels
* @return false if something failed, true otherwhise
*/
virtual bool getChannelsSummaries(std::list<RsGroupMetaData>& channels) = 0;
/**
* @brief Get channels information (description, thumbnail...).
* Blocking API.
* @jsonapi{development}
* @param[in] chanIds ids of the channels of which to get the informations
* @param[out] channelsInfo storage for the channels informations
* @return false if something failed, true otherwhise
*/
virtual bool getChannelsInfo(
const std::list<RsGxsGroupId>& chanIds,
std::vector<RsGxsChannelGroup>& channelsInfo ) = 0;
/**
* @brief Get content of specified channels. Blocking API
* @jsonapi{development}
* @param[in] chanIds id of the channels of which the content is requested
* @param[out] posts storage for the posts
* @param[out] comments storage for the comments
* @return false if something failed, true otherwhise
*/
virtual bool getChannelsContent(
const std::list<RsGxsGroupId>& chanIds,
std::vector<RsGxsChannelPost>& posts,
std::vector<RsGxsComment>& comments ) = 0;
/* Specific Service Data
* TODO: change the orrible const uint32_t &token to uint32_t token
* TODO: create a new typedef for token so code is easier to read
*/
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) = 0;
//////////////////////////////////////////////////////////////////////////////
/**
* @brief toggle message read status
* @jsonapi{development}
* @param[out] token GXS token queue token
* @param[in] msgId
* @param[in] read
*/
virtual void setMessageReadStatus(
uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
/**
* @brief Enable or disable auto-download for given channel
* @jsonapi{development}
* @param[in] groupId channel id
* @param[in] enable true to enable, false to disable
* @return false if something failed, true otherwhise
*/
virtual bool setChannelAutoDownload(
const RsGxsGroupId &groupId, bool enable) = 0;
/**
* @brief Get auto-download option value for given channel
* @jsonapi{development}
* @param[in] groupId channel id
* @param[in] enabled storage for the auto-download option value
* @return false if something failed, true otherwhise
*/
virtual bool getChannelAutoDownload(
const RsGxsGroupId &groupId, bool& enabled) = 0;
/**
* @brief Set download directory for the given channel
* @jsonapi{development}
* @param[in] channelId id of the channel
* @param[in] directory path
* @return false on error, true otherwise
*/
virtual bool setChannelDownloadDirectory(
const RsGxsGroupId& channelId, const std::string& directory) = 0;
/**
* @brief Get download directory for the given channel
* @jsonapi{development}
* @param[in] channelId id of the channel
* @param[out] directory reference to string where to store the path
* @return false on error, true otherwise
*/
virtual bool getChannelDownloadDirectory( const RsGxsGroupId& channelId,
std::string& directory ) = 0;
/**
* @brief Share channel publishing key
* This can be used to authorize other peers to post on the channel
* @jsonapi{development}
* param[in] groupId Channel id
* param[in] peers peers to which share the key
* @return false on error, true otherwise
*/
virtual bool groupShareKeys(
const RsGxsGroupId& groupId, const std::set<RsPeerId>& peers ) = 0;
/**
* @brief Request subscription to a group.
* The action is performed asyncronously, so it could fail in a subsequent
* phase even after returning true.
* @jsonapi{development}
* @param[out] token Storage for RsTokenService token to track request
* status.
* @param[in] groupId Channel id
* @param[in] subscribe
* @return false on error, true otherwise
*/
virtual bool subscribeToGroup( uint32_t& token, const RsGxsGroupId &groupId,
bool subscribe ) = 0;
/**
* @brief Request channel creation.
* The action is performed asyncronously, so it could fail in a subsequent
* phase even after returning true.
* @jsonapi{development}
* @param[out] token Storage for RsTokenService token to track request
* status.
* @param[in] group Channel data (name, description...)
* @return false on error, true otherwise
*/
virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0;
/**
* @brief Request post creation.
* The action is performed asyncronously, so it could fail in a subsequent
* phase even after returning true.
* @jsonapi{development}
* @param[out] token Storage for RsTokenService token to track request
* status.
* @param[in] post
* @return false on error, true otherwise
*/
virtual bool createPost(uint32_t& token, RsGxsChannelPost& post) = 0;
/**
* @brief Request channel change.
* The action is performed asyncronously, so it could fail in a subsequent
* phase even after returning true.
* @jsonapi{development}
* @param[out] token Storage for RsTokenService token to track request
* status.
* @param[in] group Channel data (name, description...) with modifications
* @return false on error, true otherwise
*/
virtual bool updateGroup(uint32_t& token, RsGxsChannelGroup& group) = 0;
/**
* @brief Share extra file
* Can be used to share extra file attached to a channel post
* @jsonapi{development}
* @param[in] path file path
* @return false on error, true otherwise
*/
virtual bool ExtraFileHash(const std::string& path) = 0;
/**
* @brief Remove extra file from shared files
* @jsonapi{development}
* @param[in] hash hash of the file to remove
* @return false on error, true otherwise
*/
virtual bool ExtraFileRemove(const RsFileHash& hash) = 0;
/**
* @brief Request remote channels search
* @jsonapi{development}
* @param[in] matchString string to look for in the search
* @param multiCallback function that will be called each time a search
* result is received
* @param[in] maxWait maximum wait time in seconds for search results
* @return false on error, true otherwise
*/
virtual bool turtleSearchRequest(
const std::string& matchString,
const std::function<void (const RsGxsGroupSummary& result)>& multiCallback,
std::time_t maxWait = 300 ) = 0;
//////////////////////////////////////////////////////////////////////////////
/// Distant synchronisation methods ///
//////////////////////////////////////////////////////////////////////////////
///
@ -94,29 +299,4 @@ public:
virtual bool retrieveDistantGroup(const RsGxsGroupId& group_id,RsGxsChannelGroup& distant_group)=0;
//////////////////////////////////////////////////////////////////////////////
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
virtual bool setChannelAutoDownload(const RsGxsGroupId &groupId, bool enabled) = 0;
virtual bool getChannelAutoDownload(const RsGxsGroupId &groupid, bool& enabled) = 0;
virtual bool setChannelDownloadDirectory(const RsGxsGroupId &groupId, const std::string& directory)=0;
virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::string& directory)=0;
virtual bool groupShareKeys(const RsGxsGroupId &groupId, std::set<RsPeerId>& peers)=0;
// Overloaded subscribe fn.
virtual bool subscribeToGroup(uint32_t &token, const RsGxsGroupId &groupId, bool subscribe) = 0;
virtual bool createGroup(uint32_t &token, RsGxsChannelGroup &group) = 0;
virtual bool createPost(uint32_t &token, RsGxsChannelPost &post) = 0;
virtual bool updateGroup(uint32_t &token, RsGxsChannelGroup &group) = 0;
// File Interface
virtual bool ExtraFileHash(const std::string &path, std::string filename) = 0;
virtual bool ExtraFileRemove(const RsFileHash &hash) = 0;
};
#endif

View file

@ -122,8 +122,8 @@ class RsGxsCircles: public RsGxsIfaceHelper
{
public:
RsGxsCircles(RsGxsIface *gxs) :RsGxsIfaceHelper(gxs) { return; }
virtual ~RsGxsCircles() { return; }
RsGxsCircles(RsGxsIface& gxs) :RsGxsIfaceHelper(gxs) {}
virtual ~RsGxsCircles() {}
/* External Interface (Cached stuff) */
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) = 0;

View file

@ -31,37 +31,55 @@
#include <list>
#include "rsgxsifacetypes.h"
#include "serialiser/rsserializable.h"
class RsGxsFile
struct RsGxsFile : RsSerializable
{
public:
RsGxsFile();
std::string mName;
RsFileHash mHash;
uint64_t mSize;
//std::string mPath;
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mName);
RS_SERIAL_PROCESS(mHash);
RS_SERIAL_PROCESS(mSize);
}
};
class RsGxsImage
struct RsGxsImage : RsSerializable
{
public:
RsGxsImage();
RsGxsImage();
~RsGxsImage();
RsGxsImage(const RsGxsImage& a); // TEMP use copy constructor and duplicate memory.
RsGxsImage &operator=(const RsGxsImage &a); // Need this as well?
//NB: Must make sure that we always use methods - to be consistent about malloc/free for this data.
static uint8_t *allocate(uint32_t size);
static void release(void *data);
/// Use copy constructor and duplicate memory.
RsGxsImage(const RsGxsImage& a);
RsGxsImage &operator=(const RsGxsImage &a); // Need this as well?
/** NB: Must make sure that we always use methods - to be consistent about
* malloc/free for this data. */
static uint8_t *allocate(uint32_t size);
static void release(void *data);
void take(uint8_t *data, uint32_t size); // Copies Pointer.
void copy(uint8_t *data, uint32_t size); // Allocates and Copies.
void clear(); // Frees.
void shallowClear(); // Clears Pointer.
uint8_t *mData;
uint32_t mSize;
uint8_t* mData;
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RsTypeSerializer::TlvMemBlock_proxy b(mData, mSize);
RsTypeSerializer::serial_process(j, ctx, b, "mData");
}
};
@ -84,17 +102,23 @@ namespace GXS_SERV {
class RsGxsVote
struct RsGxsVote : RsSerializable
{
public:
RsGxsVote();
RsMsgMetaData mMeta;
uint32_t mVoteType;
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(mVoteType);
}
};
class RsGxsComment
struct RsGxsComment : RsSerializable
{
public:
RsGxsComment();
RsMsgMetaData mMeta;
std::string mComment;
@ -109,6 +133,19 @@ class RsGxsComment
// This is filled in if detailed Comment Data is called.
std::list<RsGxsVote> mVotes;
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(mComment);
RS_SERIAL_PROCESS(mUpVotes);
RS_SERIAL_PROCESS(mDownVotes);
RS_SERIAL_PROCESS(mScore);
RS_SERIAL_PROCESS(mOwnVote);
RS_SERIAL_PROCESS(mVotes);
}
const std::ostream &print(std::ostream &out, std::string indent = "", std::string varName = "") const {
out << indent << varName << " of RsGxsComment Values ###################" << std::endl;
mMeta.print(out, indent + " ", "mMeta");

View file

@ -59,8 +59,7 @@ class RsGxsForums: public RsGxsIfaceHelper
{
public:
explicit RsGxsForums(RsGxsIface *gxs)
:RsGxsIfaceHelper(gxs) {}
explicit RsGxsForums(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
virtual ~RsGxsForums() {}
/* Specific Service Data */

View file

@ -32,6 +32,7 @@
#include "gxs/rsgxsdata.h"
#include "retroshare/rsgxsifacetypes.h"
#include "util/rsdeprecate.h"
#include "serialiser/rsserializable.h"
/*!
* This structure is used to transport group summary information when a GXS
@ -76,9 +77,8 @@ struct RsGxsGroupSummary : RsSerializable
/*!
* Stores ids of changed gxs groups and messages. It is used to notify the GUI about changes.
*/
class RsGxsChanges
struct RsGxsChanges
{
public:
RsGxsChanges(): mService(0){}
RsTokenService *mService;
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > mMsgs;
@ -91,13 +91,9 @@ public:
/*!
* All implementations must offer thread safety
*/
class RsGxsIface
struct RsGxsIface
{
public:
virtual ~RsGxsIface(){};
public:
virtual ~RsGxsIface() {}
/*!
* Gxs services should call this for automatic handling of

View file

@ -7,6 +7,7 @@
* RetroShare GXS. Convenience interface implementation
*
* Copyright 2012 by Christopher Evi-Parker
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -26,29 +27,30 @@
*
*/
#include <chrono>
#include <thread>
#include "retroshare/rsgxsiface.h"
#include "retroshare/rsreputations.h"
#include "rsgxsflags.h"
#include "util/rsdeprecate.h"
/*!
* The simple idea of this class is to implement the simple interface functions
* of gen exchange.
* This class provides convenience implementations of:
* - Handle msg and group changes (client class must pass changes sent by RsGenExchange to it)
* - subscription to groups
* - retrieval of msgs and group ids and meta info
* This class only make method of internal members visible tu upper level to
* offer a more friendly API.
* This is just a workaround to awkward GXS API design, do not take it as an
* example for your coding.
* To properly fix the API design many changes with the implied chain reactions
* are necessary, so at this point this workaround seems acceptable.
*/
class RsGxsIfaceHelper
struct RsGxsIfaceHelper
{
public:
/*!
*
* @param gxs handle to RsGenExchange instance of service (Usually the service class itself)
*/
RsGxsIfaceHelper(RsGxsIface* gxs)
: mGxs(gxs)
{}
/*!
* @param gxs handle to RsGenExchange instance of service (Usually the
* service class itself)
*/
RsGxsIfaceHelper(RsGxsIface& gxs) :
mGxs(gxs), mTokenService(*gxs.getTokenService()) {}
~RsGxsIfaceHelper(){}
@ -59,15 +61,7 @@ public:
*/
void receiveChanges(std::vector<RsGxsNotify *> &changes)
{
mGxs->receiveChanges(changes);
}
/*!
* @return handle to token service for this GXS service
*/
RsTokenService* getTokenService()
{
return mGxs->getTokenService();
mGxs.receiveChanges(changes);
}
/* Generic Lists */
@ -81,7 +75,7 @@ public:
bool getGroupList(const uint32_t &token,
std::list<RsGxsGroupId> &groupIds)
{
return mGxs->getGroupList(token, groupIds);
return mGxs.getGroupList(token, groupIds);
}
/*!
@ -93,7 +87,7 @@ public:
bool getMsgList(const uint32_t &token,
GxsMsgIdResult& msgIds)
{
return mGxs->getMsgList(token, msgIds);
return mGxs.getMsgList(token, msgIds);
}
/*!
@ -104,7 +98,7 @@ public:
*/
bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds)
{
return mGxs->getMsgRelatedList(token, msgIds);
return mGxs.getMsgRelatedList(token, msgIds);
}
/*!
@ -115,7 +109,7 @@ public:
bool getGroupSummary(const uint32_t &token,
std::list<RsGroupMetaData> &groupInfo)
{
return mGxs->getGroupMeta(token, groupInfo);
return mGxs.getGroupMeta(token, groupInfo);
}
/*!
@ -126,7 +120,7 @@ public:
bool getMsgSummary(const uint32_t &token,
GxsMsgMetaMap &msgInfo)
{
return mGxs->getMsgMeta(token, msgInfo);
return mGxs.getMsgMeta(token, msgInfo);
}
/*!
@ -136,7 +130,7 @@ public:
*/
bool getMsgRelatedSummary(const uint32_t &token, GxsMsgRelatedMetaMap &msgInfo)
{
return mGxs->getMsgRelatedMeta(token, msgInfo);
return mGxs.getMsgRelatedMeta(token, msgInfo);
}
/*!
@ -147,7 +141,7 @@ public:
*/
bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe)
{
return mGxs->subscribeToGroup(token, grpId, subscribe);
return mGxs.subscribeToGroup(token, grpId, subscribe);
}
/*!
@ -159,7 +153,7 @@ public:
*/
bool acknowledgeMsg(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId)
{
return mGxs->acknowledgeTokenMsg(token, msgId);
return mGxs.acknowledgeTokenMsg(token, msgId);
}
/*!
@ -171,7 +165,7 @@ public:
*/
bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId)
{
return mGxs->acknowledgeTokenGrp(token, grpId);
return mGxs.acknowledgeTokenGrp(token, grpId);
}
/*!
@ -182,7 +176,7 @@ public:
*/
bool getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats)
{
return mGxs->getServiceStatistic(token, stats);
return mGxs.getServiceStatistic(token, stats);
}
/*!
@ -193,7 +187,7 @@ public:
*/
bool getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats)
{
return mGxs->getGroupStatistic(token, stats);
return mGxs.getGroupStatistic(token, stats);
}
/*!
@ -206,7 +200,7 @@ public:
*/
void setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff)
{
return mGxs->setGroupReputationCutOff(token, grpId, CutOff);
return mGxs.setGroupReputationCutOff(token, grpId, CutOff);
}
/*!
@ -214,36 +208,111 @@ public:
*/
uint32_t getDefaultStoragePeriod()
{
return mGxs->getDefaultStoragePeriod();
return mGxs.getDefaultStoragePeriod();
}
uint32_t getStoragePeriod(const RsGxsGroupId& grpId)
{
return mGxs->getStoragePeriod(grpId);
return mGxs.getStoragePeriod(grpId);
}
void setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs)
{
mGxs->setStoragePeriod(grpId,age_in_secs);
mGxs.setStoragePeriod(grpId,age_in_secs);
}
uint32_t getDefaultSyncPeriod()
{
return mGxs->getDefaultSyncPeriod();
return mGxs.getDefaultSyncPeriod();
}
uint32_t getSyncPeriod(const RsGxsGroupId& grpId)
{
return mGxs->getSyncPeriod(grpId);
return mGxs.getSyncPeriod(grpId);
}
void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs)
{
mGxs->setSyncPeriod(grpId,age_in_secs);
mGxs.setSyncPeriod(grpId,age_in_secs);
}
RsReputations::ReputationLevel minReputationForForwardingMessages(uint32_t group_sign_flags,uint32_t identity_flags)
{
return mGxs->minReputationForForwardingMessages(group_sign_flags,identity_flags);
return mGxs.minReputationForForwardingMessages(group_sign_flags,identity_flags);
}
private:
RsGxsIface* mGxs;
/// @see RsTokenService::requestGroupInfo
bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts,
const std::list<RsGxsGroupId> &groupIds )
{ return mTokenService.requestGroupInfo(token, 0, opts, groupIds); }
/// @see RsTokenService::requestGroupInfo
bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts)
{ return mTokenService.requestGroupInfo(token, 0, opts); }
/// @see RsTokenService::requestMsgInfo
bool requestMsgInfo( uint32_t& token,
const RsTokReqOptions& opts, const GxsMsgReq& msgIds )
{ return mTokenService.requestMsgInfo(token, 0, opts, msgIds); }
/// @see RsTokenService::requestMsgInfo
bool requestMsgInfo(
uint32_t& token, const RsTokReqOptions& opts,
const std::list<RsGxsGroupId>& grpIds )
{ return mTokenService.requestMsgInfo(token, 0, opts, grpIds); }
/// @see RsTokenService::requestMsgRelatedInfo
bool requestMsgRelatedInfo(
uint32_t& token, const RsTokReqOptions& opts,
const std::vector<RsGxsGrpMsgIdPair>& msgIds )
{ return mTokenService.requestMsgRelatedInfo(token, 0, opts, msgIds); }
/**
* @jsonapi{development}
* @param[in] token
*/
RsTokenService::GxsRequestStatus requestStatus(uint32_t token)
{ return mTokenService.requestStatus(token); }
/// @see RsTokenService::requestServiceStatistic
void requestServiceStatistic(uint32_t& token)
{ mTokenService.requestServiceStatistic(token); }
/// @see RsTokenService::requestGroupStatistic
void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId)
{ mTokenService.requestGroupStatistic(token, grpId); }
/// @see RsTokenService::cancelRequest
bool cancelRequest(uint32_t token)
{ return mTokenService.cancelRequest(token); }
/**
* @deprecated
* Token service methods are already exposed by this helper, so you should
* not need to get token service pointer directly anymore.
*/
RS_DEPRECATED RsTokenService* getTokenService() { return &mTokenService; }
protected:
/**
* Block caller while request is being processed.
* Useful for blocking API implementation.
* @param[in] token token associated to the request caller is waiting for
* @param[in] maxWait maximum waiting time in milliseconds
*/
RsTokenService::GxsRequestStatus waitToken(
uint32_t token,
std::chrono::milliseconds maxWait = std::chrono::milliseconds(500) )
{
auto timeout = std::chrono::steady_clock::now() + maxWait;
auto st = requestStatus(token);
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE)
&& std::chrono::steady_clock::now() < timeout )
{
std::this_thread::sleep_for(std::chrono::milliseconds(2));
st = requestStatus(token);
}
return st;
}
private:
RsGxsIface& mGxs;
RsTokenService& mTokenService;
};
#endif // RSGXSIFACEIMPL_H

View file

@ -119,7 +119,7 @@ struct RsGroupMetaData : RsSerializable
struct RsMsgMetaData
struct RsMsgMetaData : RsSerializable
{
RsMsgMetaData() : mPublishTs(0), mMsgFlags(0), mMsgStatus(0), mChildTs(0) {}
@ -150,6 +150,24 @@ struct RsMsgMetaData
time_t mChildTs;
std::string mServiceString; // Service Specific Free-Form extra storage.
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mGroupId);
RS_SERIAL_PROCESS(mMsgId);
RS_SERIAL_PROCESS(mThreadId);
RS_SERIAL_PROCESS(mParentId);
RS_SERIAL_PROCESS(mOrigMsgId);
RS_SERIAL_PROCESS(mAuthorId);
RS_SERIAL_PROCESS(mMsgName);
RS_SERIAL_PROCESS(mPublishTs);
RS_SERIAL_PROCESS(mMsgFlags);
RS_SERIAL_PROCESS(mMsgStatus);
RS_SERIAL_PROCESS(mChildTs);
RS_SERIAL_PROCESS(mServiceString);
}
const std::ostream &print(std::ostream &out, std::string indent = "", std::string varName = "") const {
out
<< indent << varName << " of RsMsgMetaData Values ###################" << std::endl

View file

@ -91,7 +91,7 @@ public:
std::vector<RsGxsTransOutgoingRecord> outgoing_records;
};
RsGxsTrans(RsGxsIface *gxs) : RsGxsIfaceHelper(gxs) {}
RsGxsTrans(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
virtual ~RsGxsTrans() {}

View file

@ -339,7 +339,7 @@ struct RsIdentityDetails : RsSerializable
struct RsIdentity : RsGxsIfaceHelper
{
explicit RsIdentity(RsGxsIface *gxs): RsGxsIfaceHelper(gxs) {}
explicit RsIdentity(RsGxsIface& gxs): RsGxsIfaceHelper(gxs) {}
virtual ~RsIdentity() {}
/********************************************************************************************/

View file

@ -43,80 +43,89 @@
#include <vector>
#include <retroshare/rstypes.h>
struct RsLoginHelper;
/**
* Pointer to global instance of RsLoginHelper
* @jsonapi{development}
*/
extern RsLoginHelper* rsLoginHelper;
/*!
* Initialisation Class (not publicly disclosed to RsIFace)
*/
class RsInit
{
public:
/* reorganised RsInit system */
public:
enum LoadCertificateStatus : uint8_t
{
OK, /// Everything go as expected, no error occurred
ERR_ALREADY_RUNNING, /// Another istance is running already
ERR_CANT_ACQUIRE_LOCK, /// Another istance is already running?
ERR_UNKOWN /// Unkown error, maybe password is wrong?
};
/*!
* PreLogin
* Call before init retroshare, initialises rsinitconfig's public attributes
*/
static void InitRsConfig() ;
/* reorganised RsInit system */
/*!
* Should be called to load up ssl cert and private key, and intialises gpg
* this must be called before accessing rsserver (e.g. ::startupretroshare)
* @param argc passed from executable
* @param argv commandline arguments passed to executable
* @param strictCheck set to true if you want rs to continue executing if invalid argument passed and vice versa
* @return RS_INIT_...
*/
static int InitRetroShare(int argc, char **argv, bool strictCheck=true);
/*!
* PreLogin
* Call before init retroshare, initialises rsinitconfig's public attributes
*/
static void InitRsConfig();
static bool isPortable();
static bool isWindowsXP();
static bool collectEntropy(uint32_t bytes) ;
/*!
* Should be called to load up ssl cert and private key, and intialises gpg
* this must be called before accessing rsserver (e.g. ::startupretroshare)
* @param argc passed from executable
* @param argv commandline arguments passed to executable
* @param strictCheck set to true if you want rs to continue executing if
* invalid argument passed and vice versa
* @return RS_INIT_...
*/
static int InitRetroShare(int argc, char **argv, bool strictCheck=true);
/*!
* Setup Hidden Location;
*/
static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob);
static bool isPortable();
static bool isWindowsXP();
static bool collectEntropy(uint32_t bytes) ;
static bool LoadPassword(const std::string& passwd) ;
/*
* Setup Hidden Location;
*/
static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob);
/*!
static bool LoadPassword(const std::string& passwd) ;
/*
* Final Certificate load. This can be called if:
* a) InitRetroshare() returns RS_INIT_HAVE_ACCOUNT -> autoLoad/password Set.
* b) or LoadPassword()
*
* This uses the preferredId from RsAccounts.
* This wrapper also locks the profile before finalising the login
*/
static LoadCertificateStatus LockAndLoadCertificates(
bool autoLoginNT, std::string& lockFilePath );
* Final Certificate load. This can be called if:
* a) InitRetroshare() returns RS_INIT_HAVE_ACCOUNT -> autoLoad/password Set.
* b) or LoadPassword()
*
* This uses the preferredId from RsAccounts.
* This wrapper also locks the profile before finalising the login
*/
static int LockAndLoadCertificates(bool autoLoginNT, std::string& lockFilePath);
// Post Login Options
static bool getStartMinimised();
/*!
* Post Login Options
*/
static int getSslPwdLen();
static bool getAutoLogin();
static void setAutoLogin(bool autoLogin);
static bool RsClearAutoLogin() ;
static bool getStartMinimised();
private:
/** @brief Lock profile directory
* param[in] accountDir account directory to lock
* param[out] lockFilePath path of the created lock-file
*/
static LoadCertificateStatus LockConfigDirectory(
const std::string& accountDir, std::string& lockFilePath);
static int getSslPwdLen();
static bool getAutoLogin();
static void setAutoLogin(bool autoLogin);
static bool RsClearAutoLogin() ;
private:
#if 0
/* Auto Login */
static bool RsStoreAutoLogin() ;
static bool RsTryAutoLogin() ;
#endif
// THESE CAN BE REMOVED FROM THE CLASS TOO.
/* Lock/unlock profile directory */
static int LockConfigDirectory(const std::string& accountDir, std::string& lockFilePath);
static void UnlockConfigDirectory();
/* The true LoadCertificates() method */
static int LoadCertificates(bool autoLoginNT) ;
/// @brief Unlock profile directory
static void UnlockConfigDirectory();
static int LoadCertificates(bool autoLoginNT);
};
@ -170,7 +179,11 @@ public:
static bool GetAccountDetails(const RsPeerId &id, RsPgpId &gpgId, std::string &gpgName, std::string &gpgEmail, std::string &location);
static bool createNewAccount(const RsPgpId& pgp_id, const std::string& org, const std::string& loc, const std::string& country, bool ishiddenloc,bool is_auto_tor, const std::string& passwd, RsPeerId &sslId, std::string &errString);
static bool createNewAccount(
const RsPgpId& pgp_id, const std::string& org,
const std::string& loc, const std::string& country,
bool ishiddenloc, bool is_auto_tor, const std::string& passwd,
RsPeerId &sslId, std::string &errString );
static void storeSelectedAccount() ;
@ -198,6 +211,63 @@ private:
};
/**
* This helper class have been implemented because there was not reasonable way
* to login in the API that could be exposed via JSON API
*/
struct RsLoginHelper
{
/**
* @brief Normal way to attempt login
* @jsonapi{development}
* @param[in] account Id of the account to which attempt login
* @param[in] password Password for the given account
* @return RsInit::OK if login attempt success, error code otherwhise
*/
RsInit::LoadCertificateStatus attemptLogin(
const RsPeerId& account, const std::string& password );
struct Location : RsSerializable
{
RsPeerId mLocationId;
RsPgpId mPgpId;
std::string mLocationName;
std::string mPpgName;
/// @see RsSerializable::serial_process
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx );
};
/**
* @brief Get locations and associated information
* @jsonapi{development}
* @param[out] locations storage for the retrived locations
*/
void getLocations(std::vector<RsLoginHelper::Location>& locations);
/**
* @brief Creates a new RetroShare location, and log in once is created
* @jsonapi{development}
* @param[inout] location provide input information to generate the location
* and storage to output the data of the generated location
* @param[in] password to protect and unlock the associated PGP key
* @param[in] makeHidden pass true to create an hidden location. UNTESTED!
* @param[in] makeAutoTor pass true to create an automatically configured
* Tor hidden location. UNTESTED!
* @param[out] errorMessage if some error occurred human readable error
* message
* @return true if success, false otherwise
*/
bool createLocation( RsLoginHelper::Location& location,
const std::string& password, bool makeHidden,
bool makeAutoTor, std::string& errorMessage );
/**
* @brief Close RetroShare session
* @jsonapi{development}
*/
void closeSession();
};
#endif

View file

@ -92,7 +92,7 @@ const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_PGP_SIGNED ( 0x00000010 ) ; // requi
typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
typedef std::string ChatLobbyNickName ;
typedef uint64_t MessageId ;
@ -279,7 +279,7 @@ struct DistantChatPeerInfo
// Identifier for an chat endpoint like
// neighbour peer, distant peer, chatlobby, broadcast
class ChatId
class ChatId : RsSerializable
{
public:
ChatId();
@ -310,17 +310,28 @@ public:
// this defines from which peer the status string came from
RsPeerId broadcast_status_peer_id;
private:
enum Type { TYPE_NOT_SET,
TYPE_PRIVATE, // private chat with directly connected friend, peer_id is valid
TYPE_PRIVATE_DISTANT, // private chat with distant peer, gxs_id is valid
TYPE_LOBBY, // chat lobby id, lobby_id is valid
TYPE_BROADCAST // message to/from all connected peers
};
enum Type : uint8_t
{ TYPE_NOT_SET,
TYPE_PRIVATE, // private chat with directly connected friend, peer_id is valid
TYPE_PRIVATE_DISTANT, // private chat with distant peer, gxs_id is valid
TYPE_LOBBY, // chat lobby id, lobby_id is valid
TYPE_BROADCAST // message to/from all connected peers
};
Type type;
RsPeerId peer_id;
DistantChatPeerId distant_chat_id;
ChatLobbyId lobby_id;
// RsSerializable interface
public:
void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) {
RS_SERIAL_PROCESS(broadcast_status_peer_id);
RS_SERIAL_PROCESS(type);
RS_SERIAL_PROCESS(peer_id);
RS_SERIAL_PROCESS(distant_chat_id);
RS_SERIAL_PROCESS(lobby_id);
}
};
class ChatMessage
@ -340,49 +351,90 @@ public:
//bool system_message;
};
class ChatLobbyInvite
class ChatLobbyInvite : RsSerializable
{
public:
ChatLobbyId lobby_id ;
RsPeerId peer_id ;
std::string lobby_name ;
std::string lobby_topic ;
ChatLobbyFlags lobby_flags ;
public:
ChatLobbyId lobby_id ;
RsPeerId peer_id ;
std::string lobby_name ;
std::string lobby_topic ;
ChatLobbyFlags lobby_flags ;
// RsSerializable interface
public:
void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) {
RS_SERIAL_PROCESS(lobby_id);
RS_SERIAL_PROCESS(peer_id);
RS_SERIAL_PROCESS(lobby_name);
RS_SERIAL_PROCESS(lobby_topic);
RS_SERIAL_PROCESS(lobby_flags);
}
};
class VisibleChatLobbyRecord
class VisibleChatLobbyRecord : RsSerializable
{
public:
VisibleChatLobbyRecord(): lobby_id(0), total_number_of_peers(0), last_report_time(0){}
ChatLobbyId lobby_id ; // unique id of the lobby
std::string lobby_name ; // name to use for this lobby
std::string lobby_topic ; // topic to use for this lobby
std::set<RsPeerId> participating_friends ; // list of direct friend who participate.
ChatLobbyId lobby_id ; // unique id of the lobby
std::string lobby_name ; // name to use for this lobby
std::string lobby_topic ; // topic to use for this lobby
std::set<RsPeerId> participating_friends ; // list of direct friend who participate.
uint32_t total_number_of_peers ; // total number of particpating peers. Might not be
time_t last_report_time ; // last time the lobby was reported.
ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE
uint32_t total_number_of_peers ; // total number of particpating peers. Might not be
time_t last_report_time ; // last time the lobby was reported.
ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE
// RsSerializable interface
public:
void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) {
RS_SERIAL_PROCESS(lobby_id);
RS_SERIAL_PROCESS(lobby_name);
RS_SERIAL_PROCESS(lobby_topic);
RS_SERIAL_PROCESS(participating_friends);
RS_SERIAL_PROCESS(total_number_of_peers);
RS_SERIAL_PROCESS(last_report_time);
RS_SERIAL_PROCESS(lobby_flags);
}
};
class ChatLobbyInfo
class ChatLobbyInfo : RsSerializable
{
public:
ChatLobbyId lobby_id ; // unique id of the lobby
std::string lobby_name ; // name to use for this lobby
std::string lobby_topic ; // topic to use for this lobby
std::set<RsPeerId> participating_friends ; // list of direct friend who participate. Used to broadcast sent messages.
RsGxsId gxs_id ; // ID to sign messages
public:
ChatLobbyId lobby_id ; // unique id of the lobby
std::string lobby_name ; // name to use for this lobby
std::string lobby_topic ; // topic to use for this lobby
std::set<RsPeerId> participating_friends ; // list of direct friend who participate. Used to broadcast sent messages.
RsGxsId gxs_id ; // ID to sign messages
ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE
std::map<RsGxsId,time_t> gxs_ids ; // list of non direct friend who participate. Used to display only.
time_t last_activity ; // last recorded activity. Useful for removing dead lobbies.
ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE
std::map<RsGxsId, time_t> gxs_ids ; // list of non direct friend who participate. Used to display only.
time_t last_activity ; // last recorded activity. Useful for removing dead lobbies.
// RsSerializable interface
public:
void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) {
RS_SERIAL_PROCESS(lobby_id);
RS_SERIAL_PROCESS(lobby_name);
RS_SERIAL_PROCESS(lobby_topic);
RS_SERIAL_PROCESS(participating_friends);
RS_SERIAL_PROCESS(gxs_id);
RS_SERIAL_PROCESS(lobby_flags);
RS_SERIAL_PROCESS(gxs_ids);
RS_SERIAL_PROCESS(last_activity);
}
};
std::ostream &operator<<(std::ostream &out, const Rs::Msgs::MessageInfo &info);
class RsMsgs;
/**
* @brief Pointer to retroshare's message service
* @jsonapi{development}
*/
extern RsMsgs *rsMsgs;
class RsMsgs
@ -438,15 +490,59 @@ virtual bool resetMessageStandardTagTypes(Rs::Msgs::MsgTagType& tags) = 0;
// sendChat for broadcast, private, lobby and private distant chat
// note: for lobby chat, you first have to subscribe to a lobby
// for private distant chat, it is reqired to have an active distant chat session
virtual bool sendChat(ChatId id, std::string msg) = 0;
virtual uint32_t getMaxMessageSecuritySize(int type) = 0;
virtual void sendStatusString(const ChatId& id,const std::string& status_string) = 0;
virtual void clearChatLobby(const ChatId& id) = 0;
/**
* @brief sendChat send a chat message to a given id
* @jsonapi{development}
* @param[in] id id to send the message
* @param[in] msg message to send
* @return true on success
*/
virtual bool sendChat(ChatId id, std::string msg) = 0;
virtual void setCustomStateString(const std::string& status_string) = 0 ;
virtual std::string getCustomStateString() = 0 ;
virtual std::string getCustomStateString(const RsPeerId& peer_id) = 0 ;
/**
* @brief getMaxMessageSecuritySize get the maximum size of a chta message
* @jsonapi{development}
* @param[in] type chat type
* @return maximum size or zero for infinite
*/
virtual uint32_t getMaxMessageSecuritySize(int type) = 0;
/**
* @brief sendStatusString send a status string
* @jsonapi{development}
* @param[in] id chat id to send the status string to
* @param[in] status_string status string
*/
virtual void sendStatusString(const ChatId &id, const std::string &status_string) = 0;
/**
* @brief clearChatLobby clear a chat lobby
* @jsonapi{development}
* @param[in] id chat lobby id to clear
*/
virtual void clearChatLobby(const ChatId &id) = 0;
/**
* @brief setCustomStateString set your custom status message
* @jsonapi{development}
* @param[in] status_string status message
*/
virtual void setCustomStateString(const std::string &status_string) = 0;
/**
* @brief getCustomStateString get your custom status message
* @return status message
*/
virtual std::string getCustomStateString() = 0;
/**
* @brief getCustomStateString get the custom status message from a peer
* @jsonapi{development}
* @param[in] peer_id peer id to the peer you want to get the status message from
* @return status message
*/
virtual std::string getCustomStateString(const RsPeerId &peer_id) = 0;
// get avatar data for peer pid
virtual void getAvatarData(const RsPeerId& pid,unsigned char *& data,int& size) = 0 ;
@ -454,29 +550,139 @@ virtual void getAvatarData(const RsPeerId& pid,unsigned char *& data,int& size)
virtual void setOwnAvatarData(const unsigned char *data,int size) = 0 ;
virtual void getOwnAvatarData(unsigned char *& data,int& size) = 0 ;
/****************************************/
/* Chat lobbies */
/****************************************/
/****************************************/
/* Chat lobbies */
/****************************************/
/**
* @brief joinVisibleChatLobby join a lobby that is visible
* @jsonapi{development}
* @param[in] lobby_id lobby to join to
* @param[in] own_id chat id to use
* @return true on success
*/
virtual bool joinVisibleChatLobby(const ChatLobbyId &lobby_id, const RsGxsId &own_id) = 0 ;
virtual bool joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& own_id) = 0 ;
/// get ids of subscribed lobbies
virtual void getChatLobbyList(std::list<ChatLobbyId>& cl_list) = 0;
/// get lobby info of a subscribed chat lobby. Returns true if lobby id is valid.
virtual bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& info) = 0 ;
/// get info about all lobbies, subscribed and unsubscribed
virtual void getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& public_lobbies) = 0 ;
virtual void invitePeerToLobby(const ChatLobbyId& lobby_id,const RsPeerId& peer_id) = 0;
virtual bool acceptLobbyInvite(const ChatLobbyId& id,const RsGxsId& identity) = 0 ;
virtual void denyLobbyInvite(const ChatLobbyId& id) = 0 ;
virtual void getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) = 0;
virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) = 0;
virtual bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& nick) = 0;
virtual bool getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick) = 0 ;
virtual bool setDefaultIdentityForChatLobby(const RsGxsId& nick) = 0;
virtual void getDefaultIdentityForChatLobby(RsGxsId& id) = 0 ;
virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) = 0 ;
virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id) = 0 ;
virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::set<RsPeerId>& invited_friends,ChatLobbyFlags lobby_privacy_type) = 0 ;
/**
* @brief getChatLobbyList get ids of subscribed lobbies
* @jsonapi{development}
* @param[out] cl_list lobby list
*/
virtual void getChatLobbyList(std::list<ChatLobbyId> &cl_list) = 0;
/**
* @brief getChatLobbyInfo get lobby info of a subscribed chat lobby. Returns true if lobby id is valid.
* @jsonapi{development}
* @param[in] id id to get infos from
* @param[out] info lobby infos
* @return true on success
*/
virtual bool getChatLobbyInfo(const ChatLobbyId &id, ChatLobbyInfo &info) = 0 ;
/**
* @brief getListOfNearbyChatLobbies get info about all lobbies, subscribed and unsubscribed
* @jsonapi{development}
* @param[out] public_lobbies list of all visible lobbies
*/
virtual void getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord> &public_lobbies) = 0 ;
/**
* @brief invitePeerToLobby invite a peer to join a lobby
* @jsonapi{development}
* @param[in] lobby_id lobby it to invite into
* @param[in] peer_id peer to invite
*/
virtual void invitePeerToLobby(const ChatLobbyId &lobby_id, const RsPeerId &peer_id) = 0;
/**
* @brief acceptLobbyInvite accept a chat invite
* @jsonapi{development}
* @param[in] id chat lobby id you were invited into and you want to join
* @param[in] identity chat identity to use
* @return true on success
*/
virtual bool acceptLobbyInvite(const ChatLobbyId &id, const RsGxsId &identity) = 0 ;
/**
* @brief denyLobbyInvite deny a chat lobby invite
* @jsonapi{development}
* @param[in] id chat lobby id you were invited into
*/
virtual void denyLobbyInvite(const ChatLobbyId &id) = 0 ;
/**
* @brief getPendingChatLobbyInvites get a list of all pending chat lobby invites
* @jsonapi{development}
* @param[out] invites list of all pending chat lobby invites
*/
virtual void getPendingChatLobbyInvites(std::list<ChatLobbyInvite> &invites) = 0;
/**
* @brief unsubscribeChatLobby leave a chat lobby
* @jsonapi{development}
* @param[in] lobby_id lobby to leave
*/
virtual void unsubscribeChatLobby(const ChatLobbyId &lobby_id) = 0;
/**
* @brief setIdentityForChatLobby set the chat identit
* @jsonapi{development}
* @param[in] lobby_id lobby to change the chat idnetity for
* @param[in] nick new chat identity
* @return true on success
*/
virtual bool setIdentityForChatLobby(const ChatLobbyId &lobby_id, const RsGxsId &nick) = 0;
/**
* @brief getIdentityForChatLobby
* @jsonapi{development}
* @param[in] lobby_id lobby to get the chat id from
* @param[out] nick chat identity
* @return true on success
*/
virtual bool getIdentityForChatLobby(const ChatLobbyId &lobby_id, RsGxsId &nick) = 0 ;
/**
* @brief setDefaultIdentityForChatLobby set the default identity used for chat lobbies
* @jsonapi{development}
* @param[in] nick chat identitiy to use
* @return true on success
*/
virtual bool setDefaultIdentityForChatLobby(const RsGxsId &nick) = 0;
/**
* @brief getDefaultIdentityForChatLobby get the default identity used for chat lobbies
* @jsonapi{development}
* @param[out] id chat identitiy to use
*/
virtual void getDefaultIdentityForChatLobby(RsGxsId &id) = 0 ;
/**
* @brief setLobbyAutoSubscribe enable or disable auto subscribe for a chat lobby
* @jsonapi{development}
* @param[in] lobby_id lobby to auto (un)subscribe
* @param[in] autoSubscribe set value for auto subscribe
*/
virtual void setLobbyAutoSubscribe(const ChatLobbyId &lobby_id, const bool autoSubscribe) = 0 ;
/**
* @brief getLobbyAutoSubscribe get current value of auto subscribe
* @jsonapi{development}
* @param[in] lobby_id lobby to get value from
* @return wether lobby has auto subscribe enabled or disabled
*/
virtual bool getLobbyAutoSubscribe(const ChatLobbyId &lobby_id) = 0 ;
/**
* @brief createChatLobby create a new chat lobby
* @jsonapi{development}
* @param[in] lobby_name lobby name
* @param[in] lobby_identity chat id to use for new lobby
* @param[in] lobby_topic lobby toppic
* @param[in] invited_friends list of friends to invite
* @param[in] lobby_privacy_type flag for new chat lobby
* @return chat id of new lobby
*/
virtual ChatLobbyId createChatLobby(const std::string &lobby_name, const RsGxsId &lobby_identity, const std::string &lobby_topic, const std::set<RsPeerId> &invited_friends, ChatLobbyFlags lobby_privacy_type) = 0 ;
/****************************************/
/* Distant chat */

View file

@ -181,7 +181,7 @@ class RsFeedItem
// This mechanism can be used in plugins, new services, etc.
//
class NotifyClient ;
class NotifyClient;
class RsNotify
{
@ -208,42 +208,41 @@ class RsNotify
class NotifyClient
{
public:
NotifyClient() {}
virtual ~NotifyClient() {}
public:
NotifyClient() {}
virtual ~NotifyClient() {}
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 notifyChatMessage (const ChatMessage& /* msg */) {}
virtual void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) {}
virtual void notifyChatCleared (const ChatId& /* chat_id */) {}
virtual void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,const RsGxsId& /* nickname */,const std::string& /* any string */) {}
virtual void notifyChatLobbyTimeShift (int /* time_shift*/) {}
virtual void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) {}
virtual void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) {}
virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list<TurtleFileInfo>& /* files */) {}
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 notifyChatMessage (const ChatMessage& /* msg */) {}
virtual void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) {}
virtual void notifyChatCleared (const ChatId& /* chat_id */) {}
virtual void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,const RsGxsId& /* nickname */,const std::string& /* any string */) {}
virtual void notifyChatLobbyTimeShift (int /* time_shift*/) {}
virtual void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) {}
virtual void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) {}
virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list<TurtleFileInfo>& /* files */) {}
#warning MISSING CODE HERE
// virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list<TurtleGxsInfo >& /* groups */) {}
virtual void notifyPeerHasNewAvatar (std::string /* peer_id */) {}
virtual void notifyOwnAvatarChanged () {}
virtual void notifyOwnStatusMessageChanged () {}
virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {}
virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {}
virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {}
virtual void notifyConnectionWithoutCert () {}
// virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list<TurtleGxsInfo >& /* groups */) {}
virtual void notifyPeerHasNewAvatar (std::string /* peer_id */) {}
virtual void notifyOwnAvatarChanged () {}
virtual void notifyOwnStatusMessageChanged () {}
virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {}
virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {}
virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {}
virtual void notifyConnectionWithoutCert () {}
/* one or more peers has changed the states */
virtual void notifyPeerStatusChangedSummary () {}
virtual void notifyDiscInfoChanged () {}
/* one or more peers has changed the states */
virtual void notifyPeerStatusChangedSummary () {}
virtual void notifyDiscInfoChanged () {}
virtual bool askForDeferredSelfSignature (const void * /* data */, const uint32_t /* len */, unsigned char * /* sign */, unsigned int * /* signlen */,int& signature_result , std::string /*reason = ""*/) { signature_result = false ;return true; }
virtual void notifyDownloadComplete (const std::string& /* fileHash */) {}
virtual void notifyDownloadCompleteCount (uint32_t /* count */) {}
virtual void notifyHistoryChanged (uint32_t /* msgId */, int /* type */) {}
virtual bool askForPassword (const std::string& /* title */, const std::string& /* key_details */, bool /* prev_is_bad */, std::string& /* password */,bool& /* cancelled */ ) { return false ;}
virtual bool askForPluginConfirmation (const std::string& /* plugin_filename */, const std::string& /* plugin_file_hash */,bool /* first_time */) { return false ;}
virtual bool askForDeferredSelfSignature (const void * /* data */, const uint32_t /* len */, unsigned char * /* sign */, unsigned int * /* signlen */,int& signature_result , std::string /*reason = ""*/) { signature_result = false ;return true; }
virtual void notifyDownloadComplete (const std::string& /* fileHash */) {}
virtual void notifyDownloadCompleteCount (uint32_t /* count */) {}
virtual void notifyHistoryChanged (uint32_t /* msgId */, int /* type */) {}
virtual bool askForPassword (const std::string& /* title */, const std::string& /* key_details */, bool /* prev_is_bad */, std::string& /* password */,bool& /* cancelled */ ) { return false ;}
virtual bool askForPluginConfirmation (const std::string& /* plugin_filename */, const std::string& /* plugin_file_hash */,bool /* first_time */) { return false ;}
};
#endif

View file

@ -293,16 +293,25 @@ public:
std::string cipher_version;
};
class RsGroupInfo
class RsGroupInfo : RsSerializable
{
public:
RsGroupInfo();
RsGroupInfo();
RsNodeGroupId id;
std::string name;
uint32_t flag;
RsNodeGroupId id;
std::string name;
uint32_t flag;
std::set<RsPgpId> peerIds;
std::set<RsPgpId> peerIds;
// RsSerializable interface
public:
void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) {
RS_SERIAL_PROCESS(id);
RS_SERIAL_PROCESS(name);
RS_SERIAL_PROCESS(flag);
RS_SERIAL_PROCESS(peerIds);
}
};
std::ostream &operator<<(std::ostream &out, const RsPeerDetails &detail);

View file

@ -74,7 +74,7 @@ class RsPosted : public RsGxsIfaceHelper, public RsGxsCommentService
//static const uint32_t FLAG_MSGTYPE_POST;
//static const uint32_t FLAG_MSGTYPE_MASK;
explicit RsPosted(RsGxsIface* gxs) : RsGxsIfaceHelper(gxs) {}
explicit RsPosted(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
virtual ~RsPosted() {}
/* Specific Service Data */

View file

@ -119,19 +119,19 @@ class RsTokenService
public:
// TODO CLEANUP: This should be an enum
static const uint8_t GXS_REQUEST_V2_STATUS_FAILED;
static const uint8_t GXS_REQUEST_V2_STATUS_PENDING;
static const uint8_t GXS_REQUEST_V2_STATUS_PARTIAL;
static const uint8_t GXS_REQUEST_V2_STATUS_FINISHED_INCOMPLETE;
static const uint8_t GXS_REQUEST_V2_STATUS_COMPLETE;
static const uint8_t GXS_REQUEST_V2_STATUS_DONE; // ONCE ALL DATA RETRIEVED.
static const uint8_t GXS_REQUEST_V2_STATUS_CANCELLED;
enum GxsRequestStatus : uint8_t
{
FAILED,
PENDING,
PARTIAL,
COMPLETE,
DONE, /// Once all data has been retrived
CANCELLED
};
public:
RsTokenService() { return; }
virtual ~RsTokenService() { return; }
RsTokenService() {}
virtual ~RsTokenService() {}
/* Data Requests */
@ -195,7 +195,7 @@ public:
* @param token value of token to check status for
* @return the current status of request
*/
virtual uint32_t requestStatus(const uint32_t token) = 0;
virtual GxsRequestStatus requestStatus(const uint32_t token) = 0;
/*!
* This request statistics on amount of data held
@ -216,19 +216,14 @@ public:
*/
virtual void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId) = 0;
/* Cancel Request */
/*!
* If this function returns false, it may be that the request has completed
* already. Useful for very expensive request. This is a blocking operation
* @param token the token of the request to cancel
* @return false if unusuccessful in cancelling request, true if successful
*/
virtual bool cancelRequest(const uint32_t &token) = 0;
/*!
* @brief Cancel Request
* If this function returns false, it may be that the request has completed
* already. Useful for very expensive request.
* @param token the token of the request to cancel
* @return false if unusuccessful in cancelling request, true if successful
*/
virtual bool cancelRequest(const uint32_t &token) = 0;
};
#endif // RSTOKENSERVICE_H

View file

@ -29,24 +29,42 @@
#include "serialiser/rstlvbinary.h"
#include "retroshare/rstypes.h"
#include "retroshare/rsgxsifacetypes.h"
#include "serialiser/rsserializable.h"
namespace RsRegularExpression { class LinearizedExpression ; }
class RsTurtleClientService ;
class RsTurtle;
extern RsTurtle *rsTurtle ;
/**
* Pointer to global instance of RsTurtle service implementation
*/
extern RsTurtle* rsTurtle;
typedef uint32_t TurtleRequestId ;
typedef RsPeerId TurtleVirtualPeerId;
// This is the structure used to send back results of the turtle search
// to the notifyBase class, or send info to the GUI.
struct TurtleFileInfo
/**
* This is the structure used to send back results of the turtle search,
* to other peers, to the notifyBase class, to the search caller or to the GUI.
*/
struct TurtleFileInfo : RsSerializable
{
RsFileHash hash ;
std::string name ;
uint64_t size ;
uint64_t size; /// File size
RsFileHash hash; /// File hash
std::string name; /// File name
/// @see RsSerializable::serial_process
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(size);
RS_SERIAL_PROCESS(hash);
// Use String TLV serial process for retrocompatibility
RsTypeSerializer::serial_process(
j, ctx, TLV_TYPE_STR_NAME, name, "name" );
}
};
struct TurtleTunnelRequestDisplayInfo
@ -90,7 +108,7 @@ class TurtleTrafficStatisticsInfo
//
class RsTurtle
{
public:
public:
RsTurtle() {}
virtual ~RsTurtle() {}
@ -106,7 +124,9 @@ class RsTurtle
// the request id, which will be further used by the gui to store results
// as they come back.
//
virtual TurtleRequestId turtleSearch(unsigned char *search_bin_data,uint32_t search_bin_data_len,RsTurtleClientService *client_service) =0;
virtual TurtleRequestId turtleSearch(
unsigned char *search_bin_data, uint32_t search_bin_data_len,
RsTurtleClientService* client_service ) = 0;
// Initiates tunnel handling for the given file hash. tunnels. Launches
// an exception if an error occurs during the initialization process. The

View file

@ -65,15 +65,25 @@ const uint32_t RS_CONFIG_DIRECTORY = 0x0002 ;
const uint32_t RS_PGP_DIRECTORY = 0x0003 ;
const uint32_t RS_DIRECTORY_COUNT = 0x0004 ;
class TransferInfo
struct TransferInfo : RsSerializable
{
public:
/**** Need Some of these Fields ****/
RsPeerId peerId;
std::string name; /* if has alternative name? */
double tfRate; /* kbytes */
int status; /* FT_STATE_... */
uint64_t transfered ; // used when no chunkmap data is available
/**** Need Some of these Fields ****/
RsPeerId peerId;
std::string name; /* if has alternative name? */
double tfRate; /* kbytes */
int status; /* FT_STATE_... */
uint64_t transfered ; // used when no chunkmap data is available
/// @see RsSerializable
void serial_process(RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx)
{
RS_SERIAL_PROCESS(peerId);
RS_SERIAL_PROCESS(name);
RS_SERIAL_PROCESS(tfRate);
RS_SERIAL_PROCESS(status);
RS_SERIAL_PROCESS(transfered);
}
};
enum QueueMove { QUEUE_TOP = 0x00,
@ -82,9 +92,11 @@ enum QueueMove { QUEUE_TOP = 0x00,
QUEUE_BOTTOM = 0x03
};
enum DwlSpeed { SPEED_LOW = 0x00,
SPEED_NORMAL = 0x01,
SPEED_HIGH = 0x02
enum DwlSpeed : uint8_t
{
SPEED_LOW = 0x00,
SPEED_NORMAL = 0x01,
SPEED_HIGH = 0x02
};
@ -171,54 +183,76 @@ const FileStorageFlags DIR_FLAGS_PERMISSIONS_MASK ( DIR_FLAGS_ANONYMOUS_DOW
const FileStorageFlags DIR_FLAGS_LOCAL ( 0x1000 );
const FileStorageFlags DIR_FLAGS_REMOTE ( 0x2000 );
class FileInfo
struct FileInfo : RsSerializable
{
/* old BaseInfo Entries */
public:
FileInfo():
mId(0), searchId(0), size(0), avail(0), rank(0), age(0),
queue_position(0), transfered(0), tfRate(0), downloadStatus(0),
priority(SPEED_NORMAL), lastTS(0) {}
FileInfo() : mId(0), searchId(0), size(0), avail(0), rank(0), age(0), queue_position(0),
transfered(0), tfRate(0), downloadStatus(0), priority(SPEED_NORMAL), lastTS(0){}
// RsCertId id; /* key for matching everything */
/// Combination of the four RS_DIR_FLAGS_*. Updated when the file is a local stored file.
FileStorageFlags storage_permission_flags;
FileStorageFlags storage_permission_flags; // Combination of the four RS_DIR_FLAGS_*. Updated when the file is a local stored file.
TransferRequestFlags transfer_info_flags ; // various flags from RS_FILE_HINTS_*
/// various flags from RS_FILE_HINTS_*
TransferRequestFlags transfer_info_flags;
/* 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
* (GUI) Model Id -> unique number
*/
mutable unsigned int mId;
/* Old FileInfo Entries */
public:
static const int kRsFiStatusNone = 0;
static const int kRsFiStatusStall = 1;
static const int kRsFiStatusProgress = 2;
static const int kRsFiStatusDone = 2;
/// 0 if none
int searchId;
/* FileInfo(); */
std::string path;
std::string fname;
RsFileHash hash;
std::string ext;
int searchId; /* 0 if none */
std::string path;
std::string fname;
RsFileHash hash;
std::string ext;
uint64_t size;
uint64_t avail; /// how much we have
uint64_t size;
uint64_t avail; /* how much we have */
double rank;
int age;
uint32_t queue_position;
double rank;
int age;
uint32_t queue_position ;
/* Transfer Stuff */
uint64_t transfered;
double tfRate; /// in kbytes
uint32_t downloadStatus; /// FT_STATE_DOWNLOADING & co. See rstypes.h
std::vector<TransferInfo> peers;
/* Transfer Stuff */
uint64_t transfered;
double tfRate; /* in kbytes */
uint32_t downloadStatus; // FT_STATE_DOWNLOADING & co. See rstypes.h
std::vector<TransferInfo> peers;
DwlSpeed priority;
time_t lastTS;
DwlSpeed priority ;
time_t lastTS;
std::list<RsNodeGroupId> parent_groups ;
std::list<RsNodeGroupId> parent_groups;
/// @see RsSerializable
void serial_process(RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx)
{
RS_SERIAL_PROCESS(storage_permission_flags);
RS_SERIAL_PROCESS(transfer_info_flags);
RS_SERIAL_PROCESS(mId);
RS_SERIAL_PROCESS(searchId);
RS_SERIAL_PROCESS(path);
RS_SERIAL_PROCESS(fname);
RS_SERIAL_PROCESS(hash);
RS_SERIAL_PROCESS(ext);
RS_SERIAL_PROCESS(size);
RS_SERIAL_PROCESS(avail);
RS_SERIAL_PROCESS(rank);
RS_SERIAL_PROCESS(age);
RS_SERIAL_PROCESS(queue_position);
RS_SERIAL_PROCESS(transfered);
RS_SERIAL_PROCESS(tfRate);
RS_SERIAL_PROCESS(downloadStatus);
RS_SERIAL_PROCESS(peers);
RS_SERIAL_PROCESS(priority);
RS_SERIAL_PROCESS(lastTS);
RS_SERIAL_PROCESS(parent_groups);
}
};
std::ostream &operator<<(std::ostream &out, const FileInfo& info);
@ -268,36 +302,58 @@ class FileDetail
class CompressedChunkMap ;
class FileChunksInfo
struct FileChunksInfo : RsSerializable
{
public:
enum ChunkState { CHUNK_CHECKING=3, CHUNK_DONE=2, CHUNK_ACTIVE=1, CHUNK_OUTSTANDING=0 } ;
enum ChunkStrategy { CHUNK_STRATEGY_STREAMING, CHUNK_STRATEGY_RANDOM, CHUNK_STRATEGY_PROGRESSIVE } ;
enum ChunkState : uint8_t
{
CHUNK_OUTSTANDING = 0,
CHUNK_ACTIVE = 1,
CHUNK_DONE = 2,
CHUNK_CHECKING = 3
};
struct SliceInfo
{
uint32_t start ;
uint32_t size ;
RsPeerId peer_id ;
};
enum ChunkStrategy : uint8_t
{
CHUNK_STRATEGY_STREAMING,
CHUNK_STRATEGY_RANDOM,
CHUNK_STRATEGY_PROGRESSIVE
};
uint64_t file_size ; // real size of the file
uint32_t chunk_size ; // size of chunks
uint32_t strategy ;
struct SliceInfo
{
uint32_t start;
uint32_t size;
RsPeerId peer_id;
};
// dl state of chunks. Only the last chunk may have size < chunk_size
std::vector<ChunkState> chunks ;
uint64_t file_size; /// real size of the file
uint32_t chunk_size; /// size of chunks
ChunkStrategy strategy;
// For each source peer, gives the compressed bit map of have/don't have sate
std::map<RsPeerId, CompressedChunkMap> compressed_peer_availability_maps ;
/// dl state of chunks. Only the last chunk may have size < chunk_size
std::vector<ChunkState> chunks;
// For each chunk (by chunk number), gives the completion of the chunk.
//
std::vector<std::pair<uint32_t,uint32_t> > active_chunks ;
/// For each source peer, gives the compressed bit map of have/don't have sate
std::map<RsPeerId, CompressedChunkMap> compressed_peer_availability_maps;
// The list of pending requests, chunk per chunk (by chunk id)
//
std::map<uint32_t, std::vector<SliceInfo> > pending_slices ;
/// For each chunk (by chunk number), gives the completion of the chunk.
std::vector<std::pair<uint32_t,uint32_t> > active_chunks;
/// The list of pending requests, chunk per chunk (by chunk id)
std::map<uint32_t, std::vector<SliceInfo> > pending_slices;
/// @see RsSerializable
void serial_process(RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx)
{
RS_SERIAL_PROCESS(file_size);
RS_SERIAL_PROCESS(chunk_size);
RS_SERIAL_PROCESS(strategy);
RS_SERIAL_PROCESS(chunks);
RS_SERIAL_PROCESS(compressed_peer_availability_maps);
RS_SERIAL_PROCESS(active_chunks);
//RS_SERIAL_PROCESS(pending_slices);
}
};
class CompressedChunkMap : public RsSerializable

View file

@ -111,10 +111,10 @@ std::ostream &operator<<(std::ostream &out, const RsWikiComment &comment);
class RsWiki: public RsGxsIfaceHelper
{
public:
public:
RsWiki(RsGxsIface *gxs): RsGxsIfaceHelper(gxs) { return; }
virtual ~RsWiki() { return; }
RsWiki(RsGxsIface& gxs): RsGxsIfaceHelper(gxs) {}
virtual ~RsWiki() {}
/* Specific Service Data */
virtual bool getCollections(const uint32_t &token, std::vector<RsWikiCollection> &collections) = 0;

View file

@ -104,7 +104,7 @@ class RsWire: public RsGxsIfaceHelper
{
public:
explicit RsWire(RsGxsIface *gxs): RsGxsIfaceHelper(gxs) {}
explicit RsWire(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
virtual ~RsWire() {}
/* Specific Service Data */

View file

@ -77,7 +77,7 @@ struct RsItem : RsMemoryManagement::SmallObject, RsSerializable
inline uint8_t priority_level() const { return _priority_level ;}
inline void setPriorityLevel(uint8_t l) { _priority_level = l ;}
/**
/*
* TODO: This default implementation should be removed and childs structs
* implement ::serial_process(...) as soon as all the codebase is ported to
* the new serialization system

View file

@ -1410,7 +1410,10 @@ bool RsAccounts::GetAccountDetails(const RsPeerId &id,
return rsAccounts->getCurrentAccountDetails(id, pgpId, pgpName, pgpEmail, location);
}
bool RsAccounts::createNewAccount(const RsPgpId& pgp_id, const std::string& org, const std::string& loc, const std::string& country, bool ishiddenloc, bool isautotor, const std::string& passwd, RsPeerId &sslId, std::string &errString)
bool RsAccounts::createNewAccount(
const RsPgpId& pgp_id, const std::string& org, const std::string& loc,
const std::string& country, bool ishiddenloc, bool isautotor,
const std::string& passwd, RsPeerId &sslId, std::string &errString )
{
return rsAccounts->GenerateSSLCertificate(pgp_id, org, loc, country, ishiddenloc, isautotor, passwd, sslId, errString);
}

View file

@ -101,7 +101,9 @@ RsDht *rsDht = NULL ;
//std::map<std::string,std::vector<std::string> > RsInit::unsupported_keys ;
class RsInitConfig
RsLoginHelper* rsLoginHelper;
class RsInitConfig
{
public:
@ -431,7 +433,9 @@ int RsInit::InitRetroShare(int argc, char **argv, bool /* strictCheck */)
AuthSSL::AuthSSLInit();
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL, "");
int error_code ;
rsLoginHelper = new RsLoginHelper;
int error_code ;
if(!RsAccounts::init(opt_base_dir,error_code))
return error_code ;
@ -485,12 +489,21 @@ int RsInit::InitRetroShare(int argc, char **argv, bool /* strictCheck */)
* 1 : Another instance already has the lock
* 2 : Unexpected error
*/
int RsInit::LockConfigDirectory(const std::string& accountDir, std::string& lockFilePath)
RsInit::LoadCertificateStatus RsInit::LockConfigDirectory(
const std::string& accountDir, std::string& lockFilePath )
{
const std::string lockFile = accountDir + "/" + "lock";
lockFilePath = lockFile;
return RsDirUtil::createLockFile(lockFile,rsInitConfig->lockHandle) ;
int rt = RsDirUtil::createLockFile(lockFile,rsInitConfig->lockHandle);
switch (rt)
{
case 0: return RsInit::OK;
case 1: return RsInit::ERR_ALREADY_RUNNING;
case 2: return RsInit::ERR_CANT_ACQUIRE_LOCK;
default: return RsInit::ERR_UNKOWN;
}
}
/*
@ -522,38 +535,30 @@ bool RsInit::LoadPassword(const std::string& inPwd)
return true;
}
/**
* Locks the profile directory and tries to finalize the login procedure
*
* Return value:
* 0 : success
* 1 : another instance is already running
* 2 : unexpected error while locking
* 3 : unexpected error while loading certificates
*/
int RsInit::LockAndLoadCertificates(bool autoLoginNT, std::string& lockFilePath)
RsInit::LoadCertificateStatus RsInit::LockAndLoadCertificates(
bool autoLoginNT, std::string& lockFilePath )
{
try
{
if (!RsAccounts::lockPreferredAccount())
throw 3; // invalid PreferredAccount.
throw RsInit::ERR_UNKOWN; // invalid PreferredAccount.
// Logic that used to be external to RsInit...
RsPeerId accountId;
if (!RsAccounts::GetPreferredAccountId(accountId))
throw 3; // invalid PreferredAccount;
throw RsInit::ERR_UNKOWN; // invalid PreferredAccount;
RsPgpId pgpId;
std::string pgpName, pgpEmail, location;
if(!RsAccounts::GetAccountDetails(accountId, pgpId, pgpName, pgpEmail, location))
throw 3; // invalid PreferredAccount;
throw RsInit::ERR_UNKOWN; // invalid PreferredAccount;
if(0 == AuthGPG::getAuthGPG() -> GPGInit(pgpId))
throw 3; // PGP Error.
throw RsInit::ERR_UNKOWN; // PGP Error.
int retVal = LockConfigDirectory(RsAccounts::AccountDirectory(), lockFilePath);
LoadCertificateStatus retVal =
LockConfigDirectory(RsAccounts::AccountDirectory(), lockFilePath);
if(retVal > 0)
throw retVal ;
@ -561,12 +566,12 @@ int RsInit::LockAndLoadCertificates(bool autoLoginNT, std::string& lockFilePath
if(LoadCertificates(autoLoginNT) != 1)
{
UnlockConfigDirectory();
throw 3;
throw RsInit::ERR_UNKOWN;
}
return 0;
return RsInit::OK;
}
catch(int retVal)
catch(LoadCertificateStatus retVal)
{
RsAccounts::unlockPreferredAccount();
return retVal ;
@ -1929,3 +1934,89 @@ int RsServer::StartupRetroShare()
return 1;
}
RsInit::LoadCertificateStatus RsLoginHelper::attemptLogin(
const RsPeerId& account, const std::string& password)
{
if(!rsNotify->cachePgpPassphrase(password)) return RsInit::ERR_UNKOWN;
if(!rsNotify->setDisableAskPassword(true)) return RsInit::ERR_UNKOWN;
if(!RsAccounts::SelectAccount(account)) return RsInit::ERR_UNKOWN;
std::string _ignore_lockFilePath;
RsInit::LoadCertificateStatus ret =
RsInit::LockAndLoadCertificates(false, _ignore_lockFilePath);
if(!rsNotify->setDisableAskPassword(false)) return RsInit::ERR_UNKOWN;
if(!rsNotify->clearPgpPassphrase()) return RsInit::ERR_UNKOWN;
if(ret != RsInit::OK) return ret;
if(RsControl::instance()->StartupRetroShare() == 1) return RsInit::OK;
return RsInit::ERR_UNKOWN;
}
void RsLoginHelper::getLocations(std::vector<RsLoginHelper::Location>& store)
{
std::list<RsPeerId> locIds;
RsAccounts::GetAccountIds(locIds);
store.clear();
for(const RsPeerId& locId : locIds )
{
Location l; l.mLocationId = locId;
std::string discardPgpMail;
RsAccounts::GetAccountDetails( locId, l.mPgpId, l.mPpgName,
discardPgpMail, l.mLocationName );
store.push_back(l);
}
}
bool RsLoginHelper::createLocation(
RsLoginHelper::Location& l, const std::string& password,
bool makeHidden, bool makeAutoTor, std::string& errorMessage )
{
if(l.mLocationName.empty())
{
errorMessage = "Location name is needed";
return false;
}
if(l.mPgpId.isNull() && l.mPpgName.empty())
{
errorMessage = "Either PGP name or PGP id is needed";
return false;
}
if(l.mPgpId.isNull() && !RsAccounts::GeneratePGPCertificate(
l.mPpgName, "", password, l.mPgpId, 4096, errorMessage) )
{
errorMessage = "Failure creating PGP key: " + errorMessage;
return false;
}
std::string sslPassword =
RSRandom::random_alphaNumericString(RsInit::getSslPwdLen());
if(!rsNotify->cachePgpPassphrase(password)) return false;
if(!rsNotify->setDisableAskPassword(true)) return false;
bool ret = RsAccounts::createNewAccount(
l.mPgpId, "", l.mLocationName, "", makeHidden, makeAutoTor,
sslPassword, l.mLocationId, errorMessage );
ret = ret && RsInit::LoadPassword(sslPassword);
ret = ret && RsInit::OK == attemptLogin(l.mLocationId, password);
rsNotify->setDisableAskPassword(false);
return ret;
}
void RsLoginHelper::closeSession()
{
RsControl::instance()->rsGlobalShutDown();
}
void RsLoginHelper::Location::serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mLocationId);
RS_SERIAL_PROCESS(mPgpId);
RS_SERIAL_PROCESS(mLocationName);
RS_SERIAL_PROCESS(mPpgName);
}

View file

@ -244,9 +244,10 @@ bool getRawString(const void *data, uint32_t size, uint32_t *offset, std::string
}
/* check there is space for string */
if(len > size || size-len < *offset) // better than if(size < *offset + len) because it avoids integer overflow
if(len > size || size-len < *offset) // better than if(size < *offset + len) because it avoids integer overflow
{
std::cerr << "getRawString() not enough size" << std::endl;
std::cerr << "getRawString() not enough size" << std::endl;
print_stacktrace();
return false;
}
uint8_t *buf = &(((uint8_t *) data)[*offset]);

View file

@ -26,11 +26,13 @@
#include "util/rsprint.h"
#include "serialiser/rsserializer.h"
#include "serialiser/rstypeserializer.h"
#include "util/stacktrace.h"
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_NONE ( 0x0000 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_CONFIG ( 0x0001 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE ( 0x0002 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER ( 0x0004 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_YIELDING ( 0x0008 );
RsItem *RsServiceSerializer::deserialise(void *data, uint32_t *size)
{
@ -240,3 +242,31 @@ RsItem *RsRawSerialiser::deserialise(void *data, uint32_t *pktsize)
return item;
}
RsGenericSerializer::SerializeContext::SerializeContext(
uint8_t* data, uint32_t size, SerializationFlags flags,
RsJson::AllocatorType* allocator ) :
mData(data), mSize(size), mOffset(0), mOk(true), mFlags(flags),
mJson(rapidjson::kObjectType, allocator)
{
if(data)
{
if(size == 0)
{
std::cerr << __PRETTY_FUNCTION__ << " data passed without "
<< "size! This make no sense report to developers!"
<< std::endl;
print_stacktrace();
}
if(flags & SERIALIZATION_FLAG_YIELDING)
{
std::cerr << __PRETTY_FUNCTION__ << " Attempt to create a "
<< "binary serialization context with "
<< "SERIALIZATION_FLAG_YIELDING! "
<< "This make no sense report to developers!"
<< std::endl;
print_stacktrace();
}
}
}

View file

@ -151,20 +151,14 @@
#include <string.h>
#include <iostream>
#include <string>
#ifdef HAS_RAPIDJSON
#include <rapidjson/document.h>
#else
#include <rapid_json/document.h>
#endif // HAS_RAPIDJSON
#include "retroshare/rsflags.h"
#include "serialiser/rsserial.h"
#include "util/rsdeprecate.h"
#include "util/rsjson.h"
struct RsItem;
#define SERIALIZE_ERROR() std::cerr << __PRETTY_FUNCTION__ << " : "
// This is the base class for serializers.
class RsSerialType
@ -198,8 +192,6 @@ class RsRawSerialiser: public RsSerialType
virtual RsItem * deserialise(void *data, uint32_t *size);
};
typedef rapidjson::Document RsJson;
/// Top class for all services and config serializers.
struct RsGenericSerializer : RsSerialType
{
@ -226,11 +218,9 @@ struct RsGenericSerializer : RsSerialType
/** Allow shared allocator usage to avoid costly JSON deepcopy for
* nested RsSerializable */
SerializeContext(
uint8_t *data, uint32_t size,
uint8_t* data = nullptr, uint32_t size = 0,
SerializationFlags flags = SERIALIZATION_FLAG_NONE,
RsJson::AllocatorType* allocator = nullptr) :
mData(data), mSize(size), mOffset(0), mOk(true), mFlags(flags),
mJson(rapidjson::kObjectType, allocator) {}
RsJson::AllocatorType* allocator = nullptr);
RS_DEPRECATED SerializeContext(
uint8_t *data, uint32_t size, SerializationFormat format,
@ -261,6 +251,12 @@ struct RsGenericSerializer : RsSerialType
static const SerializationFlags SERIALIZATION_FLAG_SIGNATURE; // 0x0002
static const SerializationFlags SERIALIZATION_FLAG_SKIP_HEADER; // 0x0004
/** Used for JSON deserialization in JSON API, it causes the deserialization
* to continue even if some field is missing (or incorrect), this way the
* API is more user friendly as some methods need just part of the structs
* they take as parameters. */
static const SerializationFlags SERIALIZATION_FLAG_YIELDING; // 0x0008
/**
* The following functions overload RsSerialType.
* They *should not* need to be further overloaded.

View file

@ -25,7 +25,7 @@
#include "serialiser/rsbaseserial.h"
#include "serialiser/rstlvkeys.h"
#include "serialiser/rsserializable.h"
#include "util/radix64.h"
#include "util/rsprint.h"
#include <iomanip>
@ -42,7 +42,8 @@
//static const uint32_t MAX_SERIALIZED_ARRAY_SIZE = 500 ;
static const uint32_t MAX_SERIALIZED_CHUNK_SIZE = 10*1024*1024 ; // 10 MB.
#define SAFE_GET_JSON_V() \
#ifdef RSSERIAL_DEBUG
# define SAFE_GET_JSON_V() \
const char* mName = memberName.c_str(); \
bool ret = jDoc.HasMember(mName); \
if(!ret) \
@ -50,10 +51,16 @@ static const uint32_t MAX_SERIALIZED_CHUNK_SIZE = 10*1024*1024 ; // 10 MB.
std::cerr << __PRETTY_FUNCTION__ << " \"" << memberName \
<< "\" not found in JSON:" << std::endl \
<< jDoc << std::endl << std::endl; \
print_stacktrace(); \
return false; \
} \
rapidjson::Value& v = jDoc[mName]
#else // ifdef RSSERIAL_DEBUG
# define SAFE_GET_JSON_V() \
const char* mName = memberName.c_str(); \
bool ret = jDoc.HasMember(mName); \
if(!ret) return false; \
rapidjson::Value& v = jDoc[mName]
#endif // ifdef RSSERIAL_DEBUG
//============================================================================//
@ -162,23 +169,23 @@ template<> void RsTypeSerializer::print_data(const std::string& n, const bool &
}
template<> void RsTypeSerializer::print_data(const std::string& n, const int32_t& V)
{
std::cerr << " [int32_t ] " << n << ": " << V << std::endl;
std::cerr << " [int32_t ] " << n << ": " << std::to_string(V) << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const uint8_t & V)
{
std::cerr << " [uint8_t ] " << n << ": " << V << std::endl;
std::cerr << " [uint8_t ] " << n << ": " << std::to_string(V) << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const uint16_t& V)
{
std::cerr << " [uint16_t ] " << n << ": " << V << std::endl;
std::cerr << " [uint16_t ] " << n << ": " << std::to_string(V) << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const uint32_t& V)
{
std::cerr << " [uint32_t ] " << n << ": " << V << std::endl;
std::cerr << " [uint32_t ] " << n << ": " << std::to_string(V) << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const uint64_t& V)
{
std::cerr << " [uint64_t ] " << n << ": " << V << std::endl;
std::cerr << " [uint64_t ] " << n << ": " << std::to_string(V) << std::endl;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const time_t& V)
{
@ -328,6 +335,49 @@ bool RsTypeSerializer::from_JSON( const std::string& memberName,
return ret;
}
template<> /*static*/
uint32_t RsTypeSerializer::serial_size(const double&)
{
std::cerr << "Binary [de]serialization not implemented yet for double"
<< std::endl;
print_stacktrace();
return 0;
}
template<> /*static*/
bool RsTypeSerializer::serialize(uint8_t[], uint32_t, uint32_t&, const double&)
{
std::cerr << "Binary [de]serialization not implemented yet for double"
<< std::endl;
print_stacktrace();
return false;
}
template<> /*static*/
bool RsTypeSerializer::deserialize(const uint8_t[], uint32_t, uint32_t&, double&)
{
std::cerr << "Binary [de]serialization not implemented yet for double"
<< std::endl;
print_stacktrace();
return false;
}
template<> /*static*/
void RsTypeSerializer::print_data(const std::string& n, const double& V)
{ std::cerr << " [double ] " << n << ": " << V << std::endl; }
SIMPLE_TO_JSON_DEF(double)
template<> /*static*/
bool RsTypeSerializer::from_JSON( const std::string& memberName,
double& member, RsJson& jDoc )
{
SAFE_GET_JSON_V();
ret = ret && v.IsDouble();
if(ret) member = v.GetDouble();
return ret;
}
//============================================================================//
// std::string //
@ -596,9 +646,12 @@ bool RsTypeSerializer::to_JSON(
rapidjson::Value key;
key.SetString(memberName.c_str(), memberName.length(), allocator);
std::string encodedValue;
Radix64::encode( reinterpret_cast<uint8_t*>(member.first),
member.second, encodedValue );
rapidjson::Value value;
const char* tName = typeid(member).name();
value.SetString(tName, allocator);
value.SetString(encodedValue.data(), allocator);
jDoc.AddMember(key, value, allocator);
@ -606,20 +659,27 @@ bool RsTypeSerializer::to_JSON(
}
template<> /*static*/
bool RsTypeSerializer::from_JSON( const std::string& /*memberName*/,
RsTypeSerializer::TlvMemBlock_proxy&,
RsJson& /*jDoc*/)
{ return true; }
//============================================================================//
// RsJson std:ostream support //
//============================================================================//
std::ostream &operator<<(std::ostream &out, const RsJson &jDoc)
bool RsTypeSerializer::from_JSON( const std::string& memberName,
RsTypeSerializer::TlvMemBlock_proxy& member,
RsJson& jDoc)
{
rapidjson::StringBuffer buffer; buffer.Clear();
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
jDoc.Accept(writer);
return out << buffer.GetString();
SAFE_GET_JSON_V();
ret = ret && v.IsString();
if(ret)
{
std::string encodedValue = v.GetString();
std::vector<uint8_t> decodedValue = Radix64::decode(encodedValue);
member.second = decodedValue.size();
if(member.second == 0)
{
member.first = nullptr;
return ret;
}
member.first = rs_malloc(member.second);
ret = ret && member.first &&
memcpy(member.first, decodedValue.data(), member.second);
}
return ret;
}

View file

@ -31,18 +31,14 @@
#include "serialiser/rsserializer.h"
#include "serialiser/rsserializable.h"
#include "util/rsjson.h"
#ifdef HAS_RAPIDJSON
#include <rapidjson/document.h>
#else
#include <rapid_json/document.h>
#endif // HAS_RAPIDJSON
#include <typeinfo> // for typeid
#include <type_traits>
#include <errno.h>
/** INTERNAL ONLY helper to avoid copy paste code for std::{vector,list,set}<T>
/* INTERNAL ONLY helper to avoid copy paste code for std::{vector,list,set}<T>
* Can't use a template function because T is needed for const_cast */
#define RsTypeSerializer_PRIVATE_TO_JSON_ARRAY() do \
{ \
@ -58,9 +54,7 @@
{ \
/* Use same allocator to avoid deep copy */\
RsGenericSerializer::SerializeContext elCtx(\
nullptr, 0, RsGenericSerializer::FORMAT_BINARY,\
RsGenericSerializer::SERIALIZATION_FLAG_NONE,\
&allocator );\
nullptr, 0, ctx.mFlags, &allocator );\
\
/* If el is const the default serial_process template is matched */ \
/* also when specialization is necessary so the compilation break */ \
@ -78,7 +72,7 @@
ctx.mJson.AddMember(arrKey, arr, allocator);\
} while (false)
/** INTERNAL ONLY helper to avoid copy paste code for std::{vector,list,set}<T>
/* INTERNAL ONLY helper to avoid copy paste code for std::{vector,list,set}<T>
* Can't use a template function because std::{vector,list,set}<T> has different
* name for insert/push_back function
*/
@ -86,7 +80,7 @@
{\
using namespace rapidjson;\
\
bool& ok(ctx.mOk);\
bool ok = ctx.mOk || ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_YIELDING;\
Document& jDoc(ctx.mJson);\
Document::AllocatorType& allocator = jDoc.GetAllocator();\
\
@ -100,23 +94,28 @@
{\
for (auto&& arrEl : jDoc[arrKey].GetArray())\
{\
Value arrKeyT;\
arrKeyT.SetString(memberName.c_str(), memberName.length());\
\
RsGenericSerializer::SerializeContext elCtx(\
nullptr, 0, RsGenericSerializer::FORMAT_BINARY,\
RsGenericSerializer::SERIALIZATION_FLAG_NONE,\
&allocator );\
elCtx.mJson.AddMember(arrKey, arrEl, allocator);\
nullptr, 0, ctx.mFlags, &allocator );\
elCtx.mJson.AddMember(arrKeyT, arrEl, allocator);\
\
T el;\
serial_process(j, elCtx, el, memberName); \
ok = ok && elCtx.mOk;\
\
ctx.mOk &= ok;\
if(ok) v.INSERT_FUN(el);\
else break;\
}\
}\
else\
{\
ctx.mOk = false;\
}\
\
} while(false)
std::ostream &operator<<(std::ostream &out, const RsJson &jDoc);
struct RsTypeSerializer
{
@ -134,8 +133,8 @@ struct RsTypeSerializer
template<typename T>
typename std::enable_if<std::is_same<RsTlvItem,T>::value || !(std::is_base_of<RsSerializable,T>::value || std::is_enum<T>::value || std::is_base_of<RsTlvItem,T>::value)>::type
static /*void*/ serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx,
T& member, const std::string& member_name)
RsGenericSerializer::SerializeContext& ctx,
T& member, const std::string& member_name )
{
switch(j)
{
@ -157,7 +156,8 @@ struct RsTypeSerializer
ctx.mOk = ctx.mOk && to_JSON(member_name, member, ctx.mJson);
break;
case RsGenericSerializer::FROM_JSON:
ctx.mOk = ctx.mOk && from_JSON(member_name, member, ctx.mJson);
ctx.mOk &= (ctx.mOk || ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_YIELDING)
&& from_JSON(member_name, member, ctx.mJson);
break;
default:
std::cerr << __PRETTY_FUNCTION__ << " Unknown serial job: "
@ -195,8 +195,9 @@ struct RsTypeSerializer
to_JSON(member_name, type_id, member, ctx.mJson);
break;
case RsGenericSerializer::FROM_JSON:
ctx.mOk = ctx.mOk &&
from_JSON(member_name, type_id, member, ctx.mJson);
ctx.mOk &=
(ctx.mOk || ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_YIELDING)
&& from_JSON(member_name, type_id, member, ctx.mJson);
break;
default:
std::cerr << __PRETTY_FUNCTION__ << " Unknown serial job: "
@ -288,15 +289,11 @@ struct RsTypeSerializer
{
// Use same allocator to avoid deep copy
RsGenericSerializer::SerializeContext kCtx(
nullptr, 0, RsGenericSerializer::FORMAT_BINARY,
RsGenericSerializer::SERIALIZATION_FLAG_NONE,
&allocator );
nullptr, 0, ctx.mFlags, &allocator );
serial_process<T>(j, kCtx, const_cast<T&>(kv.first), "key");
RsGenericSerializer::SerializeContext vCtx(
nullptr, 0, RsGenericSerializer::FORMAT_BINARY,
RsGenericSerializer::SERIALIZATION_FLAG_NONE,
&allocator );
nullptr, 0, ctx.mFlags, &allocator );
serial_process<U>(j, vCtx, const_cast<U&>(kv.second), "value");
if(kCtx.mOk && vCtx.mOk)
@ -317,7 +314,7 @@ struct RsTypeSerializer
{
using namespace rapidjson;
bool& ok(ctx.mOk);
bool ok = ctx.mOk || ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_YIELDING;
Document& jDoc(ctx.mJson);
Document::AllocatorType& allocator = jDoc.GetAllocator();
@ -337,9 +334,7 @@ struct RsTypeSerializer
if (!ok) break;
RsGenericSerializer::SerializeContext kCtx(
nullptr, 0, RsGenericSerializer::FORMAT_BINARY,
RsGenericSerializer::SERIALIZATION_FLAG_NONE,
&allocator );
nullptr, 0, ctx.mFlags, &allocator );
if(ok)
kCtx.mJson.AddMember("key", kvEl["key"], allocator);
@ -347,9 +342,7 @@ struct RsTypeSerializer
ok = ok && (serial_process(j, kCtx, key, "key"), kCtx.mOk);
RsGenericSerializer::SerializeContext vCtx(
nullptr, 0, RsGenericSerializer::FORMAT_BINARY,
RsGenericSerializer::SERIALIZATION_FLAG_NONE,
&allocator );
nullptr, 0, ctx.mFlags, &allocator );
if(ok)
vCtx.mJson.AddMember("value", kvEl["value"], allocator);
@ -357,14 +350,102 @@ struct RsTypeSerializer
ok = ok && ( serial_process(j, vCtx, value, "value"),
vCtx.mOk );
ctx.mOk &= ok;
if(ok) v.insert(std::pair<T,U>(key,value));
else break;
}
}
else
{
ctx.mOk = false;
}
break;
}
default:
std::cerr << __PRETTY_FUNCTION__ << " Unknown serial job: "
<< static_cast<std::underlying_type<decltype(j)>::type>(j)
<< std::endl;
exit(EINVAL);
}
}
/// std::pair<T,U>
template<typename T, typename U>
static void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx,
std::pair<T,U>& p,
const std::string& memberName )
{
switch(j)
{
case RsGenericSerializer::SIZE_ESTIMATE: // fallthrough
case RsGenericSerializer::DESERIALIZE: // fallthrough
case RsGenericSerializer::SERIALIZE: // fallthrough
case RsGenericSerializer::PRINT:
serial_process(j, ctx, p.first, "pair::first");
serial_process(j, ctx, p.second, "pair::second");
break;
case RsGenericSerializer::TO_JSON:
{
RsJson& jDoc(ctx.mJson);
RsJson::AllocatorType& allocator = jDoc.GetAllocator();
// Reuse allocator to avoid deep copy later
RsGenericSerializer::SerializeContext lCtx(
nullptr, 0, ctx.mFlags, &allocator );
serial_process(j, ctx, p.first, "first");
serial_process(j, ctx, p.second, "second");
rapidjson::Value key;
key.SetString(memberName.c_str(), memberName.length(), allocator);
/* Because the passed allocator is reused it doesn't go out of scope
* and there is no need of deep copy and we can take advantage of
* the much faster rapidjson move semantic */
jDoc.AddMember(key, lCtx.mJson, allocator);
ctx.mOk = ctx.mOk && lCtx.mOk;
break;
}
case RsGenericSerializer::FROM_JSON:
{
RsJson& jDoc(ctx.mJson);
const char* mName = memberName.c_str();
bool hasMember = jDoc.HasMember(mName);
bool yielding = ctx.mFlags &
RsGenericSerializer::SERIALIZATION_FLAG_YIELDING;
if(!hasMember)
{
if(!yielding)
{
std::cerr << __PRETTY_FUNCTION__ << " \"" << memberName
<< "\" not found in JSON:" << std::endl
<< jDoc << std::endl << std::endl;
print_stacktrace();
}
ctx.mOk = false;
break;
}
rapidjson::Value& v = jDoc[mName];
RsGenericSerializer::SerializeContext lCtx(nullptr, 0, ctx.mFlags);
lCtx.mJson.SetObject() = v; // Beware of move semantic!!
serial_process(j, ctx, p.first, "first");
serial_process(j, ctx, p.second, "second");
ctx.mOk &= lCtx.mOk;
break;
}
default: break;
default:
std::cerr << __PRETTY_FUNCTION__ << " Unknown serial job: "
<< static_cast<std::underlying_type<decltype(j)>::type>(j)
<< std::endl;
exit(EINVAL);
break;
}
}
@ -404,10 +485,12 @@ struct RsTypeSerializer
case RsGenericSerializer::PRINT:
{
if(v.empty())
std::cerr << " Empty array"<< std::endl;
else
std::cerr << " Array of " << v.size() << " elements:"
std::cerr << " Empty vector \"" << memberName << "\""
<< std::endl;
else
std::cerr << " Vector of " << v.size() << " elements: \""
<< memberName << "\"" << std::endl;
for(uint32_t i=0;i<v.size();++i)
{
std::cerr << " " ;
@ -466,9 +549,12 @@ struct RsTypeSerializer
}
case RsGenericSerializer::PRINT:
{
if(v.empty()) std::cerr << " Empty set"<< std::endl;
else std::cerr << " Set of " << v.size() << " elements:"
<< std::endl;
if(v.empty())
std::cerr << " Empty set \"" << memberName << "\""
<< std::endl;
else
std::cerr << " Set of " << v.size() << " elements: \""
<< memberName << "\"" << std::endl;
break;
}
case RsGenericSerializer::TO_JSON:
@ -519,9 +605,12 @@ struct RsTypeSerializer
}
case RsGenericSerializer::PRINT:
{
if(v.empty()) std::cerr << " Empty list"<< std::endl;
else std::cerr << " List of " << v.size() << " elements:"
<< std::endl;
if(v.empty())
std::cerr << " Empty list \"" << memberName << "\""
<< std::endl;
else
std::cerr << " List of " << v.size() << " elements: \""
<< memberName << "\"" << std::endl;
break;
}
case RsGenericSerializer::TO_JSON:
@ -567,7 +656,9 @@ struct RsTypeSerializer
case RsGenericSerializer::FROM_JSON:
{
uint32_t f;
ctx.mOk = from_JSON(memberName, f, ctx.mJson);
ctx.mOk &=
(ctx.mOk || ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_YIELDING)
&& from_JSON(memberName, f, ctx.mJson);
v = t_RsFlags32<N>(f);
break;
}
@ -624,9 +715,7 @@ struct RsTypeSerializer
// Reuse allocator to avoid deep copy later
RsGenericSerializer::SerializeContext lCtx(
nullptr, 0, RsGenericSerializer::FORMAT_BINARY,
RsGenericSerializer::SERIALIZATION_FLAG_NONE,
&allocator );
nullptr, 0, ctx.mFlags, &allocator );
member.serial_process(j, lCtx);
@ -643,28 +732,32 @@ struct RsTypeSerializer
}
case RsGenericSerializer::FROM_JSON:
{
rapidjson::Document& jDoc(ctx.mJson);
RsJson& jDoc(ctx.mJson);
const char* mName = memberName.c_str();
ctx.mOk = ctx.mOk && jDoc.HasMember(mName);
bool hasMember = jDoc.HasMember(mName);
bool yielding = ctx.mFlags &
RsGenericSerializer::SERIALIZATION_FLAG_YIELDING;
if(!ctx.mOk)
if(!hasMember)
{
std::cerr << __PRETTY_FUNCTION__ << " \"" << memberName
<< "\" not found in JSON:" << std::endl
<< jDoc << std::endl << std::endl;
print_stacktrace();
if(!yielding)
{
std::cerr << __PRETTY_FUNCTION__ << " \"" << memberName
<< "\" not found in JSON:" << std::endl
<< jDoc << std::endl << std::endl;
print_stacktrace();
}
ctx.mOk = false;
break;
}
rapidjson::Value& v = jDoc[mName];
RsGenericSerializer::SerializeContext lCtx(
nullptr, 0, RsGenericSerializer::FORMAT_BINARY,
RsGenericSerializer::SERIALIZATION_FLAG_NONE );
RsGenericSerializer::SerializeContext lCtx(nullptr, 0, ctx.mFlags);
lCtx.mJson.SetObject() = v; // Beware of move semantic!!
member.serial_process(j, lCtx);
ctx.mOk = ctx.mOk && lCtx.mOk;
ctx.mOk &= lCtx.mOk;
break;
}

View file

@ -64,8 +64,13 @@ RsGxsChannels *rsGxsChannels = NULL;
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3GxsChannels::p3GxsChannels(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs)
: RsGenExchange(gds, nes, new RsGxsChannelSerialiser(), RS_SERVICE_GXS_TYPE_CHANNELS, gixs, channelsAuthenPolicy()), RsGxsChannels(this), GxsTokenQueue(this)
p3GxsChannels::p3GxsChannels(
RsGeneralDataService *gds, RsNetworkExchangeService *nes,
RsGixs* gixs ) :
RsGenExchange( gds, nes, new RsGxsChannelSerialiser(),
RS_SERVICE_GXS_TYPE_CHANNELS, gixs, channelsAuthenPolicy() ),
RsGxsChannels(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this),
mSearchCallbacksMapMutex("GXS channels search")
{
// For Dummy Msgs.
mGenActive = false;
@ -347,8 +352,6 @@ static time_t last_dummy_tick = 0;
GxsTokenQueue::checkRequests();
mCommentService->comment_tick();
return;
}
bool p3GxsChannels::getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups)
@ -392,10 +395,11 @@ bool p3GxsChannels::getGroupData(const uint32_t &token, std::vector<RsGxsChannel
return ok;
}
bool p3GxsChannels::groupShareKeys(const RsGxsGroupId &groupId, std::set<RsPeerId>& peers)
bool p3GxsChannels::groupShareKeys(
const RsGxsGroupId &groupId, const std::set<RsPeerId>& peers )
{
RsGenExchange::shareGroupPublishKey(groupId,peers) ;
return true ;
RsGenExchange::shareGroupPublishKey(groupId,peers);
return true;
}
@ -992,6 +996,50 @@ void p3GxsChannels::handleResponse(uint32_t token, uint32_t req_type)
}
}
////////////////////////////////////////////////////////////////////////////////
/// Blocking API implementation begin
////////////////////////////////////////////////////////////////////////////////
bool p3GxsChannels::getChannelsSummaries(
std::list<RsGroupMetaData>& channels )
{
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
if( !requestGroupInfo(token, opts)
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
return getGroupSummary(token, channels);
}
bool p3GxsChannels::getChannelsInfo(
const std::list<RsGxsGroupId>& chanIds,
std::vector<RsGxsChannelGroup>& channelsInfo )
{
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
if( !requestGroupInfo(token, opts, chanIds)
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
return getGroupData(token, channelsInfo);
}
bool p3GxsChannels::getChannelsContent(
const std::list<RsGxsGroupId>& chanIds,
std::vector<RsGxsChannelPost>& posts,
std::vector<RsGxsComment>& comments )
{
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
if( !requestMsgInfo(token, opts, chanIds)
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
return getPostData(token, posts, comments);
}
////////////////////////////////////////////////////////////////////////////////
/// Blocking API implementation end
////////////////////////////////////////////////////////////////////////////////
/********************************************************************************************/
/********************************************************************************************/
@ -1234,17 +1282,10 @@ bool p3GxsChannels::createPost(uint32_t &token, RsGxsChannelPost &msg)
/********************************************************************************************/
/********************************************************************************************/
bool p3GxsChannels::ExtraFileHash(const std::string &path, std::string filename)
bool p3GxsChannels::ExtraFileHash(const std::string& path)
{
/* extract filename */
filename = RsDirUtil::getTopDir(path);
TransferRequestFlags flags = RS_FILE_REQ_ANONYMOUS_ROUTING;
if(!rsFiles->ExtraFileHash(path, GXSCHANNEL_STOREPERIOD, flags))
return false;
return true;
return rsFiles->ExtraFileHash(path, GXSCHANNEL_STOREPERIOD, flags);
}
@ -1312,14 +1353,14 @@ void p3GxsChannels::dummy_tick()
#endif
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken);
if (status != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
if (status != RsTokenService::COMPLETE)
{
#ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::dummy_tick() Status: " << status;
std::cerr << std::endl;
#endif
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
if (status == RsTokenService::FAILED)
{
#ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::dummy_tick() generateDummyMsgs() FAILED";
@ -1518,6 +1559,8 @@ void p3GxsChannels::dummy_tick()
}
}
cleanTimedOutSearches();
}
@ -1733,4 +1776,60 @@ bool p3GxsChannels::retrieveDistantGroup(const RsGxsGroupId& group_id,RsGxsChann
return false ;
}
bool p3GxsChannels::turtleSearchRequest(
const std::string& matchString,
const std::function<void (const RsGxsGroupSummary&)>& multiCallback,
std::time_t maxWait )
{
if(matchString.empty())
{
std::cerr << __PRETTY_FUNCTION__ << " match string can't be empty!"
<< std::endl;
return false;
}
TurtleRequestId sId = turtleSearchRequest(matchString);
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
mSearchCallbacksMap.emplace(
sId,
std::make_pair(
multiCallback,
std::chrono::system_clock::now() +
std::chrono::seconds(maxWait) ) );
return true;
}
void p3GxsChannels::receiveDistantSearchResults(
TurtleRequestId id, const RsGxsGroupId& grpId )
{
std::cerr << __PRETTY_FUNCTION__ << "(" << id << ", " << grpId << ")"
<< std::endl;
RsGenExchange::receiveDistantSearchResults(id, grpId);
RsGxsGroupSummary gs;
gs.mGroupId = grpId;
netService()->retrieveDistantGroupSummary(grpId, gs);
{
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
auto cbpt = mSearchCallbacksMap.find(id);
if(cbpt != mSearchCallbacksMap.end())
cbpt->second.first(gs);
} // end RS_STACK_MUTEX(mSearchCallbacksMapMutex);
}
void p3GxsChannels::cleanTimedOutSearches()
{
RS_STACK_MUTEX(mSearchCallbacksMapMutex);
auto now = std::chrono::system_clock::now();
for( auto cbpt = mSearchCallbacksMap.begin();
cbpt != mSearchCallbacksMap.end(); )
if(cbpt->second.second <= now)
{
clearDistantSearchResults(cbpt->first);
cbpt = mSearchCallbacksMap.erase(cbpt);
}
else ++cbpt;
}

View file

@ -54,14 +54,14 @@ class p3GxsChannels: public RsGenExchange, public RsGxsChannels,
public GxsTokenQueue, public p3Config,
public RsTickEvent /* only needed for testing - remove after */
{
public:
public:
p3GxsChannels( RsGeneralDataService* gds, RsNetworkExchangeService* nes,
RsGixs* gixs );
virtual RsServiceInfo getServiceInfo();
p3GxsChannels(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs);
virtual RsServiceInfo getServiceInfo();
virtual void service_tick();
virtual void service_tick();
protected:
protected:
virtual RsSerialiser* setupSerialiser(); // @see p3Config::setupSerialiser()
@ -82,7 +82,7 @@ virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
public:
public:
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups);
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts);
@ -96,7 +96,8 @@ virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &p
//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
//virtual bool groupRestoreKeys(const std::string &groupId);
virtual bool groupShareKeys(const RsGxsGroupId &groupId, std::set<RsPeerId>& peers) ;
virtual bool groupShareKeys(
const RsGxsGroupId &groupId, const std::set<RsPeerId>& peers);
virtual bool createGroup(uint32_t &token, RsGxsChannelGroup &group);
virtual bool createPost(uint32_t &token, RsGxsChannelPost &post);
@ -109,6 +110,18 @@ virtual bool getChannelAutoDownload(const RsGxsGroupId &groupid, bool& enabled);
virtual bool setChannelDownloadDirectory(const RsGxsGroupId &groupId, const std::string& directory);
virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::string& directory);
/// @see RsGxsChannels::turtleSearchRequest
virtual bool turtleSearchRequest(const std::string& matchString,
const std::function<void (const RsGxsGroupSummary&)>& multiCallback,
std::time_t maxWait = 300 );
/**
* Receive results from turtle search @see RsGenExchange @see RsNxsObserver
* @see p3turtle::handleSearchResult
*/
void receiveDistantSearchResults( TurtleRequestId id,
const RsGxsGroupId& grpId );
/* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */
virtual bool getCommentData(uint32_t token, std::vector<RsGxsComment> &msgs)
{ return mCommentService->getGxsCommentData(token, msgs); }
@ -151,15 +164,30 @@ virtual void setMessageProcessedStatus(uint32_t& token, const RsGxsGrpMsgIdPair&
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
// File Interface
virtual bool ExtraFileHash(const std::string &path, std::string filename);
virtual bool ExtraFileHash(const std::string& path);
virtual bool ExtraFileRemove(const RsFileHash &hash);
protected:
/// Implementation of @see RsGxsChannels::getChannelsSummaries
virtual bool getChannelsSummaries(std::list<RsGroupMetaData>& channels);
/// Implementation of @see RsGxsChannels::getChannelsInfo
virtual bool getChannelsInfo(
const std::list<RsGxsGroupId>& chanIds,
std::vector<RsGxsChannelGroup>& channelsInfo );
/// Implementation of @see RsGxsChannels::getChannelContent
virtual bool getChannelsContent(
const std::list<RsGxsGroupId>& chanIds,
std::vector<RsGxsChannelPost>& posts,
std::vector<RsGxsComment>& comments );
protected:
// Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type);
virtual void handleResponse(uint32_t token, uint32_t req_type);
private:
private:
static uint32_t channelsAuthenPolicy();
@ -220,8 +248,20 @@ bool generateGroup(uint32_t &token, std::string groupName);
std::vector<ChannelDummyRef> mGenRefs;
RsGxsMessageId mGenThreadId;
p3GxsCommentService *mCommentService;
p3GxsCommentService *mCommentService;
std::map<RsGxsGroupId,time_t> mKnownChannels;
/** Store search callbacks with timeout*/
std::map<
TurtleRequestId,
std::pair<
std::function<void (const RsGxsGroupSummary&)>,
std::chrono::system_clock::time_point >
> mSearchCallbacksMap;
RsMutex mSearchCallbacksMapMutex;
/// Cleanup mSearchCallbacksMap
void cleanTimedOutSearches();
};
#endif

View file

@ -107,16 +107,16 @@ RsGxsCircles *rsGxsCircles = NULL;
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3GxsCircles::p3GxsCircles(RsGeneralDataService *gds, RsNetworkExchangeService *nes,
p3IdService *identities, PgpAuxUtils *pgpUtils)
: RsGxsCircleExchange(gds, nes, new RsGxsCircleSerialiser(),
RS_SERVICE_GXS_TYPE_GXSCIRCLE, identities, circleAuthenPolicy()),
RsGxsCircles(this), GxsTokenQueue(this), RsTickEvent(),
mIdentities(identities),
mPgpUtils(pgpUtils),
mCircleMtx("p3GxsCircles"),
mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache")
p3GxsCircles::p3GxsCircles(
RsGeneralDataService *gds, RsNetworkExchangeService *nes,
p3IdService *identities, PgpAuxUtils *pgpUtils) :
RsGxsCircleExchange(
gds, nes, new RsGxsCircleSerialiser(), RS_SERVICE_GXS_TYPE_GXSCIRCLE,
identities, circleAuthenPolicy() ),
RsGxsCircles(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this),
RsTickEvent(), mIdentities(identities), mPgpUtils(pgpUtils),
mCircleMtx("p3GxsCircles"),
mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" )
{
// Kick off Cache Testing, + Others.
//RsTickEvent::schedule_in(CIRCLE_EVENT_CACHETEST, CACHETEST_PERIOD);
@ -1653,8 +1653,8 @@ void p3GxsCircles::checkDummyIdData()
// check the token.
uint32_t status = rsIdentity->getTokenService()->requestStatus(mDummyIdToken);
if ( (RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == status) ||
(RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == status) )
if ( (RsTokenService::FAILED == status) ||
(RsTokenService::COMPLETE == status) )
{
std::vector<RsGxsIdGroup> ids;
if (!rsIdentity->getGroupData(mDummyIdToken, ids))

View file

@ -552,24 +552,22 @@ void p3GxsCommentService::load_PendingVoteParent(const uint32_t &token)
pit = mPendingVotes.find(parentId);
if (pit == mPendingVotes.end())
{
std::cerr << "p3GxsCommentService::load_PendingVoteParent() ERROR Finding Pending Vote";
std::cerr << std::endl;
std::cerr << __PRETTY_FUNCTION__
<< " ERROR Finding Pending Vote" << std::endl;
continue;
}
RsGxsVote vote = pit->second.mVote;
if (meta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
{
std::cerr << "p3GxsCommentService::load_PendingVoteParent() ERROR Already Voted";
std::cerr << std::endl;
std::cerr << "mGroupId: " << meta.mGroupId;
std::cerr << std::endl;
std::cerr << "mMsgId: " << meta.mMsgId;
std::cerr << std::endl;
std::cerr << __PRETTY_FUNCTION__ << " ERROR Already Voted"
<< std::endl
<< "mGroupId: " << meta.mGroupId << std::endl
<< "mMsgId: " << meta.mMsgId << std::endl;
pit->second.mStatus = VoteHolder::VOTE_ERROR;
uint32_t status = RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
mExchange->updatePublicRequestStatus(pit->second.mReqToken, status);
mExchange->updatePublicRequestStatus(
pit->second.mReqToken, RsTokenService::FAILED );
continue;
}
@ -613,8 +611,8 @@ void p3GxsCommentService::completeInternalVote(uint32_t &token)
{
if (it->second.mVoteToken == token)
{
uint32_t status = mExchange->getTokenService()->requestStatus(token);
RsTokenService::GxsRequestStatus status =
mExchange->getTokenService()->requestStatus(token);
mExchange->updatePublicRequestStatus(it->second.mReqToken, status);
#ifdef DEBUG_GXSCOMMON

View file

@ -51,7 +51,8 @@ p3GxsForums::p3GxsForums( RsGeneralDataService *gds,
RsNetworkExchangeService *nes, RsGixs* gixs ) :
RsGenExchange( gds, nes, new RsGxsForumSerialiser(),
RS_SERVICE_GXS_TYPE_FORUMS, gixs, forumsAuthenPolicy()),
RsGxsForums(this), mGenToken(0), mGenActive(false), mGenCount(0)
RsGxsForums(static_cast<RsGxsIface&>(*this)), mGenToken(0),
mGenActive(false), mGenCount(0)
{
// Test Data disabled in Repo.
//RsTickEvent::schedule_in(FORUM_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD);
@ -486,12 +487,12 @@ void p3GxsForums::dummy_tick()
std::cerr << std::endl;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken);
if (status != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
if (status != RsTokenService::COMPLETE)
{
std::cerr << "p3GxsForums::dummy_tick() Status: " << status;
std::cerr << std::endl;
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
if (status == RsTokenService::FAILED)
{
std::cerr << "p3GxsForums::dummy_tick() generateDummyMsgs() FAILED";
std::cerr << std::endl;

View file

@ -152,12 +152,14 @@ RsIdentity *rsIdentity = NULL;
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *nes, PgpAuxUtils *pgpUtils)
: RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXS_TYPE_GXSID, idAuthenPolicy()),
RsIdentity(this), GxsTokenQueue(this), RsTickEvent(),
mKeyCache(GXSID_MAX_CACHE_SIZE, "GxsIdKeyCache"),
mIdMtx("p3IdService"), mNes(nes),
mPgpUtils(pgpUtils)
p3IdService::p3IdService(
RsGeneralDataService *gds, RsNetworkExchangeService *nes,
PgpAuxUtils *pgpUtils ) :
RsGxsIdExchange( gds, nes, new RsGxsIdSerialiser(),
RS_SERVICE_GXS_TYPE_GXSID, idAuthenPolicy() ),
RsIdentity(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this),
RsTickEvent(), mKeyCache(GXSID_MAX_CACHE_SIZE, "GxsIdKeyCache"),
mIdMtx("p3IdService"), mNes(nes), mPgpUtils(pgpUtils)
{
mBgSchedule_Mode = 0;
mBgSchedule_Active = false;
@ -1532,7 +1534,7 @@ bool p3IdService::opinion_handlerequest(uint32_t token)
std::cerr << "p3IdService::opinion_handlerequest() ERROR getGroupMeta()";
std::cerr << std::endl;
updatePublicRequestStatus(req.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
updatePublicRequestStatus(req.mToken, RsTokenService::FAILED);
return false;
}
@ -1542,7 +1544,7 @@ bool p3IdService::opinion_handlerequest(uint32_t token)
std::cerr << std::endl;
// error.
updatePublicRequestStatus(req.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
updatePublicRequestStatus(req.mToken, RsTokenService::FAILED);
return false;
}
RsGroupMetaData &meta = *(groups.begin());
@ -1553,7 +1555,7 @@ bool p3IdService::opinion_handlerequest(uint32_t token)
std::cerr << std::endl;
// error.
updatePublicRequestStatus(req.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
updatePublicRequestStatus(req.mToken, RsTokenService::FAILED);
return false;
}
@ -1588,7 +1590,7 @@ bool p3IdService::opinion_handlerequest(uint32_t token)
setGroupServiceString(dummyToken, meta.mGroupId, serviceString);
cache_update_if_cached(RsGxsId(meta.mGroupId), serviceString);
updatePublicRequestStatus(req.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
updatePublicRequestStatus(req.mToken, RsTokenService::COMPLETE);
return true;
}

View file

@ -36,13 +36,12 @@ RsPosted *rsPosted = NULL;
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs)
:p3PostBase(gds, nes, gixs, new RsGxsPostedSerialiser(), RS_SERVICE_GXS_TYPE_POSTED),
RsPosted(this)
{
return;
}
p3Posted::p3Posted(
RsGeneralDataService *gds, RsNetworkExchangeService *nes,
RsGixs* gixs ) :
p3PostBase( gds, nes, gixs, new RsGxsPostedSerialiser(),
RS_SERVICE_GXS_TYPE_POSTED ),
RsPosted(static_cast<RsGxsIface&>(*this)) {}
const std::string GXS_POSTED_APP_NAME = "gxsposted";
const uint16_t GXS_POSTED_APP_MAJOR_VERSION = 1;

View file

@ -534,7 +534,7 @@ void p3Wiki::dummyTick()
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mAboutToken);
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
if (status == RsTokenService::COMPLETE)
{
std::cerr << "p3Wiki::dummyTick() AboutActive, Lines: " << mAboutLines;
std::cerr << std::endl;
@ -601,7 +601,7 @@ void p3Wiki::dummyTick()
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mImprovToken);
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
if (status == RsTokenService::COMPLETE)
{
std::cerr << "p3Wiki::dummyTick() ImprovActive, Lines: " << mImprovLines;
std::cerr << std::endl;
@ -669,7 +669,7 @@ void p3Wiki::dummyTick()
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mMarkdownToken);
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
if (status == RsTokenService::COMPLETE)
{
std::cerr << "p3Wiki::dummyTick() MarkdownActive, Lines: " << mMarkdownLines;
std::cerr << std::endl;

View file

@ -928,7 +928,6 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
for(auto it(search_results.begin());it!=search_results.end();++it)
{
(*it)->request_id = item->request_id ;
(*it)->depth = 0 ;
(*it)->PeerId(item->PeerId()) ;
sendItem(*it) ;
@ -1133,7 +1132,7 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
std::list<std::pair<RsTurtleSearchResultItem*,RsTurtleClientService*> > results_to_notify_off_mutex ;
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mTurtleMtx);
// Find who actually sent the corresponding request.
//
std::map<TurtleRequestId,TurtleSearchRequestInfo>::iterator it = _search_requests_origins.find(item->request_id) ;
@ -1195,11 +1194,10 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
// of the files found can be further reached by a tunnel.
fwd_item->PeerId(it->second.origin) ;
fwd_item->depth = 0 ; // obfuscate the depth for non immediate friends. Result will always be 0. This effectively removes the information.
sendItem(fwd_item) ;
}
}
} // mTurtleMtx end
// now we notify clients off-mutex.
@ -1212,7 +1210,16 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
if(ftsr!=NULL)
{
RsServer::notify()->notifyTurtleSearchResult(ftsr->request_id,ftsr->result) ;
ftServer *client = dynamic_cast<ftServer*>((*it).second) ;
if(!client)
{
std::cerr << "(EE) received turtle FT search result but the service is not a ftServer!!" << std::endl;
continue;
}
//RsServer::notify()->notifyTurtleSearchResult(ftsr->request_id,ftsr->result) ;
client->receiveSearchResult(ftsr);
continue ;
}

View file

@ -193,13 +193,20 @@ RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(RsRegularExpression::Linearized
void RsTurtleFTSearchResultItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process<uint32_t>(j,ctx,request_id,"request_id") ;
RsTypeSerializer::serial_process<uint16_t>(j,ctx,depth ,"depth") ;
// This depth was previously a member of SearchResult parent class that was set to be always 0. It's removed, but we have to stay backward compatible.
uint16_t depth_retrocompat_unused_placeholder = 0 ;
RsTypeSerializer::serial_process<uint16_t>(j,ctx,depth_retrocompat_unused_placeholder,"depth") ;
RsTypeSerializer::serial_process (j,ctx,result ,"result") ;
}
void RsTurtleGenericSearchResultItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process<uint32_t>(j,ctx,request_id,"request_id") ;
RsTypeSerializer::serial_process<uint16_t>(j,ctx,depth ,"depth") ;
// This depth was previously a member of SearchResult parent class that was set to be always 0. It's removed, but we have to stay backward compatible.
uint16_t depth_retrocompat_unused_placeholder = 0 ;
RsTypeSerializer::serial_process<uint16_t>(j,ctx,depth_retrocompat_unused_placeholder,"depth") ;
RsTypeSerializer::TlvMemBlock_proxy prox(result_data,result_data_len) ;
RsTypeSerializer::serial_process(j,ctx,prox,"search_data") ;
@ -212,59 +219,9 @@ RsTurtleSearchResultItem *RsTurtleGenericSearchResultItem::duplicate() const
memcpy(sr->result_data,result_data,result_data_len) ;
sr->result_data_len = result_data_len ;
sr->request_id = request_id ;
sr->depth = depth ;
return sr ;
}
template<> uint32_t RsTypeSerializer::serial_size(const TurtleFileInfo& i)
{
uint32_t s = 0 ;
s += 8 ; // size
s += i.hash.SIZE_IN_BYTES ;
s += GetTlvStringSize(i.name) ;
return s;
}
template<> bool RsTypeSerializer::deserialize(const uint8_t data[],uint32_t size,uint32_t& offset,TurtleFileInfo& i)
{
uint32_t saved_offset = offset ;
bool ok = true ;
ok &= getRawUInt64(data, size, &offset, &i.size); // file size
ok &= i.hash.deserialise(data, size, offset); // file hash
ok &= GetTlvString(data, size, &offset, TLV_TYPE_STR_NAME, i.name); // file name
if(!ok)
offset = saved_offset ;
return ok;
}
template<> bool RsTypeSerializer::serialize(uint8_t data[],uint32_t size,uint32_t& offset,const TurtleFileInfo& i)
{
uint32_t saved_offset = offset ;
bool ok = true ;
ok &= setRawUInt64(data, size, &offset, i.size); // file size
ok &= i.hash.serialise(data, size, offset); // file hash
ok &= SetTlvString(data, size, &offset, TLV_TYPE_STR_NAME, i.name); // file name
if(!ok)
offset = saved_offset ;
return ok;
}
template<> void RsTypeSerializer::print_data(const std::string& n, const TurtleFileInfo& i)
{
std::cerr << " [FileInfo ] " << n << " size=" << i.size << " hash=" << i.hash << ", name=" << i.name << std::endl;
}
RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(TurtleFileInfo)
RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(TurtleFileInfo)
void RsTurtleOpenTunnelItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process (j,ctx,file_hash ,"file_hash") ;

View file

@ -191,12 +191,9 @@ class RsTurtleGenericSearchRequestItem: public RsTurtleSearchRequestItem
class RsTurtleSearchResultItem: public RsTurtleItem
{
public:
RsTurtleSearchResultItem(uint8_t subtype) : RsTurtleItem(subtype), request_id(0), depth(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_SEARCH_RESULT) ;}
RsTurtleSearchResultItem(uint8_t subtype) : RsTurtleItem(subtype), request_id(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_SEARCH_RESULT) ;}
TurtleSearchRequestId request_id ; // Randomly generated request id.
uint16_t depth ; // The depth of a search result is obfuscated in this way:
// If the actual depth is 1, this field will be 1.
// If the actual depth is > 1, this field is a larger arbitrary integer.
virtual uint32_t count() const =0;
virtual void pop() =0;

View file

@ -47,6 +47,18 @@ sLibs =
mLibs = $$RS_SQL_LIB ssl crypto $$RS_THREAD_LIB $$RS_UPNP_LIB
dLibs =
rs_jsonapi {
RS_SRC_PATH=$$system_path($$clean_path($${PWD}/../../))
RS_BUILD_PATH=$$system_path($$clean_path($${OUT_PWD}/../../))
RESTBED_SRC_PATH=$$system_path($$clean_path($${RS_SRC_PATH}/supportlibs/restbed))
RESTBED_BUILD_PATH=$$system_path($$clean_path($${RS_BUILD_PATH}/supportlibs/restbed))
INCLUDEPATH *= $$system_path($$clean_path($${RESTBED_BUILD_PATH}/include/))
QMAKE_LIBDIR *= $$system_path($$clean_path($${RESTBED_BUILD_PATH}/library/))
# Using sLibs would fail as librestbed.a is generated at compile-time
LIBS *= -L$$system_path($$clean_path($${RESTBED_BUILD_PATH}/library/)) -lrestbed
}
linux-* {
mLibs += dl
}

View file

@ -142,11 +142,12 @@ void rslog(const RsLog::logLvl lvl, RsLog::logInfo *info, const std::string &msg
if(info->lvl == RsLog::None)
return;
RsStackMutex stack(logMtx); /******** LOCKED ****************/
bool process = info->lvl == RsLog::Default ? (lvl <= defaultLevel) : lvl <= info->lvl;
if(process)
if(!process)
return;
{
RsStackMutex stack(logMtx); /******** LOCKED ****************/
time_t t = time(NULL);
if (debugMode == RS_DEBUG_LOGCRASH)
@ -179,6 +180,9 @@ void rslog(const RsLog::logLvl lvl, RsLog::logInfo *info, const std::string &msg
fprintf(ofd, "(%s Z: %s, lvl: %u): %s \n",
timestr2.c_str(), info->name.c_str(), (unsigned int)info->lvl, msg.c_str());
fflush(ofd);
fprintf(stdout, "(%s Z: %s, lvl: %u): %s \n",
timestr2.c_str(), info->name.c_str(), (unsigned int)info->lvl, msg.c_str());
lineCount++;
}
}

View file

@ -0,0 +1,68 @@
/*******************************************************************************
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "util/rsjson.h"
#ifdef HAS_RAPIDJSON
# include <rapidjson/writer.h>
# include <rapidjson/stringbuffer.h>
# include <rapidjson/prettywriter.h>
#else
# include <rapid_json/writer.h>
# include <rapid_json/stringbuffer.h>
# include <rapid_json/prettywriter.h>
#endif // HAS_RAPIDJSON
inline int getJsonManipulatorStatePosition()
{
static int p = std::ios_base::xalloc();
return p;
}
std::ostream& compactJSON(std::ostream &out)
{
out.iword(getJsonManipulatorStatePosition()) = 1;
return out;
}
std::ostream& prettyJSON(std::ostream &out)
{
out.iword(getJsonManipulatorStatePosition()) = 0;
return out;
}
std::ostream& operator<<(std::ostream &out, const RsJson &jDoc)
{
rapidjson::StringBuffer buffer; buffer.Clear();
if(out.iword(getJsonManipulatorStatePosition()))
{
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
jDoc.Accept(writer);
}
else
{
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
jDoc.Accept(writer);
}
return out << buffer.GetString();
}

View file

@ -0,0 +1,56 @@
/*******************************************************************************
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <iostream>
#ifdef HAS_RAPIDJSON
# include <rapidjson/document.h>
#else
# include <rapid_json/document.h>
#endif // HAS_RAPIDJSON
/**
* Use this type for JSON documents representations in RetroShare code
*/
typedef rapidjson::Document RsJson;
/**
* Print out RsJson to a stream, use std::stringstream to get the string
* @param[out] out output stream
* @param[in] jDoc JSON document to print
* @return same output stream passed as out parameter
*/
std::ostream &operator<<(std::ostream &out, const RsJson &jDoc);
/**
* Stream manipulator to print RsJson in compact format
* @param[out] out output stream
* @return same output stream passed as out parameter
*/
std::ostream& compactJSON(std::ostream &out);
/**
* Stream manipulator to print RsJson in human readable format
* @param[out] out output stream
* @return same output stream passed as out parameter
*/
std::ostream& prettyJSON(std::ostream &out);