From 953b70fbe4bda9d376c7dda2512309e0edb31dac Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 1 Mar 2017 23:07:53 +0100 Subject: [PATCH] Improve async distant chat, fix chat msg receiving DistantChatService::initiateDistantChatConnexion(...) made notification message optional (enabled by default) p3ChatService removed duplicion avoidance as it is not necessary p3ChatService::sendStatusString(...) send status only if peer is online protect p3ChatService::mDistantGxsMap with mutex as operation on it may be done by different threads p3ChatService::receiveGxsMai(...) set chat message item peer id with distant tunnel id, so it is recognized as a distant message later made p3GxsTunnelService::makeGxsTunnelId(...) static as it need no access to this, now it can be used easier by other components rename RsGxsMailItem::recipientsHint to recipientHint as for now only one recipient is possible (TODO: update documentation too) GxsMailsClient::receiveGxsMail(...) changed paramethers for better abstracion, now destination id is passed too because it is usually a very useful information ChatWidget some adaptation to async chat, a couple of method have been deprecated too PopupDistantChatDialog::updateDisplay(...) adapt message shown to the user to the new async chat paradigm (TODO: need review) --- libretroshare/src/chat/distantchat.cc | 28 ++-- libretroshare/src/chat/distantchat.h | 13 +- libretroshare/src/chat/p3chatservice.cc | 149 ++++++++---------- libretroshare/src/chat/p3chatservice.h | 31 ++-- libretroshare/src/gxstunnel/p3gxstunnel.cc | 25 +-- libretroshare/src/gxstunnel/p3gxstunnel.h | 6 +- libretroshare/src/serialiser/rsgxsmailitems.h | 14 +- libretroshare/src/services/p3gxsmails.cpp | 31 ++-- libretroshare/src/services/p3gxsmails.h | 9 +- libretroshare/src/services/p3msgservice.cc | 9 +- libretroshare/src/services/p3msgservice.h | 3 +- retroshare-gui/src/gui/chat/ChatWidget.cpp | 17 +- retroshare-gui/src/gui/chat/ChatWidget.h | 8 +- .../src/gui/chat/PopupDistantChatDialog.cpp | 81 ++++++---- 14 files changed, 212 insertions(+), 212 deletions(-) diff --git a/libretroshare/src/chat/distantchat.cc b/libretroshare/src/chat/distantchat.cc index 70fb88d8c..236fe5eca 100644 --- a/libretroshare/src/chat/distantchat.cc +++ b/libretroshare/src/chat/distantchat.cc @@ -243,7 +243,9 @@ void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid) mDistantChatContacts.erase(it) ; } -bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, DistantChatPeerId& dcpid, uint32_t& error_code) +bool DistantChatService::initiateDistantChatConnexion( + const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, + DistantChatPeerId& dcpid, uint32_t& error_code, bool notify ) { RsGxsTunnelId tunnel_id ; @@ -259,17 +261,19 @@ 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->sendTime = time(NULL) ; - item->PeerId(RsPeerId(tunnel_id)) ; - handleRecvChatMsgItem(item) ; - - delete item ; // item is replaced by NULL if partial, but this is not the case here. - + if(notify) + { + // Make a self message to raise the chat window + RsChatMsgItem *item = new RsChatMsgItem; + item->message = "[Starting distant chat. Please wait for secure tunnel"; + item->message += " to be established]"; + item->chatFlags = RS_CHAT_FLAG_PRIVATE; + item->sendTime = time(NULL); + item->PeerId(RsPeerId(tunnel_id)); + handleRecvChatMsgItem(item); + delete item ; + } + return true ; } diff --git a/libretroshare/src/chat/distantchat.h b/libretroshare/src/chat/distantchat.h index 444817c06..b177e6029 100644 --- a/libretroshare/src/chat/distantchat.h +++ b/libretroshare/src/chat/distantchat.h @@ -45,10 +45,15 @@ public: bool processLoadListItem(const RsItem *item) ; void addToSaveList(std::list& 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. - // - bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId &from_gxs_id, DistantChatPeerId& dcpid, uint32_t &error_code) ; + /** + * Creates the invite if the public key of the distant peer is available. + * On success, stores the invite in the map above, so that we can respond + * to tunnel requests. */ + bool initiateDistantChatConnexion( const RsGxsId& to_gxs_id, + const RsGxsId &from_gxs_id, + DistantChatPeerId& dcpid, + uint32_t &error_code, + bool notify = true ); bool closeDistantChatConnexion(const DistantChatPeerId &tunnel_id) ; // Sets flags to only allow connexion from some people. diff --git a/libretroshare/src/chat/p3chatservice.cc b/libretroshare/src/chat/p3chatservice.cc index d85ecc7e2..d03a0c022 100644 --- a/libretroshare/src/chat/p3chatservice.cc +++ b/libretroshare/src/chat/p3chatservice.cc @@ -59,8 +59,9 @@ p3ChatService::p3ChatService( p3ServiceControl *sc, p3IdService *pids, DistributedChatService(getServiceInfo().mServiceType, sc, historyMgr,pids), mChatMtx("p3ChatService"), mServiceCtrl(sc), mLinkMgr(lm), mHistoryMgr(historyMgr), _own_avatar(NULL), - _serializer(new RsChatSerialiser()), mGxsTransport(gxsMailService), - recentlyReceivedMutex("p3ChatService recently received mutex") + _serializer(new RsChatSerialiser()), + mDGMutex("p3ChatService distant id - gxs id map mutex"), + mGxsTransport(gxsMailService) { addSerialType(_serializer); mGxsTransport.registerGxsMailsClient( GxsMailSubServices::P3_CHAT_SERVICE, @@ -76,8 +77,6 @@ int p3ChatService::tick() DistributedChatService::flush(); - cleanListOfReceivedMessageHashes(); - return 0; } @@ -203,37 +202,38 @@ void p3ChatService::sendGroupChatStatusString(const std::string& status_string) } } -void p3ChatService::sendStatusString(const ChatId& id , const std::string& status_string) +void p3ChatService::sendStatusString( const ChatId& id, + const std::string& status_string ) { - if(id.isLobbyId()) - sendLobbyStatusString(id.toLobbyId(),status_string) ; - else if(id.isBroadcast()) - sendGroupChatStatusString(status_string); - else if(id.isPeerId() || id.isDistantChatId()) - { - RsChatStatusItem *cs = new RsChatStatusItem ; + if(id.isLobbyId()) sendLobbyStatusString(id.toLobbyId(),status_string); + else if(id.isBroadcast()) sendGroupChatStatusString(status_string); + else if(id.isPeerId() || id.isDistantChatId()) + { + RsPeerId vpid; + if(id.isDistantChatId()) vpid = RsPeerId(id.toDistantChatId()); + else vpid = id.toPeerId(); - 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); + if(isOnline(vpid)) + { + RsChatStatusItem *cs = new RsChatStatusItem; + + cs->status_string = status_string; + cs->flags = RS_CHAT_FLAG_PRIVATE; + 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); - } - else - { - std::cerr << "p3ChatService::sendStatusString() Error: chat id of this type is not handled, is it empty?" << std::endl; - return; - } + sendChatItem(cs); + } + } + else + { + std::cerr << "p3ChatService::sendStatusString() Error: chat id of this " + << "type is not handled, is it empty?" << std::endl; + return; + } } void p3ChatService::clearChatLobby(const ChatId& id) @@ -339,7 +339,8 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg) if(destination.isDistantChatId()) { - DEPMap::const_iterator it = + RS_STACK_MUTEX(mDGMutex); + DIDEMap::const_iterator it = mDistantGxsMap.find(destination.toDistantChatId()); if(it != mDistantGxsMap.end()) { @@ -687,31 +688,50 @@ bool p3ChatService::checkForMessageSecurity(RsChatMsgItem *ci) return true ; } -bool p3ChatService::initiateDistantChatConnexion( - const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, - DistantChatPeerId& pid, uint32_t& error_code ) +bool p3ChatService::initiateDistantChatConnexion( const RsGxsId& to_gxs_id, + const RsGxsId& from_gxs_id, + DistantChatPeerId& pid, + uint32_t& error_code, + bool notify ) { if(DistantChatService::initiateDistantChatConnexion( to_gxs_id, from_gxs_id, pid, - error_code )) + error_code, notify )) { + RS_STACK_MUTEX(mDGMutex); DistantEndpoints ep; ep.from = from_gxs_id; ep.to = to_gxs_id; - mDistantGxsMap.insert(DEPMap::value_type(pid, ep)); + mDistantGxsMap.insert(DIDEMap::value_type(pid, ep)); return true; } return false; } -bool p3ChatService::receiveGxsMail(const RsGxsMailItem&, const uint8_t* data, uint32_t dataSize) +bool p3ChatService::receiveGxsMail( const RsGxsId& authorId, + const RsGxsId& recipientId, + const uint8_t* data, uint32_t dataSize ) { - RsChatMsgItem* item = new RsChatMsgItem( const_cast(data), - dataSize ); - handleRecvChatMsgItem(item); - delete item; - return true; + DistantChatPeerId pid; + uint32_t error_code; + if(initiateDistantChatConnexion( + authorId, recipientId, pid, error_code, false )) + { + RsChatMsgItem* item = new RsChatMsgItem( const_cast(data), + dataSize ); + RsPeerId rd(p3GxsTunnelService::makeGxsTunnelId(authorId, recipientId)); + item->PeerId(rd); + handleRecvChatMsgItem(item); + delete item; + return true; + } + + std::cerr << "p3ChatService::receiveGxsMail(...) (EE) failed initiating" + << " distant chat connection error: "<< error_code + << std::endl; + return false; } -bool p3ChatService::notifySendMailStatus(const RsGxsMailItem& originalMessage, GxsMailStatus status) +bool p3ChatService::notifySendMailStatus( const RsGxsMailItem& originalMessage, + GxsMailStatus status ) { if ( status != GxsMailStatus::RECEIPT_RECEIVED ) return true; @@ -740,29 +760,6 @@ bool p3ChatService::notifySendMailStatus(const RsGxsMailItem& originalMessage, G bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *& ci) { - time_t now = time(NULL); - - { // Check for duplicates - uint32_t sz = ci->serial_size(); - std::vector srz; srz.resize(sz); - ci->serialise(&srz[0], sz); - Sha1CheckSum hash = RsDirUtil::sha1sum(&srz[0], sz); - { - RS_STACK_MUTEX(recentlyReceivedMutex); - if( mRecentlyReceivedMessageHashes.find(hash) != - mRecentlyReceivedMessageHashes.end() ) - { - std::cerr << "p3ChatService::handleRecvChatMsgItem(...) (II) " - << "receiving distant message of hash " << hash - << " more than once. Probably it has arrived before " - << "by other means." << std::endl; - delete ci; ci=NULL; - return true; - } - mRecentlyReceivedMessageHashes[hash] = now; - } - } - std::string name; uint32_t popupChatFlag = RS_POPUP_CHAT; @@ -840,7 +837,7 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *& ci) } } - ci->recvTime = now; + ci->recvTime = time(NULL); ChatMessage cm; initChatMessage(ci, cm); @@ -1169,24 +1166,6 @@ RsChatStatusItem *p3ChatService::makeOwnCustomStateStringItem() return ci ; } -void p3ChatService::cleanListOfReceivedMessageHashes() -{ - RS_STACK_MUTEX(recentlyReceivedMutex); - - time_t now = time(NULL); - - for( auto it = mRecentlyReceivedMessageHashes.begin(); - it != mRecentlyReceivedMessageHashes.end(); ) - if( now > RECENTLY_RECEIVED_INTERVAL + it->second ) - { - std::cerr << "p3MsgService(): cleanListOfReceivedMessageHashes(" - << "). Removing old hash " << it->first << ", aged " - << now - it->second << " secs ago." << std::endl; - - it = mRecentlyReceivedMessageHashes.erase(it); - } - else ++it; -} RsChatAvatarItem *p3ChatService::makeOwnAvatarItem() { RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ diff --git a/libretroshare/src/chat/p3chatservice.h b/libretroshare/src/chat/p3chatservice.h index 365ddb4a9..993dc1d94 100644 --- a/libretroshare/src/chat/p3chatservice.h +++ b/libretroshare/src/chat/p3chatservice.h @@ -95,11 +95,11 @@ struct p3ChatService : */ bool sendPrivateChat(const RsPeerId &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) - * e.g currently used to update user when a peer 'is typing' during a chat - */ - void sendStatusString(const ChatId& id,const std::string& status_str) ; + /** + * can be used to send 'immediate' status msgs, these status updates are + * meant for immediate use by peer (not saved by rs) e.g currently used to + * update user when a peer 'is typing' during a chat */ + void sendStatusString( const ChatId& id, const std::string& status_str ); /** * @brief clearChatLobby: Signal chat was cleared by GUI. @@ -168,10 +168,12 @@ struct p3ChatService : virtual bool initiateDistantChatConnexion( const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, DistantChatPeerId &pid, - uint32_t& error_code ); + uint32_t& error_code, + bool notify = true ); /// @see GxsMailsClient::receiveGxsMail(...) - virtual bool receiveGxsMail( const RsGxsMailItem& /*originalMessage*/, + virtual bool receiveGxsMail( const RsGxsId& authorId, + const RsGxsId& recipientId, const uint8_t* data, uint32_t dataSize ); /// @see GxsMailsClient::notifySendMailStatus(...) @@ -256,7 +258,7 @@ private: AvatarInfo *_own_avatar ; std::map _avatars ; - std::map _pendingPartialMessages ; + std::map _pendingPartialMessages; std::string _custom_status_string ; std::map _state_strings ; @@ -264,16 +266,11 @@ private: RsChatSerialiser *_serializer; struct DistantEndpoints { RsGxsId from; RsGxsId to; }; - typedef std::map DEPMap; - DEPMap mDistantGxsMap; - p3GxsMails& mGxsTransport; + typedef std::map DIDEMap; + DIDEMap mDistantGxsMap; + RsMutex mDGMutex; - /** As we have multiple backends duplicates are possible, keep track of - * recently received messages hashes for at least 2h to avoid them */ - const static uint32_t RECENTLY_RECEIVED_INTERVAL = 2*3600; - std::map mRecentlyReceivedMessageHashes; - RsMutex recentlyReceivedMutex; - void cleanListOfReceivedMessageHashes(); + p3GxsMails& mGxsTransport; }; class p3ChatService::StateStringInfo diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index 3ad4198a9..2d2da50dc 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -1023,7 +1023,8 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item) // Note: for some obscure reason, the typedef does not work here. Looks like a compiler error. So I use the primary type. -GXSTunnelId p3GxsTunnelService::makeGxsTunnelId(const RsGxsId &own_id, const RsGxsId &distant_id) const // creates a unique ID from two GXS ids. +/*static*/ GXSTunnelId p3GxsTunnelService::makeGxsTunnelId( + const RsGxsId &own_id, const RsGxsId &distant_id ) { unsigned char mem[RsGxsId::SIZE_IN_BYTES * 2] ; @@ -1240,18 +1241,20 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) std::map::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ; - if(it == _gxs_tunnel_contacts.end()) - { + if(it == _gxs_tunnel_contacts.end()) + { #ifdef DEBUG_GXS_TUNNEL - std::cerr << " Cannot find contact key info for tunnel id " << tunnel_id << ". Cannot send message!" << std::endl; + std::cerr << " Cannot find contact key info for tunnel id " + << tunnel_id << ". Cannot send message!" << std::endl; #endif - return false; - } - if(it->second.status != RS_GXS_TUNNEL_STATUS_CAN_TALK) - { - std::cerr << "(EE) Cannot talk to tunnel id " << tunnel_id << ". Tunnel status is: " << it->second.status << std::endl; - return false; - } + return false; + } + if(it->second.status != RS_GXS_TUNNEL_STATUS_CAN_TALK) + { + std::cerr << "(EE) Cannot talk to tunnel id " << tunnel_id + << ". Tunnel status is: " << it->second.status << std::endl; + return false; + } it->second.total_sent += rssize ; // counts the size of clear data that is sent diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.h b/libretroshare/src/gxstunnel/p3gxstunnel.h index 9a2481623..8d4ebfefc 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.h +++ b/libretroshare/src/gxstunnel/p3gxstunnel.h @@ -232,7 +232,6 @@ private: bool locked_initDHSessionKey(DH *&dh); TurtleVirtualPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle - RsGxsTunnelId makeGxsTunnelId(const RsGxsId &own_id, const RsGxsId &distant_id) const; // creates a unique ID from two GXS ids. // item handling @@ -256,5 +255,10 @@ private: std::map mRegisteredServices ; void debug_dump(); + +public: + /// creates a unique tunnel ID from two GXS ids. + static RsGxsTunnelId makeGxsTunnelId( const RsGxsId &own_id, + const RsGxsId &distant_id ); }; diff --git a/libretroshare/src/serialiser/rsgxsmailitems.h b/libretroshare/src/serialiser/rsgxsmailitems.h index e9c565d83..ac255b3f5 100644 --- a/libretroshare/src/serialiser/rsgxsmailitems.h +++ b/libretroshare/src/serialiser/rsgxsmailitems.h @@ -131,9 +131,9 @@ struct RsGxsMailItem : RsGxsMailBaseItem * mail is directed to the actual recipient as the "apparently" * corresponding hint may be fruit of a "luky" salting of another id. */ - RsGxsId recipientsHint; + RsGxsId recipientHint; void inline saltRecipientHint(const RsGxsId& salt) - { recipientsHint = recipientsHint | salt; } + { recipientHint = recipientHint | salt; } /** * @brief maybeRecipient given an id and an hint check if they match @@ -141,7 +141,7 @@ struct RsGxsMailItem : RsGxsMailBaseItem * @return true if the id may be recipient of the hint, false otherwise */ bool inline maybeRecipient(const RsGxsId& id) const - { return (~id|recipientsHint) == allRecipientsHint; } + { return (~id|recipientHint) == allRecipientsHint; } const static RsGxsId allRecipientsHint; @@ -153,7 +153,7 @@ struct RsGxsMailItem : RsGxsMailBaseItem { return RsGxsMailBaseItem::size() + 1 + // cryptoType - recipientsHint.serial_size() + + recipientHint.serial_size() + payload.size(); } bool serialize(uint8_t* data, uint32_t size, uint32_t& offset) const @@ -162,7 +162,7 @@ struct RsGxsMailItem : RsGxsMailBaseItem ok = ok && RsGxsMailBaseItem::serialize(data, size, offset); ok = ok && setRawUInt8( data, size, &offset, static_cast(cryptoType) ); - ok = ok && recipientsHint.serialise(data, size, offset); + ok = ok && recipientHint.serialise(data, size, offset); uint32_t psz = payload.size(); ok = ok && memcpy(data+offset, &payload[0], psz); offset += psz; @@ -181,7 +181,7 @@ struct RsGxsMailItem : RsGxsMailBaseItem uint8_t crType; ok = ok && getRawUInt8(dataPtr, rssize, &roffset, &crType); cryptoType = static_cast(crType); - ok = ok && recipientsHint.deserialise(dataPtr, rssize, roffset); + ok = ok && recipientHint.deserialise(dataPtr, rssize, roffset); uint32_t psz = rssize - roffset; ok = ok && (payload.resize(psz), memcpy(&payload[0], data+roffset, psz)); ok = ok && (roffset += psz); @@ -193,7 +193,7 @@ struct RsGxsMailItem : RsGxsMailBaseItem { RsGxsMailBaseItem::clear(); cryptoType = RsGxsMailEncryptionMode::UNDEFINED_ENCRYPTION; - recipientsHint.clear(); + recipientHint.clear(); payload.clear(); } diff --git a/libretroshare/src/services/p3gxsmails.cpp b/libretroshare/src/services/p3gxsmails.cpp index a4957b4e7..06acdce96 100644 --- a/libretroshare/src/services/p3gxsmails.cpp +++ b/libretroshare/src/services/p3gxsmails.cpp @@ -262,7 +262,7 @@ void p3GxsMails::service_tick() << msg->meta.mMsgId << " with cryptoType: " << static_cast(msg->cryptoType) - << " recipientHint: " << msg->recipientsHint + << " recipientHint: " << msg->recipientHint << " mailId: "<< msg->mailId << " payload.size(): " << msg->payload.size() << std::endl; @@ -423,8 +423,10 @@ bool p3GxsMails::handleEcryptedMail(const RsGxsMailItem* mail) getRawUInt16(&mail->payload[0], mail->payload.size(), &off, &csri); std::cerr << "service: " << csri << " got CLEAR_TEXT mail!" << std::endl; - return dispatchDecryptedMail( mail, &mail->payload[0], - mail->payload.size() ); + /* As we cannot verify recipient without encryption, just pass the hint + * as recipient */ + return dispatchDecryptedMail( mail->meta.mAuthorId, mail->recipientHint, + &mail->payload[0], mail->payload.size() ); } case RsGxsMailEncryptionMode::RSA: { @@ -432,14 +434,16 @@ bool p3GxsMails::handleEcryptedMail(const RsGxsMailItem* mail) for( std::set::const_iterator it = decryptIds.begin(); it != decryptIds.end(); ++it ) { + const RsGxsId& decryptId(*it); uint8_t* decrypted_data = NULL; uint32_t decrypted_data_size = 0; uint32_t decryption_error; if( idService.decryptData( &mail->payload[0], mail->payload.size(), decrypted_data, - decrypted_data_size, *it, + decrypted_data_size, decryptId, decryption_error ) ) - ok = ok && dispatchDecryptedMail( mail, decrypted_data, + ok = ok && dispatchDecryptedMail( mail->meta.mAuthorId, + decryptId, decrypted_data, decrypted_data_size ); free(decrypted_data); } @@ -452,7 +456,8 @@ bool p3GxsMails::handleEcryptedMail(const RsGxsMailItem* mail) } } -bool p3GxsMails::dispatchDecryptedMail( const RsGxsMailItem* received_msg, +bool p3GxsMails::dispatchDecryptedMail( const RsGxsId& authorId, + const RsGxsId& decryptId, const uint8_t* decrypted_data, uint32_t decrypted_data_size ) { @@ -486,16 +491,16 @@ bool p3GxsMails::dispatchDecryptedMail( const RsGxsMailItem* received_msg, std::vector rcct; rcct.push_back(receipt); RsGenExchange::notifyNewMessages(rcct); - GxsMailsClient* reecipientService = NULL; + GxsMailsClient* recipientService = NULL; { RS_STACK_MUTEX(servClientsMutex); - reecipientService = servClients[rsrvc]; + recipientService = servClients[rsrvc]; } - if(reecipientService) - return reecipientService->receiveGxsMail( *received_msg, - &decrypted_data[offset], - decrypted_data_size-offset ); + if(recipientService) + return recipientService->receiveGxsMail( authorId, decryptId, + &decrypted_data[offset], + decrypted_data_size-offset ); else { std::cerr << "p3GxsMails::dispatchReceivedMail(...) " @@ -625,7 +630,7 @@ void p3GxsMails::processOutgoingRecord(OutgoingRecord& pr) << pr.recipient << " with cryptoType: " << static_cast(pr.mailItem.cryptoType) - << " recipientHint: " << pr.mailItem.recipientsHint + << " recipientHint: " << pr.mailItem.recipientHint << " receiptId: " << pr.mailItem.mailId << " payload size: " << pr.mailItem.payload.size() << std::endl; diff --git a/libretroshare/src/services/p3gxsmails.h b/libretroshare/src/services/p3gxsmails.h index 7941f8aa3..1a9545e66 100644 --- a/libretroshare/src/services/p3gxsmails.h +++ b/libretroshare/src/services/p3gxsmails.h @@ -34,12 +34,14 @@ struct GxsMailsClient { /** * This will be called by p3GxsMails to dispatch mails to the subservice - * @param originalMessage message as received from GXS backend (encrypted) + * @param authorId message sender + * @param decryptId recipient id * @param data buffer containing the decrypted data * @param dataSize size of the buffer * @return true if dispatching goes fine, false otherwise */ - virtual bool receiveGxsMail( const RsGxsMailItem& originalMessage, + virtual bool receiveGxsMail( const RsGxsId& authorId, + const RsGxsId& recipientId, const uint8_t* data, uint32_t dataSize ) = 0; /** @@ -242,7 +244,8 @@ private: bool handleEcryptedMail(const RsGxsMailItem* mail); /// Dispatch the message to the recipient service - bool dispatchDecryptedMail( const RsGxsMailItem* received_msg, + bool dispatchDecryptedMail( const RsGxsId& authorId, + const RsGxsId& decryptId, const uint8_t* decrypted_data, uint32_t decrypted_data_size ); diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index 6da7a91b7..7d33b2235 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -1990,11 +1990,12 @@ uint32_t p3MsgService::getDistantMessagingPermissionFlags() return mDistantMessagePermissions ; } -bool p3MsgService::receiveGxsMail( const RsGxsMailItem& originalMessage, +bool p3MsgService::receiveGxsMail( const RsGxsId& authorId, + const RsGxsId& recipientId, const uint8_t* data, uint32_t dataSize ) { - std::cout << "p3MsgService::receiveGxsMail(" << originalMessage.mailId - << ",, " << dataSize << ")" << std::endl; + std::cout << "p3MsgService::receiveGxsMail(" << authorId + << ", " << recipientId << ", " << dataSize << ")" << std::endl; Sha1CheckSum hash = RsDirUtil::sha1sum(data, dataSize); @@ -2029,7 +2030,7 @@ bool p3MsgService::receiveGxsMail( const RsGxsMailItem& originalMessage, msg_item->msgFlags &= ~RS_MSG_FLAGS_PARTIAL; // hack to pass on GXS id. - msg_item->PeerId(RsPeerId(originalMessage.meta.mAuthorId)); + msg_item->PeerId(RsPeerId(authorId)); handleIncomingItem(msg_item); } else diff --git a/libretroshare/src/services/p3msgservice.h b/libretroshare/src/services/p3msgservice.h index 8bfd1b89a..8846c3f9a 100644 --- a/libretroshare/src/services/p3msgservice.h +++ b/libretroshare/src/services/p3msgservice.h @@ -136,7 +136,8 @@ struct p3MsgService : uint32_t getDistantMessagingPermissionFlags() ; /// @see GxsMailsClient::receiveGxsMail(...) - virtual bool receiveGxsMail( const RsGxsMailItem& originalMessage, + virtual bool receiveGxsMail( const RsGxsId& authorId, + const RsGxsId& recipientId, const uint8_t* data, uint32_t dataSize ); /// @see GxsMailsClient::notifySendMailStatus(...) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index cfde6a028..f7de21ff1 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -70,7 +70,7 @@ *****/ ChatWidget::ChatWidget(QWidget *parent) : - QWidget(parent), sendingBlocked(false), ui(new Ui::ChatWidget) + QWidget(parent), ui(new Ui::ChatWidget) { ui->setupUi(this); @@ -413,18 +413,9 @@ ChatWidget::ChatType ChatWidget::chatType() return CHATTYPE_UNKNOWN; } -void ChatWidget::blockSending(QString msg) -{ - sendingBlocked = true; - ui->sendButton->setEnabled(false); - ui->sendButton->setToolTip(msg); -} +void ChatWidget::blockSending(QString msg) { ui->sendButton->setToolTip(msg); } -void ChatWidget::unblockSending() -{ - sendingBlocked = false; - updateLenOfChatTextEdit(); -} +void ChatWidget::unblockSending() { updateLenOfChatTextEdit(); } void ChatWidget::processSettings(bool load) { @@ -1096,8 +1087,6 @@ void ChatWidget::updateStatusTyping() void ChatWidget::updateLenOfChatTextEdit() { - if(sendingBlocked) return; - QTextEdit *chatWidget = ui->chatTextEdit; QString text; RsHtml::optimizeHtml(chatWidget, text); diff --git a/retroshare-gui/src/gui/chat/ChatWidget.h b/retroshare-gui/src/gui/chat/ChatWidget.h index 174b4d777..270671af4 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.h +++ b/retroshare-gui/src/gui/chat/ChatWidget.h @@ -36,6 +36,7 @@ #include #include +#include class QAction; class QTextEdit; @@ -78,9 +79,8 @@ public: ChatId getChatId(); ChatType chatType(); - // allow/disallow sendng of messages - void blockSending(QString msg); - void unblockSending(); + RS_DEPRECATED void blockSending(QString msg); + RS_DEPRECATED void unblockSending(); bool hasNewMessages() { return newMessages; } bool isTyping() { return typing; } @@ -216,8 +216,6 @@ private: bool typing; int peerStatus; - bool sendingBlocked; - time_t lastStatusSendTime; ChatStyle chatStyle; diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp index 4992b5ff5..6d0fe079d 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp @@ -104,41 +104,52 @@ void PopupDistantChatDialog::updateDisplay() QString msg; - switch(tinfo.status) - { - case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl; - _status_label->setIcon(QIcon(IMAGE_GRY_LED)) ; - msg = tr("Chat remotely closed. Please close this window."); - _status_label->setToolTip(msg) ; - getChatWidget()->updateStatusString("%1", msg, true); - getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel.")); - setPeerStatus(RS_STATUS_OFFLINE) ; - break ; - case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl; - _status_label->setIcon(QIcon(IMAGE_RED_LED)) ; - _status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ; - - getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true); - getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel.")); - setPeerStatus(RS_STATUS_OFFLINE) ; - - break ; - case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl; - _status_label->setIcon(QIcon(IMAGE_RED_LED)) ; - msg = QObject::tr("Tunnel is pending..."); - _status_label->setToolTip(msg) ; - getChatWidget()->updateStatusString("%1", msg, true); - getChatWidget()->blockSending(msg); - setPeerStatus(RS_STATUS_OFFLINE) ; - break ; - case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl; - _status_label->setIcon(QIcon(IMAGE_GRN_LED)) ; - msg = QObject::tr("Secured tunnel is working. You can talk!"); - _status_label->setToolTip(msg) ; - getChatWidget()->unblockSending(); - setPeerStatus(RS_STATUS_ONLINE) ; - break ; - } + switch(tinfo.status) + { + case RS_DISTANT_CHAT_STATUS_UNKNOWN: + //std::cerr << "Unknown hash. Error!" << std::endl; + _status_label->setIcon(QIcon(IMAGE_GRY_LED)); + msg = tr("Remote status unknown."); + _status_label->setToolTip(msg); + getChatWidget()->updateStatusString("%1", msg, true); + getChatWidget()->blockSending(tr( "Can't send message immediately, " + "because there is no tunnel " + "available." )); + setPeerStatus(RS_STATUS_OFFLINE); + break ; + case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: + std::cerr << "Chat remotely closed. " << std::endl; + _status_label->setIcon(QIcon(IMAGE_RED_LED)); + _status_label->setToolTip( + QObject::tr("Distant peer has closed the chat") ); + getChatWidget()->updateStatusString( + "%1", tr( "The person you're talking to has deleted the" + "secured chat tunnel." ), true ); + getChatWidget()->blockSending(tr( "The chat partner deleted the secure" + " tunnel, messages will be delivered" + " as soon as possible")); + setPeerStatus(RS_STATUS_OFFLINE) ; + break ; + case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: + //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl; + _status_label->setIcon(QIcon(IMAGE_RED_LED)); + msg = QObject::tr( "Tunnel is pending... Messages will be delivered as" + " soon as possible" ); + _status_label->setToolTip(msg); + getChatWidget()->updateStatusString("%1", msg, true); + getChatWidget()->blockSending(msg); + setPeerStatus(RS_STATUS_OFFLINE); + break; + case RS_DISTANT_CHAT_STATUS_CAN_TALK: + //std::cerr << "Tunnel is ok and data is transmitted." << std::endl; + _status_label->setIcon(QIcon(IMAGE_GRN_LED)); + msg = QObject::tr( "Secured tunnel is working." + "Messages are delivered immediately!" ); + _status_label->setToolTip(msg); + getChatWidget()->unblockSending(); + setPeerStatus(RS_STATUS_ONLINE); + break; + } } void PopupDistantChatDialog::closeEvent(QCloseEvent *e)