fixed GUI update of avatars and status for distant chat. Updated backend for new model. Fixed a few bugs in serialisation

This commit is contained in:
csoler 2015-11-30 00:02:44 -05:00
parent 6951d730a5
commit 81ab43beb9
27 changed files with 515 additions and 289 deletions

View File

@ -72,7 +72,7 @@ StreamBase& operator << (StreamBase& left, ChatHandler::Lobby& l)
<< makeKeyValueReference("subscribed", l.subscribed)
<< makeKeyValueReference("auto_subscribe", l.auto_subscribe)
<< makeKeyValueReference("is_private", l.is_private)
<< makeKeyValueReference("gxs_id", l.gxs_id);
<< makeKeyValueReference("distant_chat_id", l.distant_chat_id);
return left;
}
@ -81,7 +81,7 @@ StreamBase& operator << (StreamBase& left, ChatHandler::ChatInfo& info)
left << makeKeyValueReference("remote_author_id", info.remote_author_id)
<< makeKeyValueReference("remote_author_name", info.remote_author_name)
<< makeKeyValueReference("is_broadcast", info.is_broadcast)
<< makeKeyValueReference("is_gxs_id", info.is_gxs_id)
<< makeKeyValueReference("is_distant_chat_id", info.is_distant_chat_id)
<< makeKeyValueReference("is_lobby", info.is_lobby)
<< makeKeyValueReference("is_peer", info.is_peer);
return left;
@ -157,7 +157,7 @@ void ChatHandler::tick()
l.subscribed = true;
l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC);
l.gxs_id = info.gxs_id;
l.distant_chat_id.clear() ;
lobbies.push_back(l);
}
}
@ -176,7 +176,7 @@ void ChatHandler::tick()
l.subscribed = false;
l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC);
l.gxs_id = RsGxsId();
l.distant_chat_id.clear();
lobbies.push_back(l);
}
}
@ -199,11 +199,19 @@ void ChatHandler::tick()
author_id = msg.broadcast_peer_id.toStdString();
author_name = mRsPeers->getPeerName(msg.broadcast_peer_id);
}
else if(msg.chat_id.isGxsId())
else if(msg.chat_id.isDistantChatId())
{
author_id = msg.chat_id.toGxsId().toStdString();
DistantChatPeerInfo dcpinfo ;
if(!rsMsgs->getDistantChatStatus(msg.chat_id.toDistantChatId(),dcpinfo))
{
std::cerr << "(EE) cannot get info for distant chat peer " << msg.chat_id.toDistantChatId() << std::endl;
continue ;
}
author_id = dcpinfo.to_id.toStdString();
RsIdentityDetails details;
if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.chat_id.toGxsId(), details))
if(!gxs_id_failed && mRsIdentity->getIdDetails(dcpinfo.to_id, details))
{
author_name = details.mNickname;
}
@ -252,7 +260,7 @@ void ChatHandler::tick()
{
ChatInfo info;
info.is_broadcast = msg.chat_id.isBroadcast();
info.is_gxs_id = msg.chat_id.isGxsId();
info.is_distant_chat_id = msg.chat_id.isDistantChatId();
info.is_lobby = msg.chat_id.isLobbyId();
info.is_peer = msg.chat_id.isPeerId();
if(msg.chat_id.isLobbyId())
@ -263,10 +271,13 @@ void ChatHandler::tick()
info.remote_author_name = vit->name;
}
}
else if(msg.chat_id.isGxsId())
else if(msg.chat_id.isDistantChatId())
{
RsIdentityDetails details;
if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.chat_id.toGxsId(), details))
DistantChatPeerInfo dcpinfo ;
if(!gxs_id_failed && rsMsgs->getDistantChatStatus(msg.chat_id.toDistantChatId(),dcpinfo)
&& mRsIdentity->getIdDetails(dcpinfo.to_id, details))
{
info.remote_author_id = msg.chat_id.toGxsId().toStdString();
info.remote_author_name = details.mNickname;

View File

@ -65,7 +65,7 @@ public:
bool auto_subscribe;
bool is_private;
RsGxsId gxs_id;// for subscribed lobbies: the id we use to write messages
DistantChatPeerId distant_chat_id;// for subscribed lobbies: the id we use to write messages
bool operator==(const Lobby& l) const
{
@ -75,14 +75,14 @@ public:
&& subscribed == l.subscribed
&& auto_subscribe == l.auto_subscribe
&& is_private == l.is_private
&& gxs_id == l.gxs_id;
&& distant_chat_id == l.distant_chat_id;
}
};
class ChatInfo{
public:
bool is_broadcast;
bool is_gxs_id;
bool is_distant_chat_id;
bool is_lobby;
bool is_peer;
std::string remote_author_id;

View File

@ -32,6 +32,7 @@
#include "util/rsaes.h"
#include "util/rsmemory.h"
#include "util/rsprint.h"
#include <serialiser/rsmsgitems.h>
@ -90,6 +91,8 @@ bool DistantChatService::handleOutgoingItem(RsChatItem *item)
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 true;
}
@ -108,18 +111,62 @@ void DistantChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, uint32_t tunnel_status)
{
std::cerr << "DistantChatService::notifyTunnelStatus(): got notification " << std::hex << tunnel_status << std::dec << " for tunnel " << tunnel_id << std::endl;
#warning do something here
switch(tunnel_status)
{
default:
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_UNKNOWN: std::cerr << "(EE) don't know how to handle RS_GXS_TUNNEL_STATUS_UNKNOWN !" << std::endl;
break ;
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_CAN_TALK: RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(tunnel_id)),"Tunnel is secured. You can talk!") ;
RsServer::notify()->notifyPeerStatusChanged(tunnel_id.toStdString(),RS_STATUS_ONLINE) ;
break ;
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_TUNNEL_DN: RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(tunnel_id)),"tunnel is down...") ;
RsServer::notify()->notifyPeerStatusChanged(tunnel_id.toStdString(),RS_STATUS_OFFLINE) ;
break ;
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED: RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(tunnel_id)),"tunnel is down...") ;
RsServer::notify()->notifyPeerStatusChanged(tunnel_id.toStdString(),RS_STATUS_OFFLINE) ;
break ;
}
}
void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, unsigned char *data, uint32_t data_size)
{
std::cerr << "DistantChatService::receiveData(): got data of size " << data_size << " for tunnel " << tunnel_id << std::endl;
#warning do something here
std::cerr << " received: " << RsUtil::BinToHex(data,data_size) << std::endl;
std::cerr << " deserialising..." << std::endl;
RsItem *item = RsChatSerialiser().deserialise(data,&data_size) ;
// 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.
{
RS_STACK_MUTEX(mDistantChatMtx) ;
RsGxsTunnelService::GxsTunnelInfo tinfo;
if(!mGxsTunnels->getTunnelInfo(tunnel_id,tinfo))
return ;
DistantChatContact& contact(mDistantChatContacts[DistantChatPeerId(tunnel_id)]) ;
contact.to_id = tinfo.destination_gxs_id ;
contact.from_id = tinfo.source_gxs_id ;
}
if(item != NULL)
{
handleIncomingItem(item) ;
RsServer::notify()->notifyListChange(NOTIFY_LIST_PRIVATE_INCOMING_CHAT, NOTIFY_TYPE_ADD);
}
else
std::cerr << " (EE) item could not be deserialised!" << std::endl;
}
void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid)
{
mGxsTunnels->closeExistingTunnel(RsGxsTunnelService::RsGxsTunnelId(dcpid)) ;
mGxsTunnels->closeExistingTunnel(RsGxsTunnelService::RsGxsTunnelId(dcpid),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID) ;
RS_STACK_MUTEX(mDistantChatMtx) ;
@ -132,10 +179,10 @@ void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid)
bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, DistantChatPeerId& dcpid, uint32_t& error_code)
{
RsGxsTunnelId tunnel_id ;
if(!mGxsTunnels->requestSecuredTunnel(to_gxs_id,from_gxs_id,tunnel_id,error_code))
if(!mGxsTunnels->requestSecuredTunnel(to_gxs_id,from_gxs_id,tunnel_id,DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID,error_code))
return false ;
dcpid = DistantChatPeerId(tunnel_id) ;
DistantChatContact& dc_contact(mDistantChatContacts[dcpid]) ;
@ -145,6 +192,14 @@ bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id,
error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ;
// Make a self message to raise the chat window
RsChatMsgItem *item = new RsChatMsgItem;
item->message = "[Starting distant chat. Please wait for secure tunnel to be established]" ;
item->chatFlags = RS_CHAT_FLAG_PRIVATE ;
item->PeerId(RsPeerId(tunnel_id)) ;
handleRecvChatMsgItem(item) ;
return true ;
}
@ -160,14 +215,26 @@ bool DistantChatService::getDistantChatStatus(const DistantChatPeerId& tunnel_id
cinfo.to_id = tinfo.destination_gxs_id;
cinfo.own_id = tinfo.source_gxs_id;
cinfo.peer_id = tunnel_id;
cinfo.status = tinfo.tunnel_status; // see the values in rsmsgs.h
switch(tinfo.tunnel_status)
{
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_CAN_TALK : cinfo.status = RS_DISTANT_CHAT_STATUS_CAN_TALK;
break ;
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_TUNNEL_DN: cinfo.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN ;
break ;
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED: cinfo.status = RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED ;
break ;
default:
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_UNKNOWN: cinfo.status = RS_DISTANT_CHAT_STATUS_UNKNOWN;
break ;
}
return true ;
}
bool DistantChatService::closeDistantChatConnexion(const DistantChatPeerId &tunnel_id)
{
mGxsTunnels->closeExistingTunnel(RsGxsTunnelId(tunnel_id)) ;
mGxsTunnels->closeExistingTunnel(RsGxsTunnelId(tunnel_id), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID) ;
// also remove contact. Or do we wait for the notification?

View File

@ -39,7 +39,7 @@ public:
// So, public interface only uses DistandChatPeerId, but internally, this is converted into a RsGxsTunnelService::RsGxsTunnelId
DistantChatService(RsGixs *pids) : mDistantChatMtx("distant chat")
DistantChatService() : mDistantChatMtx("distant chat")
{
mGxsTunnels = NULL ;
}
@ -56,7 +56,7 @@ public:
virtual bool getDistantChatStatus(const DistantChatPeerId &tunnel_id, DistantChatPeerInfo& cinfo) ;
// derived in p3ChatService
// derived in p3ChatService, so as to pass down some info
virtual void handleIncomingItem(RsItem *) = 0;
virtual bool handleRecvChatMsgItem(RsChatMsgItem *ci)=0 ;

View File

@ -54,7 +54,7 @@ static const uint32_t MAX_AVATAR_JPEG_SIZE = 32767; // Maximum size
// Images are 96x96, which makes approx. 27000 bytes uncompressed.
p3ChatService::p3ChatService(p3ServiceControl *sc,p3IdService *pids, p3LinkMgr *lm, p3HistoryMgr *historyMgr)
:DistantChatService(pids),DistributedChatService(getServiceInfo().mServiceType,sc,historyMgr,pids), mChatMtx("p3ChatService"),mServiceCtrl(sc), mLinkMgr(lm) , mHistoryMgr(historyMgr)
: DistributedChatService(getServiceInfo().mServiceType,sc,historyMgr,pids), mChatMtx("p3ChatService"),mServiceCtrl(sc), mLinkMgr(lm) , mHistoryMgr(historyMgr)
{
_serializer = new RsChatSerialiser() ;
@ -217,24 +217,25 @@ void p3ChatService::sendStatusString(const ChatId& id , const std::string& statu
sendLobbyStatusString(id.toLobbyId(),status_string) ;
else if(id.isBroadcast())
sendGroupChatStatusString(status_string);
else if(id.isPeerId() || id.isGxsId())
{
RsChatStatusItem *cs = new RsChatStatusItem ;
else if(id.isPeerId() || id.isDistantChatId())
{
RsChatStatusItem *cs = new RsChatStatusItem ;
cs->status_string = status_string ;
cs->flags = RS_CHAT_FLAG_PRIVATE ;
RsPeerId vpid;
if(id.isGxsId())
vpid = RsPeerId(id.toGxsId());
else
vpid = id.toPeerId();
cs->PeerId(vpid);
cs->status_string = status_string ;
cs->flags = RS_CHAT_FLAG_PRIVATE ;
RsPeerId vpid;
if(id.isDistantChatId())
vpid = RsPeerId(id.toDistantChatId());
else
vpid = id.toPeerId();
cs->PeerId(vpid);
#ifdef CHAT_DEBUG
std::cerr << "sending chat status packet:" << std::endl ;
cs->print(std::cerr) ;
std::cerr << "sending chat status packet:" << std::endl ;
cs->print(std::cerr) ;
#endif
sendChatItem(cs);
sendChatItem(cs);
}
else
{
@ -286,7 +287,6 @@ bool p3ChatService::isOnline(const RsPeerId& pid)
{
// check if the id is a tunnel id or a peer id.
uint32_t status ;
DistantChatPeerInfo dcpinfo;
if(getDistantChatStatus(DistantChatPeerId(pid),dcpinfo))
@ -304,7 +304,7 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
sendPublicChat(msg);
return true;
}
else if(destination.isPeerId()==false && destination.isGxsId()==false)
else if(destination.isPeerId()==false && destination.isDistantChatId()==false)
{
std::cerr << "p3ChatService::sendChat() Error: chat id type not handled. Is it empty?" << std::endl;
return false;
@ -316,8 +316,8 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
#endif
RsPeerId vpid;
if(destination.isGxsId())
vpid = RsPeerId(destination.toGxsId()); // convert to virtual peer id
if(destination.isDistantChatId())
vpid = RsPeerId(destination.toDistantChatId()); // convert to virtual peer id
else
vpid = destination.toPeerId();
@ -769,7 +769,6 @@ void p3ChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
std::cerr << "Received status string \"" << cs->status_string << "\"" << std::endl ;
#endif
uint32_t status;
DistantChatPeerInfo dcpinfo;
if(cs->flags & RS_CHAT_FLAG_REQUEST_CUSTOM_STATE) // no state here just a request.
@ -820,7 +819,6 @@ void p3ChatService::initChatMessage(RsChatMsgItem *c, ChatMessage &m)
return;
}
uint32_t status;
DistantChatPeerInfo dcpinfo;
if(DistantChatService::getDistantChatStatus(DistantChatPeerId(c->PeerId()), dcpinfo))
m.chat_id = ChatId(DistantChatPeerId(c->PeerId()));

View File

@ -113,6 +113,8 @@ int p3GxsTunnelService::tick()
}
flush() ;
return 0 ;
}
RsServiceInfo p3GxsTunnelService::getServiceInfo()
@ -199,8 +201,8 @@ void p3GxsTunnelService::flush()
{
RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ;
cs->flags = RS_GXS_TUNNEL_FLAG_KEEP_ALIVE;
cs->PeerId(it->second.virtual_peer_id) ;
cs->status = RS_GXS_TUNNEL_FLAG_KEEP_ALIVE;
cs->PeerId(RsPeerId(it->first)) ;
// we send off-mutex to avoid deadlock.
@ -274,7 +276,7 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
RsGxsTunnelDataAckItem *ackitem = new RsGxsTunnelDataAckItem ;
ackitem->unique_item_counter = item->unique_item_counter ;
ackitem->PeerId(item->PeerId());
ackitem->PeerId(RsPeerId(tunnel_id)) ;
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
@ -299,6 +301,11 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
return ;
}
service = it->second ;
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) ;
}
service->receiveData(tunnel_id,item->data,item->data_size) ;
@ -309,13 +316,84 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
void p3GxsTunnelService::handleRecvStatusItem(const RsGxsTunnelId& tunnel_id, RsGxsTunnelStatusItem *cs)
{
if(cs->flags & RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION)
markGxsTunnelAsClosed(tunnel_id);
std::vector<uint32_t> notifications ;
std::set<RsGxsTunnelClientService*> clients ;
// nothing more to do, because the decryption routing will update the last_contact time when decrypting.
std::cerr << "p3GxsTunnelService::handleRecvStatusItem(): tunnel_id=" << tunnel_id << " status=" << cs->status << std::endl;
if(cs->flags & RS_GXS_TUNNEL_FLAG_KEEP_ALIVE)
std::cerr << "GxsTunnelService::handleRecvGxsTunnelStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << " tunnel=" << tunnel_id << std::endl;
switch(cs->status)
{
case RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION:
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
if(it == _gxs_tunnel_contacts.end())
{
std::cerr << "(EE) Cannot mark tunnel connection as closed. No connection openned for tunnel id " << tunnel_id << ". Unexpected situation." << std::endl;
return ;
}
if(it->second.direction == RsTurtleGenericDataItem::DIRECTION_CLIENT)
{
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " This is server side. Marking distant chat as remotely closed for tunnel id " << tunnel_id << std::endl;
#endif
it->second.status = RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED ;
notifications.push_back(RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED) ;
}
} // nothing more to do, because the decryption routing will update the last_contact time when decrypting.
break ;
case RS_GXS_TUNNEL_FLAG_KEEP_ALIVE:
std::cerr << "GxsTunnelService::handleRecvGxsTunnelStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << " tunnel=" << tunnel_id << std::endl;
break ;
case RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION:
{
std::cerr << "Received ACK item from the distant peer!" << std::endl;
// in this case we notify the clients using this tunnel.
notifications.push_back(RS_GXS_TUNNEL_STATUS_CAN_TALK) ;
}
break ;
default:
std::cerr << "(EE) unhandled tunnel status " << std::hex << cs->status << std::dec << std::endl;
break ;
}
// notify all clients
std::cerr << " notifying clients. Prending notifications: " << notifications.size() << std::endl;
if(notifications.size() > 0)
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
std::cerr << " " << it->second.client_services.size() << " client services for tunnel id " << tunnel_id << std::endl;
for(std::set<uint32_t>::const_iterator it2(it->second.client_services.begin());it2!=it->second.client_services.end();++it2)
{
std::map<uint32_t,RsGxsTunnelClientService*>::const_iterator it3=mRegisteredServices.find(*it2) ;
if(it3 != mRegisteredServices.end())
clients.insert(it3->second) ;
}
}
std::cerr << " notifying " << clients.size() << " clients." << std::endl;
for(std::set<RsGxsTunnelClientService*>::const_iterator it(clients.begin());it!=clients.end();++it)
for(uint32_t i=0;i<notifications.size();++i)
{
(*it)->notifyTunnelStatus(tunnel_id,notifications[i]) ;
std::cerr << " notifying client " << (void*)(*it) << " of status " << notifications[i] << std::endl;
}
}
bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/)
@ -435,6 +513,8 @@ void p3GxsTunnelService::locked_restartDHSession(const RsPeerId& virtual_peer_id
void p3GxsTunnelService::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id)
{
bool tunnel_dn = false ;
std::set<RsGxsTunnelClientService*> client_services ;
RsGxsTunnelId tunnel_id ;
#ifdef DEBUG_GXS_TUNNEL
std::cerr << "GxsTunnelService: Removing virtual peer " << virtual_peer_id << " for hash " << hash << std::endl;
@ -454,7 +534,7 @@ void p3GxsTunnelService::removeVirtualPeer(const TurtleFileHash& hash,const Turt
return ;
}
RsGxsTunnelId tunnel_id = it->second.tunnel_id ;
tunnel_id = it->second.tunnel_id ;
if(it->second.dh != NULL)
DH_free(it->second.dh) ;
@ -474,13 +554,22 @@ void p3GxsTunnelService::removeVirtualPeer(const TurtleFileHash& hash,const Turt
it2->second.virtual_peer_id.clear() ;
tunnel_dn = true ;
}
for(std::set<uint32_t>::const_iterator it(it2->second.client_services.begin());it!=it2->second.client_services.end();++it)
{
std::map<uint32_t,RsGxsTunnelClientService*>::const_iterator it2 = mRegisteredServices.find(*it) ;
if(it2 != mRegisteredServices.end())
client_services.insert(it2->second) ;
}
}
if(tunnel_dn)
{
#warning we should notify the client here
//RsServer::notify()->notifyChatStatus(ChatId(RsGxsId(virtual_peer_id)),"tunnel is down...") ;
//RsServer::notify()->notifyPeerStatusChanged(virtual_peer_id.toStdString(),RS_STATUS_OFFLINE) ;
// notify all client services that this tunnel is down
for(std::set<RsGxsTunnelClientService*>::const_iterator it(client_services.begin());it!=client_services.end();++it)
(*it)->notifyTunnelStatus(tunnel_id,RS_GXS_TUNNEL_STATUS_TUNNEL_DN) ;
}
}
@ -824,8 +913,8 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item)
RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ;
cs->flags = RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION;
cs->PeerId(vpid) ;
cs->status = RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION;
cs->PeerId(RsPeerId(tunnel_id)) ;
pendingGxsTunnelItems.push_back(cs) ;
}
@ -958,7 +1047,9 @@ bool p3GxsTunnelService::locked_initDHSessionKey(DH *& dh)
return true ;
}
// Encrypts and sends the item.
// Sends the item in clear. This is only used for DH key exchange.
// in this case only, the item's PeerId is equal to the virtual peer Id for the tunnel,
// since we ight not now the tunnel id yet.
bool p3GxsTunnelService::locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item)
{
@ -1013,27 +1104,21 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
uint64_t IV = 0;
#ifdef DEBUG_GXS_TUNNEL
std::cerr << "Sending encrypted data to tunnel wuth vpid " << item->PeerId() << std::endl;
std::cerr << "Sending encrypted data to tunnel with vpid " << item->PeerId() << std::endl;
#endif
TurtleVirtualPeerId vpid = item->PeerId() ;
RsGxsTunnelId tunnel_id ( item->PeerId() );
std::map<TurtleVirtualPeerId,GxsTunnelDHInfo>::const_iterator it2 = _gxs_tunnel_virtual_peer_ids.find(vpid) ;
if(it2 == _gxs_tunnel_virtual_peer_ids.end())
{
std::cerr << "(EE) no virtual peer " << vpid << ". Something's wrong!" << std::endl;
return false;
}
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(it2->second.tunnel_id) ;
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
if(it == _gxs_tunnel_contacts.end())
{
std::cerr << "(EE) Cannot find contact key info for virtual peer id " << vpid << ". Cannot send message!" << std::endl;
std::cerr << "(EE) Cannot find contact key info for tunnel id " << tunnel_id << ". Cannot send message!" << std::endl;
return false;
}
if(it->second.status != RS_GXS_TUNNEL_STATUS_CAN_TALK)
{
std::cerr << "(EE) Cannot talk to vpid " << vpid << ". Tunnel status is: " << it->second.status << std::endl;
std::cerr << "(EE) Cannot talk to tunnel id " << tunnel_id << ". Tunnel status is: " << it->second.status << std::endl;
return false;
}
@ -1075,7 +1160,7 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
std::cerr << " Using Key: " << RsUtil::BinToHex((char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl;
std::cerr << " hmac: " << RsUtil::BinToHex((char*)gitem->data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) ;
std::cerr << " hmac: " << RsUtil::BinToHex((char*)gitem->data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl;
#endif
#ifdef DEBUG_GXS_TUNNEL
std::cerr << "GxsTunnelService::sendEncryptedTunnelData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl;
@ -1089,7 +1174,7 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
return true ;
}
bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id, uint32_t& error_code)
bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id, uint32_t service_id, uint32_t& error_code)
{
// should be a parameter.
@ -1112,7 +1197,7 @@ bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const Rs
}
RsGxsId own_gxs_id = from_gxs_id ;
startClientGxsTunnelConnection(to_gxs_id,own_gxs_id,tunnel_id) ;
startClientGxsTunnelConnection(to_gxs_id,own_gxs_id,service_id,tunnel_id) ;
error_code = RS_GXS_TUNNEL_ERROR_NO_ERROR ;
@ -1155,6 +1240,7 @@ bool p3GxsTunnelService::sendData(const RsGxsTunnelId &tunnel_id, uint32_t servi
item->service_id = service_id;
item->data_size = size; // encrypted data size
item->data = (uint8_t*)malloc(size); // encrypted data
item->PeerId(RsPeerId(tunnel_id)) ;
memcpy(item->data,data,size) ;
GxsTunnelData& tdata( pendingGxsTunnelDataItems[item->unique_item_counter] ) ;
@ -1168,7 +1254,7 @@ bool p3GxsTunnelService::sendData(const RsGxsTunnelId &tunnel_id, uint32_t servi
}
void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,RsGxsTunnelId& tunnel_id)
void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,uint32_t service_id,RsGxsTunnelId& tunnel_id)
{
// compute a random hash for that pair, and init the DH session for it so that we can recognise it when we get the virtual peer for it.
@ -1198,6 +1284,7 @@ void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id
info.hash = hash ;
info.direction = RsTurtleGenericTunnelItem::DIRECTION_SERVER ;
info.virtual_peer_id.clear();
info.client_services.insert(service_id) ;
memset(info.aes_key,0,GXS_TUNNEL_AES_KEY_SIZE) ;
@ -1222,8 +1309,6 @@ TurtleFileHash p3GxsTunnelService::randomHashFromDestinationGxsId(const RsGxsId&
// This is in prevision for the "secured GXS tunnel" service, which will need a service ID to register,
// just like GRouter does.
static const uint32_t client = RS_SERVICE_TYPE_GXS_TUNNEL ;
assert( destination.SIZE_IN_BYTES == 16) ;
assert(Sha1CheckSum::SIZE_IN_BYTES == 20) ;
@ -1289,7 +1374,7 @@ bool p3GxsTunnelService::getTunnelStatus(const RsGxsTunnelId& tunnel_id,uint32_t
return false ;
}
bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id)
bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id, uint32_t service_id)
{
// two cases:
// - client needs to stop asking for tunnels => remove the hash from the list of tunnelled files
@ -1298,9 +1383,10 @@ bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id)
TurtleFileHash hash ;
TurtleVirtualPeerId vpid ;
bool close_tunnel = false ;
{
RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::const_iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
if(it == _gxs_tunnel_contacts.end())
{
@ -1319,16 +1405,34 @@ bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id)
if(it2 != _gxs_tunnel_virtual_peer_ids.end())
hash = it2->second.hash ;
// check how many clients are used. If empty, close the tunnel
std::set<uint32_t>::iterator it3 = it->second.client_services.find(service_id) ;
if(it3 == it->second.client_services.end())
{
std::cerr << "(EE) service id not currently using that tunnel. This is an error." << std::endl;
return false;
}
it->second.client_services.erase(it3) ;
if(it->second.client_services.empty())
close_tunnel = true ;
}
if(!close_tunnel)
return true ;
// send a status item saying that we're closing the connection
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " Sending a ACK to close the tunnel since we're managing it. tunnel id=." << tunnel_id << std::endl;
std::cerr << " Sending a ACK to close the tunnel since we're managing it and it's not used by any service. tunnel id=." << tunnel_id << std::endl;
#endif
RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ;
cs->flags = RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION;
cs->status = RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION;
cs->PeerId(vpid) ;
locked_sendEncryptedTunnelData(cs) ; // that needs to be done off-mutex and before we close the tunnel also ignoring failure.
@ -1354,27 +1458,6 @@ bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id)
return true ;
}
void p3GxsTunnelService::markGxsTunnelAsClosed(const RsGxsTunnelId& tunnel_id)
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
if(it == _gxs_tunnel_contacts.end())
{
std::cerr << "(EE) Cannot mark distant chat connection as closed. No connection openned for tunnel id " << tunnel_id << ". Unexpected situation." << std::endl;
return ;
}
if(it->second.direction == RsTurtleGenericDataItem::DIRECTION_CLIENT)
{
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " This is server side. Marking distant chat as remotely closed for tunnel id " << tunnel_id << std::endl;
#endif
it->second.status = RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED ;
}
}
void p3GxsTunnelService::debug_dump()
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/

View File

@ -45,7 +45,7 @@
//
// Interaction with services:
//
// Services request tunnels from a given GXS id and to a given GXS id. When ready, they get a handle (virtual peer id)
// Services request tunnels from a given GXS id and to a given GXS id. When ready, they get a handle (type = RsGxsTunnelId)
//
// Services send data in the tunnel using the virtual peer id
//
@ -56,6 +56,18 @@
//
// Tunnel establishment
// * we need two layers: the turtle layer, and the GXS id layer.
// - for each pair of GXS ids talking, a single turtle tunnel is used
// - that tunnel can be shared by multiple services using it.
// - services are responsoble for asking tunnels and also droppping them when unused.
// - at the turtle layer, the tunnel will be closed only when no service uses it.
// * IDs
// TurtleVirtualPeerId:
// - Used by tunnel service for each turtle tunnel
// - one virtual peer ID per GXS tunnel
//
// GxsTunnelId:
// - one GxsTunnelId per couple of GXS ids. But we also need to allow multiple services to use the tunnel.
//
// * at the turtle layer:
// - accept virtual peers from turtle tunnel service. The hash for that VP only depends on the server GXS id at server side, which is our
// own ID at server side, and destination ID at client side. What happens if two different clients request to talk to the same GXS id? (same hash)
@ -80,22 +92,22 @@
//
//
// RequestTunnel(source_own_id,destination_id)
// |
// +---------------------------> p3Turtle::monitorTunnels( hash(destination_id) )
// |
// [Turtle async work] -------------------+
// | |
// handleTunnelRequest() <-----------------------------------------------+ |
// | |
// +---------------- keep record in _gxs_tunnel_virtual_peer_id, initiate DH exchange |
// |
// handleDHPublicKey() <-----------------------------------------------------------------------------+
// |
// +---------------- update _gxs_tunnel_contacts[ tunnel_hash = hash(own_id, destination_id) ]
// |
// +---------------- notify client service that Peer(destination_id, tunnel_hash) is ready to talk to
//
// RequestTunnel(source_own_id,destination_id) -
// | |
// +---------------------------> p3Turtle::monitorTunnels( hash(destination_id) ) |
// | |
// [Turtle async work] -------------------+ | Turtle layer: one virtual peer id
// | | |
// handleTunnelRequest() <-----------------------------------------------+ | |
// | | |
// +---------------- keep record in _gxs_tunnel_virtual_peer_id, initiate DH exchange | -
// | |
// handleDHPublicKey() <-----------------------------------------------------------------------------+ |
// | |
// +---------------- update _gxs_tunnel_contacts[ tunnel_hash = hash(own_id, destination_id) ] | GxsTunnelId level
// | |
// +---------------- notify client service that Peer(destination_id, tunnel_hash) is ready to talk to |
// -
// Notes
// * one other option would be to make the turtle hash depend on both GXS ids in a way that it is possible to find which are the two ids on the server side.
// but that would prevent the use of unknown IDs, which we would like to offer as well.
@ -123,9 +135,9 @@ public:
// 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.
//
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t& error_code) ;
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) ;
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id) ;
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id,uint32_t service_id) ;
virtual bool getTunnelStatus(const RsGxsTunnelId& tunnel_id,uint32_t &status);
virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info);
virtual bool sendData(const RsGxsTunnelId& tunnel_id,uint32_t service_id,const uint8_t *data,uint32_t size) ;
@ -160,6 +172,7 @@ private:
RsGxsId own_gxs_id ; // gxs id we're using to talk.
RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server.
TurtleFileHash hash ; // hash that is last used. This is necessary for handling tunnel establishment
std::set<uint32_t> client_services ;// services that used this tunnel
};
class GxsTunnelDHInfo
@ -203,8 +216,7 @@ private:
// session handling handles
void markGxsTunnelAsClosed(const RsGxsTunnelId &tunnel_id) ;
void startClientGxsTunnelConnection(const RsGxsId &to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id) ;
void startClientGxsTunnelConnection(const RsGxsId &to_gxs_id, const RsGxsId& from_gxs_id, uint32_t service_id, RsGxsTunnelId &tunnel_id) ;
void locked_restartDHSession(const RsPeerId &virtual_peer_id, const RsGxsId &own_gxs_id) ;
// utility functions

View File

@ -79,7 +79,7 @@ std::ostream& RsGxsTunnelStatusItem::print(std::ostream &out, uint16_t indent)
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << " flags : " << std::hex << flags << std::dec << std::endl ;
out << " flags : " << std::hex << status << std::dec << std::endl ;
printRsItemEnd(out, "RsGxsTunnelStatusItem", indent);
return out;
@ -235,7 +235,7 @@ bool RsGxsTunnelStatusItem::serialise(void *data, uint32_t& pktsize)
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, flags);
ok &= setRawUInt32(data, tlvsize, &offset, status);
if (offset != tlvsize)
{
@ -249,7 +249,7 @@ bool RsGxsTunnelStatusItem::serialise(void *data, uint32_t& pktsize)
return ok;
}
bool RsGxsTunnelDataItem::serialise(void *data, uint32_t& pktsize)
bool RsGxsTunnelDataItem::serialise(void *dt, uint32_t& pktsize)
{
uint32_t tlvsize = serial_size() ;
uint32_t offset = 0;
@ -261,7 +261,7 @@ bool RsGxsTunnelDataItem::serialise(void *data, uint32_t& pktsize)
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
ok &= setRsItemHeader(dt, tlvsize, PacketId(), tlvsize);
#ifdef GXS_TUNNEL_ITEM_DEBUG
std::cerr << "RsGxsTunnelSerialiser serialising chat status item." << std::endl;
@ -273,14 +273,14 @@ bool RsGxsTunnelDataItem::serialise(void *data, uint32_t& pktsize)
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt64(data, tlvsize, &offset, unique_item_counter);
ok &= setRawUInt32(data, tlvsize, &offset, flags);
ok &= setRawUInt32(data, tlvsize, &offset, service_id);
ok &= setRawUInt32(data, tlvsize, &offset, data_size);
ok &= setRawUInt64(dt, tlvsize, &offset, unique_item_counter);
ok &= setRawUInt32(dt, tlvsize, &offset, flags);
ok &= setRawUInt32(dt, tlvsize, &offset, service_id);
ok &= setRawUInt32(dt, tlvsize, &offset, data_size);
if(offset + data_size <= tlvsize)
{
memcpy(&((uint8_t*)data)[offset],data,data_size) ;
memcpy(&((uint8_t*)dt)[offset],data,data_size) ;
offset += data_size ;
}
else
@ -451,7 +451,7 @@ RsGxsTunnelStatusItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelStatusItem(
/* get mandatory parts first */
ok &= getRawUInt32(dat, rssize, &offset, &item->flags);
ok &= getRawUInt32(dat, rssize, &offset, &item->status);
if (offset != rssize)
{

View File

@ -105,7 +105,7 @@ class RsGxsTunnelStatusItem: public RsGxsTunnelItem
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint32_t flags ;
uint32_t status ;
};
// Used to confirm reception of an encrypted item.

View File

@ -208,7 +208,7 @@ p3Config::p3Config()
}
bool p3Config::loadConfiguration(RsFileHash &loadHash)
bool p3Config::loadConfiguration(RsFileHash& /* loadHash */)
{
return loadConfig();
}

View File

@ -99,17 +99,14 @@ void p3HistoryMgr::addMessage(const ChatMessage& cm)
enabled = true;
}
if (cm.chat_id.isGxsId() && mPrivateEnable == true) {
if (cm.incoming) {
peerName = cm.chat_id.toGxsId().toStdString();
} else {
uint32_t status;
DistantChatPeerInfo dcpinfo;
if (rsMsgs->getDistantChatStatus(cm.chat_id.toPeerId(), dcpinfo))
peerName = cm.chat_id.toPeerId().toStdString();
}
enabled = true;
}
if(cm.chat_id.isDistantChatId())
{
uint32_t status;
DistantChatPeerInfo dcpinfo;
if (rsMsgs->getDistantChatStatus(cm.chat_id.toDistantChatId(), dcpinfo))
peerName = cm.chat_id.toPeerId().toStdString();
enabled = true;
}
if(enabled == false)
return;
@ -397,8 +394,8 @@ bool p3HistoryMgr::chatIdToVirtualPeerId(ChatId chat_id, RsPeerId &peer_id)
return true;
}
if (chat_id.isGxsId()) {
peer_id = RsPeerId(chat_id.toGxsId());
if (chat_id.isDistantChatId()) {
peer_id = RsPeerId(chat_id.toDistantChatId());
return true;
}
@ -436,7 +433,7 @@ bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list<HistoryMsg> &msgs
if (chatId.isLobbyId() && mLobbyEnable == true) {
enabled = true;
}
if (chatId.isGxsId() && mPrivateEnable == true) {
if (chatId.isDistantChatId() && mPrivateEnable == true) {
enabled = true;
}

View File

@ -33,16 +33,20 @@
class RsGxsTunnelService
{
public:
static const uint32_t RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000 ;
static const uint32_t RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001 ;
static const uint32_t RS_GXS_TUNNEL_STATUS_UNKNOWN = 0x00 ;
static const uint32_t RS_GXS_TUNNEL_STATUS_CAN_TALK = 0x01 ;
static const uint32_t RS_GXS_TUNNEL_STATUS_TUNNEL_DN = 0x02 ;
static const uint32_t RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED = 0x03 ;
typedef GXSTunnelId RsGxsTunnelId ;
enum {
RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000,
RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001
};
enum {
RS_GXS_TUNNEL_STATUS_UNKNOWN = 0x00,
RS_GXS_TUNNEL_STATUS_TUNNEL_DN = 0x01,
RS_GXS_TUNNEL_STATUS_CAN_TALK = 0x02,
RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED = 0x03
};
class RsGxsTunnelClientService
{
public:
@ -102,8 +106,9 @@ public:
// Asks for a tunnel. The service will request it to turtle router, and exchange a AES key using DH.
// When the tunnel is secured, the client---here supplied as argument---will be notified. He can
// then send data into the tunnel. The same tunnel may be used by different clients.
// The service id is passed on so that the client is notified when the tunnel is up.
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t& error_code) =0 ;
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) =0 ;
// Data is sent through the established tunnel, possibly multiple times, until reception is acknowledged. If the tunnel does not exist, the item is rejected and
// an error is issued. In any case, the memory ownership of the data is *not* transferred to the tunnel service, so the client should delete it afterwards, if needed.
@ -113,7 +118,7 @@ public:
// Removes any established tunnel to this GXS id. This makes the tunnel refuse further data, but the tunnel will be however kept alive
// until all pending data is flushed. All clients attached to the tunnel will be notified that the tunnel gets closed.
virtual bool closeExistingTunnel(const RsGxsTunnelId& to_id) =0;
virtual bool closeExistingTunnel(const RsGxsTunnelId& to_id,uint32_t service_id) =0;
//===================================================//
// Routage feedback from other services //

View File

@ -209,16 +209,17 @@ static const int SHA1_SIZE = 20 ;
// These constants are random, but should be different, in order to make the various IDs incompatible with each other.
//
static const uint32_t RS_GENERIC_ID_SSL_ID_TYPE = 0x0001 ;
static const uint32_t RS_GENERIC_ID_PGP_ID_TYPE = 0x0002 ;
static const uint32_t RS_GENERIC_ID_SHA1_ID_TYPE = 0x0003 ;
static const uint32_t RS_GENERIC_ID_PGP_FINGERPRINT_TYPE = 0x0004 ;
static const uint32_t RS_GENERIC_ID_GXS_GROUP_ID_TYPE = 0x0005 ;
static const uint32_t RS_GENERIC_ID_GXS_ID_TYPE = 0x0006 ;
static const uint32_t RS_GENERIC_ID_GXS_MSG_ID_TYPE = 0x0007 ;
static const uint32_t RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE = 0x0008 ;
static const uint32_t RS_GENERIC_ID_GROUTER_ID_TYPE = 0x0009 ;
static const uint32_t RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE = 0x0010 ;
static const uint32_t RS_GENERIC_ID_SSL_ID_TYPE = 0x0001 ;
static const uint32_t RS_GENERIC_ID_PGP_ID_TYPE = 0x0002 ;
static const uint32_t RS_GENERIC_ID_SHA1_ID_TYPE = 0x0003 ;
static const uint32_t RS_GENERIC_ID_PGP_FINGERPRINT_TYPE = 0x0004 ;
static const uint32_t RS_GENERIC_ID_GXS_GROUP_ID_TYPE = 0x0005 ;
static const uint32_t RS_GENERIC_ID_GXS_ID_TYPE = 0x0006 ;
static const uint32_t RS_GENERIC_ID_GXS_MSG_ID_TYPE = 0x0007 ;
static const uint32_t RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE = 0x0008 ;
static const uint32_t RS_GENERIC_ID_GROUTER_ID_TYPE = 0x0009 ;
static const uint32_t RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE = 0x0010 ;
static const uint32_t RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE = 0x0011 ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_SSL_ID_TYPE> SSLIdType ;
typedef t_RsGenericIdType< PGP_KEY_ID_SIZE , true, RS_GENERIC_ID_PGP_ID_TYPE> PGPIdType ;
@ -229,4 +230,5 @@ typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_G
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_ID_TYPE > GXSId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE > GXSCircleId ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE > GXSTunnelId ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE > DistantChatPeerId ;

View File

@ -99,8 +99,6 @@ typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
typedef RsPeerId DistantChatPeerId ;
typedef uint64_t MessageId ;
@ -254,10 +252,8 @@ public:
#define RS_DISTANT_CHAT_STATUS_UNKNOWN 0x0000
#define RS_DISTANT_CHAT_STATUS_TUNNEL_DN 0x0001
#define RS_DISTANT_CHAT_STATUS_TUNNEL_OK 0x0002
#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0003
#define RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED 0x0004
#define RS_DISTANT_CHAT_STATUS_WAITING_DH 0x0005
#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0002
#define RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED 0x0003
#define RS_DISTANT_CHAT_ERROR_NO_ERROR 0x0000
#define RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED 0x0001
@ -285,6 +281,7 @@ public:
explicit ChatId(RsPeerId id);
explicit ChatId(RsGxsId id);
explicit ChatId(ChatLobbyId id);
explicit ChatId(DistantChatPeerId id);
explicit ChatId(std::string str);
static ChatId makeBroadcastId();
@ -296,13 +293,15 @@ public:
bool isNotSet() const;
bool isPeerId() const;
bool isGxsId() const;
bool isDistantChatId() const;
bool isLobbyId() const;
bool isGxsId() const;
bool isBroadcast() const;
RsPeerId toPeerId() const;
RsGxsId toGxsId() const;
ChatLobbyId toLobbyId() const;
DistantChatPeerId toDistantChatId() const;
// for the very specific case of transfering a status string
// from the chatservice to the gui,
@ -313,13 +312,15 @@ private:
TYPE_PRIVATE, // private chat with directly connected friend, peer_id is valid
TYPE_PRIVATE_DISTANT, // private chat with distant peer, gxs_id is valid
TYPE_LOBBY, // chat lobby id, lobby_id is valid
TYPE_GXS_ID, //
TYPE_BROADCAST // message to/from all connected peers
};
Type type;
RsPeerId peer_id;
RsGxsId gxs_id;
DistantChatPeerId distant_chat_id;
ChatLobbyId lobby_id;
RsGxsId gxs_id;
};
class ChatMessage

View File

@ -58,6 +58,13 @@ ChatId::ChatId():
}
ChatId::ChatId(RsGxsId id):
lobby_id(0)
{
type = TYPE_GXS_ID;
gxs_id = id;
}
ChatId::ChatId(RsPeerId id):
lobby_id(0)
{
@ -65,11 +72,11 @@ ChatId::ChatId(RsPeerId id):
peer_id = id;
}
ChatId::ChatId(RsGxsId id):
ChatId::ChatId(DistantChatPeerId id):
lobby_id(0)
{
type = TYPE_PRIVATE_DISTANT;
gxs_id = id;
distant_chat_id = id;
}
ChatId::ChatId(ChatLobbyId id):
@ -93,7 +100,7 @@ ChatId::ChatId(std::string str):
else if(str[0] == 'D')
{
type = TYPE_PRIVATE_DISTANT;
gxs_id == GXSId(str.substr(1));
distant_chat_id == DistantChatPeerId(str.substr(1));
}
else if(str[0] == 'L')
{
@ -143,7 +150,7 @@ std::string ChatId::toStdString() const
else if(type == TYPE_PRIVATE_DISTANT)
{
str += "D";
str += gxs_id.toStdString();
str += distant_chat_id.toStdString();
}
else if(type == TYPE_LOBBY)
{
@ -186,7 +193,7 @@ bool ChatId::operator <(const ChatId& other) const
case TYPE_PRIVATE:
return peer_id < other.peer_id;
case TYPE_PRIVATE_DISTANT:
return gxs_id < other.gxs_id;
return distant_chat_id < other.distant_chat_id;
case TYPE_LOBBY:
return lobby_id < other.lobby_id;
case TYPE_BROADCAST:
@ -210,7 +217,7 @@ bool ChatId::isSameEndpoint(const ChatId &other) const
case TYPE_PRIVATE:
return peer_id == other.peer_id;
case TYPE_PRIVATE_DISTANT:
return gxs_id == other.gxs_id;
return distant_chat_id == other.distant_chat_id;
case TYPE_LOBBY:
return lobby_id == other.lobby_id;
case TYPE_BROADCAST:
@ -229,7 +236,7 @@ bool ChatId::isPeerId() const
{
return type == TYPE_PRIVATE;
}
bool ChatId::isGxsId() const
bool ChatId::isDistantChatId() const
{
return type == TYPE_PRIVATE_DISTANT;
}
@ -237,6 +244,10 @@ bool ChatId::isLobbyId() const
{
return type == TYPE_LOBBY;
}
bool ChatId::isGxsId() const
{
return type == TYPE_GXS_ID;
}
bool ChatId::isBroadcast() const
{
return type == TYPE_BROADCAST;
@ -251,16 +262,27 @@ RsPeerId ChatId::toPeerId() const
return RsPeerId();
}
}
RsGxsId ChatId::toGxsId() const
{
if(type == TYPE_PRIVATE_DISTANT)
if(type == TYPE_GXS_ID)
return gxs_id;
else
{
std::cerr << "ChatId Warning: conversation to RsGxsId requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl;
std::cerr << "ChatId Warning: conversation to gxs_id requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl;
return RsGxsId();
}
}
DistantChatPeerId ChatId::toDistantChatId() const
{
if(type == TYPE_PRIVATE_DISTANT)
return distant_chat_id;
else
{
std::cerr << "ChatId Warning: conversation to DistantChatPeerId requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl;
return DistantChatPeerId();
}
}
ChatLobbyId ChatId::toLobbyId() const
{
if(type == TYPE_LOBBY)

View File

@ -266,7 +266,7 @@ bool doPortRestrictions = false;
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
int RsInit::InitRetroShare(int argc, char **argv, bool strictCheck)
int RsInit::InitRetroShare(int argc, char **argv, bool /* strictCheck */)
{
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
#else

View File

@ -122,7 +122,7 @@ uint32_t p3GxsChannels::channelsAuthenPolicy()
/** Overloaded to cache new groups **/
RsGenExchange::ServiceCreate_Return p3GxsChannels::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet)
RsGenExchange::ServiceCreate_Return p3GxsChannels::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& /* keySet */)
{
updateSubscribedGroup(grpItem->meta);
return SERVICE_CREATE_SUCCESS;

View File

@ -40,8 +40,8 @@ class upnphandler: public pqiNetAssistFirewall
virtual bool getExternalAddress(struct sockaddr_storage &addr);
/* TO IMPLEMENT: New Port Forward interface to support as many ports as necessary */
virtual bool requestPortForward(const PortForwardParams &params) { return false; }
virtual bool statusPortForward(const uint32_t fwdId, PortForwardParams &params) { return false; }
virtual bool requestPortForward(const PortForwardParams & /* params */) { return false; }
virtual bool statusPortForward(const uint32_t /* fwdId */, PortForwardParams & /*params*/) { return false; }
/* Public functions - for background thread operation,
* but effectively private from rest of RS, as in derived class

View File

@ -93,11 +93,10 @@ void ChatDialog::init(ChatId id, const QString &title)
/* see if it already exists */
ChatDialog *cd = getExistingChat(id);
DistantChatPeerInfo pinfo ;
if (cd == NULL) {
if(id.isGxsId())
if(id.isDistantChatId())
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // force open for distant chat
if (chatflags & RS_CHAT_OPEN) {
@ -106,10 +105,11 @@ void ChatDialog::init(ChatId id, const QString &title)
cld->init();
cd = cld;
}
else if(id.isPeerId() && rsMsgs->getDistantChatStatus(id.toPeerId(),pinfo))
else if(id.isDistantChatId())
{
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toPeerId());
pdcd->init(pinfo.peer_id, QString("This is a distant chat")) ;
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toDistantChatId());
pdcd->init(id.toDistantChatId());
cd = pdcd;
}
else
@ -172,7 +172,7 @@ void ChatDialog::init(ChatId id, const QString &title)
if(msg.chat_id.isBroadcast())
return; // broadcast is not handled by a chat dialog
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isGxsId()))
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isDistantChatId()))
// play sound when recv a message
SoundManager::play(SOUND_NEW_CHAT_MESSAGE);
@ -338,8 +338,8 @@ void ChatDialog::setPeerStatus(uint32_t status)
RsPeerId vpid;
if(mChatId.isPeerId())
vpid = mChatId.toPeerId();
if(mChatId.isGxsId())
vpid = RsPeerId(mChatId.toGxsId());
if(mChatId.isDistantChatId())
vpid = RsPeerId(mChatId.toDistantChatId());
cw->updateStatus(QString::fromStdString(vpid.toStdString()), status);
}
}

View File

@ -109,7 +109,7 @@ void ChatUserNotify::chatMessageReceived(ChatMessage msg)
if(!msg.chat_id.isBroadcast()
&&( ChatDialog::getExistingChat(msg.chat_id)
|| (Settings->getChatFlags() & RS_CHAT_OPEN)
|| msg.chat_id.isGxsId()))
|| msg.chat_id.isDistantChatId()))
{
ChatDialog::chatMessageReceived(msg);
}

View File

@ -249,7 +249,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
RsPeerId ownId = rsPeers->getOwnId();
setName(QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()));
if(chatId.isPeerId() || chatId.isGxsId())
if(chatId.isPeerId() || chatId.isDistantChatId())
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
if(chatId.isBroadcast() || chatId.isLobbyId())
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PUBLIC);
@ -328,7 +328,8 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
continue;
QString name;
if (chatId.isLobbyId() || chatId.isGxsId()) {
if (chatId.isLobbyId() || chatId.isDistantChatId())
{
RsIdentityDetails details;
if (rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details))
name = QString::fromUtf8(details.mNickname.c_str());
@ -360,7 +361,7 @@ ChatWidget::ChatType ChatWidget::chatType()
// but maybe it is good to have separate types in libretroshare and gui
if(chatId.isPeerId())
return CHATTYPE_PRIVATE;
if(chatId.isGxsId())
if(chatId.isDistantChatId())
return CHATTYPE_DISTANT;
if(chatId.isLobbyId())
return CHATTYPE_LOBBY;
@ -1501,77 +1502,83 @@ void ChatWidget::updateStatus(const QString &peer_id, int status)
// make virtual peer id from gxs id in case of distant chat
RsPeerId vpid;
if(chatId.isGxsId())
vpid = RsPeerId(chatId.toGxsId());
if(chatId.isDistantChatId())
vpid = RsPeerId(chatId.toDistantChatId());
else
vpid = chatId.toPeerId();
/* set font size for status */
if (peer_id.toStdString() == vpid.toStdString()) {
// the peers status has changed
if (peer_id.toStdString() == vpid.toStdString())
{
// the peers status has changed
QString peerName ;
if(chatId.isGxsId())
{
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(chatId.toGxsId(),details))
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
else
peerName = QString::fromStdString(chatId.toGxsId().toStdString()) ;
}
else
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
QString peerName ;
if(chatId.isDistantChatId())
{
DistantChatPeerInfo dcpinfo ;
RsIdentityDetails details ;
// is scrollbar at the end?
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
bool atEnd = (scrollbar->value() == scrollbar->maximum());
if(rsMsgs->getDistantChatStatus(chatId.toDistantChatId(),dcpinfo))
if(rsIdentity->getIdDetails(dcpinfo.to_id,details))
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
else
peerName = QString::fromStdString(dcpinfo.to_id.toStdString()) ;
else
peerName = QString::fromStdString(chatId.toDistantChatId().toStdString()) ;
}
else
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
switch (status) {
case RS_STATUS_OFFLINE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online"));
break;
// is scrollbar at the end?
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
bool atEnd = (scrollbar->value() == scrollbar->maximum());
case RS_STATUS_INACTIVE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
break;
switch (status) {
case RS_STATUS_OFFLINE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online"));
break;
case RS_STATUS_ONLINE:
ui->infoFrame->setVisible(false);
break;
case RS_STATUS_INACTIVE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
break;
case RS_STATUS_AWAY:
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
ui->infoFrame->setVisible(true);
break;
case RS_STATUS_ONLINE:
ui->infoFrame->setVisible(false);
break;
case RS_STATUS_BUSY:
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
ui->infoFrame->setVisible(true);
break;
}
case RS_STATUS_AWAY:
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
ui->infoFrame->setVisible(true);
break;
ui->titleLabel->setText(peerName);
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
case RS_STATUS_BUSY:
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
ui->infoFrame->setVisible(true);
break;
}
peerStatus = status;
ui->titleLabel->setText(peerName);
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
if (atEnd) {
// scroll to the end
scrollbar->setValue(scrollbar->maximum());
}
peerStatus = status;
emit infoChanged(this);
emit statusChanged(status);
if (atEnd) {
// scroll to the end
scrollbar->setValue(scrollbar->maximum());
}
// Notify all ChatWidgetHolder
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
chatWidgetHolder->updateStatus(status);
}
emit infoChanged(this);
emit statusChanged(status);
return;
}
// Notify all ChatWidgetHolder
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
chatWidgetHolder->updateStatus(status);
}
return;
}
// ignore status change
}

View File

@ -60,7 +60,7 @@ PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_i
updateDisplay() ;
}
void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id, const QString &title)
void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id)
{
_tunnel_id = peer_id;
DistantChatPeerInfo tinfo;
@ -68,12 +68,18 @@ void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id, const QStrin
if(!rsMsgs->getDistantChatStatus(_tunnel_id,tinfo))
return ;
PopupChatDialog::init(ChatId(tinfo.to_id), title) ;
RsIdentityDetails iddetails ;
if(rsIdentity->getIdDetails(tinfo.to_id,iddetails))
PopupChatDialog::init(ChatId(peer_id), QString::fromUtf8(iddetails.mNickname.c_str())) ;
else
PopupChatDialog::init(ChatId(peer_id), QString::fromStdString(tinfo.to_id.toStdString())) ;
// Do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
// it will not be transmitted.
ui.ownAvatarWidget->setId(ChatId(tinfo.own_id));
ui.ownAvatarWidget->setOwnId() ; // sets the flag
ui.ownAvatarWidget->setId(ChatId(peer_id)) ; // sets the actual Id
}
void PopupDistantChatDialog::updateDisplay()
@ -91,7 +97,7 @@ void PopupDistantChatDialog::updateDisplay()
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
ui.avatarWidget->setId(ChatId(tinfo.to_id));
ui.avatarWidget->setId(ChatId(_tunnel_id));
QString msg;
switch(tinfo.status)

View File

@ -38,7 +38,7 @@ class PopupDistantChatDialog: public PopupChatDialog
/** Default destructor */
virtual ~PopupDistantChatDialog();
virtual void init(const DistantChatPeerId& peer_id, const QString &title);
virtual void init(const DistantChatPeerId& peer_id);
virtual void closeEvent(QCloseEvent *e) ;
virtual QString getPeerName(const ChatId &id) const ;

View File

@ -124,8 +124,6 @@ void AvatarWidget::setFrameType(FrameType type)
void AvatarWidget::setId(const ChatId &id)
{
mId = id;
// mPgpId = rsPeers->getGPGId(id) ;
// mFlag.isGpg = false ;
setPixmap(QPixmap());
@ -133,15 +131,12 @@ void AvatarWidget::setId(const ChatId &id)
setEnabled(false);
}
if(mId.isGxsId())
std::cerr << "(EE) AvatarWidget should not be set to a GXS id." << std::endl;
refreshAvatarImage();
refreshStatus();
}
void AvatarWidget::setOwnId(const RsGxsId& own_gxs_id)
{
mFlag.isOwnId = true;
setId(ChatId(own_gxs_id));
}
void AvatarWidget::setOwnId()
{
mFlag.isOwnId = true;
@ -181,7 +176,7 @@ void AvatarWidget::refreshStatus()
rsStatus->getOwnStatus(statusInfo);
status = statusInfo.status ;
}
else if(mId.isGxsId())
else if(mId.isDistantChatId())
status = RS_STATUS_ONLINE ;
else
{
@ -198,12 +193,15 @@ void AvatarWidget::refreshStatus()
rsStatus->getStatus(mId.toPeerId(), statusInfo);
status = statusInfo.status ;
}
else if(mId.isGxsId())
{
//if(!rsMsgs->getDistantChatStatus(mId.toGxsId(),status))
status = RS_STATUS_OFFLINE ;
#warning we need to do something clever here
}
else if(mId.isDistantChatId())
{
DistantChatPeerInfo dcpinfo ;
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
status = dcpinfo.status ;
else
std::cerr << "(EE) cannot get distant chat status for ID=" << mId.toDistantChatId() << std::endl;
}
else
{
std::cerr << "Unhandled chat id type in AvatarWidget::refreshStatus()" << std::endl;
@ -236,10 +234,11 @@ void AvatarWidget::updateStatus(int status)
void AvatarWidget::updateAvatar(const QString &peerId)
{
if(mId.isPeerId() && mId.toPeerId() == RsPeerId(peerId.toStdString()))
refreshAvatarImage() ;
if(mId.isGxsId() && mId.toGxsId() == RsGxsId(peerId.toStdString()))
refreshAvatarImage() ;
refreshAvatarImage() ;
else if(mId.isDistantChatId() && mId.toDistantChatId() == DistantChatPeerId(peerId.toStdString()))
refreshAvatarImage() ;
else
std::cerr << "(EE) cannot update avatar. mId has unhandled type." << std::endl;
}
void AvatarWidget::refreshAvatarImage()
{
@ -263,12 +262,29 @@ void AvatarWidget::refreshAvatarImage()
setPixmap(avatar);
return;
}
else if (mId.isGxsId())
// else if (mId.isGxsId())
// {
// QPixmap avatar;
//
// AvatarDefs::getAvatarFromGxsId(mId.toGxsId(), avatar, defaultAvatar);
// setPixmap(avatar);
// return;
// }
else if (mId.isDistantChatId())
{
QPixmap avatar;
AvatarDefs::getAvatarFromGxsId(mId.toGxsId(), avatar, defaultAvatar);
setPixmap(avatar);
return;
QPixmap avatar;
DistantChatPeerInfo dcpinfo ;
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
{
if(mFlag.isOwnId)
AvatarDefs::getAvatarFromGxsId(dcpinfo.own_id, avatar, defaultAvatar);
else
AvatarDefs::getAvatarFromGxsId(dcpinfo.to_id, avatar, defaultAvatar);
setPixmap(avatar);
return;
}
}
else
std::cerr << "WARNING: unhandled situation in AvatarWidget::refreshAvatarImage()" << std::endl;

View File

@ -51,7 +51,6 @@ public:
void setFrameType(FrameType type);
void setId(const ChatId& id) ;
void setOwnId();
void setOwnId(const RsGxsId&);
void setDefaultAvatar(const QString &avatar_file_name);
protected:

View File

@ -116,7 +116,7 @@ ImHistoryBrowser::ImHistoryBrowser(const ChatId &chatId, QTextEdit *edit, QWidge
ui.filterLineEdit->showFilterIcon();
// embed smileys ?
if (m_chatId.isPeerId() || m_chatId.isGxsId()) {
if (m_chatId.isPeerId() || m_chatId.isDistantChatId()) {
embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_PrivatChat", true).toBool();
} else {
embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_GroupChat", true).toBool();
@ -275,7 +275,7 @@ void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, HistoryMsg& msg)
QString messageText = RsHtml().formatText(NULL, QString::fromUtf8(msg.message.c_str()), formatTextFlag);
QString name;
if (m_chatId.isLobbyId() || m_chatId.isGxsId()) {
if (m_chatId.isLobbyId() || m_chatId.isDistantChatId()) {
RsIdentityDetails details;
if (rsIdentity->getIdDetails(RsGxsId(msg.peerName), details))
name = QString::fromUtf8(details.mNickname.c_str());

View File

@ -112,7 +112,7 @@ bool RsharePeerSettings::getSettingsIdOfPeerId(const ChatId& chatId, std::string
m_SslToGpg[peerId] = settingsId ;
return true;
}
if(chatId.isGxsId() || chatId.isLobbyId() || chatId.isBroadcast())
if(chatId.isDistantChatId() || chatId.isLobbyId() || chatId.isBroadcast())
{
settingsId = chatId.toStdString();
return true;