Merging branches/v0.6-initdev into trunk.

These split at 6672 -> 7075, so quite a bit merge.
libretroshare compiles - but untested.
retroshare-gui needs GenCertDialog.ui and IdEditDialog.ui to be properly merged. (compile errors).
some plugins will be broken.
retroshare-nogui is untested.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7078 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2014-02-01 14:16:15 +00:00
commit c0738eec7f
407 changed files with 23716 additions and 50779 deletions

View file

@ -136,14 +136,14 @@ bool p3BanList::recvBanItem(RsBanListItem *item)
for(it = item->peerList.entries.begin(); it != item->peerList.entries.end(); it++)
{
// Order is important!.
updated = (addBanEntry(item->PeerId(), it->addr, it->level,
updated = (addBanEntry(item->PeerId(), it->addr.addr, it->level,
it->reason, it->age) || updated);
}
return updated;
}
/* overloaded from pqiNetAssistSharePeer */
void p3BanList::updatePeer(std::string /*id*/, struct sockaddr_in addr, int /*type*/, int /*reason*/, int age)
void p3BanList::updatePeer(std::string /*id*/, const struct sockaddr_storage &addr, int /*type*/, int /*reason*/, int age)
{
std::string ownId = mLinkMgr->getOwnId();
@ -160,7 +160,7 @@ void p3BanList::updatePeer(std::string /*id*/, struct sockaddr_in addr, int /*ty
}
bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in &addr, int level, uint32_t reason, uint32_t age)
bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_storage &addr, int level, uint32_t reason, uint32_t age)
{
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
@ -174,10 +174,10 @@ bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in
#endif
/* Only Accept it - if external address */
if (!isExternalNet(&(addr.sin_addr)))
if (!sockaddr_storage_isExternalNet(addr))
{
#ifdef DEBUG_BANLIST
std::cerr << "p3BanList::addBanEntry() Ignoring Non External Addr: " << rs_inet_ntoa(addr.sin_addr);
std::cerr << "p3BanList::addBanEntry() Ignoring Non External Addr: " << sockaddr_storage_iptostring(addr);
std::cerr << std::endl;
#endif
return false;
@ -197,8 +197,14 @@ bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in
updated = true;
}
std::map<uint32_t, BanListPeer>::iterator mit;
mit = it->second.mBanPeers.find(addr.sin_addr.s_addr);
// index is FAMILY + IP - the rest should be Zeros..
struct sockaddr_storage bannedaddr;
sockaddr_storage_clear(bannedaddr);
sockaddr_storage_copyip(bannedaddr, addr);
sockaddr_storage_setport(bannedaddr, 0);
std::map<struct sockaddr_storage, BanListPeer>::iterator mit;
mit = it->second.mBanPeers.find(bannedaddr);
if (mit == it->second.mBanPeers.end())
{
/* add in */
@ -208,7 +214,8 @@ bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in
blp.level = level;
blp.mTs = now - age;
it->second.mBanPeers[addr.sin_addr.s_addr] = blp;
it->second.mBanPeers[bannedaddr] = blp;
it->second.mLastUpdate = now;
updated = true;
}
@ -266,7 +273,7 @@ int p3BanList::condenseBanSources_locked()
std::cerr << std::endl;
#endif
std::map<uint32_t, BanListPeer>::const_iterator lit;
std::map<struct sockaddr_storage, BanListPeer>::const_iterator lit;
for(lit = it->second.mBanPeers.begin();
lit != it->second.mBanPeers.end(); lit++)
{
@ -276,7 +283,7 @@ int p3BanList::condenseBanSources_locked()
#ifdef DEBUG_BANLIST_CONDENSE
std::cerr << "p3BanList::condenseBanSources_locked()";
std::cerr << " Ignoring Out-Of-Date Entry for: ";
std::cerr << rs_inet_ntoa(lit->second.addr.sin_addr);
std::cerr << sockaddr_storage_iptostring(lit->second.addr);
std::cerr << std::endl;
#endif
continue;
@ -289,19 +296,25 @@ int p3BanList::condenseBanSources_locked()
lvl++;
}
struct sockaddr_storage bannedaddr;
sockaddr_storage_clear(bannedaddr);
sockaddr_storage_copyip(bannedaddr, lit->second.addr);
sockaddr_storage_setport(bannedaddr, 0);
/* check if it exists in the Set already */
std::map<uint32_t, BanListPeer>::iterator sit;
sit = mBanSet.find(lit->second.addr.sin_addr.s_addr);
std::map<struct sockaddr_storage, BanListPeer>::iterator sit;
sit = mBanSet.find(bannedaddr);
if ((sit == mBanSet.end()) || (lvl < sit->second.level))
{
BanListPeer bp = lit->second;
bp.level = lvl;
bp.addr.sin_port = 0;
mBanSet[lit->second.addr.sin_addr.s_addr] = bp;
sockaddr_storage_setport(bp.addr, 0);
mBanSet[bannedaddr] = bp;
#ifdef DEBUG_BANLIST_CONDENSE
std::cerr << "p3BanList::condenseBanSources_locked()";
std::cerr << " Added New Entry for: ";
std::cerr << rs_inet_ntoa(lit->second.addr.sin_addr);
std::cerr << sockaddr_storage_iptostring(bannedaddr);
std::cerr << std::endl;
#endif
}
@ -310,7 +323,7 @@ int p3BanList::condenseBanSources_locked()
#ifdef DEBUG_BANLIST_CONDENSE
std::cerr << "p3BanList::condenseBanSources_locked()";
std::cerr << " Merging Info for: ";
std::cerr << rs_inet_ntoa(lit->second.addr.sin_addr);
std::cerr << sockaddr_storage_iptostring(bannedaddr);
std::cerr << std::endl;
#endif
/* update if necessary */
@ -405,7 +418,7 @@ int p3BanList::sendBanSet(std::string peerid)
{
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
std::map<uint32_t, BanListPeer>::iterator it;
std::map<struct sockaddr_storage, BanListPeer>::iterator it;
for(it = mBanSet.begin(); it != mBanSet.end(); it++)
{
if (it->second.level >= RSBANLIST_SOURCE_FRIEND)
@ -414,7 +427,7 @@ int p3BanList::sendBanSet(std::string peerid)
}
RsTlvBanListEntry bi;
bi.addr = it->second.addr;
bi.addr.addr = it->second.addr;
bi.reason = it->second.reason;
bi.level = it->second.level;
bi.age = now - it->second.mTs;
@ -435,10 +448,10 @@ int p3BanList::printBanSet_locked(std::ostream &out)
time_t now = time(NULL);
std::map<uint32_t, BanListPeer>::iterator it;
std::map<struct sockaddr_storage, BanListPeer>::iterator it;
for(it = mBanSet.begin(); it != mBanSet.end(); it++)
{
out << "Ban: " << rs_inet_ntoa(it->second.addr.sin_addr);
out << "Ban: " << sockaddr_storage_iptostring(it->second.addr);
out << " Reason: " << it->second.reason;
out << " Level: " << it->second.level;
if (it->second.level > RSBANLIST_SOURCE_FRIEND)
@ -465,12 +478,12 @@ int p3BanList::printBanSources_locked(std::ostream &out)
out << " LastUpdate: " << now - it->second.mLastUpdate;
out << std::endl;
std::map<uint32_t, BanListPeer>::const_iterator lit;
std::map<struct sockaddr_storage, BanListPeer>::const_iterator lit;
for(lit = it->second.mBanPeers.begin();
lit != it->second.mBanPeers.end(); lit++)
{
out << "\t";
out << "Ban: " << rs_inet_ntoa(lit->second.addr.sin_addr);
out << "Ban: " << sockaddr_storage_iptostring(lit->second.addr);
out << " Reason: " << lit->second.reason;
out << " Level: " << lit->second.level;
out << " Age: " << now - lit->second.mTs;

View file

@ -42,7 +42,7 @@ class BanListPeer
{
public:
struct sockaddr_in addr;
struct sockaddr_storage addr;
uint32_t reason; // Dup Self, Dup Friend
int level; // LOCAL, FRIEND, FoF.
time_t mTs;
@ -54,7 +54,7 @@ class BanList
std::string mPeerId; /* from */
time_t mLastUpdate;
std::map<uint32_t, BanListPeer> mBanPeers;
std::map<struct sockaddr_storage, BanListPeer> mBanPeers;
};
@ -74,7 +74,7 @@ class p3BanList: /* public RsBanList, */ public p3Service, public pqiNetAssistPe
/***** overloaded from pqiNetAssistPeerShare *****/
virtual void updatePeer(std::string id, struct sockaddr_in addr, int type, int reason, int age);
virtual void updatePeer(std::string id, const struct sockaddr_storage &addr, int type, int reason, int age);
/***** overloaded from p3Service *****/
@ -93,7 +93,7 @@ class p3BanList: /* public RsBanList, */ public p3Service, public pqiNetAssistPe
bool processIncoming();
bool recvBanItem(RsBanListItem *item);
bool addBanEntry(const std::string &peerId, const struct sockaddr_in &addr,
bool addBanEntry(const std::string &peerId, const struct sockaddr_storage &addr,
int level, uint32_t reason, uint32_t age);
void sendBanLists();
int sendBanSet(std::string peerid);
@ -123,7 +123,7 @@ class p3BanList: /* public RsBanList, */ public p3Service, public pqiNetAssistPe
time_t mSentListTime;
std::map<std::string, BanList> mBanSources;
std::map<uint32_t, BanListPeer> mBanSet;
std::map<struct sockaddr_storage, BanListPeer> mBanSet;
p3LinkMgr *mLinkMgr;
p3NetMgr *mNetMgr;

View file

@ -1,404 +0,0 @@
/*
* libretroshare/src/services: p3Blogs.cc
*
* RetroShare C++ Interface.
*
* Copyright 2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "services/p3blogs.h"
#include "util/rsdir.h"
std::ostream &operator<<(std::ostream &out, const BlogInfo &info)
{
std::string name(info.blogName.begin(), info.blogName.end());
std::string desc(info.blogDesc.begin(), info.blogDesc.end());
out << "BlogInfo:";
out << std::endl;
out << "BlogId: " << info.blogId << std::endl;
out << "BlogName: " << name << std::endl;
out << "BlogDesc: " << desc << std::endl;
out << "BlogFlags: " << info.blogFlags << std::endl;
out << "Pop: " << info.pop << std::endl;
out << "LastPost: " << info.lastPost << std::endl;
return out;
}
std::ostream &operator<<(std::ostream &out, const BlogMsgSummary &info)
{
out << "BlogMsgSummary:";
out << std::endl;
out << "BlogId: " << info.blogId << std::endl;
return out;
}
std::ostream &operator<<(std::ostream &out, const BlogMsgInfo &info)
{
out << "BlogMsgInfo:";
out << std::endl;
out << "BlogId: " << info.blogId << std::endl;
return out;
}
RsBlogs *rsBlogs = NULL;
/* Blogs will be initially stored for 1 year
* remember 2^16 = 64K max units in store period.
* PUBPERIOD * 2^16 = max STORE PERIOD */
#define BLOG_STOREPERIOD (90*24*3600) /* 30 * 24 * 3600 - secs in a year */
#define BLOG_PUBPERIOD 600 /* 10 minutes ... (max = 455 days) */
p3Blogs::p3Blogs(uint16_t type, CacheStrapper *cs,
CacheTransfer *cft,
std::string srcdir, std::string storedir)
:p3GroupDistrib(type, cs, cft, srcdir, storedir, "",
CONFIG_TYPE_QBLOG, BLOG_STOREPERIOD, BLOG_PUBPERIOD)
{
return;
}
p3Blogs::~p3Blogs()
{
return;
}
/****************************************/
bool p3Blogs::blogsChanged(std::list<std::string> &blogIds)
{
return groupsChanged(blogIds);
}
bool p3Blogs::getBlogInfo(std::string cId, BlogInfo &ci)
{
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
/* extract details */
GroupInfo *gi = locked_getGroupInfo(cId);
if (!gi)
return false;
ci.blogId = gi->grpId;
ci.blogName = gi->grpName;
ci.blogDesc = gi->grpDesc;
ci.blogFlags = gi->flags;
ci.pop = gi->sources.size();
ci.lastPost = gi->lastPost;
ci.pngChanImage = gi->grpIcon.pngImageData;
if(ci.pngChanImage != NULL)
ci.pngImageLen = gi->grpIcon.imageSize;
else
ci.pngImageLen = 0;
return true;
}
bool p3Blogs::getBlogList(std::list<BlogInfo> &blogList)
{
std::list<std::string> grpIds;
std::list<std::string>::iterator it;
getAllGroupList(grpIds);
for(it = grpIds.begin(); it != grpIds.end(); it++)
{
BlogInfo ci;
if (getBlogInfo(*it, ci))
{
blogList.push_back(ci);
}
}
return true;
}
bool p3Blogs::getBlogMsgList(std::string cId, std::list<BlogMsgSummary> &msgs)
{
std::list<std::string> msgIds;
std::list<std::string>::iterator it;
getAllMsgList(cId, msgIds);
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
for(it = msgIds.begin(); it != msgIds.end(); it++)
{
/* get details */
RsDistribMsg *msg = locked_getGroupMsg(cId, *it);
RsBlogMsg *cmsg = dynamic_cast<RsBlogMsg *>(msg);
if (!cmsg)
continue;
BlogMsgSummary tis;
tis.blogId = msg->grpId;
tis.msgId = msg->msgId;
tis.ts = msg->timestamp;
/* the rest must be gotten from the derived Msg */
tis.subject = cmsg->subject;
tis.msg = cmsg->message;
msgs.push_back(tis);
}
return true;
}
bool p3Blogs::getBlogMessage(std::string fId, std::string mId, BlogMsgInfo &info)
{
std::list<std::string> msgIds;
std::list<std::string>::iterator it;
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
RsDistribMsg *msg = locked_getGroupMsg(fId, mId);
RsBlogMsg *cmsg = dynamic_cast<RsBlogMsg *>(msg);
if (!cmsg)
return false;
info.blogId = msg->grpId;
info.msgId = msg->msgId;
info.ts = msg->timestamp;
/* the rest must be gotten from the derived Msg */
info.subject = cmsg->subject;
info.msg = cmsg->message;
return true;
}
bool p3Blogs::BlogMessageSend(BlogMsgInfo &info)
{
RsBlogMsg *cmsg = new RsBlogMsg();
cmsg->grpId = info.blogId;
cmsg->subject = info.subject;
cmsg->message = info.msg;
cmsg->timestamp = time(NULL);
std::string msgId = publishMsg(cmsg, true);
return true;
}
bool p3Blogs::BlogMessageReply(BlogMsgInfo& reply){
// ensure it has a value
if(isReply(reply)){
std::cerr << "p3Blogs::BlogMessageReply()" << " This is not a reply " << std::endl;
return false;
}
// also check that msgId exists for group
return BlogMessageSend(reply);
}
bool p3Blogs::isReply(BlogMsgInfo& info){
// if replies list is empty then this is not a reply to a blog
return !info.msgIdReply.empty();
}
std::string p3Blogs::createBlog(std::wstring blogName, std::wstring blogDesc, uint32_t blogFlags,
unsigned char* pngImageData, uint32_t imageSize)
{
std::string id = createGroup(blogName, blogDesc, blogFlags, pngImageData, imageSize);
return id;
}
RsSerialType *p3Blogs::createSerialiser()
{
return new RsBlogSerialiser();
}
bool p3Blogs::locked_checkDistribMsg(RsDistribMsg *msg)
{
return true;
}
RsDistribGrp *p3Blogs::locked_createPublicDistribGrp(GroupInfo &info)
{
RsDistribGrp *grp = NULL; //new RsChannelGrp();
return grp;
}
RsDistribGrp *p3Blogs::locked_createPrivateDistribGrp(GroupInfo &info)
{
RsDistribGrp *grp = NULL; //new RsChannelGrp();
return grp;
}
bool p3Blogs::blogSubscribe(std::string cId, bool subscribe)
{
std::cerr << "p3Blogs::channelSubscribe() ";
std::cerr << cId;
std::cerr << std::endl;
return subscribeToGroup(cId, subscribe);
}
/***************************************************************************************/
/****************** Event Feedback (Overloaded form p3distrib) *************************/
/***************************************************************************************/
/* only download in the first week of channel
* older stuff can be manually downloaded.
*/
const uint32_t DOWNLOAD_PERIOD = 7 * 24 * 3600;
/* This is called when we receive a msg, and also recalled
*
*/
bool p3Blogs::locked_eventDuplicateMsg(GroupInfo *grp, RsDistribMsg *msg, const std::string& id, bool historical)
{
return true;
}
bool p3Blogs::locked_eventNewMsg(GroupInfo *grp, RsDistribMsg *msg, const std::string& id, bool historical)
{
std::string grpId = msg->grpId;
std::string msgId = msg->msgId;
std::string nullId;
std::cerr << "p3Blogs::locked_eventNewMsg() ";
std::cerr << " grpId: " << grpId;
std::cerr << " msgId: " << msgId;
std::cerr << " peerId: " << id;
std::cerr << std::endl;
if (!historical)
{
getPqiNotify()->AddFeedItem(RS_FEED_ITEM_BLOG_MSG, grpId, msgId, nullId);
}
/* request the files
* NB: This could result in duplicates.
* which must be handled by ft side.
*
* this is exactly what DuplicateMsg does.
* */
return locked_eventDuplicateMsg(grp, msg, id, historical);
}
void p3Blogs::locked_notifyGroupChanged(GroupInfo &grp, uint32_t flags, bool historical)
{
std::string grpId = grp.grpId;
std::string msgId;
std::string nullId;
std::cerr << "p3Blogs::locked_notifyGroupChanged() ";
std::cerr << grpId;
std::cerr << " flags:" << flags;
std::cerr << std::endl;
switch(flags)
{
case GRP_NEW_UPDATE:
std::cerr << "p3Blogs::locked_notifyGroupChanged() NEW UPDATE";
std::cerr << std::endl;
if (!historical)
{
getPqiNotify()->AddFeedItem(RS_FEED_ITEM_BLOG_NEW, grpId, msgId, nullId);
}
break;
case GRP_UPDATE:
std::cerr << "p3Blogs::locked_notifyGroupChanged() UPDATE";
std::cerr << std::endl;
if (!historical)
{
getPqiNotify()->AddFeedItem(RS_FEED_ITEM_BLOG_UPDATE, grpId, msgId, nullId);
}
break;
case GRP_LOAD_KEY:
std::cerr << "p3Blogs::locked_notifyGroupChanged() LOAD_KEY";
std::cerr << std::endl;
break;
case GRP_NEW_MSG:
std::cerr << "p3Blogs::locked_notifyGroupChanged() NEW MSG";
std::cerr << std::endl;
break;
case GRP_SUBSCRIBED:
std::cerr << "p3Blogs::locked_notifyGroupChanged() SUBSCRIBED";
std::cerr << std::endl;
break;
case GRP_UNSUBSCRIBED:
std::cerr << "p3Blogs::locked_notifyGroupChanged() UNSUBSCRIBED";
std::cerr << std::endl;
/* won't stop downloads... */
break;
default:
std::cerr << "p3Blogs::locked_notifyGroupChanged() Unknown DEFAULT";
std::cerr << std::endl;
break;
}
return p3GroupDistrib::locked_notifyGroupChanged(grp, flags);
}
//TODO: if you want to enable config saving and loading implement this
bool p3Blogs::childLoadList(std::list<RsItem* >& configSaves)
{
return true;
}
//TODO:
std::list<RsItem *> p3Blogs::childSaveList()
{
std::list<RsItem *> saveL;
return saveL;
}
/****************************************/

View file

@ -1,137 +0,0 @@
#ifndef RS_P3_BLOGS_INTERFACE_H
#define RS_P3_BLOGS_INTERFACE_H
/*
* libretroshare/src/services: p3blogs.h
*
* RetroShare C++ Interface.
*
* Copyright 2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "retroshare/rsblogs.h"
#include "retroshare/rsfiles.h"
#include "distrib/p3distrib.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rsblogitems.h"
/*!
* implements the blog interface using the distrib service. it allows users to send blogs using
* retroshare's cache service. its use
*/
class p3Blogs: public p3GroupDistrib, public RsBlogs
{
public:
/*!
* @param CacheStrapper needed to push blogs onto the cache service
* @param CacheTransfer maintains distrib servi
* @param srcdir
* @param storedir
*/
p3Blogs(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
std::string srcdir, std::string storedir);
virtual ~p3Blogs();
/****************************************/
/********* rsBlogs Interface ***********/
/**
* check if any of the blogs has been changed
* @param blogIds list blogs by ids to be checked
* @return false if changed and vice versa
*/
virtual bool blogsChanged(std::list<std::string> &blogIds);
/**
* creates a new blog
*/
virtual std::string createBlog(std::wstring blogName, std::wstring blogDesc, uint32_t blogFlags,
unsigned char* pngImageData, uint32_t imageSize);
/**
* @param cId the id for the blog
* @param BloogInfo blog information is stored here
*/
virtual bool getBlogInfo(std::string cId, BlogInfo &ci);
/**
* get list of blogs from the group peer belongs to
*/
virtual bool getBlogList(std::list<BlogInfo> &blogList);
/**
* Returns a list of all the messages sent
* @param cId group id
* @param msgs
*/
virtual bool getBlogMsgList(std::string cId, std::list<BlogMsgSummary> &msgs);
virtual bool getBlogMessage(std::string cId, std::string mId, BlogMsgInfo &msg);
virtual bool BlogMessageSend(BlogMsgInfo &info);
/**
* subscribes or unsubscribes peer to a blog message
* @param cId the id of the blog message peer wants to subscribe
* @param subscribe set to true to subscribe, false otherwise
*/
virtual bool blogSubscribe(std::string cId, bool subscribe);
/**
* send a reply to a blog msg, ensure msgIdReply has valid id to a message
*/
virtual bool BlogMessageReply(BlogMsgInfo &info);
/**
* check if a particular blog is a reply
* @return false if not a reply, true otherwise
*/
virtual bool isReply(BlogMsgInfo& info);
/***************************************************************************************/
/****************** Event Feedback (Overloaded form p3distrib) *************************/
/***************************************************************************************/
protected:
virtual void locked_notifyGroupChanged(GroupInfo &info, uint32_t flags, bool historical);
virtual bool locked_eventNewMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
virtual bool locked_eventDuplicateMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
/****************************************/
/********* Overloaded Functions *********/
virtual RsSerialType *createSerialiser();
virtual bool locked_checkDistribMsg(RsDistribMsg *msg);
virtual RsDistribGrp *locked_createPublicDistribGrp(GroupInfo &info);
virtual RsDistribGrp *locked_createPrivateDistribGrp(GroupInfo &info);
virtual bool childLoadList(std::list<RsItem* >& configSaves);
virtual std::list<RsItem *> childSaveList();
/****************************************/
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,130 +0,0 @@
#ifndef RS_P3_CHANNELS_INTERFACE_H
#define RS_P3_CHANNELS_INTERFACE_H
/*
* libretroshare/src/services: p3channels.h
*
* RetroShare C++ Interface.
*
* Copyright 2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "retroshare/rschannels.h"
#include "retroshare/rsfiles.h"
#include "distrib/p3distrib.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rschannelitems.h"
#define RS_CHAN_STATUS_MASK 0x000f
#define RS_CHAN_STATUS_AUTO_DL 0x0002
typedef std::map<std::string, uint32_t> statMap;
typedef std::map<std::string, statMap> chanStatMap;
//! Channels is a distributed 'feed' service
/*!
* Implementations of rschannels interface
* @see RsChannels for definition of implemented interface
*/
class p3Channels: public p3GroupDistrib, public RsChannels
{
public:
p3Channels(uint16_t type, CacheStrapper *cs, CacheTransfer *cft, RsFiles *files,
std::string srcdir, std::string storedir, std::string channelsdir);
virtual ~p3Channels();
/*!
* cleans up dowloaded files older than one month,
* should be called during shutdown of rs
*/
void cleanUpOldFiles();
/****************************************/
/********* rsChannels Interface ***********/
virtual bool channelsChanged(std::list<std::string> &chanIds);
virtual std::string createChannel(std::wstring chanName, std::wstring chanDesc, uint32_t chanFlags,
unsigned char* pngImageData, uint32_t size);
virtual bool getChannelInfo(const std::string &cId, ChannelInfo &ci);
virtual bool getChannelList(std::list<ChannelInfo> &chanList);
virtual bool getChannelMsgList(const std::string &cId, std::list<ChannelMsgSummary> &msgs);
virtual bool getChannelMessage(const std::string &cId, const std::string &mId, ChannelMsgInfo &msg);
virtual bool ChannelMessageSend(ChannelMsgInfo &info);
virtual bool setMessageStatus(const std::string& cId, const std::string& mId, const uint32_t status, const uint32_t statusMask);
virtual bool getMessageStatus(const std::string& cId, const std::string& mId, uint32_t& status);
virtual bool getMessageCount(const std::string &cId, unsigned int &newCount, unsigned int &unreadCount);
virtual bool channelSubscribe(const std::string &cId, bool subscribe, bool autoDl);
virtual bool channelExtraFileHash(const std::string &path, const std::string &chId, FileInfo& fInfo);
virtual bool channelExtraFileRemove(const std::string &hash, const std::string &chId);
virtual bool channelRestoreKeys(const std::string &chId);
virtual bool channelShareKeys(const std::string &chId, std::list<std::string>& peers);
virtual bool channelEditInfo(const std::string &chId, ChannelInfo &ci);
virtual void getPubKeysAvailableGrpIds(std::list<std::string>& grpIds);
virtual bool channelSetAutoDl(const std::string& chId, bool autoDl);
virtual bool channelGetAutoDl(const std::string& chId, bool& autoDl);
virtual bool channelSetDestinationDirectory(const std::string& chId,const std::string& dest_dir) ;
/***************************************************************************************/
/****************** Event Feedback (Overloaded form p3distrib) *************************/
/***************************************************************************************/
protected:
virtual void locked_notifyGroupChanged(GroupInfo &info, uint32_t flags, bool historical);
virtual bool locked_eventNewMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
virtual bool locked_eventDuplicateMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
/****************************************/
/********* Overloaded Functions *********/
virtual RsSerialType *createSerialiser();
virtual bool locked_checkDistribMsg(RsDistribMsg *msg);
virtual bool childLoadList(std::list<RsItem* >& configSaves);
virtual std::list<RsItem *> childSaveList();
/****************************************/
private:
void processChanReadStatus(RsChannelReadStatus* drs);
void addChannelReadStatusEntry(const std::string& cId);
void removeChannelReadStatusEntry(const std::string& cId);
RsFiles *mRsFiles;
std::string mChannelsDir;
std::list<RsItem *> saveList;
std::list<RsChannelReadStatus *> mReadStatus;
chanStatMap mMsgReadStatus;
statMap mChannelStatus;
std::map<std::string,std::string> mDestinationDirectories ;
};
#endif

View file

@ -128,8 +128,8 @@ int p3ChatService::tick()
if (visible_lobbies_tmp.size()==0){
last_req_chat_lobby_list = now-LOBBY_LIST_AUTO_UPDATE_TIME+MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ;
} else {
last_req_chat_lobby_list = now ;
}
last_req_chat_lobby_list = now ;
}
}
// Flush items that could not be sent, probably because of a Mutex protected zone.
@ -149,7 +149,7 @@ int p3ChatService::status()
/***************** Chat Stuff **********************/
int p3ChatService::sendPublicChat(const std::wstring &msg)
int p3ChatService::sendPublicChat(const std::string &msg)
{
/* go through all the peers */
@ -468,7 +468,7 @@ bool p3ChatService::isOnline(const std::string& id)
return true ;
}
bool p3ChatService::sendPrivateChat(const std::string &id, const std::wstring &msg)
bool p3ChatService::sendPrivateChat(const std::string &id, const std::string &msg)
{
// look into ID. Is it a peer, or a chat lobby?
@ -627,7 +627,7 @@ bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatLobbyMsgItem *ci)
if(it != _pendingPartialLobbyMessages.end())
{
#ifdef CHAT_DEBUG
std::cerr << " Pending message found. Aappending it." << std::endl;
std::cerr << " Pending message found. Appending it." << std::endl;
#endif
// Yes, there is. Add the item to the list of stored sub-items
@ -651,7 +651,7 @@ bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatLobbyMsgItem *ci)
#ifdef CHAT_DEBUG
std::cerr << " Message is complete ! Re-forming it and returning true." << std::endl;
#endif
std::wstring msg ;
std::string msg ;
uint32_t flags = 0 ;
for(uint32_t i=0;i<it->second.size();++i)
@ -705,6 +705,7 @@ void p3ChatService::receiveChatQueue()
while(NULL != (item=recvItem()))
handleIncomingItem(item) ;
}
class MsgCounter
{
public:
@ -809,7 +810,6 @@ void p3ChatService::handleIncomingItem(RsItem *item)
case RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE: handleFriendUnsubscribeLobby (dynamic_cast<RsChatLobbyUnsubscribeItem *>(item)) ; break ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: handleRecvChatLobbyListRequest(dynamic_cast<RsChatLobbyListRequestItem *>(item)) ; break ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: handleRecvChatLobbyList (dynamic_cast<RsChatLobbyListItem *>(item)) ; break ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated: handleRecvChatLobbyList (dynamic_cast<RsChatLobbyListItem_deprecated *>(item)) ; break ;
default:
{
@ -870,96 +870,8 @@ void p3ChatService::handleRecvChatLobbyListRequest(RsChatLobbyListRequestItem *c
std::cerr << " Sending list to " << clr->PeerId() << std::endl;
#endif
sendItem(item);
// *********** Also send an item in old formats. To be removed.
RsChatLobbyListItem_deprecated *itemd = new RsChatLobbyListItem_deprecated;
RsChatLobbyListItem_deprecated2 *itemd2 = new RsChatLobbyListItem_deprecated2;
for(uint32_t i=0;i<item->lobby_ids.size();++i)
if(item->lobby_privacy_levels[i] == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC)
{
itemd->lobby_ids.push_back(item->lobby_ids[i]) ;
itemd->lobby_names.push_back(item->lobby_names[i]) ;
itemd->lobby_counts.push_back(item->lobby_counts[i]) ;
itemd2->lobby_ids.push_back(item->lobby_ids[i]) ;
itemd2->lobby_names.push_back(item->lobby_names[i]) ;
itemd2->lobby_counts.push_back(item->lobby_counts[i]) ;
itemd2->lobby_topics.push_back(item->lobby_topics[i]) ;
}
itemd->PeerId(clr->PeerId()) ;
itemd2->PeerId(clr->PeerId()) ;
sendItem(itemd) ;
sendItem(itemd2) ;
// End of part to remove in future versions. *************
}
void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem_deprecated *item)
{
if(item->lobby_ids.size() > MAX_ALLOWED_LOBBIES_IN_LIST_WARNING)
std::cerr << "Warning: Peer " << item->PeerId() << "(" << rsPeers->getPeerName(item->PeerId()) << ") is sending a lobby list of " << item->lobby_ids.size() << " lobbies. This is unusual, and probably a attempt to crash you." << std::endl;
{
time_t now = time(NULL) ;
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
for(uint32_t i=0;i<item->lobby_ids.size() && i < MAX_ALLOWED_LOBBIES_IN_LIST_WARNING;++i)
{
VisibleChatLobbyRecord& rec(_visible_lobbies[item->lobby_ids[i]]) ;
rec.lobby_id = item->lobby_ids[i] ;
rec.lobby_name = item->lobby_names[i] ;
rec.participating_friends.insert(item->PeerId()) ;
if(_should_reset_lobby_counts)
rec.total_number_of_peers = item->lobby_counts[i] ;
else
rec.total_number_of_peers = std::max(rec.total_number_of_peers,item->lobby_counts[i]) ;
rec.last_report_time = now ;
rec.lobby_privacy_level = RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC ;
}
}
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
_should_reset_lobby_counts = false ;
}
void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem_deprecated2 *item)
{
if(item->lobby_ids.size() > MAX_ALLOWED_LOBBIES_IN_LIST_WARNING)
std::cerr << "Warning: Peer " << item->PeerId() << "(" << rsPeers->getPeerName(item->PeerId()) << ") is sending a lobby list of " << item->lobby_ids.size() << " lobbies. This is unusual, and probably a attempt to crash you." << std::endl;
{
time_t now = time(NULL) ;
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
for(uint32_t i=0;i<item->lobby_ids.size() && i < MAX_ALLOWED_LOBBIES_IN_LIST_WARNING;++i)
{
VisibleChatLobbyRecord& rec(_visible_lobbies[item->lobby_ids[i]]) ;
rec.lobby_id = item->lobby_ids[i] ;
rec.lobby_name = item->lobby_names[i] ;
rec.lobby_topic = item->lobby_topics[i] ;
rec.participating_friends.insert(item->PeerId()) ;
if(_should_reset_lobby_counts)
rec.total_number_of_peers = item->lobby_counts[i] ;
else
rec.total_number_of_peers = std::max(rec.total_number_of_peers,item->lobby_counts[i]) ;
rec.last_report_time = now ;
rec.lobby_privacy_level = RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC ;
}
}
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
_should_reset_lobby_counts = false ;
}
void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem *item)
{
if(item->lobby_ids.size() > MAX_ALLOWED_LOBBIES_IN_LIST_WARNING)
@ -1175,10 +1087,9 @@ bool p3ChatService::checkForMessageSecurity(RsChatMsgItem *ci)
// Remove too big messages
if (ci->message.length() > 6000 && (ci->chatFlags & RS_CHAT_FLAG_LOBBY))
{
wchar_t tmp[300];
mbstowcs(tmp, rsPeers->getPeerName(ci->PeerId()).c_str(), 299);
ci->message = std::wstring(L"**** Security warning: Message bigger than 6000 characters, forwarded to you by ") + tmp + L", dropped. ****";
ci->message = "**** Security warning: Message bigger than 6000 characters, forwarded to you by ";
ci->message += rsPeers->getPeerName(ci->PeerId());
ci->message += ", dropped. ****";
return false;
}
@ -1212,23 +1123,18 @@ bool p3ChatService::checkForMessageSecurity(RsChatMsgItem *ci)
// https://en.wikipedia.org/wiki/Billion_laughs
// This should be done for all incoming HTML messages (also in forums
// etc.) so this should be a function in some other file.
wchar_t tmp[10];
mbstowcs(tmp, "<!", 9);
if (ci->message.find(tmp) != std::string::npos)
if (ci->message.find("<!") != std::string::npos)
{
// Drop any message with "<!doctype" or "<!entity"...
// TODO: check what happens with partial messages
//
std::wcout << "handleRecvChatMsgItem: " << ci->message << std::endl;
std::wcout << "**********" << std::endl;
std::wcout << "********** entity attack by " << ci->PeerId().c_str() << std::endl;
std::wcout << "**********" << std::endl;
std::cout << "handleRecvChatMsgItem: " << ci->message << std::endl;
std::cout << "**********" << std::endl;
std::cout << "********** entity attack by " << ci->PeerId().c_str() << std::endl;
std::cout << "**********" << std::endl;
wchar_t tmp2[300];
mbstowcs(tmp2, rsPeers->getPeerName(ci->PeerId()).c_str(), 299);
ci->message = std::wstring(L"**** This message (from peer id ") + tmp2 + L") has been removed because it contains the string \"<!\".****" ;
ci->message = "**** This message (from peer id " + rsPeers->getPeerName(ci->PeerId()) + ") has been removed because it contains the string \"<!\".****" ;
return false;
}
// For a future whitelist:
@ -1365,8 +1271,9 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci)
ci->chatFlags |= RS_CHAT_FLAG_AVATAR_AVAILABLE ;
}
std::string message;
librs::util::ConvertUtf16ToUtf8(ci->message, message);
std::string message = ci->message;
//librs::util::ConvertUtf16ToUtf8(ci->message, message);
if (ci->chatFlags & RS_CHAT_FLAG_PRIVATE) {
/* notify private chat message */
RsServer::notify()->AddPopupMessage(popupChatFlag, ci->PeerId(), name, message);
@ -1910,7 +1817,7 @@ void p3ChatService::sendAvatarJpegData(const std::string& peer_id)
RsChatAvatarItem *ci = makeOwnAvatarItem();
ci->PeerId(peer_id);
// take avatar, and embed it into a std::wstring.
// take avatar, and embed it into a std::string.
//
#ifdef CHAT_DEBUG
std::cerr << "p3ChatService::sending avatar image to peer" << peer_id << ", image size = " << ci->image_size << std::endl ;
@ -2374,7 +2281,7 @@ bool p3ChatService::locked_initLobbyBouncableObject(const ChatLobbyId& lobby_id,
return true ;
}
bool p3ChatService::sendLobbyChat(const std::string &id, const std::wstring& msg, const ChatLobbyId& lobby_id)
bool p3ChatService::sendLobbyChat(const std::string &id, const std::string& msg, const ChatLobbyId& lobby_id)
{
#ifdef CHAT_DEBUG
std::cerr << "Sending chat lobby message to lobby " << std::hex << lobby_id << std::dec << std::endl;
@ -2697,7 +2604,7 @@ bool p3ChatService::acceptLobbyInvite(const ChatLobbyId& lobby_id)
item->lobby_id = entry.lobby_id ;
item->msg_id = 0 ;
item->nick = "Lobby management" ;
item->message = std::wstring(L"Welcome to chat lobby") ;
item->message = std::string("Welcome to chat lobby") ;
item->PeerId(entry.virtual_peer_id) ;
item->chatFlags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_LOBBY ;

View file

@ -70,14 +70,14 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor, publi
/*!
* public chat sent to all peers
*/
int sendPublicChat(const std::wstring &msg);
int sendPublicChat(const std::string &msg);
/********* RsMsgs ***********/
/*!
* chat is sent to specifc peer
* @param id peer to send chat msg to
*/
bool sendPrivateChat(const std::string &id, const std::wstring &msg);
bool sendPrivateChat(const std::string &id, const std::string &msg);
/*!
* can be used to send 'immediate' status msgs, these status updates are meant for immediate use by peer (not saved by rs)
@ -226,8 +226,6 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor, publi
void handleRecvChatAvatarItem(RsChatAvatarItem *item) ;
void handleRecvChatLobbyListRequest(RsChatLobbyListRequestItem *item) ;
void handleRecvChatLobbyList(RsChatLobbyListItem *item) ;
void handleRecvChatLobbyList(RsChatLobbyListItem_deprecated *item) ;
void handleRecvChatLobbyList(RsChatLobbyListItem_deprecated2 *item) ;
void handleRecvChatLobbyEventItem(RsChatLobbyEventItem *item) ;
/// Checks that the lobby object is not flooding a lobby.
@ -249,7 +247,7 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor, publi
/// receive and handle chat lobby item
bool recvLobbyChat(RsChatLobbyMsgItem*,const std::string& src_peer_id) ;
bool sendLobbyChat(const std::string &id, const std::wstring&, const ChatLobbyId&) ;
bool sendLobbyChat(const std::string &id, const std::string&, const ChatLobbyId&) ;
void handleRecvLobbyInvite(RsChatLobbyInviteItem*) ;
void checkAndRedirectMsgToLobby(RsChatMsgItem*) ;
void handleConnectionChallenge(RsChatLobbyConnectChallengeItem *item) ;

File diff suppressed because it is too large Load diff

View file

@ -1,178 +0,0 @@
/*
* libretroshare/src/services: p3disc.h
*
* Services for RetroShare.
*
* Copyright 2004-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef MRK_PQI_AUTODISC_H
#define MRK_PQI_AUTODISC_H
// The AutoDiscovery Class
#include <string>
#include <list>
// system specific network headers
#include "pqi/pqinetwork.h"
#include "pqi/pqi.h"
#include "pqi/pqipersongrp.h"
class p3ConnectMgr;
#include "pqi/pqimonitor.h"
#include "serialiser/rsdiscitems.h"
#include "services/p3service.h"
#include "pqi/authgpg.h"
class autoserver
{
public:
autoserver()
:ts(0), discFlags(0) { return;}
std::string id;
struct sockaddr_in localAddr;
struct sockaddr_in remoteAddr;
time_t ts;
uint32_t discFlags;
};
class autoneighbour: public autoserver
{
public:
autoneighbour()
:autoserver(), authoritative(false) {}
bool authoritative;
bool validAddrs;
std::map<std::string, autoserver> neighbour_of;
};
class p3PeerMgr;
class p3LinkMgr;
class p3NetMgr;
class p3disc: public p3Service, public pqiMonitor, public p3Config, public AuthGPGService
{
public:
p3disc(p3PeerMgr *pm, p3LinkMgr *lm, p3NetMgr *nm, pqipersongrp *persGrp);
/************* from pqiMonitor *******************/
virtual void statusChange(const std::list<pqipeer> &plist);
/************* from pqiMonitor *******************/
int tick();
/* GUI requires access */
bool potentialGPGproxies(const std::string& id, std::list<std::string> &proxyGPGIds);
bool potentialproxies(const std::string& id, std::list<std::string> &proxyIds);
void getversions(std::map<std::string, std::string> &versions);
void getWaitingDiscCount(unsigned int *sendCount, unsigned int *recvCount);
/************* from AuthGPService ****************/
virtual AuthGPGOperation *getGPGOperation();
virtual void setGPGOperation(AuthGPGOperation *operation);
protected:
/*****************************************************************/
/*********************** p3config ******************************/
/* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser();
virtual bool saveList(bool &cleanup, std::list<RsItem *>&);
virtual bool loadList(std::list<RsItem *>& load);
/*****************************************************************/
private:
void sendAllInfoToJustConnectedPeer(const std::string &id);
void sendJustConnectedPeerInfoToAllPeer(const std::string &id);
/* Network Output */
//void sendOwnDetails(std::string to);
void sendOwnVersion(std::string to);
RsDiscReply *createDiscReply(const std::string &to, const std::string &about);
//void sendPeerIssuer(std::string to, std::string about);
void sendHeartbeat(std::string to);
void askInfoToAllPeers(std::string about);
/* Network Input */
int handleIncoming();
void recvAskInfo(RsDiscAskInfo *item);
void recvPeerDetails(RsDiscReply *item, const std::string &certGpgId);
//void recvPeerIssuerMsg(RsDiscIssuer *item);
void recvPeerVersionMsg(RsDiscVersion *item);
void recvHeartbeatMsg(RsDiscHeartbeat *item);
void recvDiscReply(RsDiscReply *dri);
void removeFriend(std::string ssl_id); //keep tracks of removed friend so we're not gonna add them again immediately
/* handle network shape */
int addDiscoveryData(const std::string& fromId, const std::string& aboutId,
const std::string& fromGPGId,const std::string& aboutGPGId,
const struct sockaddr_in& laddr, const struct sockaddr_in& raddr,
uint32_t flags, time_t ts,bool& new_info);
//int idServers();
private:
p3PeerMgr *mPeerMgr;
p3LinkMgr *mLinkMgr;
p3NetMgr *mNetMgr;
pqipersongrp *mPqiPersonGrp;
/* data */
RsMutex mDiscMtx;
time_t mLastSentHeartbeatTime;
bool mDiscEnabled;
//std::map<std::string, time_t> deletedSSLFriendsIds;
std::map<std::string, std::list<std::string> > mSendIdList;
std::list<RsDiscReply*> mPendingDiscReplyInList;
// Neighbors at the gpg level.
std::map<std::string,std::set<std::string> > gpg_neighbors ;
// Original mapping.
std::map<std::string, autoneighbour> neighbours;
// Rs Version.
std::map<std::string, std::string> versions;
};
#endif // MRK_PQI_AUTODISC_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,151 @@
/*
* libretroshare/src/services: p3discovery2.h
*
* Services for RetroShare.
*
* Copyright 2004-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef MRK_SERVICES_DISCOVERY2_H
#define MRK_SERVICES_DISCOVERY2_H
// Discovery2: Improved discovery service.
#include "retroshare/rsdisc.h"
#include "pqi/p3peermgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/p3netmgr.h"
#include "pqi/pqimonitor.h"
#include "serialiser/rsdiscovery2items.h"
#include "services/p3service.h"
#include "pqi/authgpg.h"
typedef std::string PGPID;
typedef std::string SSLID;
class DiscSslInfo
{
public:
DiscSslInfo() { mDiscStatus = 0; }
uint16_t mDiscStatus;
};
class DiscPeerInfo
{
public:
DiscPeerInfo() {}
std::string mVersion;
//uint32_t mStatus;
};
class DiscPgpInfo
{
public:
DiscPgpInfo() {}
void mergeFriendList(const std::list<PGPID> &friends);
//PGPID mPgpId;
std::set<PGPID> mFriendSet;
std::map<SSLID, DiscSslInfo> mSslIds;
};
class p3discovery2: public RsDisc, public p3Service, public pqiMonitor, public AuthGPGService
{
public:
p3discovery2(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr, p3NetMgr *netMgr);
virtual ~p3discovery2();
/************* from pqiMonitor *******************/
virtual void statusChange(const std::list<pqipeer> &plist);
/************* from pqiMonitor *******************/
int tick();
/* external interface */
virtual bool getDiscFriends(const std::string &id, std::list<std::string> &friends);
virtual bool getDiscPgpFriends(const std::string &pgpid, std::list<std::string> &gpg_friends);
virtual bool getPeerVersion(const std::string &id, std::string &version);
virtual bool getWaitingDiscCount(unsigned int *sendCount, unsigned int *recvCount);
/************* from AuthGPService ****************/
virtual AuthGPGOperation *getGPGOperation();
virtual void setGPGOperation(AuthGPGOperation *operation);
private:
PGPID getPGPId(const SSLID &id);
int handleIncoming();
void updatePgpFriendList();
void addFriend(const SSLID &sslId);
void removeFriend(const SSLID &sslId);
void updatePeerAddresses(const RsDiscContactItem *item);
void updatePeerAddressList(const RsDiscContactItem *item);
void sendOwnContactInfo(const SSLID &sslid);
void recvOwnContactInfo(const SSLID &fromId, const RsDiscContactItem *item);
void sendPGPList(const SSLID &toId);
void processPGPList(const SSLID &fromId, const RsDiscPgpListItem *item);
void processContactInfo(const SSLID &fromId, const RsDiscContactItem *info);
void requestPGPCertificate(const PGPID &aboutId, const SSLID &toId);
void recvPGPCertificateRequest(const SSLID &fromId, const RsDiscPgpListItem *item);
void sendPGPCertificate(const PGPID &aboutId, const SSLID &toId);
void recvPGPCertificate(const SSLID &fromId, RsDiscPgpCertItem *item);
bool setPeerVersion(const SSLID &peerId, const std::string &version);
private:
p3PeerMgr *mPeerMgr;
p3LinkMgr *mLinkMgr;
p3NetMgr *mNetMgr;
/* data */
RsMutex mDiscMtx;
void updatePeers_locked(const SSLID &aboutId);
void sendContactInfo_locked(const PGPID &aboutId, const SSLID &toId);
time_t mLastPgpUpdate;
std::map<PGPID, DiscPgpInfo> mFriendList;
std::map<SSLID, DiscPeerInfo> mLocationMap;
std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertInList;
std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertOutList;
};
#endif // MRK_SERVICES_DISCOVERY2_H

View file

@ -1,816 +0,0 @@
/*
* libretroshare/src/services: rsforums.cc
*
* RetroShare C++ Interface.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "services/p3forums.h"
#include "pqi/authssl.h"
#include "util/rsdir.h"
#include "rsserver/p3face.h"
uint32_t convertToInternalFlags(uint32_t extFlags);
uint32_t convertToExternalFlags(uint32_t intFlags);
std::ostream &operator<<(std::ostream &out, const ForumInfo &info)
{
std::string name(info.forumName.begin(), info.forumName.end());
std::string desc(info.forumDesc.begin(), info.forumDesc.end());
out << "ForumInfo:";
out << std::endl;
out << "ForumId: " << info.forumId << std::endl;
out << "ForumName: " << name << std::endl;
out << "ForumDesc: " << desc << std::endl;
out << "ForumFlags: " << info.forumFlags << std::endl;
out << "Pop: " << info.pop << std::endl;
out << "LastPost: " << info.lastPost << std::endl;
return out;
}
std::ostream &operator<<(std::ostream &out, const ThreadInfoSummary &/*info*/)
{
out << "ThreadInfoSummary:";
out << std::endl;
//out << "ForumId: " << forumId << std::endl;
//out << "ThreadId: " << threadId << std::endl;
return out;
}
std::ostream &operator<<(std::ostream &out, const ForumMsgInfo &/*info*/)
{
out << "ForumMsgInfo:";
out << std::endl;
//out << "ForumId: " << forumId << std::endl;
//out << "ThreadId: " << threadId << std::endl;
return out;
}
RsForums *rsForums = NULL;
/* Forums will be initially stored for 1 year
* remember 2^16 = 64K max units in store period.
* PUBPERIOD * 2^16 = max STORE PERIOD */
#define FORUM_STOREPERIOD (365*24*3600) /* 365 * 24 * 3600 - secs in a year */
#define FORUM_PUBPERIOD 600 /* 10 minutes ... (max = 455 days) */
p3Forums::p3Forums(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
std::string srcdir, std::string storedir, std::string forumDir)
:p3GroupDistrib(type, cs, cft, srcdir, storedir, forumDir,
CONFIG_TYPE_FORUMS, FORUM_STOREPERIOD, FORUM_PUBPERIOD),
mForumsDir(forumDir)
{
/* create chanDir */
if (!RsDirUtil::checkCreateDirectory(mForumsDir)) {
std::cerr << "p3Channels() Failed to create forums Directory: " << mForumsDir << std::endl;
}
return;
}
p3Forums::~p3Forums()
{
return;
}
/****************************************/
bool p3Forums::forumsChanged(std::list<std::string> &forumIds)
{
return groupsChanged(forumIds);
}
bool p3Forums::getForumInfo(const std::string &fId, ForumInfo &fi)
{
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
/* extract details */
GroupInfo *gi = locked_getGroupInfo(fId);
if (!gi)
return false;
fi.forumId = gi->grpId;
fi.forumName = gi->grpName;
fi.forumDesc = gi->grpDesc;
fi.forumFlags = gi->grpFlags;
fi.subscribeFlags = gi->flags;
fi.pop = gi->sources.size();
fi.lastPost = gi->lastPost;
return true;
}
/*!
* allows peers to change information for the forum:
* can only change name and descriptions
*
*/
bool p3Forums::setForumInfo(const std::string &fId, ForumInfo &fi)
{
GroupInfo gi;
RsStackMutex stack(distribMtx);
gi.grpName = fi.forumName;
gi.grpDesc = fi.forumDesc;
return locked_editGroup(fId, gi);
}
bool p3Forums::getForumList(std::list<ForumInfo> &forumList)
{
std::list<std::string> grpIds;
std::list<std::string>::iterator it;
getAllGroupList(grpIds);
for(it = grpIds.begin(); it != grpIds.end(); it++)
{
ForumInfo fi;
if (getForumInfo(*it, fi))
{
forumList.push_back(fi);
}
}
return true;
}
bool p3Forums::getForumThreadList(const std::string &fId, std::list<ThreadInfoSummary> &msgs)
{
std::list<std::string> msgIds;
std::list<std::string>::iterator it;
getParentMsgList(fId, "", msgIds);
std::list<std::string> msgDummyIds;
getDummyParentMsgList(fId, "", msgDummyIds);
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
for(it = msgIds.begin(); it != msgIds.end(); it++)
{
/* get details */
RsDistribMsg *msg = locked_getGroupMsg(fId, *it);
RsForumMsg *fmsg = dynamic_cast<RsForumMsg *>(msg);
if (!fmsg)
continue;
ThreadInfoSummary tis;
tis.forumId = msg->grpId;
tis.msgId = msg->msgId;
tis.parentId = ""; // always NULL (see request)
tis.threadId = msg->msgId; // these are the thread heads!
tis.ts = msg->timestamp;
tis.childTS = msg->childTS;
/* the rest must be gotten from the derived Msg */
tis.title = fmsg->title;
tis.msg = fmsg->msg;
msgs.push_back(tis);
}
// now add dummy msgs.
for(it = msgDummyIds.begin(); it != msgDummyIds.end(); it++)
{
/* get details */
RsDistribDummyMsg *msg = locked_getGroupDummyMsg(fId, *it);
ThreadInfoSummary tis;
tis.forumId = fId;
tis.msgId = msg->msgId;
tis.parentId = ""; // always NULL (see request)
tis.threadId = msg->msgId; // these are the thread heads!
tis.ts = msg->timestamp;
tis.childTS = msg->childTS;
/* dummy msg */
tis.title = L"[ ... Missing Message ... ]";
tis.msg = L"Placeholder for missing Message";
tis.msgflags |= RS_DISTRIB_MISSING_MSG;
msgs.push_back(tis);
}
return true;
}
bool p3Forums::getForumThreadMsgList(const std::string &fId, const std::string &pId, std::list<ThreadInfoSummary> &msgs)
{
std::list<std::string> msgIds;
std::list<std::string>::iterator it;
getParentMsgList(fId, pId, msgIds);
std::list<std::string> msgDummyIds;
getDummyParentMsgList(fId, pId, msgDummyIds);
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
for(it = msgIds.begin(); it != msgIds.end(); it++)
{
/* get details */
RsDistribMsg *msg = locked_getGroupMsg(fId, *it);
RsForumMsg *fmsg = dynamic_cast<RsForumMsg *>(msg);
if (!fmsg)
continue;
ThreadInfoSummary tis;
tis.forumId = msg->grpId;
tis.msgId = msg->msgId;
tis.parentId = msg->parentId;
tis.threadId = msg->threadId;
tis.ts = msg->timestamp;
tis.childTS = msg->childTS;
/* the rest must be gotten from the derived Msg */
tis.title = fmsg->title;
tis.msg = fmsg->msg;
if (fmsg->personalSignature.keyId.empty() == false) {
tis.msgflags |= RS_DISTRIB_AUTHEN_REQ;
}
msgs.push_back(tis);
}
// now add dummy msgs.
for(it = msgDummyIds.begin(); it != msgDummyIds.end(); it++)
{
/* get details */
RsDistribDummyMsg *msg = locked_getGroupDummyMsg(fId, *it);
ThreadInfoSummary tis;
tis.forumId = fId;
tis.msgId = msg->msgId;
tis.parentId = msg->parentId;
tis.threadId = msg->threadId;
tis.ts = msg->timestamp;
tis.childTS = msg->childTS;
/* dummy msg */
tis.title = L"[ ... Missing Message ... ]";
tis.msg = L"Placeholder for missing Message";
tis.msgflags |= RS_DISTRIB_MISSING_MSG;
msgs.push_back(tis);
}
return true;
}
bool p3Forums::getForumMessage(const std::string &fId, const std::string &mId, ForumMsgInfo &info)
{
processCacheOptReq(fId);
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
RsDistribMsg *msg = locked_getGroupMsg(fId, mId);
RsForumMsg *fmsg = dynamic_cast<RsForumMsg *>(msg);
if (!fmsg)
{
/* try for a dummy msg */
RsDistribDummyMsg *dmsg = locked_getGroupDummyMsg(fId, mId);
if (!dmsg)
return false;
/* fill in the dummy msg */
info.forumId = fId;
info.msgId = dmsg->msgId;
info.parentId = dmsg->parentId;
info.threadId = dmsg->threadId;
info.ts = dmsg->timestamp;
info.childTS = dmsg->childTS;
info.title = L"[ ... Missing Message ... ]";
info.msg = L"Placeholder for missing Message";
info.msgflags |= RS_DISTRIB_MISSING_MSG;
info.srcId = "";
return true;
}
info.forumId = msg->grpId;
info.msgId = msg->msgId;
info.parentId = msg->parentId;
info.threadId = msg->threadId;
info.ts = msg->timestamp;
info.childTS = msg->childTS;
/* the rest must be gotten from the derived Msg */
info.title = fmsg->title;
info.msg = fmsg->msg;
// should only use actual signature ....
//info.srcId = fmsg->srcId;
info.srcId = fmsg->personalSignature.keyId;
if (fmsg->personalSignature.keyId.empty() == false) {
info.msgflags |= RS_DISTRIB_AUTHEN_REQ;
}
return true;
}
bool p3Forums::ForumMessageSend(ForumMsgInfo &info)
{
bool signIt = (info.msgflags == RS_DISTRIB_AUTHEN_REQ);
std::string mId = createForumMsg(info.forumId, info.parentId,
info.title, info.msg, signIt);
if (mId.empty()) {
return false;
}
// return id
info.msgId = mId;
return setMessageStatus(info.forumId, mId, FORUM_MSG_STATUS_READ | FORUM_MSG_STATUS_LOAD_EMBEDDED_IMAGES, FORUM_MSG_STATUS_MASK);
}
bool p3Forums::setMessageStatus(const std::string& fId,const std::string& mId,const uint32_t status, const uint32_t statusMask)
{
bool changed = false;
uint32_t newStatus = 0;
{
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
std::map<std::string, RsForumReadStatus*>::iterator mit = mReadStatus.find(fId);
if (mit != mReadStatus.end())
{
RsForumReadStatus* rsi = mit->second;
uint32_t oldStatus = rsi->msgReadStatus[mId];
rsi->msgReadStatus[mId] &= ~statusMask;
rsi->msgReadStatus[mId] |= (status & statusMask);
newStatus = rsi->msgReadStatus[mId];
if (oldStatus != newStatus) {
changed = true;
}
} else {
// if forum id does not exist create one
RsForumReadStatus* rsi = new RsForumReadStatus();
rsi->forumId = fId;
rsi->msgReadStatus[mId] = status & statusMask;
mReadStatus[fId] = rsi;
mSaveList.push_back(rsi);
newStatus = rsi->msgReadStatus[mId];
changed = true;
}
IndicateConfigChanged();
} /******* UNLOCKED ********/
if (changed) {
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_MOD);
RsServer::notify()->notifyForumMsgReadSatusChanged(fId, mId, newStatus);
}
return true;
}
bool p3Forums::getMessageStatus(const std::string& fId, const std::string& mId, uint32_t& status)
{
status = 0;
RsStackMutex stack(distribMtx);
std::map<std::string, RsForumReadStatus*>::iterator fit = mReadStatus.find(fId);
if (fit == mReadStatus.end())
{
return false;
}
std::map<std::string, uint32_t >::iterator rit = fit->second->msgReadStatus.find(mId);
if(rit != fit->second->msgReadStatus.end())
{
status = rit->second;
return true;
}
return false;
}
bool p3Forums::forumRestoreKeys(const std::string& fIds)
{
return p3GroupDistrib::restoreGrpKeys(fIds);
}
std::string p3Forums::createForum(const std::wstring &forumName, const std::wstring &forumDesc, uint32_t forumFlags)
{
std::string id = createGroup(forumName, forumDesc,
convertToInternalFlags(forumFlags), NULL, 0);
return id;
}
std::string p3Forums::createForumMsg(std::string fId, std::string pId,
std::wstring title, std::wstring msg, bool signIt)
{
RsForumMsg *fmsg = new RsForumMsg();
fmsg->grpId = fId;
fmsg->parentId = pId;
processCacheOptReq(fId);
{
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
RsDistribMsg *msg = locked_getGroupMsg(fId, pId);
if (!msg)
{
fmsg->parentId = "";
fmsg->threadId = "";
}
else
{
if (msg->parentId == "")
{
fmsg->threadId = fmsg->parentId;
}
else
{
fmsg->threadId = msg->threadId;
}
}
}
fmsg->title = title;
fmsg->msg = msg;
if (signIt)
{
fmsg->srcId = AuthSSL::getAuthSSL()->OwnId();
}
fmsg->timestamp = time(NULL);
std::string msgId = publishMsg(fmsg, signIt);
if (msgId.empty()) {
delete(fmsg);
}
return msgId;
}
RsSerialType *p3Forums::createSerialiser()
{
return new RsForumSerialiser();
}
bool p3Forums::locked_checkDistribMsg(RsDistribMsg */*msg*/)
{
return true;
}
RsDistribGrp *p3Forums::locked_createPublicDistribGrp(GroupInfo &/*info*/)
{
RsDistribGrp *grp = NULL; //new RsForumGrp();
return grp;
}
RsDistribGrp *p3Forums::locked_createPrivateDistribGrp(GroupInfo &/*info*/)
{
RsDistribGrp *grp = NULL; //new RsForumGrp();
return grp;
}
uint32_t convertToInternalFlags(uint32_t extFlags)
{
return extFlags;
}
uint32_t convertToExternalFlags(uint32_t intFlags)
{
return intFlags;
}
bool p3Forums::forumSubscribe(const std::string &fId, bool subscribe)
{
return subscribeToGroup(fId, subscribe);
}
bool p3Forums::getMessageCount(const std::string &fId, unsigned int &newCount, unsigned int &unreadCount)
{
newCount = 0;
unreadCount = 0;
std::list<std::string> grpIds;
if (fId.empty()) {
// count all messages of all subscribed forums
getAllGroupList(grpIds);
} else {
// count all messages of one forum
grpIds.push_back(fId);
}
std::list<std::string>::iterator git;
for (git = grpIds.begin(); git != grpIds.end(); git++) {
std::string fId = *git;
uint32_t grpFlags;
{
// only flag is needed
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
GroupInfo *gi = locked_getGroupInfo(fId);
if (gi == NULL) {
return false;
}
grpFlags = gi->flags;
} /******* UNLOCKED ********/
if (grpFlags & (RS_DISTRIB_ADMIN | RS_DISTRIB_SUBSCRIBED)) {
std::list<std::string> msgIds;
if (getAllMsgList(fId, msgIds)) {
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
std::map<std::string, RsForumReadStatus*>::iterator fit = mReadStatus.find(fId);
if (fit == mReadStatus.end()) {
// no status available -> all messages are new
newCount += msgIds.size();
unreadCount += msgIds.size();
continue;
}
std::list<std::string>::iterator mit;
for (mit = msgIds.begin(); mit != msgIds.end(); mit++) {
std::map<std::string, uint32_t >::iterator rit = fit->second->msgReadStatus.find(*mit);
if (rit == fit->second->msgReadStatus.end()) {
// no status available -> message is new
newCount++;
unreadCount++;
continue;
}
if (rit->second & FORUM_MSG_STATUS_READ) {
// message is not new
if (rit->second & FORUM_MSG_STATUS_UNREAD_BY_USER) {
// message is unread
unreadCount++;
}
} else {
newCount++;
unreadCount++;
}
}
} /******* UNLOCKED ********/
}
}
return true;
}
/***************************************************************************************/
/****************** Event Feedback (Overloaded form p3distrib) *************************/
/***************************************************************************************/
void p3Forums::locked_notifyGroupChanged(GroupInfo &grp, uint32_t flags, bool historical)
{
const std::string &grpId = grp.grpId;
std::string msgId;
std::string nullId;
switch(flags)
{
case GRP_NEW_UPDATE:
if (!historical)
{
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_FORUM_NEW, grpId, msgId, nullId);
}
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_ADD);
break;
case GRP_UPDATE:
if (!historical)
{
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_FORUM_UPDATE, grpId, msgId, nullId);
}
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_MOD);
break;
case GRP_LOAD_KEY:
break;
case GRP_NEW_MSG:
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_ADD);
break;
case GRP_SUBSCRIBED:
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_ADD);
break;
case GRP_UNSUBSCRIBED:
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_DEL);
break;
}
return p3GroupDistrib::locked_notifyGroupChanged(grp, flags, historical);
}
bool p3Forums::locked_eventDuplicateMsg(GroupInfo */*grp*/, RsDistribMsg */*msg*/, const std::string& /*id*/, bool /*historical*/)
{
return true;
}
bool p3Forums::forumShareKeys(std::string fId, std::list<std::string>& peers)
{
#ifdef FORUM_DEBUG
std::cerr << "p3Forums::forumShareKeys() " << fId << std::endl;
#endif
return sharePubKey(fId, peers);
}
bool p3Forums::locked_eventNewMsg(GroupInfo */*grp*/, RsDistribMsg *msg, const std::string& /*id*/, bool historical)
{
std::string grpId = msg->grpId;
std::string msgId = msg->msgId;
std::string nullId;
if (!historical)
{
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_FORUM_MSG, grpId, msgId, nullId);
}
return true;
}
/****************************************/
void p3Forums::loadDummyData()
{
ForumInfo fi;
std::string forumId;
std::string msgId;
time_t now = time(NULL);
fi.forumId = "FID1234";
fi.forumName = L"Forum 1";
fi.forumDesc = L"Forum 1";
fi.forumFlags = RS_DISTRIB_ADMIN;
fi.pop = 2;
fi.lastPost = now - 123;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
fi.forumId = "FID2345";
fi.forumName = L"Forum 2";
fi.forumDesc = L"Forum 2";
fi.forumFlags = RS_DISTRIB_SUBSCRIBED;
fi.pop = 3;
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
msgId = createForumMsg(forumId, "", L"WELCOME TO Forum1", L"Hello!", true);
msgId = createForumMsg(forumId, msgId, L"Love this forum", L"Hello2!", true);
return;
/* ignore this */
fi.forumId = "FID3456";
fi.forumName = L"Forum 3";
fi.forumDesc = L"Forum 3";
fi.forumFlags = 0;
fi.pop = 3;
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
fi.forumId = "FID4567";
fi.forumName = L"Forum 4";
fi.forumDesc = L"Forum 4";
fi.forumFlags = 0;
fi.pop = 5;
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
fi.forumId = "FID5678";
fi.forumName = L"Forum 5";
fi.forumDesc = L"Forum 5";
fi.forumFlags = 0;
fi.pop = 1;
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
fi.forumId = "FID6789";
fi.forumName = L"Forum 6";
fi.forumDesc = L"Forum 6";
fi.forumFlags = 0;
fi.pop = 2;
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
fi.forumId = "FID7890";
fi.forumName = L"Forum 7";
fi.forumDesc = L"Forum 7";
fi.forumFlags = 0;
fi.pop = 4;
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
fi.forumId = "FID8901";
fi.forumName = L"Forum 8";
fi.forumDesc = L"Forum 8";
fi.forumFlags = 0;
fi.pop = 3;
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
fi.forumId = "FID9012";
fi.forumName = L"Forum 9";
fi.forumDesc = L"Forum 9";
fi.forumFlags = 0;
fi.pop = 2;
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
fi.forumId = "FID9123";
fi.forumName = L"Forum 10";
fi.forumDesc = L"Forum 10";
fi.forumFlags = 0;
fi.pop = 1;
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
}
std::list<RsItem* > p3Forums::childSaveList()
{
return mSaveList;
}
bool p3Forums::childLoadList(std::list<RsItem* >& configSaves)
{
RsForumReadStatus* drs = NULL;
std::list<RsItem* >::iterator it;
for(it = configSaves.begin(); it != configSaves.end(); it++)
{
if(NULL != (drs = dynamic_cast<RsForumReadStatus* >(*it)))
{
mReadStatus[drs->forumId] = drs;
mSaveList.push_back(drs);
}
else
{
std::cerr << "p3Forums::childLoadList(): Configs items loaded were incorrect!"
<< std::endl;
return false;
}
}
return true;
}

View file

@ -1,105 +0,0 @@
#ifndef RS_P3_FORUMS_INTERFACE_H
#define RS_P3_FORUMS_INTERFACE_H
/*
* libretroshare/src/services: p3forums.h
*
* RetroShare C++ Interface.
*
* Copyright 2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "retroshare/rsforums.h"
#include "distrib/p3distrib.h"
#include "serialiser/rsforumitems.h"
class p3Forums: public p3GroupDistrib, public RsForums
{
public:
p3Forums(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
std::string srcdir, std::string storedir, std::string forumdir);
virtual ~p3Forums();
void loadDummyData();
/****************************************/
/********* rsForums Interface ***********/
virtual bool forumsChanged(std::list<std::string> &forumIds);
virtual std::string createForum(const std::wstring &forumName, const std::wstring &forumDesc, uint32_t forumFlags);
virtual bool getForumInfo(const std::string &fId, ForumInfo &fi);
virtual bool setForumInfo(const std::string &fId, ForumInfo &fi);
virtual bool getForumList(std::list<ForumInfo> &forumList);
virtual bool getForumThreadList(const std::string &fId, std::list<ThreadInfoSummary> &msgs);
virtual bool getForumThreadMsgList(const std::string &fId, const std::string &tId, std::list<ThreadInfoSummary> &msgs);
virtual bool getForumMessage(const std::string &fId, const std::string &mId, ForumMsgInfo &msg);
virtual bool ForumMessageSend(ForumMsgInfo &info);
virtual bool setMessageStatus(const std::string& fId, const std::string& mId, const uint32_t status, const uint32_t statusMask);
virtual bool getMessageStatus(const std::string& fId, const std::string& mId, uint32_t& status);
virtual bool forumRestoreKeys(const std::string& fId);
virtual bool forumShareKeys(std::string fId, std::list<std::string>& peers);
virtual bool forumSubscribe(const std::string &fId, bool subscribe);
virtual bool getMessageCount(const std::string &fId, unsigned int &newCount, unsigned int &unreadCount);
/***************************************************************************************/
/****************** Event Feedback (Overloaded form p3distrib) *************************/
/***************************************************************************************/
virtual void locked_notifyGroupChanged(GroupInfo &grp, uint32_t flags, bool historical);
virtual bool locked_eventDuplicateMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
virtual bool locked_eventNewMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
/****************************************/
/********* Overloaded Functions *********/
//virtual RsSerialiser *setupSerialiser();
//virtual pqistreamer *createStreamer(BinInterface *bio, std::string src, uint32_t bioflags);
virtual RsSerialType *createSerialiser();
virtual bool locked_checkDistribMsg(RsDistribMsg *msg);
virtual RsDistribGrp *locked_createPublicDistribGrp(GroupInfo &info);
virtual RsDistribGrp *locked_createPrivateDistribGrp(GroupInfo &info);
virtual bool childLoadList(std::list<RsItem *>& );
virtual std::list<RsItem *> childSaveList();
/****************************************/
std::string createForumMsg(std::string fId, std::string pId,
std::wstring title, std::wstring msg, bool signIt);
private:
std::string mForumsDir;
std::list<RsItem *> mSaveList; // store save data
std::map<std::string, RsForumReadStatus*> mReadStatus;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,151 +0,0 @@
/*
* libretroshare/src/services: p3gamelauncher.h
*
* Services for RetroShare.
*
* Copyright 2004-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef SERVICE_GAME_LAUNCHER_HEADER
#define SERVICE_GAME_LAUNCHER_HEADER
/*
* A central point to setup games between peers.
*
*/
#include <list>
#include <string>
#include "services/p3service.h"
#include "serialiser/rsgameitems.h"
#include "retroshare/rsgame.h"
class p3LinkMgr;
class gameAvail
{
uint32_t serviceId;
std::string gameName;
uint16_t minPlayers;
uint16_t maxPlayers;
};
class gameStatus
{
public:
uint32_t serviceId;
std::string gameId;
std::wstring gameName;
bool areServer; /* are we the server? */
std::string serverId; /* if not, who is? */
uint16_t numPlayers;
std::list<std::string> allowedPeers; /* who can play ( controlled by server) */
std::list<std::string> interestedPeers; /* who wants to play ( controlled by server) */
std::list<std::string> peerIds; /* in order of turns */
uint32_t state;
};
class p3GameService;
/* We're going to add the external Interface - directly on here! */
class p3GameLauncher: public p3Service, public RsGameLauncher
{
public:
p3GameLauncher(p3LinkMgr *lm);
/***** EXTERNAL RsGameLauncher Interface *******/
/* server commands */
virtual std::string createGame(uint32_t gameType, std::wstring name);
virtual bool deleteGame(std::string gameId);
virtual bool inviteGame(std::string gameId);
virtual bool playGame(std::string gameId);
//virtual bool quitGame(std::string gameId);
virtual bool invitePeer(std::string gameId, std::string peerId);
virtual bool uninvitePeer(std::string gameId, std::string peerId);
virtual bool confirmPeer(std::string gameId, std::string peerId,
int16_t pos = -1);
virtual bool unconfirmPeer(std::string gameId, std::string peerId);
/* client commands */
virtual bool interestedPeer(std::string gameId);
virtual bool uninterestedPeer(std::string gameId);
/* get details */
virtual bool getGameList(std::list<RsGameInfo> &gameList);
virtual bool getGameDetail(std::string gameId, RsGameDetail &detail);
/***** EXTERNAL RsGameLauncher Interface *******/
/* support functions */
private:
std::string newGame(uint16_t srvId, std::wstring name);
bool confirmGame(std::string gameId);
bool quitGame(std::string gameId);
bool inviteResponse(std::string gameId, bool interested);
/* p3Service Overloaded */
virtual int tick();
virtual int status();
/* add in the Game */
int addGameService(p3GameService *game);
/* notify gameService/peers */
//int getGameList(std::list<gameAvail> &games);
//int getGamesCurrent(std::list<std::string> &games);
//int getGameDetails(std::string gid, gameStatus &status);
/**** GUI Interface ****/
bool resumeGame(std::string gameId);
/**** Network Interface ****/
int checkIncoming();
int handleIncoming(RsGameItem *gi);
int handleClientStart(RsGameItem *gi); /* START msg */
int handleClientInvited(RsGameItem *gi); /* REJECT msg */
int handleClientReady(RsGameItem *gi); /* CONFIRM / REJECT / PLAY msg */
int handleClientActive(RsGameItem *gi); /* PAUSE / QUIT msg */
int handleServerSetup(RsGameItem *gi); /* INTERESTED / REJECT msg */
int handleServerActive(RsGameItem *gi); /* PAUSE / QUIT msg */
int sendRejectMsg(RsGameItem *gi); /* --- error msg */
void cleanupGame(std::string gameId); /* remove from list */
bool checkGameProperties(uint16_t serviceId, uint16_t players);
std::map<uint16_t, p3GameService *> gameList;
std::map<std::string, gameStatus> gamesCurrent;
p3LinkMgr *mLinkMgr;
std::string mOwnId;
};
#endif // SERVICE_GAME_LAUNCHER_HEADER

View file

@ -1,90 +0,0 @@
/*
* libretroshare/src/services: p3gameservice.h
*
* Services for RetroShare.
*
* Copyright 2004-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_SERVICE_GAME_HEADER
#define P3_SERVICE_GAME_HEADER
/*
* A central point to setup games between peers.
*
*/
#include <list>
#include <string>
#include "services/p3service.h"
class StoredGame
{
public:
std::string gameId;
time_t startTime;
std::list<std::string> peerIds; /* in order of turns */
};
class p3GameLauncher;
class p3Service;
class p3GameService
{
public:
p3GameService(uint16_t sId, std::string name, uint16_t min, uint16_t max, p3GameLauncher *l)
:serviceId(sId), gameName(name), minPlayers(min), maxPlayers(max),
service(NULL), launcher(l)
{ return; }
virtual ~p3GameService()
{ return; }
/*************** Game Interface ******************/
/* saved games */
virtual void getSavedGames(std::list<StoredGame> &gList);
/* start a game */
virtual void startGame(StoredGame &newGame, bool resume);
virtual void quitGame(std::string gameId);
virtual void deleteGame(std::string gameId);
/*************** Game Interface ******************/
/* details for the Launcher */
uint16_t getServiceId() { return serviceId; }
std::string getGameName() { return gameName; }
uint16_t getMinPlayers() { return minPlayers; }
uint16_t getMaxPlayers() { return maxPlayers; }
p3GameLauncher *getLauncher() { return launcher; }
private:
uint16_t serviceId;
std::string gameName;
uint16_t minPlayers, maxPlayers;
p3Service *service;
p3GameLauncher *launcher;
};
#endif // P3_SERVICE_GAME_HEADER

View file

@ -1165,7 +1165,7 @@ bool p3GxsChannels::generateVote(uint32_t &token, const RsGxsGroupId &grpId, con
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
uint32_t i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++) ;
if (it != ownIds.end())
{

View file

@ -1511,7 +1511,7 @@ void p3GxsCircles::generateDummyCircle()
int selection = (RSRandom::random_u32() % npgps);
std::list<RsGxsId>::iterator it = mDummyPgpLinkedIds.begin();
for(int j = 0; (it != mDummyPgpLinkedIds.end()) && (j < selection); j++, it++);
for(int j = 0; (it != mDummyPgpLinkedIds.end()) && (j < selection); j++, it++) ;
if (it != mDummyPgpLinkedIds.end())
{
idset.insert(*it);
@ -1525,7 +1525,7 @@ void p3GxsCircles::generateDummyCircle()
int selection = (RSRandom::random_u32() % mDummyOwnIds.size());
std::list<RsGxsId>::iterator it = mDummyOwnIds.begin();
mDummyOwnIds.push_back(*it);
for(int j = 0; (it != mDummyOwnIds.end()) && (j < selection); j++, it++);
for(int j = 0; (it != mDummyOwnIds.end()) && (j < selection); j++, it++) ;
if (it != mDummyOwnIds.end())
{
idset.insert(*it);

View file

@ -215,6 +215,21 @@ bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
return true;
}
bool p3GxsForums::updateGroup(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsGxsForumGroup &group)
{
std::cerr << "p3GxsForums::updateGroup()" << std::endl;
if(meta.getGroupId().empty())
return false;
RsGxsForumGroupItem* grpItem = new RsGxsForumGroupItem();
grpItem->mGroup = group;
grpItem->meta = group.mMeta;
grpItem->meta.mGroupId = meta.getGroupId();
RsGenExchange::updateGroup(token, meta, grpItem);
return true;
}
bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg)
{
@ -423,7 +438,7 @@ bool p3GxsForums::generateMessage(uint32_t &token, const RsGxsGroupId &grpId, co
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
int i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++) ;
if (it != ownIds.end())
{

View file

@ -74,6 +74,13 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group);
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg);
/*!
* To update forum group with new information
* @param token the token used to check completion status of update
* @param group group to be updated, groupId element must be set or will be rejected
* @return false groupId not set, true if set and accepted (still check token for completion)
*/
virtual bool updateGroup(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsGxsForumGroup &group);
private:

File diff suppressed because it is too large Load diff

View file

@ -1,191 +0,0 @@
/*
* libretroshare/src/services p3gxsservice.h
*
* Generic Service Support Class for RetroShare.
*
* Copyright 2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_GXS_SERVICE_HEADER
#define P3_GXS_SERVICE_HEADER
#include "services/p3service.h"
#include "retroshare/rsidentityVEG.h"
/*
* This class provides useful generic support for GXS style services.
* I expect much of this will be incorporated into the base GXS.
*
*/
#define GXS_REQUEST_STATUS_FAILED 0
#define GXS_REQUEST_STATUS_PENDING 1
#define GXS_REQUEST_STATUS_PARTIAL 2
#define GXS_REQUEST_STATUS_FINISHED_INCOMPLETE 3
#define GXS_REQUEST_STATUS_COMPLETE 4
#define GXS_REQUEST_STATUS_DONE 5 // ONCE ALL DATA RETRIEVED.
#define GXS_REQUEST_TYPE_GROUPS 0x00010000
#define GXS_REQUEST_TYPE_MSGS 0x00020000
#define GXS_REQUEST_TYPE_MSGRELATED 0x00040000
class gxsRequest
{
public:
uint32_t token;
uint32_t reqTime;
uint32_t ansType;
uint32_t reqType;
RsTokReqOptionsVEG Options;
uint32_t status;
std::list<std::string> inList;
std::list<std::string> outList;
//std::map<std::string, void *> readyData;
};
class p3GxsServiceVEG: public p3Service
{
protected:
p3GxsServiceVEG(uint16_t type);
public:
//virtual ~p3Service() { p3Service::~p3Service(); return; }
bool generateToken(uint32_t &token);
bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptionsVEG &opts, const uint32_t &type, const std::list<std::string> &ids);
bool clearRequest(const uint32_t &token);
bool updateRequestStatus(const uint32_t &token, const uint32_t &status);
bool updateRequestInList(const uint32_t &token, std::list<std::string> ids);
bool updateRequestOutList(const uint32_t &token, std::list<std::string> ids);
//bool updateRequestData(const uint32_t &token, std::map<std::string, void *> data);
bool checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, uint32_t &anstype, time_t &ts);
// special ones for testing (not in final design)
bool tokenList(std::list<uint32_t> &tokens);
bool popRequestInList(const uint32_t &token, std::string &id);
bool popRequestOutList(const uint32_t &token, std::string &id);
bool loadRequestOutList(const uint32_t &token, std::list<std::string> &ids);
virtual bool fakeprocessrequests();
protected:
RsMutex mReqMtx;
uint32_t mNextToken;
std::map<uint32_t, gxsRequest> mRequests;
};
class GxsDataProxyVEG
{
public:
GxsDataProxyVEG();
virtual bool getGroupList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds, std::list<std::string> &outGroupIds);
virtual bool getMsgList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds, std::list<std::string> &outMsgIds);
virtual bool getMsgRelatedList(uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &msgIds, std::list<std::string> &outMsgIds);
/* This functions return a token - which can be used to retrieve the RsGroupMetaData, later
* This is required, as signatures and keys might have to be generated in the background
* Though at the moment: for this test system it won't change anything? FIXME.
*/
virtual bool createGroup(void *groupData);
virtual bool createMsg(void *msgData);
/* These Functions must be overloaded to complete the service */
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta);
/* extract Data */
bool getGroupSummary(const std::list<std::string> &groupIds, std::list<RsGroupMetaData> &groupSummary);
bool getMsgSummary(const std::list<std::string> &msgIds, std::list<RsMsgMetaData> &msgSummary);
bool getGroupSummary(const std::string &groupId, RsGroupMetaData &groupSummary);
bool getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSummary);
//bool getGroupData(const std::list<std::string> &groupIds, std::list<void *> &groupData);
//bool getMsgData(const std::list<std::string> &msgIds, std::list<void *> &msgData);
bool getGroupData(const std::string &groupId, void * &groupData);
bool getMsgData(const std::string &msgId, void * &msgData);
bool isUniqueGroup(const std::string &groupId);
bool isUniqueMsg(const std::string &msgId);
/* Handle Status & Subscribe Modes */
// This is removed as redundant - use getGroupList - with OptFlags to find these.
//virtual bool requestGroupsChanged(uint32_t &token); //std::list<std::string> &groupIds);
// Get Message Status - is retrived via MessageSummary.
// These operations could have a token, but for the moment we are going to assume
// they are async and always succeed - (or fail silently).
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
protected:
bool filterGroupList(const RsTokReqOptionsVEG &opts, std::list<std::string> &groupIds);
bool filterMsgList(const RsTokReqOptionsVEG &opts, std::list<std::string> &msgIds);
RsMutex mDataMtx;
std::map<std::string, void *> mGroupData;
std::map<std::string, void *> mMsgData;
std::map<std::string, RsGroupMetaData> mGroupMetaData;
std::map<std::string, RsMsgMetaData> mMsgMetaData;
};
class p3GxsDataServiceVEG: public p3GxsServiceVEG
{
public:
p3GxsDataServiceVEG(uint16_t type, GxsDataProxyVEG *proxy);
virtual bool fakeprocessrequests();
protected:
GxsDataProxyVEG *mProxy;
};
#endif // P3_GXS_SERVICE_HEADER

View file

@ -0,0 +1,124 @@
/*
* libretroshare/src/services: p3heartbeat.cc
*
* Services for RetroShare.
*
* Copyright 2004-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "services/p3heartbeat.h"
#include "serialiser/rsheartbeatitems.h"
#define HEART_DEBUG 1
p3heartbeat::p3heartbeat(p3LinkMgr *linkMgr, pqipersongrp *pqipg)
:p3Service(RS_SERVICE_TYPE_HEARTBEAT), mLinkMgr(linkMgr), mPqiPersonGrp(pqipg),
mHeartMtx("p3heartbeat")
{
RsStackMutex stack(mHeartMtx); /********** STACK LOCKED MTX ******/
addSerialType(new RsHeartbeatSerialiser());
#ifdef HEART_DEBUG
std::cerr << "p3heartbeat::p3heartbeat()";
std::cerr << std::endl;
#endif
mLastHeartbeat = 0;
return;
}
p3heartbeat::~p3heartbeat()
{
return;
}
int p3heartbeat::tick()
{
//send a heartbeat to all connected peers
RsStackMutex stack(mHeartMtx); /********** STACK LOCKED MTX ******/
if (time(NULL) - mLastHeartbeat > HEARTBEAT_REPEAT_TIME)
{
mLastHeartbeat = time(NULL);
std::list<std::string> peers;
std::list<std::string>::const_iterator pit;
mLinkMgr->getOnlineList(peers);
for (pit = peers.begin(); pit != peers.end(); ++pit)
{
sendHeartbeat(*pit);
}
}
int nhandled = 0;
RsItem *item = NULL;
// While messages read
while(NULL != (item = recvItem()))
{
RsHeartbeatItem *beat = NULL;
nhandled++;
// if discovery reply then respond if haven't already.
if (NULL != (beat = dynamic_cast<RsHeartbeatItem *> (item)))
{
recvHeartbeat(beat->PeerId());
}
else
{
// unknown.
}
delete item;
}
return nhandled ;
}
void p3heartbeat::sendHeartbeat(const std::string &toId)
{
#ifdef HEART_DEBUG
std::cerr << "p3heartbeat::sendHeartbeat() to " << toId;
std::cerr << std::endl;
#endif
RsHeartbeatItem *item = new RsHeartbeatItem();
item->PeerId(toId);
sendItem(item);
}
void p3heartbeat::recvHeartbeat(const std::string &fromId)
{
#ifdef HEART_DEBUG
std::cerr << "p3heartbeat::recvHeartbeat() from " << fromId;
std::cerr << std::endl;
#endif
mPqiPersonGrp->tagHeartbeatRecvd(fromId);
}

View file

@ -0,0 +1,61 @@
/*
* libretroshare/src/services: p3heartbeat.h
*
* Services for RetroShare.
*
* Copyright 2004-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef MRK_SERVICES_HEARTBEAT_H
#define MRK_SERVICES_HEARTBEAT_H
// Moved Heartbeat to a seperate service.
#include "pqi/p3linkmgr.h"
#include "pqi/pqipersongrp.h"
#include "services/p3service.h"
class p3heartbeat: public p3Service
{
public:
p3heartbeat(p3LinkMgr *linkMgr, pqipersongrp *pqipg);
virtual ~p3heartbeat();
int tick();
private:
void sendHeartbeat(const std::string &toId);
void recvHeartbeat(const std::string &fromId);
private:
p3LinkMgr *mLinkMgr;
pqipersongrp *mPqiPersonGrp;
/* data */
RsMutex mHeartMtx;
time_t mLastHeartbeat;
};
#endif // MRK_SERVICES_HEARTBEAT_H

File diff suppressed because it is too large Load diff

View file

@ -38,9 +38,12 @@
#include "util/rsmemcache.h"
#include "util/rstickevent.h"
#include "util/rsrecogn.h"
#include "pqi/authgpg.h"
#include "serialiser/rsgxsrecognitems.h"
/*
* Identity Service
*
@ -73,6 +76,27 @@ virtual std::string save() const;
std::string pgpId;
};
class SSGxsIdRecognTags: public SSBit
{
public:
SSGxsIdRecognTags()
:tagFlags(0), publishTs(0), lastCheckTs(0) { return; }
virtual bool load(const std::string &input);
virtual std::string save() const;
void setTags(bool processed, bool pending, uint32_t flags);
bool tagsProcessed() const; // have we processed?
bool tagsPending() const; // should we reprocess?
bool tagValid(int i) const;
uint32_t tagFlags;
time_t publishTs;
time_t lastCheckTs;
};
class SSGxsIdScore: public SSBit
{
public:
@ -113,11 +137,14 @@ virtual std::string save() const;
// pgphash status
SSGxsIdPgp pgp;
// recogTags.
SSGxsIdRecognTags recogntags;
// reputation score.
SSGxsIdScore score;
SSGxsIdCumulator opinion;
SSGxsIdCumulator reputation;
};
#define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000
@ -133,10 +160,14 @@ class RsGxsIdCache
{
public:
RsGxsIdCache();
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey);
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey,
const std::list<RsRecognTag> &tagList);
void updateServiceString(std::string serviceString);
time_t mPublishTs;
std::list<RsRecognTag> mRecognTags; // Only partially validated.
RsIdentityDetails details;
RsTlvSecurityKey pubkey;
};
@ -165,6 +196,12 @@ static uint32_t idAuthenPolicy();
virtual void service_tick(); // needed for background processing.
/*!
* Design hack, id service must be constructed first as it
* is need for construction of subsequent net services
*/
void setNes(RsNetworkExchangeService* nes);
/* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */
/* Data Specific Interface */
@ -175,6 +212,7 @@ virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opin
// These are local - and not exposed via RsIdentity.
virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group);
virtual bool updateGroup(uint32_t& token, RsGxsIdGroup &group);
virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion);
/**************** RsIdentity External Interface.
@ -197,6 +235,13 @@ virtual bool getOwnIds(std::list<RsGxsId> &ownIds);
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion);
virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params);
virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group);
virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname,
const std::string &tag, RsRecognTagDetails &details);
virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag);
/**************** RsGixs Implementation
* Notes:
@ -219,7 +264,7 @@ virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key);
// get Reputation.
virtual bool haveReputation(const RsGxsId &id);
virtual bool loadReputation(const RsGxsId &id);
virtual bool loadReputation(const RsGxsId &id, const std::list<std::string>& peers);
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep);
@ -245,16 +290,20 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
*/
int cache_tick();
bool cache_request_load(const RsGxsId &id);
bool cache_request_load(const RsGxsId &id, const std::list<std::string>& peers = std::list<std::string>());
bool cache_start_load();
bool cache_load_for_token(uint32_t token);
bool cache_store(const RsGxsIdGroupItem *item);
bool cache_update_if_cached(const RsGxsId &id, std::string serviceString);
bool isPendingNetworkRequest(const RsGxsId& gxsId) const;
void requestIdsFromNet();
// Mutex protected.
std::list<RsGxsId> mCacheLoad_ToCache;
//std::list<RsGxsId> mCacheLoad_ToCache;
std::map<RsGxsId, std::list<std::string> > mCacheLoad_ToCache, mPendingCache;
// Switching to RsMemCache for Key Caching.
RsMemCache<RsGxsId, RsGxsIdCache> mPublicKeyCache;
@ -303,6 +352,39 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
std::map<PGPIdType, PGPFingerprintType> mPgpFingerprintMap;
std::list<RsGxsIdGroup> mGroupsToProcess;
/************************************************************************
* recogn processing.
*
*/
bool recogn_schedule();
bool recogn_start();
bool recogn_handlerequest(uint32_t token);
bool recogn_process();
// helper functions.
bool recogn_extract_taginfo(const RsGxsIdGroupItem *item, std::list<RsGxsRecognTagItem *> &tagItems);
bool cache_process_recogntaginfo(const RsGxsIdGroupItem *item, std::list<RsRecognTag> &tagList);
bool recogn_checktag(const RsGxsId &id, const std::string &nickname, RsGxsRecognTagItem *item, bool doSignCheck, bool &isPending);
void loadRecognKeys();
/************************************************************************
* for getting identities that are not present
*
*/
void checkPeerForIdentities();
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
bool checkRecognSignature_locked(std::string encoded, RSA &key, std::string signature);
bool getRecognKey_locked(std::string signer, RSA &key);
std::list<RsGxsGroupId> mRecognGroupIds;
std::list<RsGxsIdGroupItem *> mRecognGroupsToProcess;
std::map<std::string, RsGxsRecognSignerItem *> mRecognSignKeys;
std::map<std::string, uint32_t> mRecognOldSignKeys;
/************************************************************************
* Below is the background task for processing opinions => reputations
*
@ -348,6 +430,12 @@ std::string genRandomId(int len = 20);
std::vector<RsGxsGroupChange*> mGroupChange;
std::vector<RsGxsMsgChange*> mMsgChange;
private:
std::map<uint32_t, std::set<RsGxsGroupId> > mIdsPendingCache;
std::map<uint32_t, std::list<RsGxsGroupId> > mGroupNotPresent;
std::map<RsGxsId, std::list<std::string> > mIdsNotPresent;
RsNetworkExchangeService* mNes;
};
#endif // P3_IDENTITY_SERVICE_HEADER

View file

@ -166,14 +166,10 @@ void p3MsgService::processMsg(RsMsgItem *mi, bool incoming)
p3Notify *notify = RsServer::notify();
if (notify)
{
std::string title, message;
librs::util::ConvertUtf16ToUtf8(mi->subject, title);
librs::util::ConvertUtf16ToUtf8(mi->message, message);
if(mi->msgFlags & RS_MSG_FLAGS_ENCRYPTED)
notify->AddPopupMessage(RS_POPUP_ENCRYPTED_MSG, mi->PeerId(), title, message);
notify->AddPopupMessage(RS_POPUP_ENCRYPTED_MSG, mi->PeerId(), mi->subject, mi->message);
else
notify->AddPopupMessage(RS_POPUP_MSG, mi->PeerId(), title, message);
notify->AddPopupMessage(RS_POPUP_MSG, mi->PeerId(), mi->subject, mi->message);
std::string out;
rs_sprintf(out, "%lu", mi->msgId);
@ -707,12 +703,12 @@ void p3MsgService::loadWelcomeMsg()
msg -> recvTime = time(NULL);
msg -> msgFlags = RS_MSG_FLAGS_NEW;
msg -> subject = L"Welcome to Retroshare";
msg -> subject = "Welcome to Retroshare";
msg -> message = L"Send and receive messages with your friends...\n";
msg -> message += L"These can hold recommendations from your local shared files.\n\n";
msg -> message += L"Add recommendations through the Local Files Dialog.\n\n";
msg -> message += L"Enjoy.";
msg -> message = "Send and receive messages with your friends...\n";
msg -> message += "These can hold recommendations from your local shared files.\n\n";
msg -> message += "Add recommendations through the Local Files Dialog.\n\n";
msg -> message += "Enjoy.";
msg -> msgId = getNewUniqueMsgId();
@ -1110,7 +1106,7 @@ bool p3MsgService::MessageSend(MessageInfo &info)
return true;
}
bool p3MsgService::SystemMessage(const std::wstring &title, const std::wstring &message, uint32_t systemFlag)
bool p3MsgService::SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag)
{
if ((systemFlag & RS_MSG_SYSTEM) == 0) {
/* no flag specified */
@ -1884,22 +1880,21 @@ bool p3MsgService::encryptMessage(const std::string& pgp_id,RsMsgItem *item)
#endif
// Now turn the binary encrypted chunk into a readable radix string.
//
#ifdef DEBUG_DISTANT_MSG
std::cerr << " Converting to radix64" << std::endl;
#endif
std::string armoured_data ;
Radix64::encode((char *)encrypted_data,encrypted_size,armoured_data) ;
delete[] encrypted_data ;
std::wstring encrypted_msg ;
#ifdef DEBUG_DISTANT_MSG
std::cerr << " Converting to radix64" << std::endl;
#endif
if(!librs::util::ConvertUtf8ToUtf16(armoured_data,encrypted_msg))
return false;
//std::wstring encrypted_msg = armoured_data;
//if(!librs::util::ConvertUtf8ToUtf16(armoured_data,encrypted_msg))
// return false;
// wipe the item clean and replace the message by the encrypted data.
item->message = encrypted_msg ;
item->subject = L"" ;
item->message = armoured_data ;
item->subject = "" ;
item->msgcc.ids.clear() ;
item->msgbcc.ids.clear() ;
item->msgto.ids.clear() ;
@ -1925,11 +1920,13 @@ bool p3MsgService::decryptMessage(const std::string& mId)
std::map<uint32_t, RsMsgItem *>::iterator mit = imsg.find(msgId);
if(mit == imsg.end() || !librs::util::ConvertUtf16ToUtf8(mit->second->message,encrypted_string))
if(mit == imsg.end())
{
std::cerr << "Can't find this message in msg list. Id=" << mId << std::endl;
return false;
}
encrypted_string = mit->second->message ;
}
char *encrypted_data ;

View file

@ -75,7 +75,7 @@ bool getMsgParentId(const std::string &msgId, std::string &msgParentId);
bool setMsgParentId(uint32_t msgId, uint32_t msgParentId);
bool MessageSend(MessageInfo &info);
bool SystemMessage(const std::wstring &title, const std::wstring &message, uint32_t systemFlag);
bool SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag);
bool MessageToDraft(MessageInfo &info, const std::string &msgParentId);
bool MessageToTrash(const std::string &mid, bool bTrash);

View file

@ -0,0 +1,723 @@
/*
* libretroshare/src/services p3posted.cc
*
* Posted interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <retroshare/rsidentity.h>
#include "retroshare/rsgxsflags.h"
#include <stdio.h>
#include <math.h>
#include "services/p3postbase.h"
#include "serialiser/rsgxscommentitems.h"
// For Dummy Msgs.
#include "util/rsrandom.h"
#include "util/rsstring.h"
/****
* #define POSTBASE_DEBUG 1
****/
#define POSTBASE_BACKGROUND_PROCESSING 0x0002
#define PROCESSING_START_PERIOD 30
#define PROCESSING_INC_PERIOD 15
#define POSTBASE_ALL_GROUPS 0x0011
#define POSTBASE_UNPROCESSED_MSGS 0x0012
#define POSTBASE_ALL_MSGS 0x0013
#define POSTBASE_BG_POST_META 0x0014
/********************************************************************************/
/******************* Startup / Tick ******************************************/
/********************************************************************************/
p3PostBase::p3PostBase(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs,
RsSerialType* serviceSerialiser, uint16_t serviceType)
: RsGenExchange(gds, nes, serviceSerialiser, serviceType, gixs, postBaseAuthenPolicy()), GxsTokenQueue(this), RsTickEvent(), mPostBaseMtx("PostBaseMtx")
{
mBgProcessing = false;
mCommentService = new p3GxsCommentService(this, serviceType);
RsTickEvent::schedule_in(POSTBASE_BACKGROUND_PROCESSING, PROCESSING_START_PERIOD);
}
uint32_t p3PostBase::postBaseAuthenPolicy()
{
uint32_t policy = 0;
uint32_t flag = 0;
flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS);
flag |= GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS);
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS);
flag = 0;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS);
return policy;
}
void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
std::cerr << "p3PostBase::notifyChanges()";
std::cerr << std::endl;
std::vector<RsGxsNotify *> changesForGUI;
std::vector<RsGxsNotify *>::iterator it;
for(it = changes.begin(); it != changes.end(); it++)
{
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it);
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
if (msgChange)
{
std::cerr << "p3PostBase::notifyChanges() Found Message Change Notification";
std::cerr << std::endl;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::iterator mit;
for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); mit++)
{
std::cerr << "p3PostBase::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << std::endl;
// To start with we are just going to trigger updates on these groups.
// FUTURE OPTIMISATION.
// It could be taken a step further and directly request these msgs for an update.
addGroupForProcessing(mit->first);
}
delete msgChange;
}
/* pass on Group Changes to GUI */
if (groupChange)
{
std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification";
std::cerr << std::endl;
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for(git = groupList.begin(); git != groupList.end(); git++)
{
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git;
std::cerr << std::endl;
}
changesForGUI.push_back(groupChange);
}
}
changes.clear();
receiveHelperChanges(changesForGUI);
std::cerr << "p3PostBase::notifyChanges() -> receiveChanges()";
std::cerr << std::endl;
}
void p3PostBase::service_tick()
{
RsTickEvent::tick_events();
GxsTokenQueue::checkRequests();
mCommentService->comment_tick();
return;
}
/********************************************************************************************/
/********************************************************************************************/
void p3PostBase::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read)
{
uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNREAD | GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
uint32_t status = GXS_SERV::GXS_MSG_STATUS_UNREAD;
if (read)
{
status = 0;
}
setMsgStatusFlags(token, msgId, status, mask);
}
// Overloaded from RsTickEvent for Event callbacks.
void p3PostBase::handle_event(uint32_t event_type, const std::string & /* elabel */)
{
std::cerr << "p3PostBase::handle_event(" << event_type << ")";
std::cerr << std::endl;
// stuff.
switch(event_type)
{
case POSTBASE_BACKGROUND_PROCESSING:
background_tick();
break;
default:
/* error */
std::cerr << "p3PostBase::handle_event() Unknown Event Type: " << event_type;
std::cerr << std::endl;
break;
}
}
/*********************************************************************************
* Background Calculations.
*
* Get list of change groups from Notify....
* this doesn't imclude your own submissions (at this point).
* So they will not be processed until someone else changes something.
* TODO FIX: Must push for that change.
*
* Eventually, we should just be able to get the new messages from Notify,
* and only process them!
*/
void p3PostBase::background_tick()
{
#if 0
{
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
if (mBgGroupList.empty())
{
background_requestAllGroups();
}
}
#endif
background_requestUnprocessedGroup();
RsTickEvent::schedule_in(POSTBASE_BACKGROUND_PROCESSING, PROCESSING_INC_PERIOD);
}
bool p3PostBase::background_requestAllGroups()
{
std::cerr << "p3PostBase::background_requestAllGroups()";
std::cerr << std::endl;
uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS;
uint32_t token = 0;
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts);
GxsTokenQueue::queueRequest(token, POSTBASE_ALL_GROUPS);
return true;
}
void p3PostBase::background_loadGroups(const uint32_t &token)
{
/* get messages */
std::cerr << "p3PostBase::background_loadGroups()";
std::cerr << std::endl;
std::list<RsGxsGroupId> groupList;
bool ok = RsGenExchange::getGroupList(token, groupList);
if (!ok)
{
return;
}
std::list<RsGxsGroupId>::iterator it;
for(it = groupList.begin(); it != groupList.end(); it++)
{
addGroupForProcessing(*it);
}
}
void p3PostBase::addGroupForProcessing(RsGxsGroupId grpId)
{
#ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::addGroupForProcessing(" << grpId << ")";
std::cerr << std::endl;
#endif // POSTBASE_DEBUG
{
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
// no point having multiple lookups queued.
if (mBgGroupList.end() == std::find(mBgGroupList.begin(),
mBgGroupList.end(), grpId))
{
mBgGroupList.push_back(grpId);
}
}
}
void p3PostBase::background_requestUnprocessedGroup()
{
#ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::background_requestUnprocessedGroup()";
std::cerr << std::endl;
#endif // POSTBASE_DEBUG
RsGxsGroupId grpId;
{
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
if (mBgProcessing)
{
std::cerr << "p3PostBase::background_requestUnprocessedGroup() Already Active";
std::cerr << std::endl;
return;
}
if (mBgGroupList.empty())
{
std::cerr << "p3PostBase::background_requestUnprocessedGroup() No Groups to Process";
std::cerr << std::endl;
return;
}
grpId = mBgGroupList.front();
mBgGroupList.pop_front();
mBgProcessing = true;
}
background_requestGroupMsgs(grpId, true);
}
void p3PostBase::background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly)
{
std::cerr << "p3PostBase::background_requestGroupMsgs() id: " << grpId;
std::cerr << std::endl;
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
if (unprocessedOnly)
{
opts.mStatusFilter = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
opts.mStatusMask = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
}
std::list<RsGxsGroupId> grouplist;
grouplist.push_back(grpId);
uint32_t token = 0;
RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, grouplist);
if (unprocessedOnly)
{
GxsTokenQueue::queueRequest(token, POSTBASE_UNPROCESSED_MSGS);
}
else
{
GxsTokenQueue::queueRequest(token, POSTBASE_ALL_MSGS);
}
}
void p3PostBase::background_loadUnprocessedMsgs(const uint32_t &token)
{
background_loadMsgs(token, true);
}
void p3PostBase::background_loadAllMsgs(const uint32_t &token)
{
background_loadMsgs(token, false);
}
/* This function is generalised to support any collection of messages, across multiple groups */
void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
{
/* get messages */
std::cerr << "p3PostBase::background_loadMsgs()";
std::cerr << std::endl;
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> > msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if (!ok)
{
std::cerr << "p3PostBase::background_loadMsgs() Failed to getMsgData()";
std::cerr << std::endl;
/* cleanup */
background_cleanup();
return;
}
{
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
mBgStatsMap.clear();
mBgIncremental = unprocessed;
}
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > postMap;
// generate vector of changes to push to the GUI.
std::vector<RsGxsNotify *> changes;
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED);
RsGxsGroupId groupId;
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> >::iterator mit;
std::vector<RsGxsMsgItem*>::iterator vit;
for (mit = msgData.begin(); mit != msgData.end(); mit++)
{
groupId = mit->first;
for (vit = mit->second.begin(); vit != mit->second.end(); vit++)
{
RsGxsMessageId parentId = (*vit)->meta.mParentId;
RsGxsMessageId threadId = (*vit)->meta.mThreadId;
bool inc_counters = false;
uint32_t vote_up_inc = 0;
uint32_t vote_down_inc = 0;
uint32_t comment_inc = 0;
bool add_voter = false;
RsGxsId voterId;
RsGxsCommentItem *commentItem;
RsGxsVoteItem *voteItem;
/* THIS Should be handled by UNPROCESSED Filter - but isn't */
if (!IS_MSG_UNPROCESSED((*vit)->meta.mMsgStatus))
{
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
if (mBgIncremental)
{
std::cerr << "p3PostBase::background_loadMsgs() Msg already Processed - Skipping";
std::cerr << std::endl;
std::cerr << "p3PostBase::background_loadMsgs() ERROR This should not happen";
std::cerr << std::endl;
delete(*vit);
continue;
}
}
/* 3 types expected: PostedPost, Comment and Vote */
if (parentId.empty())
{
/* we don't care about top-level (Posts) */
std::cerr << "\tIgnoring TopLevel Item";
std::cerr << std::endl;
/* but we need to notify GUI about them */
msgChanges->msgChangeMap[mit->first].push_back((*vit)->meta.mMsgId);
}
else if (NULL != (commentItem = dynamic_cast<RsGxsCommentItem *>(*vit)))
{
/* comment - want all */
/* Comments are counted by Thread Id */
std::cerr << "\tProcessing Comment: " << commentItem;
std::cerr << std::endl;
inc_counters = true;
comment_inc = 1;
}
else if (NULL != (voteItem = dynamic_cast<RsGxsVoteItem *>(*vit)))
{
/* vote - only care about direct children */
if (parentId == threadId)
{
/* Votes are organised by Parent Id,
* ie. you can vote for both Posts and Comments
*/
std::cerr << "\tProcessing Vote: " << voteItem;
std::cerr << std::endl;
inc_counters = true;
add_voter = true;
voterId = voteItem->meta.mAuthorId;
if (voteItem->mMsg.mVoteType == GXS_VOTE_UP)
{
vote_up_inc = 1;
}
else
{
vote_down_inc = 1;
}
}
}
else
{
/* unknown! */
std::cerr << "p3PostBase::background_processNewMessages() ERROR Strange NEW Message:";
std::cerr << std::endl;
std::cerr << "\t" << (*vit)->meta;
std::cerr << std::endl;
}
if (inc_counters)
{
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
std::map<RsGxsMessageId, PostStats>::iterator sit = mBgStatsMap.find(threadId);
if (sit == mBgStatsMap.end())
{
// add to map of ones to update.
postMap[groupId].push_back(threadId);
mBgStatsMap[threadId] = PostStats(0,0,0);
sit = mBgStatsMap.find(threadId);
}
sit->second.comments += comment_inc;
sit->second.up_votes += vote_up_inc;
sit->second.down_votes += vote_down_inc;
if (add_voter)
{
sit->second.voters.push_back(voterId);
}
std::cerr << "\tThreadId: " << threadId;
std::cerr << " Comment Total: " << sit->second.comments;
std::cerr << " UpVote Total: " << sit->second.up_votes;
std::cerr << " DownVote Total: " << sit->second.down_votes;
std::cerr << std::endl;
}
/* flag all messages as processed */
if ((*vit)->meta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED)
{
uint32_t token_a;
RsGxsGrpMsgIdPair msgId = std::make_pair(groupId, (*vit)->meta.mMsgId);
RsGenExchange::setMsgStatusFlags(token_a, msgId, 0, GXS_SERV::GXS_MSG_STATUS_UNPROCESSED);
}
delete(*vit);
}
}
/* push updates of new Posts */
if (msgChanges->msgChangeMap.size() > 0)
{
std::cerr << "p3PostBase::background_processNewMessages() -> receiveChanges()";
std::cerr << std::endl;
changes.push_back(msgChanges);
receiveHelperChanges(changes);
}
/* request the summary info from the parents */
uint32_t token_b;
uint32_t anstype = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_META;
RsGenExchange::getTokenService()->requestMsgInfo(token_b, anstype, opts, postMap);
GxsTokenQueue::queueRequest(token_b, POSTBASE_BG_POST_META);
return;
}
#define RSGXS_MAX_SERVICE_STRING 1024
bool encodePostCache(std::string &str, const PostStats &s)
{
char line[RSGXS_MAX_SERVICE_STRING];
snprintf(line, RSGXS_MAX_SERVICE_STRING, "%d %d %d", s.comments, s.up_votes, s.down_votes);
str = line;
return true;
}
bool extractPostCache(const std::string &str, PostStats &s)
{
uint32_t iupvotes, idownvotes, icomments;
if (3 == sscanf(str.c_str(), "%d %d %d", &icomments, &iupvotes, &idownvotes))
{
s.comments = icomments;
s.up_votes = iupvotes;
s.down_votes = idownvotes;
return true;
}
return false;
}
void p3PostBase::background_updateVoteCounts(const uint32_t &token)
{
std::cerr << "p3PostBase::background_updateVoteCounts()";
std::cerr << std::endl;
GxsMsgMetaMap parentMsgList;
GxsMsgMetaMap::iterator mit;
std::vector<RsMsgMetaData>::iterator vit;
bool ok = RsGenExchange::getMsgMeta(token, parentMsgList);
if (!ok)
{
std::cerr << "p3PostBase::background_updateVoteCounts() ERROR";
std::cerr << std::endl;
background_cleanup();
return;
}
// generate vector of changes to push to the GUI.
std::vector<RsGxsNotify *> changes;
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED);
for(mit = parentMsgList.begin(); mit != parentMsgList.end(); mit++)
{
for(vit = mit->second.begin(); vit != mit->second.end(); vit++)
{
std::cerr << "p3PostBase::background_updateVoteCounts() Processing Msg(" << mit->first;
std::cerr << ", " << vit->mMsgId << ")";
std::cerr << std::endl;
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
/* extract current vote count */
PostStats stats;
if (mBgIncremental)
{
if (!extractPostCache(vit->mServiceString, stats))
{
if (!(vit->mServiceString.empty()))
{
std::cerr << "p3PostBase::background_updateVoteCounts() Failed to extract Votes";
std::cerr << std::endl;
std::cerr << "\tFrom String: " << vit->mServiceString;
std::cerr << std::endl;
}
}
}
/* get increment */
std::map<RsGxsMessageId, PostStats>::iterator it;
it = mBgStatsMap.find(vit->mMsgId);
if (it != mBgStatsMap.end())
{
std::cerr << "p3PostBase::background_updateVoteCounts() Adding to msgChangeMap: ";
std::cerr << mit->first << " MsgId: " << vit->mMsgId;
std::cerr << std::endl;
stats.increment(it->second);
msgChanges->msgChangeMap[mit->first].push_back(vit->mMsgId);
}
else
{
// warning.
std::cerr << "p3PostBase::background_updateVoteCounts() Warning No New Votes found.";
std::cerr << " For MsgId: " << vit->mMsgId;
std::cerr << std::endl;
}
std::string str;
if (!encodePostCache(str, stats))
{
std::cerr << "p3PostBase::background_updateVoteCounts() Failed to encode Votes";
std::cerr << std::endl;
}
else
{
std::cerr << "p3PostBase::background_updateVoteCounts() Encoded String: " << str;
std::cerr << std::endl;
/* store new result */
uint32_t token_c;
RsGxsGrpMsgIdPair msgId = std::make_pair(vit->mGroupId, vit->mMsgId);
RsGenExchange::setMsgServiceString(token_c, msgId, str);
}
}
}
if (msgChanges->msgChangeMap.size() > 0)
{
std::cerr << "p3PostBase::background_updateVoteCounts() -> receiveChanges()";
std::cerr << std::endl;
changes.push_back(msgChanges);
receiveHelperChanges(changes);
}
// DONE!.
background_cleanup();
return;
}
bool p3PostBase::background_cleanup()
{
std::cerr << "p3PostBase::background_cleanup()";
std::cerr << std::endl;
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
// Cleanup.
mBgStatsMap.clear();
mBgProcessing = false;
return true;
}
// Overloaded from GxsTokenQueue for Request callbacks.
void p3PostBase::handleResponse(uint32_t token, uint32_t req_type)
{
std::cerr << "p3PostBase::handleResponse(" << token << "," << req_type << ")";
std::cerr << std::endl;
// stuff.
switch(req_type)
{
case POSTBASE_ALL_GROUPS:
background_loadGroups(token);
break;
case POSTBASE_UNPROCESSED_MSGS:
background_loadUnprocessedMsgs(token);
break;
case POSTBASE_ALL_MSGS:
background_loadAllMsgs(token);
break;
case POSTBASE_BG_POST_META:
background_updateVoteCounts(token);
break;
default:
/* error */
std::cerr << "p3PostBase::handleResponse() Unknown Request Type: " << req_type;
std::cerr << std::endl;
break;
}
}

View file

@ -0,0 +1,135 @@
/*
* libretroshare/src/services: p3postbase.h
*
* GxsChannel interface for RetroShare.
*
* Copyright 2012-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_POSTBASE_SERVICE_HEADER
#define P3_POSTBASE_SERVICE_HEADER
#include "services/p3gxscommon.h"
#include "gxs/rsgenexchange.h"
#include "util/rstickevent.h"
#include <retroshare/rsidentity.h>
#include <map>
#include <string>
#include <list>
/*
*
*/
class PostStats
{
public:
PostStats() :up_votes(0), down_votes(0), comments(0) { return; }
PostStats(int up, int down, int c) :up_votes(up), down_votes(down), comments(c) { return; }
void increment(const PostStats &s)
{
up_votes += s.up_votes;
down_votes += s.down_votes;
comments += s.comments;
return;
}
int up_votes;
int down_votes;
int comments;
std::list<RsGxsId> voters;
};
bool encodePostCache(std::string &str, const PostStats &s);
bool extractPostCache(const std::string &str, PostStats &s);
class p3PostBase: public RsGenExchange, public GxsTokenQueue, public RsTickEvent
{
public:
p3PostBase(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs,
RsSerialType* serviceSerialiser, uint16_t serviceType);
virtual void service_tick();
// This should be overloaded to call RsGxsIfaceHelper::receiveChanges().
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes) = 0;
protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
// Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
public:
//////////////////////////////////////////////////////////////////////////////
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
protected:
p3GxsCommentService *mCommentService;
private:
static uint32_t postBaseAuthenPolicy();
// Background processing.
void background_tick();
bool background_requestAllGroups();
void background_loadGroups(const uint32_t &token);
void addGroupForProcessing(RsGxsGroupId grpId);
void background_requestUnprocessedGroup();
void background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly);
void background_loadUnprocessedMsgs(const uint32_t &token);
void background_loadAllMsgs(const uint32_t &token);
void background_loadMsgs(const uint32_t &token, bool unprocessed);
void background_updateVoteCounts(const uint32_t &token);
bool background_cleanup();
RsMutex mPostBaseMtx;
bool mBgProcessing;
bool mBgIncremental;
std::list<RsGxsGroupId> mBgGroupList;
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -28,10 +28,7 @@
#include "retroshare/rsposted.h"
#include "services/p3gxscommon.h"
#include "gxs/rsgenexchange.h"
#include "util/rstickevent.h"
#include "services/p3postbase.h"
#include <retroshare/rsidentity.h>
@ -43,72 +40,41 @@
*
*/
class PostStats
{
public:
PostStats() :up_votes(0), down_votes(0), comments(0) { return; }
PostStats(int up, int down, int c) :up_votes(up), down_votes(down), comments(c) { return; }
void increment(const PostStats &s)
{
up_votes += s.up_votes;
down_votes += s.down_votes;
comments += s.comments;
return;
}
int up_votes;
int down_votes;
int comments;
std::list<RsGxsId> voters;
};
bool encodePostedCache(std::string &str, const PostStats &s);
bool extractPostedCache(const std::string &str, PostStats &s);
class p3Posted: public RsGenExchange, public RsPosted,
public GxsTokenQueue,
public RsTickEvent /* only needed for testing - remove after */
class p3Posted: public p3PostBase, public RsPosted
{
public:
p3Posted(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs);
virtual void service_tick();
protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
// Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes)
{
return p3PostBase::notifyChanges(changes);
}
public:
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
{
return RsGxsIfaceHelper::receiveChanges(changes);
}
// Posted Specific DataTypes.
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups);
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts);
virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost> &posts);
//////////////////////////////////////////////////////////////////////////////
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
//virtual bool groupRestoreKeys(const std::string &groupId);
//virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
virtual bool createGroup(uint32_t &token, RsPostedGroup &group);
virtual bool createPost(uint32_t &token, RsPostedPost &post);
//////////////////////////////////////////////////////////////////////////////
// WRAPPERS due to the separate Interface.
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read)
{
return p3PostBase::setMessageReadStatus(token, msgId, read);
}
/* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */
@ -145,82 +111,6 @@ virtual bool acknowledgeVote(const uint32_t& token, std::pair<RsGxsGroupId, RsGx
}
return acknowledgeMsg(token, msgId);
}
private:
static uint32_t postedAuthenPolicy();
bool calculateScores(RsPostedPost &post, time_t ref_time);
// Background processing.
void background_tick();
bool background_requestAllGroups();
void background_loadGroups(const uint32_t &token);
void addGroupForProcessing(RsGxsGroupId grpId);
void background_requestUnprocessedGroup();
void background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly);
void background_loadUnprocessedMsgs(const uint32_t &token);
void background_loadAllMsgs(const uint32_t &token);
void background_loadMsgs(const uint32_t &token, bool unprocessed);
void background_updateVoteCounts(const uint32_t &token);
bool background_cleanup();
RsMutex mPostedMtx;
bool mBgProcessing;
bool mBgIncremental;
std::list<RsGxsGroupId> mBgGroupList;
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
// DUMMY DATA,
virtual bool generateDummyData();
std::string genRandomId();
void dummy_tick();
bool generatePost(uint32_t &token, const RsGxsGroupId &grpId);
bool generateComment(uint32_t &token, const RsGxsGroupId &grpId,
const RsGxsMessageId &parentId, const RsGxsMessageId &threadId);
bool generateGroup(uint32_t &token, std::string groupName);
class PostedDummyRef
{
public:
PostedDummyRef() { return; }
PostedDummyRef(const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, const RsGxsMessageId &msgId)
:mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) { return; }
RsGxsGroupId mGroupId;
RsGxsMessageId mThreadId;
RsGxsMessageId mMsgId;
};
uint32_t mGenToken;
bool mGenActive;
int mGenCount;
std::vector<PostedDummyRef> mGenRefs;
RsGxsMessageId mGenThreadId;
p3GxsCommentService *mCommentService;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,190 +0,0 @@
/*
* libretroshare/src/services: p3posted.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3_POSTED_SERVICE_VEG_HEADER
#define P3_POSTED_SERVICE_VEG_HEADER
#include "services/p3gxsserviceVEG.h"
#include "retroshare/rspostedVEG.h"
#include <map>
#include <string>
/*
* Posted Service
*
*/
class PostedDataProxy: public GxsDataProxyVEG
{
public:
bool addGroup(const RsPostedGroup &group);
bool addPost(const RsPostedPost &post);
bool addVote(const RsPostedVote &vote);
bool addComment(const RsPostedComment &comment);
bool getGroup(const std::string &id, RsPostedGroup &group);
bool getPost(const std::string &id, RsPostedPost &post);
bool getVote(const std::string &id, RsPostedVote &vote);
bool getComment(const std::string &id, RsPostedComment &comment);
/* These Functions must be overloaded to complete the service */
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta);
};
class p3PostedServiceVEG: public p3GxsDataServiceVEG, public RsPostedVEG
{
public:
p3PostedServiceVEG(uint16_t type);
virtual int tick();
public:
// NEW INTERFACE.
/************* Extern Interface *******/
virtual bool updated();
/* Data Requests */
virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds);
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list<std::string> &msgIds);
/* Generic Lists */
virtual bool getGroupList( const uint32_t &token, std::list<std::string> &groupIds);
virtual bool getMsgList( const uint32_t &token, std::list<std::string> &msgIds);
/* Generic Summary */
virtual bool getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
virtual bool getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo);
/* Actual Data -> specific to Interface */
/* Specific Service Data */
virtual bool getGroup(const uint32_t &token, RsPostedGroup &group);
virtual bool getPost(const uint32_t &token, RsPostedPost &post);
virtual bool getComment(const uint32_t &token, RsPostedComment &comment);
/* Poll */
virtual uint32_t requestStatus(const uint32_t token);
/* Cancel Request */
virtual bool cancelRequest(const uint32_t &token);
//////////////////////////////////////////////////////////////////////////////
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
virtual bool groupRestoreKeys(const std::string &groupId);
virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
virtual bool submitGroup(uint32_t &token, RsPostedGroup &group, bool isNew);
virtual bool submitPost(uint32_t &token, RsPostedPost &post, bool isNew);
virtual bool submitVote(uint32_t &token, RsPostedVote &vote, bool isNew);
virtual bool submitComment(uint32_t &token, RsPostedComment &comment, bool isNew);
// Extended Interface for Collated Data View.
virtual bool setViewMode(uint32_t mode);
virtual bool setViewPeriod(uint32_t period);
virtual bool setViewRange(uint32_t first, uint32_t count);
virtual bool requestRanking(uint32_t &token, std::string groupId);
virtual bool getRankedPost(const uint32_t &token, RsPostedPost &post);
// These are exposed for GUI usage.
virtual bool encodePostedCache(std::string &str, uint32_t votes, uint32_t comments);
virtual bool extractPostedCache(const std::string &str, uint32_t &votes, uint32_t &comments);
virtual float calcPostScore(const RsMsgMetaData &meta);
private:
//
bool checkRankingRequest();
bool processPosts();
// background processing of Votes.
// NB: These should probably be handled by a background thread.
// At the moment they are run from the tick() thread.
bool background_checkTokenRequest();
bool background_requestGroups();
bool background_requestNewMessages();
bool background_processNewMessages();
bool background_updateVoteCounts();
bool background_cleanup();
std::string genRandomId();
bool generateDummyData();
bool addExtraDummyData();
PostedDataProxy *mPostedProxy;
RsMutex mPostedMtx;
bool mUpdated;
// Ranking view mode, stored here.
uint32_t mViewMode;
uint32_t mViewPeriod;
uint32_t mViewStart;
uint32_t mViewCount;
// Processing Ranking stuff.
bool mProcessingRanking;
uint32_t mRankingState;
uint32_t mRankingExternalToken;
uint32_t mRankingInternalToken;
// background processing - Mutex protected.
time_t mLastBgCheck;
bool mBgProcessing;
uint32_t mBgPhase;
uint32_t mBgToken;
std::map<std::string, uint32_t> mBgVoteMap; // ParentId -> Vote Count.
std::map<std::string, uint32_t> mBgCommentMap; // ThreadId -> Comment Count.
// extra dummy data.
std::list<RsPostedVote> mDummyLaterVotes;
std::list<RsPostedComment> mDummyLaterComments;
};
#endif

View file

@ -0,0 +1,432 @@
/*
* libretroshare/src/services p3rtt.cc
*
* Round Trip Time Measurement for RetroShare.
*
* Copyright 2011-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "util/rsdir.h"
#include "retroshare/rsiface.h"
#include "pqi/pqibin.h"
#include "pqi/pqistore.h"
#include "pqi/p3linkmgr.h"
#include "services/p3rtt.h"
#include "serialiser/rsrttitems.h"
#include <sys/time.h>
/****
* #define DEBUG_RTT 1
****/
/* DEFINE INTERFACE POINTER! */
RsRtt *rsRtt = NULL;
#define MAX_PONG_RESULTS 150
#define RTT_PING_PERIOD 10
/************ IMPLEMENTATION NOTES *********************************
*
* Voice over Retroshare ;)
*
* This will be a simple test VoIP system aimed at testing out the possibilities.
*
* Important things to test:
* 1) lag, and variability in data rate
* - To do this we time tag every packet..., the destination can use this info to calculate the results.
* - Like imixitup. Dt = clock_diff + lag.
* we expect clock_diff to be relatively constant, but lag to vary.
* lag cannot be negative, so minimal Dt is ~clock_diff, and delays on this are considered +lag.
*
* 2) we could directly measure lag. ping back and forth with Timestamps.
*
* 3) we also want to measure bandwidth...
* - not sure the best method?
* one way: send a ping, then a large amount of data (5 seconds worth), then another ping.
* the delta in timestamps should be a decent indication of bandwidth.
* say we have a 100kb/s connection... need 500kb.
* actually the amount of data should be based on a reasonable maximum that we require.
* what does decent video require?
* Audio we can test for 64kb/s - which seems like a decent rate: e.g. mono, 16bit 22k = 1 x 2 x 22k = 44 kilobytes/sec
* best to do this without a VoIP call going on ;)
*
*
*/
#ifdef WINDOWS_SYS
#include <time.h>
#include <sys/timeb.h>
#endif
static double getCurrentTS()
{
#ifndef WINDOWS_SYS
struct timeval cts_tmp;
gettimeofday(&cts_tmp, NULL);
double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0;
#else
struct _timeb timebuf;
_ftime( &timebuf);
double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0;
#endif
return cts;
}
static uint64_t convertTsTo64bits(double ts)
{
uint32_t secs = (uint32_t) ts;
uint32_t usecs = (uint32_t) ((ts - (double) secs) * 1000000);
uint64_t bits = (((uint64_t) secs) << 32) + usecs;
return bits;
}
static double convert64bitsToTs(uint64_t bits)
{
uint32_t usecs = (uint32_t) (bits & 0xffffffff);
uint32_t secs = (uint32_t) ((bits >> 32) & 0xffffffff);
double ts = (secs) + ((double) usecs) / 1000000.0;
return ts;
}
p3rtt::p3rtt(p3LinkMgr *lm)
:p3FastService(RS_SERVICE_TYPE_RTT), mRttMtx("p3rtt"), mLinkMgr(lm)
{
addSerialType(new RsRttSerialiser());
mSentPingTime = 0;
mCounter = 0;
}
int p3rtt::tick()
{
sendPackets();
return 0;
}
int p3rtt::status()
{
return 1;
}
int p3rtt::sendPackets()
{
time_t now = time(NULL);
time_t pt;
{
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
pt = mSentPingTime;
}
if (now - pt > RTT_PING_PERIOD)
{
sendPingMeasurements();
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
mSentPingTime = now;
}
return true ;
}
void p3rtt::sendPingMeasurements()
{
/* we ping our peers */
/* who is online? */
std::list<std::string> idList;
mLinkMgr->getOnlineList(idList);
double ts = getCurrentTS();
#ifdef DEBUG_RTT
std::cerr << "p3rtt::sendPingMeasurements() @ts: " << ts;
std::cerr << std::endl;
#endif
/* prepare packets */
std::list<std::string>::iterator it;
for(it = idList.begin(); it != idList.end(); it++)
{
#ifdef DEBUG_RTT
std::cerr << "p3rtt::sendPingMeasurements() Pinging: " << *it;
std::cerr << std::endl;
#endif
/* create the packet */
RsRttPingItem *pingPkt = new RsRttPingItem();
pingPkt->PeerId(*it);
pingPkt->mSeqNo = mCounter;
pingPkt->mPingTS = convertTsTo64bits(ts);
storePingAttempt(*it, ts, mCounter);
#ifdef DEBUG_RTT
std::cerr << "p3rtt::sendPingMeasurements() With Packet:";
std::cerr << std::endl;
pingPkt->print(std::cerr, 10);
#endif
sendItem(pingPkt);
}
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
mCounter++;
}
bool p3rtt::recvItem(RsItem *item)
{
switch(item->PacketSubType())
{
default:
break;
case RS_PKT_SUBTYPE_RTT_PING:
{
handlePing(item);
}
break;
case RS_PKT_SUBTYPE_RTT_PONG:
{
handlePong(item);
}
break;
}
/* clean up */
delete item;
return true ;
}
int p3rtt::handlePing(RsItem *item)
{
/* cast to right type */
RsRttPingItem *ping = (RsRttPingItem *) item;
#ifdef DEBUG_RTT
std::cerr << "p3rtt::handlePing() Recvd Packet from: " << ping->PeerId();
std::cerr << std::endl;
#endif
/* with a ping, we just respond as quickly as possible - they do all the analysis */
RsRttPongItem *pong = new RsRttPongItem();
pong->PeerId(ping->PeerId());
pong->mPingTS = ping->mPingTS;
pong->mSeqNo = ping->mSeqNo;
// add our timestamp.
double ts = getCurrentTS();
pong->mPongTS = convertTsTo64bits(ts);
#ifdef DEBUG_RTT
std::cerr << "p3rtt::handlePing() With Packet:";
std::cerr << std::endl;
pong->print(std::cerr, 10);
#endif
sendItem(pong);
return true ;
}
int p3rtt::handlePong(RsItem *item)
{
/* cast to right type */
RsRttPongItem *pong = (RsRttPongItem *) item;
#ifdef DEBUG_RTT
std::cerr << "p3rtt::handlePong() Recvd Packet from: " << pong->PeerId();
std::cerr << std::endl;
pong->print(std::cerr, 10);
#endif
/* with a pong, we do the maths! */
double recvTS = getCurrentTS();
double pingTS = convert64bitsToTs(pong->mPingTS);
double pongTS = convert64bitsToTs(pong->mPongTS);
double rtt = recvTS - pingTS;
double offset = pongTS - (recvTS - rtt / 2.0); // so to get to their time, we go ourTS + offset.
#ifdef DEBUG_RTT
std::cerr << "p3rtt::handlePong() Timing:";
std::cerr << std::endl;
std::cerr << "\tpingTS: " << pingTS;
std::cerr << std::endl;
std::cerr << "\tpongTS: " << pongTS;
std::cerr << std::endl;
std::cerr << "\trecvTS: " << recvTS;
std::cerr << std::endl;
std::cerr << "\t ==> rtt: " << rtt;
std::cerr << std::endl;
std::cerr << "\t ==> offset: " << offset;
std::cerr << std::endl;
#endif
storePongResult(pong->PeerId(), pong->mSeqNo, pingTS, rtt, offset);
return true ;
}
int p3rtt::storePingAttempt(std::string id, double ts, uint32_t seqno)
{
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
/* find corresponding local data */
RttPeerInfo *peerInfo = locked_GetPeerInfo(id);
peerInfo->mCurrentPingTS = ts;
peerInfo->mCurrentPingCounter = seqno;
peerInfo->mSentPings++;
if (!peerInfo->mCurrentPongRecvd)
{
peerInfo->mLostPongs++;
}
peerInfo->mCurrentPongRecvd = true;
return 1;
}
int p3rtt::storePongResult(std::string id, uint32_t counter, double ts, double rtt, double offset)
{
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
/* find corresponding local data */
RttPeerInfo *peerInfo = locked_GetPeerInfo(id);
if (peerInfo->mCurrentPingCounter != counter)
{
#ifdef DEBUG_RTT
std::cerr << "p3rtt::storePongResult() ERROR Severly Delayed Measurements!" << std::endl;
#endif
}
else
{
peerInfo->mCurrentPongRecvd = true;
}
peerInfo->mPongResults.push_back(RsRttPongResult(ts, rtt, offset));
while(peerInfo->mPongResults.size() > MAX_PONG_RESULTS)
{
peerInfo->mPongResults.pop_front();
}
/* should do calculations */
return 1;
}
uint32_t p3rtt::getPongResults(std::string id, int n, std::list<RsRttPongResult> &results)
{
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
RttPeerInfo *peer = locked_GetPeerInfo(id);
std::list<RsRttPongResult>::reverse_iterator it;
int i = 0;
for(it = peer->mPongResults.rbegin(); (it != peer->mPongResults.rend()) && (i < n); it++, i++)
{
/* reversing order - so its easy to trim later */
results.push_back(*it);
}
return i ;
}
RttPeerInfo *p3rtt::locked_GetPeerInfo(std::string id)
{
std::map<std::string, RttPeerInfo>::iterator it;
it = mPeerInfo.find(id);
if (it == mPeerInfo.end())
{
/* add it in */
RttPeerInfo pinfo;
/* initialise entry */
pinfo.initialisePeerInfo(id);
mPeerInfo[id] = pinfo;
it = mPeerInfo.find(id);
}
return &(it->second);
}
bool RttPeerInfo::initialisePeerInfo(std::string id)
{
mId = id;
/* reset variables */
mCurrentPingTS = 0;
mCurrentPingCounter = 0;
mCurrentPongRecvd = true;
mSentPings = 0;
mLostPongs = 0;
mPongResults.clear();
return true;
}

View file

@ -0,0 +1,118 @@
/*
* libretroshare/src/services/p3rtt.h
*
* Round Trip Time Measurement for RetroShare.
*
* Copyright 2011-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef SERVICE_RSRTT_HEADER
#define SERVICE_RSRTT_HEADER
#include <list>
#include <string>
#include "serialiser/rsrttitems.h"
#include "services/p3service.h"
#include "retroshare/rsrtt.h"
class p3LinkMgr;
class RttPeerInfo
{
public:
bool initialisePeerInfo(std::string id);
std::string mId;
double mCurrentPingTS;
double mCurrentPingCounter;
bool mCurrentPongRecvd;
uint32_t mLostPongs;
uint32_t mSentPings;
std::list<RsRttPongResult> mPongResults;
};
//!The RS Rtt Test service.
/**
*
* Used to test Latency.
*/
class p3rtt: public RsRtt, public p3FastService
{
public:
p3rtt(p3LinkMgr *cm);
/***** overloaded from rsRtt *****/
virtual uint32_t getPongResults(std::string id, int n, std::list<RsRttPongResult> &results);
/***** overloaded from p3Service *****/
virtual int tick();
virtual int status();
int sendPackets();
void sendPingMeasurements();
virtual bool recvItem(RsItem *item); // Overloaded from p3FastService.
int handlePing(RsItem *item);
int handlePong(RsItem *item);
int storePingAttempt(std::string id, double ts, uint32_t mCounter);
int storePongResult(std::string id, uint32_t counter, double ts, double rtt, double offset);
/*!
* This retrieves all public chat msg items
*/
//bool getPublicChatQueue(std::list<ChatInfo> &chats);
/*************** pqiMonitor callback ***********************/
//virtual void statusChange(const std::list<pqipeer> &plist);
/************* from p3Config *******************/
//virtual RsSerialiser *setupSerialiser() ;
//virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
//virtual void saveDone();
//virtual bool loadList(std::list<RsItem*>& load) ;
private:
RsMutex mRttMtx;
RttPeerInfo *locked_GetPeerInfo(std::string id);
std::map<std::string, RttPeerInfo> mPeerInfo;
time_t mSentPingTime;
uint32_t mCounter;
p3LinkMgr *mLinkMgr;
};
#endif // SERVICE_RSRTT_HEADER

View file

@ -3,11 +3,11 @@
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2008 by Robert Fernie.
* Copyright 2004-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -36,18 +36,14 @@
* #define SERV_DEBUG 1
****/
void p3Service::addSerialType(RsSerialType *st)
{
rsSerialiser->addSerialType(st);
}
RsItem *p3Service::recvItem()
{
srvMtx.lock(); /***** LOCK MUTEX *****/
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
if (recv_queue.size() == 0)
{
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
return NULL; /* nothing there! */
}
@ -55,75 +51,82 @@ RsItem *p3Service::recvItem()
RsItem *item = recv_queue.front();
recv_queue.pop_front();
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
return item;
}
bool p3Service::receivedItems()
{
srvMtx.lock(); /***** LOCK MUTEX *****/
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
bool moreData = (recv_queue.size() != 0);
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
return moreData;
return (!recv_queue.empty());
}
int p3Service::sendItem(RsItem *item)
bool p3Service::recvItem(RsItem *item)
{
srvMtx.lock(); /***** LOCK MUTEX *****/
if (item)
{
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
send_queue.push_back(item);
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
return 1;
recv_queue.push_back(item);
}
return true;
}
void p3FastService::addSerialType(RsSerialType *st)
{
rsSerialiser->addSerialType(st);
}
// overloaded pqiService interface.
int p3Service::receive(RsRawItem *raw)
bool p3FastService::recv(RsRawItem *raw)
{
srvMtx.lock(); /***** LOCK MUTEX *****/
#ifdef SERV_DEBUG
std::cerr << "p3Service::receive()";
std::cerr << std::endl;
#endif
/* convert to RsServiceItem */
uint32_t size = raw->getRawLength();
RsItem *item = rsSerialiser->deserialise(raw->getRawData(), &size);
if ((!item) || (size != raw->getRawLength()))
RsItem *item = NULL;
{
/* error in conversion */
#ifdef SERV_DEBUG
std::cerr << "p3Service::receive() Error" << std::endl;
std::cerr << "p3Service::receive() Size: " << size << std::endl;
std::cerr << "p3Service::receive() RawLength: " << raw->getRawLength() << std::endl;
#endif
if (item)
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
#ifdef SERV_DEBUG
std::cerr << "p3Service::recv()";
std::cerr << std::endl;
#endif
/* convert to RsServiceItem */
uint32_t size = raw->getRawLength();
item = rsSerialiser->deserialise(raw->getRawData(), &size);
if ((!item) || (size != raw->getRawLength()))
{
#ifdef SERV_DEBUG
std::cerr << "p3Service::receive() Bad Item:";
std::cerr << std::endl;
item->print(std::cerr, 0);
std::cerr << std::endl;
#endif
delete item;
item=NULL ;
/* error in conversion */
#ifdef SERV_DEBUG
std::cerr << "p3Service::recv() Error" << std::endl;
std::cerr << "p3Service::recv() Size: " << size << std::endl;
std::cerr << "p3Service::recv() RawLength: " << raw->getRawLength() << std::endl;
#endif
if (item)
{
#ifdef SERV_DEBUG
std::cerr << "p3Service::recv() Bad Item:";
std::cerr << std::endl;
item->print(std::cerr, 0);
std::cerr << std::endl;
#endif
delete item;
item=NULL ;
}
}
}
/* if we have something - pass it on */
if (item)
{
#ifdef SERV_DEBUG
std::cerr << "p3Service::receive() item:";
std::cerr << "p3Service::recv() item:";
std::cerr << std::endl;
item->print(std::cerr, 0);
std::cerr << std::endl;
@ -131,33 +134,22 @@ int p3Service::receive(RsRawItem *raw)
/* ensure PeerId is transferred */
item->PeerId(raw->PeerId());
recv_queue.push_back(item);
recvItem(item);
}
/* cleanup input */
delete raw;
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
return (item != NULL);
}
RsRawItem *p3Service::send()
int p3FastService::sendItem(RsItem *si)
{
srvMtx.lock(); /***** LOCK MUTEX *****/
if (send_queue.size() == 0)
{
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
return NULL; /* nothing there! */
}
/* get something off front */
RsItem *si = send_queue.front();
send_queue.pop_front();
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
#ifdef SERV_DEBUG
std::cerr << "p3Service::send() Sending item:";
std::cerr << "p3Service::sendItem() Sending item:";
std::cerr << std::endl;
si->print(std::cerr, 0);
std::cerr << std::endl;
@ -167,34 +159,29 @@ RsRawItem *p3Service::send()
uint32_t size = rsSerialiser->size(si);
if (!size)
{
#ifdef SERV_DEBUG
std::cerr << "p3Service::send() ERROR size == 0";
std::cerr << std::endl;
#endif
/* can't convert! */
delete si;
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
return NULL;
return 0;
}
RsRawItem *raw = new RsRawItem(si->PacketId(), size);
if (!rsSerialiser->serialise(si, raw->getRawData(), &size))
{
#ifdef SERV_DEBUG
std::cerr << "p3Service::send() ERROR serialise failed";
std::cerr << std::endl;
#endif
delete raw;
raw = NULL;
}
if ((raw) && (size != raw->getRawLength()))
{
#ifdef SERV_DEBUG
std::cerr << "p3Service::send() ERROR serialise size mismatch";
std::cerr << std::endl;
#endif
delete raw;
raw = NULL;
}
@ -207,7 +194,7 @@ RsRawItem *p3Service::send()
if(si->priority_level() == QOS_PRIORITY_UNKNOWN)
{
std::cerr << "************************************************************" << std::endl;
std::cerr << "********** Warning: p3service::send() ********" << std::endl;
std::cerr << "********** Warning: p3Service::send() ********" << std::endl;
std::cerr << "********** Warning: caught a RsItem with undefined ********" << std::endl;
std::cerr << "********** priority level. That should not ********" << std::endl;
std::cerr << "********** happen. Please fix your items! ********" << std::endl;
@ -219,38 +206,11 @@ RsRawItem *p3Service::send()
/* cleanup */
delete si;
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
#ifdef SERV_DEBUG
std::cerr << "p3Service::send() returning RawItem.";
std::cerr << std::endl;
std::cerr << "p3Service::send() returning RawItem.";
std::cerr << std::endl;
#endif
return raw;
return pqiService::send(raw);
}
std::string generateRandomServiceId()
{
std::string out;
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
/* 4 bytes per random number: 4 x 4 = 16 bytes */
for(int i = 0; i < 4; i++)
{
uint32_t rint = random();
rs_sprintf_append(out, "%08x", rint);
}
#else
srand(time(NULL));
/* 2 bytes per random number: 8 x 2 = 16 bytes */
for(int i = 0; i < 8; i++)
{
uint16_t rint = rand(); /* only gives 16 bits */
rs_sprintf_append(out, "%04x", rint);
}
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
return out;
}

View file

@ -52,13 +52,14 @@ std::string generateRandomServiceId();
//TODO : encryption and upload / download rate implementation
class p3Service: public pqiService
class p3FastService: public pqiService
{
protected:
p3Service(uint16_t type)
p3FastService(uint16_t type)
:pqiService((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + (((uint32_t) type) << 8)),
srvMtx("p3Service"), rsSerialiser(NULL)
srvMtx("p3FastService"), rsSerialiser(NULL)
{
rsSerialiser = new RsSerialiser();
return;
@ -66,33 +67,59 @@ class p3Service: public pqiService
public:
virtual ~p3Service() { delete rsSerialiser; return; }
virtual ~p3FastService() { delete rsSerialiser; return; }
/*************** INTERFACE ******************************/
/* called from Thread/tick/GUI */
int sendItem(RsItem *);
RsItem * recvItem();
bool receivedItems();
virtual int tick() { return 0; }
/*************** INTERFACE ******************************/
public:
// overloaded pqiService interface.
virtual int receive(RsRawItem *);
virtual RsRawItem * send();
virtual bool recv(RsRawItem *);
// called by recv().
virtual bool recvItem(RsItem *item) = 0;
protected:
void addSerialType(RsSerialType *);
private:
RsMutex srvMtx;
/* below locked by Mutex */
RsMutex srvMtx; /* below locked by Mutex */
RsSerialiser *rsSerialiser;
std::list<RsItem *> recv_queue, send_queue;
};
class p3Service: public p3FastService
{
protected:
p3Service(uint16_t type)
:p3FastService(type)
{
return;
}
public:
/*************** INTERFACE ******************************/
/* called from Thread/tick/GUI */
//int sendItem(RsItem *);
RsItem * recvItem();
bool receivedItems();
//virtual int tick() { return 0; }
/*************** INTERFACE ******************************/
public:
// overloaded p3FastService interface.
virtual bool recvItem(RsItem *item);
private:
/* below locked by srvMtx Mutex */
std::list<RsItem *> recv_queue;
};
@ -110,16 +137,17 @@ class nullService: public pqiService
public:
// overloaded NULL pqiService interface.
virtual int receive(RsRawItem *item)
virtual bool recv(RsRawItem *item)
{
/* drop any items */
delete item;
return 1;
return true;
}
virtual RsRawItem * send()
virtual bool send(RsRawItem *item)
{
return NULL;
delete item;
return true;
}
};

View file

@ -504,7 +504,7 @@ std::string chooseRandomAuthorId()
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
int i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++) ;
std::string answer;
if (it != ownIds.end())