Merge pull request #223 from csoler/v0.6-ContactList

V0.6 contact list
This commit is contained in:
Cyril Soler 2015-12-27 22:22:51 -05:00
commit 00517fe68d
25 changed files with 590 additions and 332 deletions

View File

@ -25,6 +25,7 @@
#include <unistd.h>
#include <sstream>
#include "openssl/rand.h"
#include "openssl/dh.h"
@ -59,6 +60,12 @@ static const uint32_t DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID = 0xa0001 ;
typedef RsGxsTunnelService::RsGxsTunnelId RsGxsTunnelId;
DistantChatService::DistantChatService() : mDistantChatMtx("distant chat")
{
mGxsTunnels = NULL ;
mDistantChatPermissions = RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE ; // default: accept everyone
}
void DistantChatService::connectToGxsTunnelService(RsGxsTunnelService *tr)
{
mGxsTunnels = tr ;
@ -90,8 +97,9 @@ bool DistantChatService::handleOutgoingItem(RsChatItem *item)
std::cerr << "(EE) serialisation error. Something's really wrong!" << std::endl;
return false;
}
#ifdef DEBUG_DISTANT_CHAT
std::cerr << " sending: " << RsUtil::BinToHex(mem,size) << std::endl;
#endif
mGxsTunnels->sendData( RsGxsTunnelId(item->PeerId()),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID,mem,size);
return true;
@ -99,6 +107,14 @@ bool DistantChatService::handleOutgoingItem(RsChatItem *item)
void DistantChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
{
if(cs->flags & RS_CHAT_FLAG_CONNEXION_REFUSED)
{
#ifdef DEBUG_DISTANT_CHAT
std::cerr << "(II) Distant chat: received notification that peer refuses conversation." << std::endl;
#endif
RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(cs->PeerId())),"Connexion refused by distant peer!") ;
}
if(cs->flags & RS_CHAT_FLAG_CLOSING_DISTANT_CONNECTION)
markDistantChatAsClosed(DistantChatPeerId(cs->PeerId())) ;
@ -108,9 +124,50 @@ void DistantChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
std::cerr << "DistantChatService::handleRecvChatStatusItem(): received keep alive packet for inactive chat! peerId=" << cs->PeerId() << std::endl;
}
bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id)
{
bool res = true ;
if(mDistantChatPermissions & RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS)
res = (rsIdentity!=NULL) && rsIdentity->isARegularContact(gxs_id) ;
if(mDistantChatPermissions & RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY)
res = false ;
if(!res)
{
#ifdef DEBUG_DISTANT_CHAT
std::cerr << "(II) refusing distant chat from peer " << gxs_id << ". Sending a notification back to tunnel " << tunnel_id << std::endl;
#endif
RsChatStatusItem *item = new RsChatStatusItem ;
item->flags = RS_CHAT_FLAG_CONNEXION_REFUSED ;
item->status_string.clear() ; // is not used yet! But could be set in GUI to some message (??).
item->PeerId(RsPeerId(tunnel_id)) ;
// we do not use handleOutGoingItem() because there's no distant chat contact, as the chat is refused.
uint32_t size = item->serial_size() ;
RsTemporaryMemory mem(size) ;
if(!item->serialise(mem,size))
{
std::cerr << "(EE) serialisation error. Something's really wrong!" << std::endl;
return false;
}
std::cerr << " sending: " << RsUtil::BinToHex(mem,size) << std::endl;
mGxsTunnels->sendData( RsGxsTunnelId(item->PeerId()),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID,mem,size);
}
return res ;
}
void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, uint32_t tunnel_status)
{
#ifdef DEBUG_DISTANT_CHAT
std::cerr << "DistantChatService::notifyTunnelStatus(): got notification " << std::hex << tunnel_status << std::dec << " for tunnel " << tunnel_id << std::endl;
#endif
switch(tunnel_status)
{
@ -134,11 +191,11 @@ void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunne
void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, unsigned char *data, uint32_t data_size)
{
#ifdef DEBUG_DISTANT_CHAT
std::cerr << "DistantChatService::receiveData(): got data of size " << data_size << " for tunnel " << tunnel_id << std::endl;
std::cerr << " received: " << RsUtil::BinToHex(data,data_size) << std::endl;
std::cerr << " deserialising..." << std::endl;
RsItem *item = RsChatSerialiser().deserialise(data,&data_size) ;
#endif
// always make the contact up to date. This is useful for server side, which doesn't know about the chat until it
// receives the first item.
@ -149,12 +206,17 @@ void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tu
if(!mGxsTunnels->getTunnelInfo(tunnel_id,tinfo))
return ;
// Check if the data is accepted. We cannot prevent the creation of tunnels at the level of p3GxsTunnels, since tunnels are shared between services.
// however,
DistantChatContact& contact(mDistantChatContacts[DistantChatPeerId(tunnel_id)]) ;
contact.to_id = tinfo.destination_gxs_id ;
contact.from_id = tinfo.source_gxs_id ;
}
RsItem *item = RsChatSerialiser().deserialise(data,&data_size) ;
if(item != NULL)
{
item->PeerId(RsPeerId(tunnel_id)) ; // just in case, but normally this is already done.
@ -243,4 +305,64 @@ bool DistantChatService::closeDistantChatConnexion(const DistantChatPeerId &tunn
return true ;
}
uint32_t DistantChatService::getDistantChatPermissionFlags()
{
return mDistantChatPermissions ;
}
bool DistantChatService::setDistantChatPermissionFlags(uint32_t flags)
{
if(mDistantChatPermissions != flags)
{
mDistantChatPermissions = flags ;
#ifdef DEBUG_DISTANT_CHAT
std::cerr << "(II) Changing distant chat permissions to " << flags << ". Existing openned chats will however remain active until closed" << std::endl;
#endif
triggerConfigSave() ;
}
return true ;
}
void DistantChatService::addToSaveList(std::list<RsItem*>& list) const
{
/* Save permission flags */
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
RsTlvKeyValue kv;
kv.key = "DISTANT_CHAT_PERMISSION_FLAGS" ;
kv.value = RsUtil::NumberToString(mDistantChatPermissions) ;
vitem->tlvkvs.pairs.push_back(kv) ;
list.push_back(vitem) ;
}
bool DistantChatService::processLoadListItem(const RsItem *item)
{
const RsConfigKeyValueSet *vitem = NULL ;
if(NULL != (vitem = dynamic_cast<const RsConfigKeyValueSet*>(item)))
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
if(kit->key == "DISTANT_CHAT_PERMISSION_FLAGS")
{
#ifdef DEBUG_DISTANT_CHAT
std::cerr << "Loaded distant chat permission flags: " << kit->value << std::endl ;
#endif
if (!kit->value.empty())
{
std::istringstream is(kit->value) ;
uint32_t tmp ;
is >> tmp ;
if(tmp < 3)
mDistantChatPermissions = tmp ;
else
std::cerr << "(EE) Invalid value read for DistantChatPermission flags in config: " << tmp << std::endl;
}
return true;
}
return false ;
}

View File

@ -39,14 +39,11 @@ public:
// So, public interface only uses DistandChatPeerId, but internally, this is converted into a RsGxsTunnelService::RsGxsTunnelId
DistantChatService() : mDistantChatMtx("distant chat")
{
mGxsTunnels = NULL ;
}
DistantChatService() ;
// Overloaded methods from RsGxsTunnelClientService
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
virtual void triggerConfigSave()=0 ;
bool processLoadListItem(const RsItem *item) ;
void addToSaveList(std::list<RsItem*>& list) const;
// Creates the invite if the public key of the distant peer is available.
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
@ -54,6 +51,14 @@ public:
bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId &from_gxs_id, DistantChatPeerId& dcpid, uint32_t &error_code) ;
bool closeDistantChatConnexion(const DistantChatPeerId &tunnel_id) ;
// Sets flags to only allow connexion from some people.
uint32_t getDistantChatPermissionFlags() ;
bool setDistantChatPermissionFlags(uint32_t flags) ;
// Returns the status of a distant chat contact. The contact is defined by the tunnel id (turned into a DistantChatPeerId) because
// each pair of talking GXS id needs to be treated separately
virtual bool getDistantChatStatus(const DistantChatPeerId &tunnel_id, DistantChatPeerInfo& cinfo) ;
// derived in p3ChatService, so as to pass down some info
@ -74,8 +79,17 @@ private:
//
std::map<DistantChatPeerId, DistantChatContact> mDistantChatContacts ; // current peers we can talk to
// Permission handling
uint32_t mDistantChatPermissions ;
// Overloaded from RsGxsTunnelClientService
public:
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
private:
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelService::RsGxsTunnelId& tunnel_id) ;
virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ;
virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ;
@ -84,6 +98,5 @@ private:
void markDistantChatAsClosed(const DistantChatPeerId& dcpid) ;
RsGxsTunnelService *mGxsTunnels ;
RsMutex mDistantChatMtx ;
};

View File

@ -1192,11 +1192,8 @@ bool p3ChatService::loadList(std::list<RsItem*>& load)
continue;
}
if(DistributedChatService::processLoadListItem(*it))
{
delete *it;
continue;
}
DistributedChatService::processLoadListItem(*it) ;
DistantChatService::processLoadListItem(*it) ;
// delete unknown items
delete *it;
@ -1238,6 +1235,7 @@ bool p3ChatService::saveList(bool& cleanup, std::list<RsItem*>& list)
}
DistributedChatService::addToSaveList(list) ;
DistantChatService::addToSaveList(list) ;
return true;
}

View File

@ -48,6 +48,7 @@ const uint32_t RS_CHAT_FLAG_LOBBY = 0x0200;
const uint32_t RS_CHAT_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400;
const uint32_t RS_CHAT_FLAG_ACK_DISTANT_CONNECTION = 0x0800;
const uint32_t RS_CHAT_FLAG_KEEP_ALIVE = 0x1000;
const uint32_t RS_CHAT_FLAG_CONNEXION_REFUSED = 0x2000;
const uint32_t RS_CHATMSG_CONFIGFLAG_INCOMING = 0x0001;

View File

@ -73,6 +73,10 @@ class GRouterClientService
// 2 - call pt->registerTunnelService(this), so that the TR knows that service and can send back information to it.
//
virtual void connectToGlobalRouter(p3GRouter *pt) = 0 ;
// should be derived to determine wether the client accepts data from this peer or not. If not, the data is dropped.
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id) =0;
};

View File

@ -1661,10 +1661,13 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
std::cerr << " notyfying client." << std::endl;
#endif
if(client->acceptDataFromPeer(decrypted_item->signature.keyId))
{
client->receiveGRouterData(decrypted_item->destination_key,decrypted_item->signature.keyId,service_id,decrypted_item->data_bytes,decrypted_item->data_size);
decrypted_item->data_bytes = NULL ;
decrypted_item->data_size = 0 ;
}
delete decrypted_item ;
}

View File

@ -327,6 +327,8 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
#endif
RsGxsTunnelClientService *service = NULL ;
RsGxsId peer_from ;
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
std::map<uint32_t,RsGxsTunnelClientService *>::const_iterator it = mRegisteredServices.find(item->service_id) ;
@ -341,9 +343,13 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it2 = _gxs_tunnel_contacts.find(tunnel_id) ;
if(it2 != _gxs_tunnel_contacts.end())
{
it2->second.client_services.insert(item->service_id) ;
peer_from = it2->second.to_gxs_id ;
}
}
if(service->acceptDataFromPeer(peer_from,tunnel_id))
service->receiveData(tunnel_id,item->data,item->data_size) ;
item->data = NULL ; // avoids deletion, since the client has the memory now

View File

@ -32,7 +32,7 @@
#include "gxstunnel/rsgxstunnelitems.h"
#define GXS_TUNNEL_ITEM_DEBUG 1
//#define GXS_TUNNEL_ITEM_DEBUG 1
std::ostream& RsGxsTunnelDHPublicKeyItem::print(std::ostream &out, uint16_t indent)
{

View File

@ -63,6 +63,10 @@ public:
// Used by the creator of the service to supply a pointer to the GXS tunnel service for it to be able to send data etc.
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) =0;
// Gives feedback about type of data that is allowed in. For security reasons, this always needs to be re-derived (Clients can return true on default)
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id) = 0 ;
};
class GxsTunnelInfo

View File

@ -250,6 +250,7 @@ virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag) = 0;
virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) = 0 ;
virtual bool isARegularContact(const RsGxsId& id) = 0 ;
// Specific RsIdentity Functions....
/* Specific Service Data */

View File

@ -264,11 +264,15 @@ public:
#define RS_DISTANT_CHAT_FLAG_SIGNED 0x0001
#define RS_DISTANT_CHAT_FLAG_SIGNATURE_OK 0x0002
// flags to define who we accept to talk to
// flags to define who we accept to talk to. Each flag *removes* some people.
#define RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_NONE 0x0000
#define RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_EVERYBODY 0x0001
#define RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_CONTACT_LIST 0x0002
#define RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NONE 0x0000
#define RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS 0x0001
#define RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY 0x0002
#define RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE 0x0000
#define RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS 0x0001
#define RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY 0x0002
struct DistantChatPeerInfo
{
@ -482,6 +486,9 @@ virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId&
/* Distant chat */
/****************************************/
virtual uint32_t getDistantChatPermissionFlags()=0 ;
virtual bool setDistantChatPermissionFlags(uint32_t flags)=0 ;
virtual bool initiateDistantChatConnexion(const RsGxsId& to_pid,const RsGxsId& from_pid,DistantChatPeerId& pid,uint32_t& error_code) = 0;
virtual bool getDistantChatStatus(const DistantChatPeerId& pid,DistantChatPeerInfo& info)=0;
virtual bool closeDistantChatConnexion(const DistantChatPeerId& pid)=0;

View File

@ -537,4 +537,12 @@ bool p3Msgs::closeDistantChatConnexion(const DistantChatPeerId &pid)
{
return mChatSrv->closeDistantChatConnexion(pid) ;
}
bool p3Msgs::setDistantChatPermissionFlags(uint32_t flags)
{
return mChatSrv->setDistantChatPermissionFlags(flags) ;
}
uint32_t p3Msgs::getDistantChatPermissionFlags()
{
return mChatSrv->getDistantChatPermissionFlags() ;
}

View File

@ -159,6 +159,9 @@ class p3Msgs: public RsMsgs
virtual bool getDistantChatStatus(const DistantChatPeerId& gxs_id,DistantChatPeerInfo& info);
virtual bool closeDistantChatConnexion(const DistantChatPeerId &pid) ;
virtual uint32_t getDistantChatPermissionFlags() ;
virtual bool setDistantChatPermissionFlags(uint32_t flags) ;
private:
p3MsgService *mMsgSrv;

View File

@ -212,6 +212,13 @@ uint32_t p3IdService::idAuthenPolicy()
return policy;
}
bool p3IdService::isARegularContact(const RsGxsId& id)
{
RsStackMutex stack(mIdMtx);
return mContacts.find(id) != mContacts.end() ;
}
bool p3IdService::setAsRegularContact(const RsGxsId& id,bool b)
{
std::set<RsGxsId>::iterator it = mContacts.find(id) ;

View File

@ -266,6 +266,7 @@ virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag);
virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) ;
virtual bool isARegularContact(const RsGxsId& id) ;
/**************** RsGixs Implementation ***************/

View File

@ -87,6 +87,7 @@ p3MsgService::p3MsgService(p3ServiceControl *sc, p3IdService *id_serv)
mShouldEnableDistantMessaging = true ;
mDistantMessagingEnabled = false ;
mDistantMessagePermissions = RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NONE ;
/* Initialize standard tag types */
if(sc)
@ -469,6 +470,10 @@ bool p3MsgService::saveList(bool& cleanup, std::list<RsItem*>& itemList)
kv.value = mShouldEnableDistantMessaging?"YES":"NO" ;
vitem->tlvkvs.pairs.push_back(kv) ;
kv.key = "DISTANT_MESSAGE_PERMISSION_FLAGS" ;
kv.value = RsUtil::NumberToString(mDistantMessagePermissions) ;
vitem->tlvkvs.pairs.push_back(kv) ;
itemList.push_back(vitem) ;
return true;
@ -598,6 +603,7 @@ bool p3MsgService::loadList(std::list<RsItem*>& load)
if(NULL != (vitem = dynamic_cast<RsConfigKeyValueSet*>(*it)))
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
{
if(kit->key == "DISTANT_MESSAGES_ENABLED")
{
#ifdef MSG_DEBUG
@ -605,6 +611,25 @@ bool p3MsgService::loadList(std::list<RsItem*>& load)
#endif
mShouldEnableDistantMessaging = (kit->value == "YES") ;
}
if(kit->key == "DISTANT_MESSAGE_PERMISSION_FLAGS")
{
#ifdef MSG_DEBUG
std::cerr << "Loaded distant message permission flags: " << kit->value << std::endl ;
#endif
if (!kit->value.empty())
{
std::istringstream is(kit->value) ;
uint32_t tmp ;
is >> tmp ;
if(tmp < 3)
mDistantMessagePermissions = tmp ;
else
std::cerr << "(EE) Invalid value read for DistantMessagePermission flags in config: " << tmp << std::endl;
}
}
}
}
@ -1791,6 +1816,32 @@ void p3MsgService::notifyDataStatus(const GRouterMsgPropagationId& id,uint32_t d
RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD);
IndicateConfigChanged() ;
}
bool p3MsgService::acceptDataFromPeer(const RsGxsId& to_gxs_id)
{
if(mDistantMessagePermissions & RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS)
return (rsIdentity!=NULL) && rsIdentity->isARegularContact(to_gxs_id) ;
if(mDistantMessagePermissions & RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY)
return false ;
return true ;
}
void p3MsgService::setDistantMessagingPermissionFlags(uint32_t flags)
{
if(flags != mDistantMessagePermissions)
{
mDistantMessagePermissions = flags ;
IndicateConfigChanged() ;
}
}
uint32_t p3MsgService::getDistantMessagingPermissionFlags()
{
return mDistantMessagePermissions ;
}
void p3MsgService::receiveGRouterData(const RsGxsId& destination_key, const RsGxsId& signing_key,GRouterServiceId& client_id,uint8_t *data,uint32_t data_size)
{
std::cerr << "p3MsgService::receiveGRouterData(): received message item of size " << data_size << ", for key " << destination_key << std::endl;

View File

@ -126,8 +126,9 @@ class p3MsgService: public p3Service, public p3Config, public pqiServiceMonitor,
};
void enableDistantMessaging(bool b) ;
bool distantMessagingEnabled() ;
void setDistantMessagingPermissionFlags(uint32_t flags) {}
uint32_t getDistantMessagingPermissionFlags() { return 0 ;}
void setDistantMessagingPermissionFlags(uint32_t flags) ;
uint32_t getDistantMessagingPermissionFlags() ;
private:
void sendDistantMsgItem(RsMsgItem *msgitem) ;
@ -139,6 +140,7 @@ class p3MsgService: public p3Service, public p3Config, public pqiServiceMonitor,
// Overloaded from GRouterClientService
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id) ;
virtual void receiveGRouterData(const RsGxsId& destination_key,const RsGxsId& signing_key, GRouterServiceId &client_id, uint8_t *data, uint32_t data_size) ;
virtual void notifyDataStatus(const GRouterMsgPropagationId& msg_id,uint32_t data_status) ;
@ -205,6 +207,7 @@ class p3MsgService: public p3Service, public p3Config, public pqiServiceMonitor,
std::string config_dir;
bool mDistantMessagingEnabled ;
uint32_t mDistantMessagePermissions ;
bool mShouldEnableDistantMessaging ;
};

View File

@ -27,6 +27,7 @@
#include "util/rsprint.h"
#include "util/rsstring.h"
#include <iomanip>
#include <sstream>
#include <openssl/sha.h>
#include <sys/time.h>
@ -35,6 +36,15 @@
#include <sys/timeb.h>
#endif
std::string RsUtil::NumberToString(uint64_t n)
{
std::ostringstream os ;
os << n ;
os.flush() ;
return os.str();
}
std::string RsUtil::BinToHex(const std::string &bin)
{
return BinToHex(bin.c_str(), bin.length());

View File

@ -36,6 +36,7 @@ namespace RsUtil {
std::string BinToHex(const std::string &bin);
std::string BinToHex(const char *arr, const uint32_t len);
std::string BinToHex(const unsigned char *arr, const uint32_t len);
std::string NumberToString(uint64_t n);
std::string HashId(const std::string &id, bool reverse = false);
//std::string AccurateTimeString();

View File

@ -113,7 +113,7 @@ QString RSGraphSource::legend(int i,float v) const
return displayName(i) + " (" + displayValue(v) + " )";
}
void RSGraphSource::getDataPoints(int index,std::vector<QPointF>& pts) const
void RSGraphSource::getDataPoints(int index,std::vector<QPointF>& pts,float filter_factor) const
{
pts.clear() ;
qint64 now = getTime() ;
@ -126,8 +126,15 @@ void RSGraphSource::getDataPoints(int index,std::vector<QPointF>& pts) const
if(n != index)
return ;
float last_value = it->second.empty()?0.0f:(it->second.begin()->second) ;
for(std::list<std::pair<qint64,float> >::const_iterator it2=it->second.begin();it2!=it->second.end();++it2)
pts.push_back(QPointF( (now - (*it2).first)/1000.0f,(*it2).second)) ;
{
float val = (1-filter_factor)*(*it2).second + filter_factor*last_value;
last_value = val ;
pts.push_back(QPointF( (now - (*it2).first)/1000.0f, val)) ;
}
}
void RSGraphWidget::setShowEntry(uint32_t entry,bool b)
@ -231,6 +238,7 @@ RSGraphWidget::RSGraphWidget(QWidget *parent)
_opacity = 0.6 ;
_flags = 0;
_time_scale = 5.0f ; // in pixels per second.
_time_filter = 1.0f ;
_timer = new QTimer ;
QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(updateIfPossible())) ;
@ -370,7 +378,8 @@ void RSGraphWidget::paintData()
if( _masked_entries.find(source.displayName(i).toStdString()) == _masked_entries.end() )
{
std::vector<QPointF> values ;
source.getDataPoints(i,values) ;
//std::cerr << "time filter = " << _time_filter << ", factor=" << 1./_time_scale*_time_filter/(1+_time_filter/_time_scale) << std::endl;
source.getDataPoints(i,values,1./_time_scale*_time_filter/(1.0f+_time_filter/_time_scale)) ;
QVector<QPointF> points ;
pointsFromData(values,points) ;
@ -601,6 +610,12 @@ void RSGraphWidget::paintScale2()
void RSGraphWidget::wheelEvent(QWheelEvent *e)
{
if(e->modifiers() & Qt::ShiftModifier)
if(e->delta() > 0)
_time_filter *= 1.1 ;
else
_time_filter /= 1.1 ;
else
if(e->delta() > 0)
_time_scale *= 1.1 ;
else

View File

@ -73,7 +73,7 @@ public:
virtual QString legend(int i,float v) const ;
// Returns the n^th interpolated value at the given time in floating point seconds backward.
virtual void getDataPoints(int index, std::vector<QPointF>& pts) const ;
virtual void getDataPoints(int index, std::vector<QPointF>& pts, float filter_factor=0.0f) const ;
// returns the name to give to the nth entry in the graph
virtual QString displayName(int index) const ;
@ -207,6 +207,7 @@ class RSGraphWidget: public QFrame
std::set<std::string> _masked_entries ;
qreal _time_scale ; // horizontal scale in pixels per sec.
qreal _time_filter ; // time filter. Goes from 0 to infinity. Will be converted into 1-1/(1+f)
/** Show the respective lines and counters. */
//bool _showRSDHT;

View File

@ -506,16 +506,15 @@ void ChatPage::distantChatComboBoxChanged(int i)
{
switch(i)
{
case 0: ;
default:
case 0: rsMsgs->setDistantChatPermissionFlags(RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE) ;
break ;
case 1: ;
case 1: rsMsgs->setDistantChatPermissionFlags(RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS) ;
break ;
case 2: ;
case 2: rsMsgs->setDistantChatPermissionFlags(RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY) ;
break ;
default: ;
}
}

View File

@ -64,13 +64,13 @@ void MessagePage::distantMsgsComboBoxChanged(int i)
{
switch(i)
{
case 0: rsMail->setDistantMessagingPermissionFlags(RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_EVERYBODY |RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_CONTACT_LIST) ;
case 0: rsMail->setDistantMessagingPermissionFlags(RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NONE) ;
break ;
case 1: rsMail->setDistantMessagingPermissionFlags(RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_CONTACT_LIST) ;
case 1: rsMail->setDistantMessagingPermissionFlags(RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS) ;
break ;
case 2: rsMail->setDistantMessagingPermissionFlags(RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_NONE) ;
case 2: rsMail->setDistantMessagingPermissionFlags(RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY) ;
break ;
@ -123,9 +123,9 @@ MessagePage::load()
uint32_t flags = rsMail->getDistantMessagingPermissionFlags() ;
if(flags == (RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_CONTACT_LIST | RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_EVERYBODY))
if(flags & RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY)
ui.comboBox->setCurrentIndex(2);
else if(flags == RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_CONTACT_LIST)
else if(flags & RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS)
ui.comboBox->setCurrentIndex(1);
else
ui.comboBox->setCurrentIndex(0);