2007-12-11 20:43:17 -05:00
/*
* libretroshare / src / services msgservice . cc
*
* Services for RetroShare .
*
* Copyright 2004 - 2008 by Robert Fernie .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* USA .
*
* Please report all bugs and problems to " retroshare@lunamutt.com " .
*
*/
2010-08-06 05:40:23 -04:00
# include "retroshare/rsiface.h"
2013-05-01 17:13:40 -04:00
# include "retroshare/rspeers.h"
2014-03-29 10:18:05 -04:00
# include "retroshare/rsidentity.h"
2009-02-22 12:36:39 -05:00
2007-12-11 20:43:17 -05:00
# include "pqi/pqibin.h"
# include "pqi/pqiarchive.h"
2011-07-09 14:39:34 -04:00
# include "pqi/p3linkmgr.h"
2013-04-29 16:44:48 -04:00
# include "pqi/authgpg.h"
2014-03-29 10:18:05 -04:00
# include "pqi/p3cfgmgr.h"
# include "gxs/gxssecurity.h"
2007-12-11 20:43:17 -05:00
2014-03-29 10:18:05 -04:00
# include "services/p3idservice.h"
2007-12-11 20:43:17 -05:00
# include "services/p3msgservice.h"
2014-03-29 10:18:05 -04:00
2013-05-03 17:02:44 -04:00
# include "pgp/pgpkeyutil.h"
2014-01-07 17:51:22 -05:00
# include "rsserver/p3face.h"
2013-12-27 15:06:47 -05:00
# include "serialiser/rsconfigitems.h"
2014-03-29 10:18:05 -04:00
2014-01-30 17:14:37 -05:00
# include "grouter/p3grouter.h"
# include "grouter/groutertypes.h"
2007-12-11 20:43:17 -05:00
2008-07-10 12:29:18 -04:00
# include "util/rsdebug.h"
2008-02-04 12:55:13 -05:00
# include "util/rsdir.h"
2012-03-30 19:02:52 -04:00
# include "util/rsstring.h"
2013-05-04 18:03:48 -04:00
# include "util/radix64.h"
2013-04-29 16:44:48 -04:00
# include "util/rsrandom.h"
2014-03-29 10:18:05 -04:00
# include "util/rsprint.h"
2008-02-04 12:55:13 -05:00
2014-05-19 18:16:04 -04:00
# include <unistd.h>
2007-12-11 20:43:17 -05:00
# include <iomanip>
2010-09-25 08:54:34 -04:00
# include <map>
2014-03-29 10:18:05 -04:00
# include <sstream>
2007-12-11 20:43:17 -05:00
2013-11-29 17:09:13 -05:00
//#define MSG_DEBUG 1
2013-08-09 13:02:29 -04:00
//#define DEBUG_DISTANT_MSG
2013-08-04 10:11:59 -04:00
//#define DISABLE_DISTANT_MESSAGES
2014-05-17 17:36:07 -04:00
//#define DEBUG_DISTANT_MSG
2013-05-08 12:58:22 -04:00
2007-12-11 20:43:17 -05:00
const int msgservicezone = 54319 ;
/* Another little hack ..... unique message Ids
* will be handled in this class . . . . .
* These are unique within this run of the server ,
* and are not stored long term . . . .
*
* Only 3 entry points :
* ( 1 ) from network . . . .
* ( 2 ) from local send
* ( 3 ) from storage . . .
*/
2014-03-29 10:18:05 -04:00
p3MsgService : : p3MsgService ( p3ServiceControl * sc , p3IdService * id_serv )
: p3Service ( ) , p3Config ( ) , mIdService ( id_serv ) , mServiceCtrl ( sc ) , mMsgMtx ( " p3MsgService " ) , mMsgUniqueId ( time ( NULL ) )
2007-12-11 20:43:17 -05:00
{
2013-05-01 17:13:40 -04:00
_serialiser = new RsMsgSerialiser ( ) ;
addSerialType ( _serialiser ) ;
2010-09-23 17:27:34 -04:00
2013-09-05 14:45:40 -04:00
mDistantMessagingEnabled = true ;
2012-05-01 05:18:55 -04:00
/* Initialize standard tag types */
2014-03-28 23:57:44 -04:00
if ( sc )
2012-05-01 05:18:55 -04:00
initStandardTagTypes ( ) ;
2014-01-30 17:14:37 -05:00
2007-12-11 20:43:17 -05:00
}
2014-03-21 23:53:44 -04:00
const std : : string MSG_APP_NAME = " msg " ;
const uint16_t MSG_APP_MAJOR_VERSION = 1 ;
const uint16_t MSG_APP_MINOR_VERSION = 0 ;
const uint16_t MSG_MIN_MAJOR_VERSION = 1 ;
const uint16_t MSG_MIN_MINOR_VERSION = 0 ;
RsServiceInfo p3MsgService : : getServiceInfo ( )
{
return RsServiceInfo ( RS_SERVICE_TYPE_MSG ,
MSG_APP_NAME ,
MSG_APP_MAJOR_VERSION ,
MSG_APP_MINOR_VERSION ,
MSG_MIN_MAJOR_VERSION ,
MSG_MIN_MINOR_VERSION ) ;
}
2008-02-04 16:40:34 -05:00
uint32_t p3MsgService : : getNewUniqueMsgId ( )
2008-02-04 12:55:13 -05:00
{
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
return mMsgUniqueId + + ;
}
2007-12-11 20:43:17 -05:00
int p3MsgService : : tick ( )
{
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::tick() " ) ;
/* don't worry about increasing tick rate!
* ( handled by p3service )
*/
incomingMsgs ( ) ;
2013-04-29 16:44:48 -04:00
static time_t last_management_time = 0 ;
time_t now = time ( NULL ) ;
if ( now > last_management_time + 5 )
{
manageDistantPeers ( ) ;
2013-08-31 17:10:04 -04:00
checkOutgoingMessages ( ) ;
2013-04-29 16:44:48 -04:00
last_management_time = now ;
}
2007-12-11 20:43:17 -05:00
return 0 ;
}
int p3MsgService : : status ( )
{
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::status() " ) ;
return 1 ;
}
2012-05-01 05:18:55 -04:00
void p3MsgService : : processMsg ( RsMsgItem * mi , bool incoming )
2011-05-21 12:26:00 -04:00
{
mi - > recvTime = time ( NULL ) ;
mi - > msgId = getNewUniqueMsgId ( ) ;
{
2012-04-26 19:41:14 -04:00
RsStackMutex stack ( mMsgMtx ) ; /*** STACK LOCKED MTX ***/
2011-05-21 12:26:00 -04:00
2012-05-01 05:18:55 -04:00
if ( incoming )
2011-05-21 12:26:00 -04:00
{
2012-04-26 19:41:14 -04:00
/* from a peer */
2015-02-20 05:34:11 -05:00
mi - > msgFlags & = ( RS_MSG_FLAGS_DISTANT | RS_MSG_FLAGS_SYSTEM ) ; // remove flags except those
2012-05-01 05:18:55 -04:00
mi - > msgFlags | = RS_MSG_FLAGS_NEW ;
2014-01-07 17:51:22 -05:00
p3Notify * notify = RsServer : : notify ( ) ;
2012-04-26 19:41:14 -04:00
if ( notify )
{
2015-02-20 05:34:11 -05:00
notify - > AddPopupMessage ( RS_POPUP_MSG , mi - > PeerId ( ) . toStdString ( ) , mi - > subject , mi - > message ) ;
2012-04-26 19:41:14 -04:00
std : : string out ;
rs_sprintf ( out , " %lu " , mi - > msgId ) ;
notify - > AddFeedItem ( RS_FEED_ITEM_MESSAGE , out , " " , " " ) ;
}
}
2012-05-01 05:18:55 -04:00
else
{
mi - > msgFlags | = RS_MSG_OUTGOING ;
}
2012-04-26 19:41:14 -04:00
imsg [ mi - > msgId ] = mi ;
RsMsgSrcId * msi = new RsMsgSrcId ( ) ;
msi - > msgId = mi - > msgId ;
msi - > srcId = mi - > PeerId ( ) ;
mSrcIds . insert ( std : : pair < uint32_t , RsMsgSrcId * > ( msi - > msgId , msi ) ) ;
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2011-05-21 12:26:00 -04:00
}
2015-02-18 14:07:58 -05:00
// If the peer is allowed to push files, then auto-download the recommended files.
if ( rsPeers - > servicePermissionFlags ( mi - > PeerId ( ) ) & RS_NODE_PERM_ALLOW_PUSH )
for ( std : : list < RsTlvFileItem > : : const_iterator it ( mi - > attachment . items . begin ( ) ) ; it ! = mi - > attachment . items . end ( ) ; + + it )
rsFiles - > FileRequest ( ( * it ) . name , ( * it ) . hash , ( * it ) . filesize , std : : string ( ) , RS_FILE_REQ_ANONYMOUS_ROUTING , std : : list < RsPeerId > ( ) ) ;
2011-05-21 12:26:00 -04:00
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_ADD ) ;
2011-05-21 12:26:00 -04:00
/**** STACK UNLOCKED ***/
}
2011-09-09 15:37:38 -04:00
bool p3MsgService : : checkAndRebuildPartialMessage ( RsMsgItem * ci )
{
// Check is the item is ending an incomplete item.
//
2014-03-17 16:56:06 -04:00
std : : map < RsPeerId , RsMsgItem * > : : iterator it = _pendingPartialMessages . find ( ci - > PeerId ( ) ) ;
2011-09-09 15:37:38 -04:00
bool ci_is_partial = ci - > msgFlags & RS_MSG_FLAGS_PARTIAL ;
if ( it ! = _pendingPartialMessages . end ( ) )
{
2013-11-29 17:09:13 -05:00
# ifdef MSG_DEBUG
std : : cerr < < " Pending message found. Appending it. " < < std : : endl ;
# endif
2011-09-09 15:37:38 -04:00
// Yes, there is. Append the item to ci.
ci - > message = it - > second - > message + ci - > message ;
ci - > msgFlags | = it - > second - > msgFlags ;
delete it - > second ;
if ( ! ci_is_partial )
_pendingPartialMessages . erase ( it ) ;
}
if ( ci_is_partial )
{
2013-11-29 17:09:13 -05:00
# ifdef MSG_DEBUG
2011-09-09 15:37:38 -04:00
std : : cerr < < " Message is partial, storing for later. " < < std : : endl ;
2013-11-29 17:09:13 -05:00
# endif
2011-09-09 15:37:38 -04:00
// The item is a partial message. Push it, and wait for the rest.
//
_pendingPartialMessages [ ci - > PeerId ( ) ] = ci ;
return false ;
}
else
{
2013-11-29 17:09:13 -05:00
# ifdef MSG_DEBUG
2011-09-09 15:37:38 -04:00
std : : cerr < < " Message is complete, using it now. " < < std : : endl ;
2013-11-29 17:09:13 -05:00
# endif
2011-09-09 15:37:38 -04:00
return true ;
}
}
2011-05-21 12:26:00 -04:00
int p3MsgService : : incomingMsgs ( )
2007-12-11 20:43:17 -05:00
{
RsMsgItem * mi ;
int i = 0 ;
2009-02-22 12:36:39 -05:00
2007-12-11 20:43:17 -05:00
while ( ( mi = ( RsMsgItem * ) recvItem ( ) ) ! = NULL )
{
2013-04-29 16:44:48 -04:00
handleIncomingItem ( mi ) ;
+ + i ;
}
2008-02-04 16:40:34 -05:00
2013-04-29 16:44:48 -04:00
return i ;
}
void p3MsgService : : handleIncomingItem ( RsMsgItem * mi )
{
bool changed = false ;
if ( checkAndRebuildPartialMessage ( mi ) ) // only returns true when a msg is complete.
{
processMsg ( mi , true ) ;
changed = true ;
2007-12-11 20:43:17 -05:00
}
2009-02-22 12:36:39 -05:00
if ( changed )
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2007-12-11 20:43:17 -05:00
}
2014-03-28 23:57:44 -04:00
void p3MsgService : : statusChange ( const std : : list < pqiServicePeer > & plist )
2008-02-07 11:18:34 -05:00
{
/* should do it properly! */
2014-03-28 23:57:44 -04:00
/* only do this when a new peer is connected */
bool newPeers = false ;
std : : list < pqiServicePeer > : : const_iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = plist . begin ( ) ; it ! = plist . end ( ) ; + + it )
2014-03-28 23:57:44 -04:00
{
if ( it - > actions & RS_SERVICE_PEER_CONNECTED )
{
newPeers = true ;
}
}
if ( newPeers )
{
checkOutgoingMessages ( ) ;
}
2008-02-07 11:18:34 -05:00
}
2011-09-09 15:37:38 -04:00
void p3MsgService : : checkSizeAndSendMessage ( RsMsgItem * msg )
{
// We check the message item, and possibly split it into multiple messages, if the message is too big.
static const uint32_t MAX_STRING_SIZE = 15000 ;
2015-01-11 17:18:28 -05:00
std : : cerr < < " Msg is size " < < msg - > message . size ( ) < < std : : endl ;
2014-03-17 16:56:06 -04:00
2011-09-09 15:37:38 -04:00
while ( msg - > message . size ( ) > MAX_STRING_SIZE )
{
// chop off the first 15000 wchars
RsMsgItem * item = new RsMsgItem ( * msg ) ;
item - > message = item - > message . substr ( 0 , MAX_STRING_SIZE ) ;
msg - > message = msg - > message . substr ( MAX_STRING_SIZE , msg - > message . size ( ) - MAX_STRING_SIZE ) ;
2013-09-08 07:42:13 -04:00
# ifdef DEBUG_DISTANT_MSG
2011-09-09 15:37:38 -04:00
std : : cerr < < " Chopped off msg of size " < < item - > message . size ( ) < < std : : endl ;
2013-09-08 07:42:13 -04:00
# endif
2011-09-09 15:37:38 -04:00
// Indicate that the message is to be continued.
//
item - > msgFlags | = RS_MSG_FLAGS_PARTIAL ;
2015-01-11 17:18:28 -05:00
sendItem ( item ) ;
2011-09-09 15:37:38 -04:00
}
2013-09-08 07:42:13 -04:00
# ifdef DEBUG_DISTANT_MSG
2011-09-09 15:37:38 -04:00
std : : cerr < < " Chopped off msg of size " < < msg - > message . size ( ) < < std : : endl ;
2013-09-08 07:42:13 -04:00
# endif
2013-04-29 18:32:58 -04:00
2015-01-11 17:18:28 -05:00
sendItem ( msg ) ;
2011-09-09 15:37:38 -04:00
}
2007-12-11 20:43:17 -05:00
int p3MsgService : : checkOutgoingMessages ( )
{
/* iterate through the outgoing queue
*
* if online , send
*/
2010-05-07 18:23:38 -04:00
bool changed = false ;
2013-05-01 17:13:40 -04:00
std : : list < RsMsgItem * > output_queue ;
2008-02-04 12:55:13 -05:00
2007-12-11 20:43:17 -05:00
{
2014-03-28 23:57:44 -04:00
const RsPeerId & ownId = mServiceCtrl - > getOwnId ( ) ;
2007-12-11 20:43:17 -05:00
2010-05-07 18:23:38 -04:00
std : : list < uint32_t > : : iterator it ;
std : : list < uint32_t > toErase ;
2015-01-11 17:18:28 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-05-07 18:23:38 -04:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
2014-10-24 18:07:26 -04:00
for ( mit = msgOutgoing . begin ( ) ; mit ! = msgOutgoing . end ( ) ; + + mit )
2008-01-25 02:49:28 -05:00
{
2015-01-11 17:18:28 -05:00
if ( mit - > second - > msgFlags & RS_MSG_FLAGS_TRASH )
2010-05-28 10:42:54 -04:00
continue ;
2010-05-07 18:23:38 -04:00
/* find the certificate */
2014-03-29 10:18:05 -04:00
RsPeerId pid = mit - > second - > PeerId ( ) ;
2010-05-07 18:23:38 -04:00
2014-04-19 12:02:11 -04:00
if ( pid = = ownId
2015-01-11 17:18:28 -05:00
| | ( ( mit - > second - > msgFlags & RS_MSG_FLAGS_DISTANT ) & & ( ! ( mit - > second - > msgFlags & RS_MSG_FLAGS_ROUTED ) ) )
| | mServiceCtrl - > isPeerConnected ( getServiceInfo ( ) . mServiceType , pid ) ) /* FEEDBACK Msg to Ourselves */
2010-05-07 18:23:38 -04:00
{
/* send msg */
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::checkOutGoingMessages() Sending out message " ) ;
/* remove the pending flag */
2013-05-01 17:13:40 -04:00
output_queue . push_back ( mit - > second ) ;
2010-05-07 18:23:38 -04:00
2014-04-19 12:02:11 -04:00
// When the message is a distant msg, dont remove it yet from the list. Only mark it as being sent, so that we don't send it again.
//
if ( ! ( mit - > second - > msgFlags & RS_MSG_FLAGS_DISTANT ) )
{
2014-04-21 09:08:42 -04:00
( mit - > second ) - > msgFlags & = ~ RS_MSG_FLAGS_PENDING ;
2014-04-19 12:02:11 -04:00
toErase . push_back ( mit - > first ) ;
changed = true ;
}
else
2014-04-21 09:08:42 -04:00
{
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Message id " < < mit - > first < < " is distant: kept in outgoing, and marked as ROUTED " < < std : : endl ;
# endif
2014-04-19 12:02:11 -04:00
mit - > second - > msgFlags | = RS_MSG_FLAGS_ROUTED ;
2014-04-21 09:08:42 -04:00
}
2010-05-07 18:23:38 -04:00
}
else
{
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::checkOutGoingMessages() Delaying until available... " ) ;
}
2007-12-11 20:43:17 -05:00
}
2010-05-07 18:23:38 -04:00
/* clean up */
2014-10-24 18:07:26 -04:00
for ( it = toErase . begin ( ) ; it ! = toErase . end ( ) ; + + it )
2007-12-11 20:43:17 -05:00
{
2010-05-07 18:23:38 -04:00
mit = msgOutgoing . find ( * it ) ;
if ( mit ! = msgOutgoing . end ( ) )
{
msgOutgoing . erase ( mit ) ;
}
2010-11-10 15:37:02 -05:00
std : : map < uint32_t , RsMsgSrcId * > : : iterator srcIt = mSrcIds . find ( * it ) ;
if ( srcIt ! = mSrcIds . end ( ) ) {
delete ( srcIt - > second ) ;
mSrcIds . erase ( srcIt ) ;
}
2007-12-11 20:43:17 -05:00
}
2008-02-04 12:55:13 -05:00
2010-05-07 18:23:38 -04:00
if ( toErase . size ( ) > 0 )
2008-02-04 12:55:13 -05:00
{
2010-05-07 18:23:38 -04:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-02-04 12:55:13 -05:00
}
}
2015-01-11 17:18:28 -05:00
for ( std : : list < RsMsgItem * > : : const_iterator it ( output_queue . begin ( ) ) ; it ! = output_queue . end ( ) ; + + it )
if ( ( * it ) - > msgFlags & RS_MSG_FLAGS_DISTANT ) // don't split distant messages. The global router takes care of it.
sendDistantMsgItem ( * it ) ;
else
checkSizeAndSendMessage ( * it ) ;
2013-05-01 17:13:40 -04:00
2010-05-07 18:23:38 -04:00
if ( changed )
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2008-02-07 11:18:34 -05:00
2007-12-11 20:43:17 -05:00
return 0 ;
}
2010-12-18 14:35:07 -05:00
bool p3MsgService : : saveList ( bool & cleanup , std : : list < RsItem * > & itemList )
2007-12-11 20:43:17 -05:00
{
2010-09-20 18:11:09 -04:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
std : : map < uint32_t , RsMsgTagType * > : : iterator mit2 ;
std : : map < uint32_t , RsMsgTags * > : : iterator mit3 ;
2010-11-10 15:37:02 -05:00
std : : map < uint32_t , RsMsgSrcId * > : : iterator lit ;
2010-11-02 17:11:11 -04:00
std : : map < uint32_t , RsMsgParentId * > : : iterator mit4 ;
2008-02-04 16:40:34 -05:00
2010-10-31 15:29:26 -04:00
MsgTagType stdTags ;
2010-09-25 08:54:34 -04:00
2010-09-20 18:11:09 -04:00
cleanup = false ;
2007-12-11 20:43:17 -05:00
2010-09-20 18:11:09 -04:00
mMsgMtx . lock ( ) ;
2007-12-11 20:43:17 -05:00
2014-10-24 18:07:26 -04:00
for ( mit = imsg . begin ( ) ; mit ! = imsg . end ( ) ; + + mit )
2010-09-20 18:11:09 -04:00
itemList . push_back ( mit - > second ) ;
2007-12-11 20:43:17 -05:00
2014-10-24 18:07:26 -04:00
for ( lit = mSrcIds . begin ( ) ; lit ! = mSrcIds . end ( ) ; + + lit )
2010-11-10 15:37:02 -05:00
itemList . push_back ( lit - > second ) ;
2010-10-31 15:29:26 -04:00
2014-10-24 18:07:26 -04:00
for ( mit = msgOutgoing . begin ( ) ; mit ! = msgOutgoing . end ( ) ; + + mit )
2010-09-20 18:11:09 -04:00
itemList . push_back ( mit - > second ) ;
2010-08-19 17:47:26 -04:00
2014-10-24 18:07:26 -04:00
for ( mit2 = mTags . begin ( ) ; mit2 ! = mTags . end ( ) ; + + mit2 )
2011-05-21 12:26:00 -04:00
itemList . push_back ( mit2 - > second ) ;
2010-08-19 17:47:26 -04:00
2014-10-24 18:07:26 -04:00
for ( mit3 = mMsgTags . begin ( ) ; mit3 ! = mMsgTags . end ( ) ; + + mit3 )
2010-09-20 18:11:09 -04:00
itemList . push_back ( mit3 - > second ) ;
2010-08-19 17:47:26 -04:00
2014-10-24 18:07:26 -04:00
for ( mit4 = mParentId . begin ( ) ; mit4 ! = mParentId . end ( ) ; + + mit4 )
2010-11-02 17:11:11 -04:00
itemList . push_back ( mit4 - > second ) ;
2013-08-09 13:02:29 -04:00
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
RsTlvKeyValue kv ;
kv . key = " DISTANT_MESSAGES_ENABLED " ;
kv . value = mDistantMessagingEnabled ? " YES " : " NO " ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
itemList . push_back ( vitem ) ;
2010-12-18 14:35:07 -05:00
return true ;
2010-09-20 18:11:09 -04:00
}
2009-03-20 19:37:06 -04:00
2010-09-20 18:11:09 -04:00
void p3MsgService : : saveDone ( )
{
// unlocks mutex which has been locked by savelist
mMsgMtx . unlock ( ) ;
}
2009-03-20 19:37:06 -04:00
2010-09-20 18:11:09 -04:00
RsSerialiser * p3MsgService : : setupSerialiser ( )
{
2013-08-09 13:02:29 -04:00
RsSerialiser * rss = new RsSerialiser ;
rss - > addSerialType ( new RsMsgSerialiser ( true ) ) ;
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
2010-09-20 18:11:09 -04:00
return rss ;
2007-12-11 20:43:17 -05:00
}
2010-08-22 18:12:26 -04:00
// build list of standard tag types
static void getStandardTagTypes ( MsgTagType & tags )
{
/* create standard tag types, the text must be translated in the GUI */
tags . types [ RS_MSGTAGTYPE_IMPORTANT ] = std : : pair < std : : string , uint32_t > ( " Important " , 0xFF0000 ) ;
tags . types [ RS_MSGTAGTYPE_WORK ] = std : : pair < std : : string , uint32_t > ( " Work " , 0xFF9900 ) ;
tags . types [ RS_MSGTAGTYPE_PERSONAL ] = std : : pair < std : : string , uint32_t > ( " Personal " , 0x009900 ) ;
tags . types [ RS_MSGTAGTYPE_TODO ] = std : : pair < std : : string , uint32_t > ( " Todo " , 0x3333FF ) ;
tags . types [ RS_MSGTAGTYPE_LATER ] = std : : pair < std : : string , uint32_t > ( " Later " , 0x993399 ) ;
}
// Initialize the standard tag types after load
void p3MsgService : : initStandardTagTypes ( )
{
bool bChanged = false ;
2014-03-28 23:57:44 -04:00
const RsPeerId & ownId = mServiceCtrl - > getOwnId ( ) ;
2010-08-22 18:12:26 -04:00
MsgTagType tags ;
getStandardTagTypes ( tags ) ;
std : : map < uint32_t , std : : pair < std : : string , uint32_t > > : : iterator tit ;
2014-10-24 18:07:26 -04:00
for ( tit = tags . types . begin ( ) ; tit ! = tags . types . end ( ) ; + + tit ) {
2010-08-22 18:12:26 -04:00
std : : map < uint32_t , RsMsgTagType * > : : iterator mit = mTags . find ( tit - > first ) ;
if ( mit = = mTags . end ( ) ) {
RsMsgTagType * tagType = new RsMsgTagType ( ) ;
2014-03-17 16:56:06 -04:00
tagType - > PeerId ( ownId ) ;
2010-08-22 18:12:26 -04:00
tagType - > tagId = tit - > first ;
tagType - > text = tit - > second . first ;
tagType - > rgb_color = tit - > second . second ;
mTags . insert ( std : : pair < uint32_t , RsMsgTagType * > ( tit - > first , tagType ) ) ;
bChanged = true ;
}
}
if ( bChanged ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
}
2010-12-18 14:35:07 -05:00
bool p3MsgService : : loadList ( std : : list < RsItem * > & load )
2007-12-11 20:43:17 -05:00
{
2010-08-19 17:47:26 -04:00
RsMsgItem * mitem ;
RsMsgTagType * mtt ;
RsMsgTags * mti ;
2010-10-31 15:29:26 -04:00
RsMsgSrcId * msi ;
2010-11-02 17:11:11 -04:00
RsMsgParentId * msp ;
2014-03-17 16:56:06 -04:00
// RsPublicMsgInviteConfigItem* msv;
2007-12-11 20:43:17 -05:00
2010-09-20 18:11:09 -04:00
std : : list < RsMsgItem * > items ;
2010-09-25 08:54:34 -04:00
std : : list < RsItem * > : : iterator it ;
std : : map < uint32_t , RsMsgTagType * > : : iterator tagIt ;
2014-03-17 16:56:06 -04:00
std : : map < uint32_t , RsPeerId > srcIdMsgMap ;
std : : map < uint32_t , RsPeerId > : : iterator srcIt ;
2010-10-31 15:29:26 -04:00
2013-08-09 13:02:29 -04:00
bool distant_messaging_set = false ;
2008-02-04 16:40:34 -05:00
2010-06-04 19:39:33 -04:00
// load items and calculate next unique msgId
2014-10-24 18:07:26 -04:00
for ( it = load . begin ( ) ; it ! = load . end ( ) ; + + it )
2007-12-11 20:43:17 -05:00
{
2010-09-20 18:11:09 -04:00
if ( NULL ! = ( mitem = dynamic_cast < RsMsgItem * > ( * it ) ) )
2007-12-11 20:43:17 -05:00
{
/* STORE MsgID */
2010-06-04 19:39:33 -04:00
if ( mitem - > msgId > = mMsgUniqueId ) {
mMsgUniqueId = mitem - > msgId + 1 ;
}
items . push_back ( mitem ) ;
}
2010-09-20 18:11:09 -04:00
else if ( NULL ! = ( mtt = dynamic_cast < RsMsgTagType * > ( * it ) ) )
2013-05-05 15:13:27 -04:00
{
// delete standard tags as they are now save in config
if ( mTags . end ( ) = = ( tagIt = mTags . find ( mtt - > tagId ) ) )
{
mTags . insert ( std : : pair < uint32_t , RsMsgTagType * > ( mtt - > tagId , mtt ) ) ;
}
else
{
delete mTags [ mtt - > tagId ] ;
mTags . erase ( tagIt ) ;
mTags . insert ( std : : pair < uint32_t , RsMsgTagType * > ( mtt - > tagId , mtt ) ) ;
}
2010-09-25 08:54:34 -04:00
2010-08-19 17:47:26 -04:00
}
2010-09-20 18:11:09 -04:00
else if ( NULL ! = ( mti = dynamic_cast < RsMsgTags * > ( * it ) ) )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
mMsgTags . insert ( std : : pair < uint32_t , RsMsgTags * > ( mti - > msgId , mti ) ) ;
2010-08-19 17:47:26 -04:00
}
2010-10-31 15:29:26 -04:00
else if ( NULL ! = ( msi = dynamic_cast < RsMsgSrcId * > ( * it ) ) )
{
2014-03-17 16:56:06 -04:00
srcIdMsgMap . insert ( std : : pair < uint32_t , RsPeerId > ( msi - > msgId , msi - > srcId ) ) ;
2010-11-10 15:37:02 -05:00
mSrcIds . insert ( std : : pair < uint32_t , RsMsgSrcId * > ( msi - > msgId , msi ) ) ; // does not need to be kept
2010-10-31 15:29:26 -04:00
}
2010-11-02 17:11:11 -04:00
else if ( NULL ! = ( msp = dynamic_cast < RsMsgParentId * > ( * it ) ) )
{
mParentId . insert ( std : : pair < uint32_t , RsMsgParentId * > ( msp - > msgId , msp ) ) ;
}
2013-08-09 13:02:29 -04:00
RsConfigKeyValueSet * vitem = NULL ;
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 " )
{
2013-11-29 17:09:13 -05:00
# ifdef MSG_DEBUG
2013-08-09 13:02:29 -04:00
std : : cerr < < " Loaded config default nick name for distant chat: " < < kit - > value < < std : : endl ;
# endif
enableDistantMessaging ( kit - > value = = " YES " ) ;
distant_messaging_set = true ;
}
}
2014-04-21 09:08:42 -04:00
if ( mDistantMessagingEnabled | | ! distant_messaging_set )
2013-08-09 13:02:29 -04:00
{
2013-09-08 07:42:13 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-08-09 13:02:29 -04:00
std : : cerr < < " No config value for distant messaging. Setting it to true. " < < std : : endl ;
2013-09-08 07:42:13 -04:00
# endif
2013-08-09 13:02:29 -04:00
enableDistantMessaging ( true ) ;
2010-06-04 19:39:33 -04:00
}
2008-02-07 11:18:34 -05:00
2010-06-04 19:39:33 -04:00
// sort items into lists
2010-09-20 18:11:09 -04:00
std : : list < RsMsgItem * > : : iterator msgIt ;
2014-10-24 18:07:26 -04:00
for ( msgIt = items . begin ( ) ; msgIt ! = items . end ( ) ; + + msgIt )
2010-06-04 19:39:33 -04:00
{
2010-09-20 18:11:09 -04:00
mitem = * msgIt ;
2008-07-09 05:55:09 -04:00
2010-06-04 19:39:33 -04:00
/* STORE MsgID */
if ( mitem - > msgId = = 0 ) {
mitem - > msgId = getNewUniqueMsgId ( ) ;
}
2008-02-07 11:18:34 -05:00
2010-11-10 15:37:02 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
srcIt = srcIdMsgMap . find ( mitem - > msgId ) ;
if ( srcIt ! = srcIdMsgMap . end ( ) ) {
mitem - > PeerId ( srcIt - > second ) ;
srcIdMsgMap . erase ( srcIt ) ;
}
2010-06-04 19:39:33 -04:00
/* switch depending on the PENDING
* flags
*/
if ( mitem - > msgFlags & RS_MSG_FLAGS_PENDING )
{
//std::cerr << "MSG_PENDING";
//std::cerr << std::endl;
//mitem->print(std::cerr);
msgOutgoing [ mitem - > msgId ] = mitem ;
2007-12-11 20:43:17 -05:00
}
else
{
2010-11-10 15:37:02 -05:00
imsg [ mitem - > msgId ] = mitem ;
}
}
2010-10-31 15:29:26 -04:00
2010-11-10 15:37:02 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-06-04 19:39:33 -04:00
2010-11-10 15:37:02 -05:00
/* remove missing msgId in mSrcIds */
2014-10-24 18:07:26 -04:00
for ( srcIt = srcIdMsgMap . begin ( ) ; srcIt ! = srcIdMsgMap . end ( ) ; + + srcIt ) {
2010-11-10 15:37:02 -05:00
std : : map < uint32_t , RsMsgSrcId * > : : iterator it = mSrcIds . find ( srcIt - > first ) ;
if ( it ! = mSrcIds . end ( ) ) {
delete ( it - > second ) ;
mSrcIds . erase ( it ) ;
2007-12-11 20:43:17 -05:00
}
}
2010-11-02 17:11:11 -04:00
/* remove missing msgId in mParentId */
std : : map < uint32_t , RsMsgParentId * > : : iterator mit = mParentId . begin ( ) ;
while ( mit ! = mParentId . end ( ) ) {
if ( imsg . find ( mit - > first ) = = imsg . end ( ) ) {
if ( msgOutgoing . find ( mit - > first ) = = msgOutgoing . end ( ) ) {
/* not found */
mParentId . erase ( mit + + ) ;
continue ;
}
}
2014-10-24 18:07:26 -04:00
+ + mit ;
2010-11-02 17:11:11 -04:00
}
2008-02-07 11:18:34 -05:00
return true ;
2007-12-11 20:43:17 -05:00
}
void p3MsgService : : loadWelcomeMsg ( )
{
/* Load Welcome Message */
RsMsgItem * msg = new RsMsgItem ( ) ;
2014-03-28 23:57:44 -04:00
//msg -> PeerId(mServiceCtrl->getOwnId());
2007-12-11 20:43:17 -05:00
2011-03-06 07:58:18 -05:00
msg - > sendTime = time ( NULL ) ;
msg - > recvTime = time ( NULL ) ;
msg - > msgFlags = RS_MSG_FLAGS_NEW ;
2007-12-11 20:43:17 -05:00
2013-10-03 17:41:34 -04:00
msg - > subject = " Welcome to Retroshare " ;
2007-12-11 20:43:17 -05:00
2013-10-03 17:41:34 -04:00
msg - > message = " Send and receive messages with your friends... \n " ;
msg - > message + = " These can hold recommendations from your local shared files. \n \n " ;
msg - > message + = " Add recommendations through the Local Files Dialog. \n \n " ;
msg - > message + = " Enjoy. " ;
2007-12-11 20:43:17 -05:00
2008-02-04 12:55:13 -05:00
msg - > msgId = getNewUniqueMsgId ( ) ;
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-11-04 14:03:54 -04:00
imsg [ msg - > msgId ] = msg ;
IndicateConfigChanged ( ) ;
2008-02-04 12:55:13 -05:00
}
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
/****************************************/
/****************************************/
bool p3MsgService : : getMessageSummaries ( std : : list < MsgInfoSummary > & msgList )
{
/* do stuff */
msgList . clear ( ) ;
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-04 12:55:13 -05:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
2014-10-24 18:07:26 -04:00
for ( mit = imsg . begin ( ) ; mit ! = imsg . end ( ) ; + + mit )
2008-02-04 12:55:13 -05:00
{
MsgInfoSummary mis ;
initRsMIS ( mit - > second , mis ) ;
msgList . push_back ( mis ) ;
}
2014-10-24 18:07:26 -04:00
for ( mit = msgOutgoing . begin ( ) ; mit ! = msgOutgoing . end ( ) ; + + mit )
2008-02-04 12:55:13 -05:00
{
MsgInfoSummary mis ;
initRsMIS ( mit - > second , mis ) ;
msgList . push_back ( mis ) ;
}
2010-05-13 15:20:40 -04:00
return true ;
2007-12-11 20:43:17 -05:00
}
2010-11-02 17:11:11 -04:00
bool p3MsgService : : getMessage ( const std : : string & mId , MessageInfo & msg )
2008-02-04 12:55:13 -05:00
{
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
uint32_t msgId = atoi ( mId . c_str ( ) ) ;
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-04 12:55:13 -05:00
mit = imsg . find ( msgId ) ;
if ( mit = = imsg . end ( ) )
{
mit = msgOutgoing . find ( msgId ) ;
if ( mit = = msgOutgoing . end ( ) )
{
return false ;
}
}
/* mit valid */
initRsMI ( mit - > second , msg ) ;
2014-05-07 16:53:16 -04:00
std : : map < uint32_t , RsMsgSrcId * > : : const_iterator it = mSrcIds . find ( msgId ) ;
if ( it ! = mSrcIds . end ( ) )
msg . rsgxsid_srcId = RsGxsId ( it - > second - > srcId ) ;
2008-02-04 12:55:13 -05:00
return true ;
}
2010-05-28 10:42:54 -04:00
void p3MsgService : : getMessageCount ( unsigned int * pnInbox , unsigned int * pnInboxNew , unsigned int * pnOutbox , unsigned int * pnDraftbox , unsigned int * pnSentbox , unsigned int * pnTrashbox )
2010-05-13 15:20:40 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
if ( pnInbox ) * pnInbox = 0 ;
if ( pnInboxNew ) * pnInboxNew = 0 ;
if ( pnOutbox ) * pnOutbox = 0 ;
if ( pnDraftbox ) * pnDraftbox = 0 ;
if ( pnSentbox ) * pnSentbox = 0 ;
2010-05-28 10:42:54 -04:00
if ( pnTrashbox ) * pnTrashbox = 0 ;
2010-05-13 15:20:40 -04:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
std : : map < uint32_t , RsMsgItem * > * apMsg [ 2 ] = { & imsg , & msgOutgoing } ;
for ( int i = 0 ; i < 2 ; i + + ) {
2014-10-24 18:07:26 -04:00
for ( mit = apMsg [ i ] - > begin ( ) ; mit ! = apMsg [ i ] - > end ( ) ; + + mit ) {
2010-05-13 15:20:40 -04:00
MsgInfoSummary mis ;
initRsMIS ( mit - > second , mis ) ;
2010-05-28 10:42:54 -04:00
if ( mis . msgflags & RS_MSG_TRASH ) {
2014-10-21 18:33:02 -04:00
if ( pnTrashbox ) + + ( * pnTrashbox ) ;
2010-05-28 10:42:54 -04:00
continue ;
}
2010-05-13 15:20:40 -04:00
switch ( mis . msgflags & RS_MSG_BOXMASK ) {
case RS_MSG_INBOX :
2014-10-21 18:33:02 -04:00
if ( pnInbox ) + + ( * pnInbox ) ;
2010-05-13 15:20:40 -04:00
if ( ( mis . msgflags & RS_MSG_NEW ) = = RS_MSG_NEW ) {
2014-10-21 18:33:02 -04:00
if ( pnInboxNew ) + + ( * pnInboxNew ) ;
2010-05-13 15:20:40 -04:00
}
break ;
case RS_MSG_OUTBOX :
2014-10-21 18:33:02 -04:00
if ( pnOutbox ) + + ( * pnOutbox ) ;
2010-05-13 15:20:40 -04:00
break ;
case RS_MSG_DRAFTBOX :
2014-10-21 18:33:02 -04:00
if ( pnDraftbox ) + + ( * pnDraftbox ) ;
2010-05-13 15:20:40 -04:00
break ;
case RS_MSG_SENTBOX :
2014-10-21 18:33:02 -04:00
if ( pnSentbox ) + + ( * pnSentbox ) ;
2010-05-13 15:20:40 -04:00
break ;
}
}
}
}
2008-02-04 12:55:13 -05:00
/* remove based on the unique mid (stored in sid) */
2010-11-02 17:11:11 -04:00
bool p3MsgService : : removeMsgId ( const std : : string & mid )
2008-02-04 12:55:13 -05:00
{
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
uint32_t msgId = atoi ( mid . c_str ( ) ) ;
2010-08-22 18:12:26 -04:00
if ( msgId = = 0 ) {
std : : cerr < < " p3MsgService::removeMsgId: Unknown msgId " < < msgId < < std : : endl ;
return false ;
}
bool changed = false ;
2008-02-04 12:55:13 -05:00
{
2009-02-22 12:36:39 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-04 12:55:13 -05:00
2009-02-22 12:36:39 -05:00
mit = imsg . find ( msgId ) ;
if ( mit ! = imsg . end ( ) )
{
2010-08-22 18:12:26 -04:00
changed = true ;
2009-02-22 12:36:39 -05:00
RsMsgItem * mi = mit - > second ;
imsg . erase ( mit ) ;
delete mi ;
}
2008-02-04 12:55:13 -05:00
2009-02-22 12:36:39 -05:00
mit = msgOutgoing . find ( msgId ) ;
if ( mit ! = msgOutgoing . end ( ) )
{
changed = true ;
RsMsgItem * mi = mit - > second ;
msgOutgoing . erase ( mit ) ;
delete mi ;
}
2010-11-10 15:37:02 -05:00
std : : map < uint32_t , RsMsgSrcId * > : : iterator srcIt = mSrcIds . find ( msgId ) ;
if ( srcIt ! = mSrcIds . end ( ) ) {
changed = true ;
delete ( srcIt - > second ) ;
mSrcIds . erase ( srcIt ) ;
}
2008-02-04 12:55:13 -05:00
}
2010-08-22 18:12:26 -04:00
if ( changed ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
setMessageTag ( mid , 0 , false ) ;
2010-11-02 17:11:11 -04:00
setMsgParentId ( msgId , 0 ) ;
2010-08-22 18:12:26 -04:00
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2010-08-22 18:12:26 -04:00
}
2009-02-22 12:36:39 -05:00
2010-08-22 18:12:26 -04:00
return changed ;
2008-02-04 12:55:13 -05:00
}
2011-05-23 19:45:31 -04:00
bool p3MsgService : : markMsgIdRead ( const std : : string & mid , bool unreadByUser )
2008-02-04 12:55:13 -05:00
{
2009-02-22 12:36:39 -05:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
2008-02-04 12:55:13 -05:00
uint32_t msgId = atoi ( mid . c_str ( ) ) ;
2010-08-22 18:12:26 -04:00
bool changed = false ;
2008-02-04 12:55:13 -05:00
{
2009-02-22 12:36:39 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
mit = imsg . find ( msgId ) ;
if ( mit ! = imsg . end ( ) )
{
RsMsgItem * mi = mit - > second ;
2010-08-22 18:12:26 -04:00
uint32_t msgFlags = mi - > msgFlags ;
/* remove new state */
mi - > msgFlags & = ~ ( RS_MSG_FLAGS_NEW ) ;
/* set state from user */
2011-05-23 19:45:31 -04:00
if ( unreadByUser ) {
2010-08-22 18:12:26 -04:00
mi - > msgFlags | = RS_MSG_FLAGS_UNREAD_BY_USER ;
} else {
mi - > msgFlags & = ~ RS_MSG_FLAGS_UNREAD_BY_USER ;
}
if ( mi - > msgFlags ! = msgFlags )
{
changed = true ;
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
} else {
return false ;
2009-02-22 12:36:39 -05:00
}
2010-08-22 18:12:26 -04:00
} /* UNLOCKED */
2009-02-22 12:36:39 -05:00
2010-08-22 18:12:26 -04:00
if ( changed ) {
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2010-08-09 08:16:21 -04:00
}
2010-08-22 18:12:26 -04:00
return true ;
2008-02-04 12:55:13 -05:00
}
2010-11-02 17:11:11 -04:00
bool p3MsgService : : setMsgFlag ( const std : : string & mid , uint32_t flag , uint32_t mask )
{
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
uint32_t msgId = atoi ( mid . c_str ( ) ) ;
bool changed = false ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
mit = imsg . find ( msgId ) ;
if ( mit = = imsg . end ( ) )
{
mit = msgOutgoing . find ( msgId ) ;
if ( mit = = msgOutgoing . end ( ) )
{
return false ;
}
}
uint32_t oldFlag = mit - > second - > msgFlags ;
mit - > second - > msgFlags & = ~ mask ;
mit - > second - > msgFlags | = flag ;
if ( mit - > second - > msgFlags ! = oldFlag ) {
changed = true ;
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
} /* UNLOCKED */
if ( changed ) {
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2010-11-02 17:11:11 -04:00
}
return true ;
}
bool p3MsgService : : getMsgParentId ( const std : : string & msgId , std : : string & msgParentId )
{
msgParentId . clear ( ) ;
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < uint32_t , RsMsgParentId * > : : iterator mit = mParentId . find ( atoi ( msgId . c_str ( ) ) ) ;
if ( mit = = mParentId . end ( ) ) {
return false ;
}
2012-04-17 17:00:54 -04:00
rs_sprintf ( msgParentId , " %lu " , mit - > second - > msgParentId ) ;
2010-11-02 17:11:11 -04:00
return true ;
}
bool p3MsgService : : setMsgParentId ( uint32_t msgId , uint32_t msgParentId )
{
std : : map < uint32_t , RsMsgParentId * > : : iterator mit ;
bool changed = false ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
mit = mParentId . find ( msgId ) ;
if ( mit = = mParentId . end ( ) )
{
if ( msgParentId ) {
RsMsgParentId * msp = new RsMsgParentId ( ) ;
2014-03-28 23:57:44 -04:00
msp - > PeerId ( mServiceCtrl - > getOwnId ( ) ) ;
2010-11-02 17:11:11 -04:00
msp - > msgId = msgId ;
msp - > msgParentId = msgParentId ;
mParentId . insert ( std : : pair < uint32_t , RsMsgParentId * > ( msgId , msp ) ) ;
changed = true ;
}
} else {
if ( msgParentId ) {
if ( mit - > second - > msgParentId ! = msgParentId ) {
mit - > second - > msgParentId = msgParentId ;
changed = true ;
}
} else {
delete mit - > second ;
mParentId . erase ( mit ) ;
changed = true ;
}
}
} /* UNLOCKED */
if ( changed ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
return true ;
}
2008-02-04 12:55:13 -05:00
/****************************************/
/****************************************/
/* Message Items */
2015-01-11 17:18:28 -05:00
uint32_t p3MsgService : : sendMessage ( RsMsgItem * item )
2008-02-04 12:55:13 -05:00
{
2014-03-29 10:18:05 -04:00
if ( ! item )
return 0 ;
2008-02-04 12:55:13 -05:00
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::sendMessage() " ) ;
2008-02-07 11:18:34 -05:00
item - > msgId = getNewUniqueMsgId ( ) ; /* grabs Mtx as well */
2010-11-10 15:37:02 -05:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-04 16:40:34 -05:00
2010-11-10 15:37:02 -05:00
/* add pending flag */
item - > msgFlags | = ( RS_MSG_FLAGS_OUTGOING | RS_MSG_FLAGS_PENDING ) ;
/* STORE MsgID */
msgOutgoing [ item - > msgId ] = item ;
2014-03-28 23:57:44 -04:00
if ( item - > PeerId ( ) ! = mServiceCtrl - > getOwnId ( ) ) {
2010-11-10 15:37:02 -05:00
/* not to the loopback device */
RsMsgSrcId * msi = new RsMsgSrcId ( ) ;
msi - > msgId = item - > msgId ;
msi - > srcId = item - > PeerId ( ) ;
mSrcIds . insert ( std : : pair < uint32_t , RsMsgSrcId * > ( msi - > msgId , msi ) ) ;
2015-01-11 17:18:28 -05:00
}
2010-11-10 15:37:02 -05:00
}
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_ADD ) ;
2011-07-03 09:02:18 -04:00
2015-01-11 17:18:28 -05:00
return item - > msgId ;
}
uint32_t p3MsgService : : sendDistantMessage ( RsMsgItem * item , const RsGxsId & from )
{
uint32_t msg_id = sendMessage ( item ) ;
2008-02-04 12:55:13 -05:00
2015-01-11 17:18:28 -05:00
RS_STACK_MUTEX ( mMsgMtx ) ;
mDistantOutgoingMsgSigners [ msg_id ] = from ;
return msg_id ;
2008-02-04 12:55:13 -05:00
}
bool p3MsgService : : MessageSend ( MessageInfo & info )
{
2014-10-24 18:07:26 -04:00
for ( std : : list < RsPeerId > : : const_iterator pit = info . rspeerid_msgto . begin ( ) ; pit ! = info . rspeerid_msgto . end ( ) ; + + pit ) sendMessage ( initMIRsMsg ( info , * pit ) ) ;
for ( std : : list < RsPeerId > : : const_iterator pit = info . rspeerid_msgcc . begin ( ) ; pit ! = info . rspeerid_msgcc . end ( ) ; + + pit ) sendMessage ( initMIRsMsg ( info , * pit ) ) ;
for ( std : : list < RsPeerId > : : const_iterator pit = info . rspeerid_msgbcc . begin ( ) ; pit ! = info . rspeerid_msgbcc . end ( ) ; + + pit ) sendMessage ( initMIRsMsg ( info , * pit ) ) ;
2013-08-31 08:49:04 -04:00
2015-01-11 17:18:28 -05:00
for ( std : : list < RsGxsId > : : const_iterator pit = info . rsgxsid_msgto . begin ( ) ; pit ! = info . rsgxsid_msgto . end ( ) ; + + pit ) sendDistantMessage ( initMIRsMsg ( info , * pit ) , info . rsgxsid_srcId ) ;
for ( std : : list < RsGxsId > : : const_iterator pit = info . rsgxsid_msgcc . begin ( ) ; pit ! = info . rsgxsid_msgcc . end ( ) ; + + pit ) sendDistantMessage ( initMIRsMsg ( info , * pit ) , info . rsgxsid_srcId ) ;
for ( std : : list < RsGxsId > : : const_iterator pit = info . rsgxsid_msgbcc . begin ( ) ; pit ! = info . rsgxsid_msgbcc . end ( ) ; + + pit ) sendDistantMessage ( initMIRsMsg ( info , * pit ) , info . rsgxsid_srcId ) ;
2008-02-04 12:55:13 -05:00
/* send to ourselves as well */
2014-03-28 23:57:44 -04:00
RsMsgItem * msg = initMIRsMsg ( info , mServiceCtrl - > getOwnId ( ) ) ;
2014-03-29 10:18:05 -04:00
2008-02-04 12:55:13 -05:00
if ( msg )
{
2014-03-29 10:18:05 -04:00
std : : list < RsPgpId > : : iterator it ;
2013-08-31 08:49:04 -04:00
2013-08-31 08:54:47 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNED )
msg - > msgFlags | = RS_MSG_FLAGS_SIGNATURE_CHECKS ; // this is always true, since we are sending the message
2011-05-21 12:26:00 -04:00
/* use processMsg to get the new msgId */
2012-05-01 05:18:55 -04:00
processMsg ( msg , false ) ;
2011-05-21 12:26:00 -04:00
// return new message id
2012-04-17 17:00:54 -04:00
rs_sprintf ( info . msgId , " %lu " , msg - > msgId ) ;
2008-02-04 12:55:13 -05:00
}
return true ;
}
2013-10-03 17:41:34 -04:00
bool p3MsgService : : SystemMessage ( const std : : string & title , const std : : string & message , uint32_t systemFlag )
2012-05-01 05:18:55 -04:00
{
if ( ( systemFlag & RS_MSG_SYSTEM ) = = 0 ) {
/* no flag specified */
return false ;
}
2014-03-28 23:57:44 -04:00
const RsPeerId & ownId = mServiceCtrl - > getOwnId ( ) ;
2012-05-01 05:18:55 -04:00
RsMsgItem * msg = new RsMsgItem ( ) ;
msg - > PeerId ( ownId ) ;
msg - > msgFlags = 0 ;
if ( systemFlag & RS_MSG_USER_REQUEST ) {
msg - > msgFlags | = RS_MSG_FLAGS_USER_REQUEST ;
}
2012-05-05 18:20:05 -04:00
if ( systemFlag & RS_MSG_FRIEND_RECOMMENDATION ) {
msg - > msgFlags | = RS_MSG_FLAGS_FRIEND_RECOMMENDATION ;
}
2015-02-07 20:01:48 -05:00
if ( systemFlag & RS_MSG_PUBLISH_KEY ) {
msg - > msgFlags | = RS_MSG_FLAGS_PUBLISH_KEY ;
}
2012-05-01 05:18:55 -04:00
msg - > msgId = 0 ;
msg - > sendTime = time ( NULL ) ;
msg - > recvTime = 0 ;
msg - > subject = title ;
msg - > message = message ;
2014-03-29 10:18:05 -04:00
msg - > rspeerid_msgto . ids . push_back ( ownId ) ;
2012-05-01 05:18:55 -04:00
processMsg ( msg , true ) ;
return true ;
}
2010-11-02 17:11:11 -04:00
bool p3MsgService : : MessageToDraft ( MessageInfo & info , const std : : string & msgParentId )
2010-05-25 05:32:14 -04:00
{
2014-03-28 23:57:44 -04:00
RsMsgItem * msg = initMIRsMsg ( info , mServiceCtrl - > getOwnId ( ) ) ;
2010-05-25 05:32:14 -04:00
if ( msg )
{
uint32_t msgId = 0 ;
if ( info . msgId . empty ( ) = = false ) {
2010-05-28 10:42:54 -04:00
msgId = atoi ( info . msgId . c_str ( ) ) ;
2010-05-25 05:32:14 -04:00
}
if ( msgId ) {
msg - > msgId = msgId ;
} else {
msg - > msgId = getNewUniqueMsgId ( ) ; /* grabs Mtx as well */
}
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
/* add pending flag */
msg - > msgFlags | = ( RS_MSG_OUTGOING | RS_MSG_FLAGS_DRAFT ) ;
if ( msgId ) {
// remove existing message
2010-05-28 10:42:54 -04:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
mit = imsg . find ( msgId ) ;
if ( mit ! = imsg . end ( ) ) {
RsMsgItem * mi = mit - > second ;
imsg . erase ( mit ) ;
delete mi ;
2010-05-25 05:32:14 -04:00
}
}
/* STORE MsgID */
imsg [ msg - > msgId ] = msg ;
2010-09-11 06:39:40 -04:00
// return new message id
2012-04-17 17:00:54 -04:00
rs_sprintf ( info . msgId , " %lu " , msg - > msgId ) ;
2010-05-25 05:32:14 -04:00
}
2010-11-02 17:11:11 -04:00
setMsgParentId ( msg - > msgId , atoi ( msgParentId . c_str ( ) ) ) ;
2010-05-25 05:32:14 -04:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2010-05-25 05:32:14 -04:00
return true ;
}
return false ;
}
2010-08-22 18:12:26 -04:00
bool p3MsgService : : getMessageTagTypes ( MsgTagType & tags )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-08-19 17:47:26 -04:00
std : : map < uint32_t , RsMsgTagType * > : : iterator mit ;
2014-10-24 18:07:26 -04:00
for ( mit = mTags . begin ( ) ; mit ! = mTags . end ( ) ; + + mit ) {
2010-08-19 17:47:26 -04:00
std : : pair < std : : string , uint32_t > p ( mit - > second - > text , mit - > second - > rgb_color ) ;
tags . types . insert ( std : : pair < uint32_t , std : : pair < std : : string , uint32_t > > ( mit - > first , p ) ) ;
}
return true ;
}
2010-08-22 18:12:26 -04:00
bool p3MsgService : : setMessageTagType ( uint32_t tagId , std : : string & text , uint32_t rgb_color )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
int nNotifyType = 0 ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
std : : map < uint32_t , RsMsgTagType * > : : iterator mit ;
mit = mTags . find ( tagId ) ;
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
if ( mit = = mTags . end ( ) ) {
if ( tagId < RS_MSGTAGTYPE_USER ) {
std : : cerr < < " p3MsgService::MessageSetTagType: Standard tag type " < < tagId < < " cannot be inserted " < < std : : endl ;
return false ;
}
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
/* new tag */
RsMsgTagType * tagType = new RsMsgTagType ( ) ;
2014-03-28 23:57:44 -04:00
tagType - > PeerId ( mServiceCtrl - > getOwnId ( ) ) ;
2010-08-22 18:12:26 -04:00
tagType - > rgb_color = rgb_color ;
tagType - > tagId = tagId ;
tagType - > text = text ;
mTags . insert ( std : : pair < uint32_t , RsMsgTagType * > ( tagId , tagType ) ) ;
nNotifyType = NOTIFY_TYPE_ADD ;
} else {
if ( mit - > second - > text ! = text | | mit - > second - > rgb_color ! = rgb_color ) {
/* modify existing tag */
if ( tagId > = RS_MSGTAGTYPE_USER ) {
mit - > second - > text = text ;
} else {
/* don't change text for standard tag types */
if ( mit - > second - > text ! = text ) {
std : : cerr < < " p3MsgService::MessageSetTagType: Text " < < text < < " for standard tag type " < < tagId < < " cannot be changed " < < std : : endl ;
}
}
mit - > second - > rgb_color = rgb_color ;
nNotifyType = NOTIFY_TYPE_MOD ;
}
}
} /* UNLOCKED */
if ( nNotifyType ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2010-08-19 17:47:26 -04:00
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGE_TAGS , nNotifyType ) ;
2010-08-22 18:12:26 -04:00
2010-08-19 17:47:26 -04:00
return true ;
}
return false ;
}
2010-08-22 18:12:26 -04:00
bool p3MsgService : : removeMessageTagType ( uint32_t tagId )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
if ( tagId < RS_MSGTAGTYPE_USER ) {
std : : cerr < < " p3MsgService::MessageRemoveTagType: Can't delete standard tag type " < < tagId < < std : : endl ;
return false ;
}
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
std : : map < uint32_t , RsMsgTagType * > : : iterator mit ;
mit = mTags . find ( tagId ) ;
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
if ( mit = = mTags . end ( ) ) {
/* tag id not found */
std : : cerr < < " p3MsgService::MessageRemoveTagType: Tag Id not found " < < tagId < < std : : endl ;
return false ;
}
/* search for messages with this tag type */
std : : map < uint32_t , RsMsgTags * > : : iterator mit1 ;
for ( mit1 = mMsgTags . begin ( ) ; mit1 ! = mMsgTags . end ( ) ; ) {
RsMsgTags * tag = mit1 - > second ;
std : : list < uint32_t > : : iterator lit ;
lit = std : : find ( tag - > tagIds . begin ( ) , tag - > tagIds . end ( ) , tagId ) ;
if ( lit ! = tag - > tagIds . end ( ) ) {
tag - > tagIds . erase ( lit ) ;
2014-10-21 18:33:02 -04:00
if ( tag - > tagIds . empty ( ) ) {
2010-08-22 18:12:26 -04:00
/* remove empty tag */
delete ( tag ) ;
2010-10-11 11:52:12 -04:00
mMsgTags . erase ( mit1 + + ) ;
2010-08-22 18:12:26 -04:00
continue ;
}
}
2014-10-24 18:07:26 -04:00
+ + mit1 ;
2010-08-22 18:12:26 -04:00
}
/* remove tag type */
delete ( mit - > second ) ;
mTags . erase ( mit ) ;
} /* UNLOCKED */
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGE_TAGS , NOTIFY_TYPE_DEL ) ;
2010-08-22 18:12:26 -04:00
return true ;
}
2010-11-02 17:11:11 -04:00
bool p3MsgService : : getMessageTag ( const std : : string & msgId , MsgTagInfo & info )
2010-08-22 18:12:26 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
uint32_t mid = atoi ( msgId . c_str ( ) ) ;
if ( mid = = 0 ) {
std : : cerr < < " p3MsgService::MessageGetMsgTag: Unknown msgId " < < msgId < < std : : endl ;
return false ;
}
std : : map < uint32_t , RsMsgTags * > : : iterator mit ;
if ( mMsgTags . end ( ) ! = ( mit = mMsgTags . find ( mid ) ) ) {
2012-04-17 17:00:54 -04:00
rs_sprintf ( info . msgId , " %lu " , mit - > second - > msgId ) ;
2010-08-22 18:12:26 -04:00
info . tagIds = mit - > second - > tagIds ;
return true ;
}
return false ;
2010-08-19 17:47:26 -04:00
}
2010-08-22 18:12:26 -04:00
/* set == false && tagId == 0 --> remove all */
2010-11-02 17:11:11 -04:00
bool p3MsgService : : setMessageTag ( const std : : string & msgId , uint32_t tagId , bool set )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
uint32_t mid = atoi ( msgId . c_str ( ) ) ;
if ( mid = = 0 ) {
std : : cerr < < " p3MsgService::MessageSetMsgTag: Unknown msgId " < < msgId < < std : : endl ;
return false ;
}
if ( tagId = = 0 ) {
if ( set = = true ) {
std : : cerr < < " p3MsgService::MessageSetMsgTag: No valid tagId given " < < tagId < < std : : endl ;
return false ;
}
}
int nNotifyType = 0 ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < uint32_t , RsMsgTags * > : : iterator mit ;
mit = mMsgTags . find ( mid ) ;
if ( mit = = mMsgTags . end ( ) ) {
if ( set ) {
/* new msg */
RsMsgTags * tag = new RsMsgTags ( ) ;
2014-03-28 23:57:44 -04:00
tag - > PeerId ( mServiceCtrl - > getOwnId ( ) ) ;
2010-08-22 18:12:26 -04:00
tag - > msgId = mid ;
tag - > tagIds . push_back ( tagId ) ;
mMsgTags . insert ( std : : pair < uint32_t , RsMsgTags * > ( tag - > msgId , tag ) ) ;
nNotifyType = NOTIFY_TYPE_ADD ;
}
} else {
RsMsgTags * tag = mit - > second ;
/* search existing tagId */
std : : list < uint32_t > : : iterator lit ;
if ( tagId ) {
lit = std : : find ( tag - > tagIds . begin ( ) , tag - > tagIds . end ( ) , tagId ) ;
} else {
lit = tag - > tagIds . end ( ) ;
}
if ( set ) {
if ( lit = = tag - > tagIds . end ( ) ) {
tag - > tagIds . push_back ( tagId ) ;
/* keep the list sorted */
tag - > tagIds . sort ( ) ;
nNotifyType = NOTIFY_TYPE_ADD ;
}
} else {
if ( tagId = = 0 ) {
/* remove all */
delete ( tag ) ;
mMsgTags . erase ( mit ) ;
nNotifyType = NOTIFY_TYPE_DEL ;
} else {
if ( lit ! = tag - > tagIds . end ( ) ) {
tag - > tagIds . erase ( lit ) ;
nNotifyType = NOTIFY_TYPE_DEL ;
2014-10-21 18:33:02 -04:00
if ( tag - > tagIds . empty ( ) ) {
2010-08-22 18:12:26 -04:00
/* remove empty tag */
delete ( tag ) ;
mMsgTags . erase ( mit ) ;
}
}
}
}
}
} /* UNLOCKED */
if ( nNotifyType ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2010-08-19 17:47:26 -04:00
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGE_TAGS , nNotifyType ) ;
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
return true ;
}
return false ;
2010-08-19 17:47:26 -04:00
}
2010-08-22 18:12:26 -04:00
bool p3MsgService : : resetMessageStandardTagTypes ( MsgTagType & tags )
{
MsgTagType standardTags ;
2010-09-25 08:54:34 -04:00
getStandardTagTypes ( standardTags ) ;
2010-08-22 18:12:26 -04:00
std : : map < uint32_t , std : : pair < std : : string , uint32_t > > : : iterator mit ;
2014-10-24 18:07:26 -04:00
for ( mit = standardTags . types . begin ( ) ; mit ! = standardTags . types . end ( ) ; + + mit ) {
2010-08-22 18:12:26 -04:00
tags . types [ mit - > first ] = mit - > second ;
}
return true ;
}
2010-08-19 17:47:26 -04:00
2010-05-28 10:42:54 -04:00
/* move message to trash based on the unique mid */
2010-11-02 17:11:11 -04:00
bool p3MsgService : : MessageToTrash ( const std : : string & mid , bool bTrash )
2010-05-28 10:42:54 -04:00
{
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
uint32_t msgId = atoi ( mid . c_str ( ) ) ;
bool bChanged = false ;
bool bFound = false ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
RsMsgItem * mi = NULL ;
mit = imsg . find ( msgId ) ;
if ( mit ! = imsg . end ( ) ) {
mi = mit - > second ;
} else {
mit = msgOutgoing . find ( msgId ) ;
if ( mit ! = msgOutgoing . end ( ) ) {
mi = mit - > second ;
}
}
if ( mi ) {
bFound = true ;
if ( bTrash ) {
if ( ( mi - > msgFlags & RS_MSG_FLAGS_TRASH ) = = 0 ) {
mi - > msgFlags | = RS_MSG_FLAGS_TRASH ;
bChanged = true ;
}
} else {
if ( mi - > msgFlags & RS_MSG_FLAGS_TRASH ) {
mi - > msgFlags & = ~ RS_MSG_FLAGS_TRASH ;
bChanged = true ;
}
}
}
}
if ( bChanged ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
checkOutgoingMessages ( ) ;
2014-01-07 17:51:22 -05:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2010-05-28 10:42:54 -04:00
}
return bFound ;
}
2008-02-04 12:55:13 -05:00
/****************************************/
/****************************************/
/****************************************/
/**** HELPER FNS For Chat/Msg/Channel Lists ************
* These aren ' t required to be locked , unless
* the data used is from internal stores - > then they should be .
*/
void p3MsgService : : initRsMI ( RsMsgItem * msg , MessageInfo & mi )
{
mi . msgflags = 0 ;
/* translate flags, if we sent it... outgoing */
2013-08-02 19:00:36 -04:00
2014-03-29 10:18:05 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_OUTGOING ) mi . msgflags | = RS_MSG_OUTGOING ;
if ( msg - > msgFlags & RS_MSG_FLAGS_PENDING ) mi . msgflags | = RS_MSG_PENDING ; /* if it has a pending flag, then its in the outbox */
if ( msg - > msgFlags & RS_MSG_FLAGS_DRAFT ) mi . msgflags | = RS_MSG_DRAFT ;
if ( msg - > msgFlags & RS_MSG_FLAGS_NEW ) mi . msgflags | = RS_MSG_NEW ;
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNED ) mi . msgflags | = RS_MSG_SIGNED ;
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNATURE_CHECKS ) mi . msgflags | = RS_MSG_SIGNATURE_CHECKS ;
2015-02-20 05:34:11 -05:00
if ( msg - > msgFlags & RS_MSG_FLAGS_DISTANT ) mi . msgflags | = RS_MSG_DISTANT ;
2014-03-29 10:18:05 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_TRASH ) mi . msgflags | = RS_MSG_TRASH ;
if ( msg - > msgFlags & RS_MSG_FLAGS_UNREAD_BY_USER ) mi . msgflags | = RS_MSG_UNREAD_BY_USER ;
if ( msg - > msgFlags & RS_MSG_FLAGS_REPLIED ) mi . msgflags | = RS_MSG_REPLIED ;
if ( msg - > msgFlags & RS_MSG_FLAGS_FORWARDED ) mi . msgflags | = RS_MSG_FORWARDED ;
if ( msg - > msgFlags & RS_MSG_FLAGS_STAR ) mi . msgflags | = RS_MSG_STAR ;
if ( msg - > msgFlags & RS_MSG_FLAGS_USER_REQUEST ) mi . msgflags | = RS_MSG_USER_REQUEST ;
if ( msg - > msgFlags & RS_MSG_FLAGS_FRIEND_RECOMMENDATION ) mi . msgflags | = RS_MSG_FRIEND_RECOMMENDATION ;
2015-02-07 20:01:48 -05:00
if ( msg - > msgFlags & RS_MSG_FLAGS_PUBLISH_KEY ) mi . msgflags | = RS_MSG_PUBLISH_KEY ;
2014-03-29 10:18:05 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES ) mi . msgflags | = RS_MSG_LOAD_EMBEDDED_IMAGES ;
2008-02-04 12:55:13 -05:00
mi . ts = msg - > sendTime ;
2014-03-29 10:18:05 -04:00
mi . rspeerid_srcId = msg - > PeerId ( ) ;
2008-02-04 12:55:13 -05:00
2014-03-29 10:18:05 -04:00
mi . rspeerid_msgto = msg - > rspeerid_msgto . ids ;
mi . rspeerid_msgcc = msg - > rspeerid_msgcc . ids ;
mi . rspeerid_msgbcc = msg - > rspeerid_msgbcc . ids ;
2008-02-04 12:55:13 -05:00
2014-03-29 10:18:05 -04:00
mi . rsgxsid_msgto = msg - > rsgxsid_msgto . ids ;
mi . rsgxsid_msgcc = msg - > rsgxsid_msgcc . ids ;
mi . rsgxsid_msgbcc = msg - > rsgxsid_msgbcc . ids ;
2008-02-04 12:55:13 -05:00
mi . title = msg - > subject ;
mi . msg = msg - > message ;
mi . attach_title = msg - > attachment . title ;
mi . attach_comment = msg - > attachment . comment ;
mi . count = 0 ;
mi . size = 0 ;
2014-10-24 18:07:26 -04:00
for ( std : : list < RsTlvFileItem > : : iterator it = msg - > attachment . items . begin ( ) ; it ! = msg - > attachment . items . end ( ) ; + + it )
2008-02-04 12:55:13 -05:00
{
FileInfo fi ;
2011-03-06 07:58:18 -05:00
fi . fname = RsDirUtil : : getTopDir ( it - > name ) ;
2008-02-04 12:55:13 -05:00
fi . size = it - > filesize ;
fi . hash = it - > hash ;
fi . path = it - > path ;
mi . files . push_back ( fi ) ;
mi . count + + ;
mi . size + = fi . size ;
}
}
void p3MsgService : : initRsMIS ( RsMsgItem * msg , MsgInfoSummary & mis )
{
mis . msgflags = 0 ;
2015-02-20 05:34:11 -05:00
if ( msg - > msgFlags & RS_MSG_FLAGS_DISTANT )
mis . msgflags | = RS_MSG_DISTANT ;
2013-10-16 16:02:28 -04:00
2013-08-02 19:00:36 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNED )
mis . msgflags | = RS_MSG_SIGNED ;
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNATURE_CHECKS )
mis . msgflags | = RS_MSG_SIGNATURE_CHECKS ;
2008-02-04 12:55:13 -05:00
/* translate flags, if we sent it... outgoing */
if ( ( msg - > msgFlags & RS_MSG_FLAGS_OUTGOING )
2014-03-28 23:57:44 -04:00
/*|| (msg->PeerId() == mServiceCtrl->getOwnId())*/ )
2008-02-04 12:55:13 -05:00
{
mis . msgflags | = RS_MSG_OUTGOING ;
}
/* if it has a pending flag, then its in the outbox */
if ( msg - > msgFlags & RS_MSG_FLAGS_PENDING )
{
mis . msgflags | = RS_MSG_PENDING ;
}
2011-03-06 07:58:18 -05:00
if ( msg - > msgFlags & RS_MSG_FLAGS_DRAFT )
{
mis . msgflags | = RS_MSG_DRAFT ;
}
if ( msg - > msgFlags & RS_MSG_FLAGS_NEW )
2008-02-04 12:55:13 -05:00
{
mis . msgflags | = RS_MSG_NEW ;
}
2010-05-28 10:42:54 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_TRASH )
{
mis . msgflags | = RS_MSG_TRASH ;
}
2012-04-26 19:41:14 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_UNREAD_BY_USER )
2010-08-22 18:12:26 -04:00
{
mis . msgflags | = RS_MSG_UNREAD_BY_USER ;
}
2010-11-02 17:11:11 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_REPLIED )
{
mis . msgflags | = RS_MSG_REPLIED ;
}
if ( msg - > msgFlags & RS_MSG_FLAGS_FORWARDED )
{
mis . msgflags | = RS_MSG_FORWARDED ;
}
2011-05-23 19:45:31 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_STAR )
{
mis . msgflags | = RS_MSG_STAR ;
}
2012-05-01 05:18:55 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_USER_REQUEST )
{
mis . msgflags | = RS_MSG_USER_REQUEST ;
}
2012-05-05 18:20:05 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_FRIEND_RECOMMENDATION )
{
mis . msgflags | = RS_MSG_FRIEND_RECOMMENDATION ;
}
2015-02-07 20:01:48 -05:00
if ( msg - > msgFlags & RS_MSG_FLAGS_PUBLISH_KEY )
{
mis . msgflags | = RS_MSG_PUBLISH_KEY ;
}
2013-09-24 16:19:21 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES )
{
mis . msgflags | = RS_MSG_LOAD_EMBEDDED_IMAGES ;
}
2008-02-04 12:55:13 -05:00
mis . srcId = msg - > PeerId ( ) ;
{
//msg->msgId;
2012-04-17 17:00:54 -04:00
rs_sprintf ( mis . msgId , " %lu " , msg - > msgId ) ;
2008-02-04 12:55:13 -05:00
}
mis . title = msg - > subject ;
mis . count = msg - > attachment . items . size ( ) ;
mis . ts = msg - > sendTime ;
}
2014-03-29 10:18:05 -04:00
void p3MsgService : : initMIRsMsg ( RsMsgItem * msg , const MessageInfo & info )
2008-02-04 12:55:13 -05:00
{
msg - > msgFlags = 0 ;
msg - > msgId = 0 ;
msg - > sendTime = time ( NULL ) ;
msg - > recvTime = 0 ;
msg - > subject = info . title ;
2014-03-29 10:18:05 -04:00
msg - > message = info . msg ;
2013-05-03 17:02:44 -04:00
2014-03-29 10:18:05 -04:00
msg - > rspeerid_msgto . ids = info . rspeerid_msgto ;
msg - > rspeerid_msgcc . ids = info . rspeerid_msgcc ;
2008-02-04 12:55:13 -05:00
2014-03-29 10:18:05 -04:00
msg - > rsgxsid_msgto . ids = info . rsgxsid_msgto ;
msg - > rsgxsid_msgcc . ids = info . rsgxsid_msgcc ;
2008-02-04 12:55:13 -05:00
/* We don't fill in bcc (unless to ourselves) */
2014-03-29 10:18:05 -04:00
if ( msg - > PeerId ( ) = = mServiceCtrl - > getOwnId ( ) )
2008-02-04 12:55:13 -05:00
{
2014-03-29 10:18:05 -04:00
msg - > rsgxsid_msgbcc . ids = info . rsgxsid_msgbcc ;
msg - > rspeerid_msgbcc . ids = info . rspeerid_msgbcc ;
2008-02-04 12:55:13 -05:00
}
msg - > attachment . title = info . attach_title ;
msg - > attachment . comment = info . attach_comment ;
2014-10-24 18:07:26 -04:00
for ( std : : list < FileInfo > : : const_iterator it = info . files . begin ( ) ; it ! = info . files . end ( ) ; + + it )
2008-02-04 12:55:13 -05:00
{
RsTlvFileItem mfi ;
mfi . hash = it - > hash ;
mfi . name = it - > fname ;
mfi . filesize = it - > size ;
msg - > attachment . items . push_back ( mfi ) ;
}
2012-05-01 05:18:55 -04:00
/* translate flags from outside */
if ( info . msgflags & RS_MSG_USER_REQUEST )
2015-01-11 17:18:28 -05:00
msg - > msgFlags | = RS_MSG_FLAGS_USER_REQUEST ;
2013-04-29 18:32:58 -04:00
2012-05-05 18:20:05 -04:00
if ( info . msgflags & RS_MSG_FRIEND_RECOMMENDATION )
msg - > msgFlags | = RS_MSG_FLAGS_FRIEND_RECOMMENDATION ;
2014-03-29 10:18:05 -04:00
}
RsMsgItem * p3MsgService : : initMIRsMsg ( const MessageInfo & info , const RsGxsId & to )
{
2015-01-11 17:18:28 -05:00
RsMsgItem * msg = new RsMsgItem ( ) ;
2014-03-29 10:18:05 -04:00
2015-01-11 17:18:28 -05:00
initMIRsMsg ( msg , info ) ;
2014-03-29 10:18:05 -04:00
2015-01-11 17:18:28 -05:00
msg - > PeerId ( RsPeerId ( to ) ) ;
msg - > msgFlags | = RS_MSG_FLAGS_DISTANT ;
2012-05-01 05:18:55 -04:00
2015-01-11 17:18:28 -05:00
if ( info . msgflags & RS_MSG_SIGNED )
msg - > msgFlags | = RS_MSG_FLAGS_SIGNED ;
2013-08-02 19:00:36 -04:00
2015-01-11 17:18:28 -05:00
// // We replace the msg text by the whole message serialized possibly signed,
// // and binary encrypted, so as to obfuscate all its content.
// //
// if(!createDistantMessage(to,info.rsgxsid_srcId,msg))
// {
// std::cerr << "Cannot encrypt distant message. Something went wrong." << std::endl;
// delete msg ;
// return NULL ;
// }
2014-03-29 10:18:05 -04:00
return msg ;
}
RsMsgItem * p3MsgService : : initMIRsMsg ( const MessageInfo & info , const RsPeerId & to )
{
2015-01-11 17:18:28 -05:00
RsMsgItem * msg = new RsMsgItem ( ) ;
2014-03-29 10:18:05 -04:00
initMIRsMsg ( msg , info ) ;
2013-05-03 17:02:44 -04:00
2014-03-29 10:18:05 -04:00
msg - > PeerId ( to ) ;
/* load embedded images from own messages */
msg - > msgFlags | = RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES ;
2013-05-03 17:02:44 -04:00
2008-02-04 12:55:13 -05:00
return msg ;
}
2013-04-29 16:44:48 -04:00
2014-03-29 10:18:05 -04:00
void p3MsgService : : connectToGlobalRouter ( p3GRouter * gr )
2013-04-29 16:44:48 -04:00
{
2014-03-29 10:18:05 -04:00
mGRouter = gr ;
gr - > registerClientService ( GROUTER_CLIENT_ID_MESSAGES , this ) ;
}
2013-04-29 16:44:48 -04:00
2014-03-29 10:18:05 -04:00
void p3MsgService : : enableDistantMessaging ( bool b )
{
// Normally this method should work on the basis of each GXS id. For now, we just blindly enable
// messaging for all GXS ids for which we have the private key.
bool cchanged ;
2013-04-29 16:44:48 -04:00
{
2014-03-29 10:18:05 -04:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2013-04-29 18:32:58 -04:00
2014-03-29 10:18:05 -04:00
cchanged = ( mDistantMessagingEnabled ! = b ) ;
mDistantMessagingEnabled = b ;
2013-04-29 16:44:48 -04:00
}
2013-12-27 15:06:47 -05:00
2014-03-29 10:18:05 -04:00
std : : list < RsGxsId > own_id_list ;
mIdService - > getOwnIds ( own_id_list ) ;
2013-04-29 16:44:48 -04:00
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2014-03-29 10:18:05 -04:00
for ( std : : list < RsGxsId > : : const_iterator it ( own_id_list . begin ( ) ) ; it ! = own_id_list . end ( ) ; + + it )
std : : cerr < < ( b ? " Enabling " : " Disabling " ) < < " distant messaging, with peer id = " < < * it < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2013-05-01 17:13:40 -04:00
2015-01-11 17:18:28 -05:00
for ( std : : list < RsGxsId > : : const_iterator it ( own_id_list . begin ( ) ) ; it ! = own_id_list . end ( ) ; + + it )
{
if ( b )
mGRouter - > registerKey ( * it , GROUTER_CLIENT_ID_MESSAGES , " Messaging contact " ) ;
else
mGRouter - > unregisterKey ( * it , GROUTER_CLIENT_ID_MESSAGES ) ;
}
2014-03-29 10:18:05 -04:00
if ( cchanged )
IndicateConfigChanged ( ) ;
}
bool p3MsgService : : distantMessagingEnabled ( )
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
return mDistantMessagingEnabled ;
2013-04-29 16:44:48 -04:00
}
void p3MsgService : : manageDistantPeers ( )
{
// now possibly flush pending messages
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
std : : cerr < < " p3MsgService::manageDistantPeers() " < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2014-04-21 09:08:42 -04:00
enableDistantMessaging ( mDistantMessagingEnabled ) ;
2013-04-29 16:44:48 -04:00
}
2015-01-22 09:33:19 -05:00
void p3MsgService : : notifyDataStatus ( const GRouterMsgPropagationId & id , uint32_t data_status )
2014-04-19 12:02:11 -04:00
{
2015-01-22 09:33:19 -05:00
if ( data_status = = GROUTER_CLIENT_SERVICE_DATA_STATUS_FAILED )
{
std : : cerr < < __PRETTY_FUNCTION__ < < " : Not fully implemented. The global router fails to send apacket, but we don't deal with it. Please remind the devs to do it " < < std : : endl ;
return ;
}
if ( data_status ! = GROUTER_CLIENT_SERVICE_DATA_STATUS_RECEIVED )
{
std : : cerr < < " p3MsgService: unhandled data status info from global router for msg ID " < < id < < " : this is a bug. " < < std : : endl ;
return ;
}
2014-04-19 12:02:11 -04:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " p3MsgService::acknowledgeDataReceived(): acknowledging data received for msg propagation id " < < id < < std : : endl ;
# endif
std : : map < GRouterMsgPropagationId , uint32_t > : : iterator it = _ongoing_messages . find ( id ) ;
if ( it = = _ongoing_messages . end ( ) )
{
std : : cerr < < " (EE) cannot find pending message to acknowledge. Weird. grouter id = " < < id < < std : : endl ;
return ;
}
uint32_t msg_id = it - > second ;
// we should now remove the item from the msgOutgoing list.
std : : map < uint32_t , RsMsgItem * > : : iterator it2 = msgOutgoing . find ( msg_id ) ;
if ( it2 = = msgOutgoing . end ( ) )
{
std : : cerr < < " (EE) message has been ACKed, but is not in outgoing list. Something's wrong!! " < < std : : endl ;
return ;
}
delete it2 - > second ;
msgOutgoing . erase ( it2 ) ;
2014-04-21 09:08:42 -04:00
RsServer : : notify ( ) - > notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_ADD ) ;
2014-04-19 12:02:11 -04:00
IndicateConfigChanged ( ) ;
2013-04-29 16:44:48 -04:00
}
2015-01-11 17:18:28 -05:00
void p3MsgService : : receiveGRouterData ( const RsGxsId & destination_key , const RsGxsId & signing_key , GRouterServiceId & client_id , uint8_t * data , uint32_t data_size )
2013-12-27 15:06:47 -05:00
{
2015-01-11 17:18:28 -05:00
std : : cerr < < " p3MsgService::receiveGRouterData(): received message item of size " < < data_size < < " , for key " < < destination_key < < std : : endl ;
RsItem * item = _serialiser - > deserialise ( data , & data_size ) ;
2013-12-27 15:06:47 -05:00
2015-01-11 17:18:28 -05:00
free ( data ) ;
2013-12-27 15:06:47 -05:00
2015-01-11 17:18:28 -05:00
RsMsgItem * msg_item = dynamic_cast < RsMsgItem * > ( item ) ;
2013-12-27 15:06:47 -05:00
2015-01-11 17:18:28 -05:00
if ( msg_item ! = NULL )
2015-01-19 08:53:36 -05:00
{
std : : cerr < < " Encrypted item correctly deserialised. Passing on to incoming list. " < < std : : endl ;
2013-04-29 16:44:48 -04:00
2015-02-20 05:34:11 -05:00
msg_item - > msgFlags | = RS_MSG_FLAGS_DISTANT ;
2015-01-11 17:18:28 -05:00
msg_item - > PeerId ( RsPeerId ( signing_key ) ) ; // hack to pass on GXS id.
handleIncomingItem ( msg_item ) ;
2015-01-19 08:53:36 -05:00
}
else
std : : cerr < < " Item could not be deserialised. Format error?? " < < std : : endl ;
2014-03-17 16:56:06 -04:00
}
2015-01-11 17:18:28 -05:00
void p3MsgService : : sendDistantMsgItem ( RsMsgItem * msgitem )
2013-04-29 16:44:48 -04:00
{
2015-01-11 17:18:28 -05:00
RsGxsId destination_key_id ( msgitem - > PeerId ( ) ) ;
RsGxsId signing_key_id ;
2015-02-20 05:34:11 -05:00
msgitem - > msgFlags | = RS_MSG_FLAGS_DISTANT ;
2015-01-11 17:18:28 -05:00
{
RS_STACK_MUTEX ( mMsgMtx ) ;
signing_key_id = mDistantOutgoingMsgSigners [ msgitem - > msgId ] ;
if ( signing_key_id . isNull ( ) )
{
std : : cerr < < " ERROR: cannot find signing key id for msg id " < < msgitem - > msgId < < std : : endl ;
std : : cerr < < " available keys are: " < < std : : endl ;
for ( std : : map < uint32_t , RsGxsId > : : const_iterator it ( mDistantOutgoingMsgSigners . begin ( ) ) ; it ! = mDistantOutgoingMsgSigners . end ( ) ; + + it )
std : : cerr < < " " < < it - > first < < " " < < it - > second < < std : : endl ;
return ;
}
}
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2015-01-11 17:18:28 -05:00
std : : cerr < < " p3MsgService::sendDistanteMsgItem(): sending distant msg item " < < std : : endl ;
std : : cerr < < " msg ID : " < < msgitem - > msgId < < std : : endl ;
std : : cerr < < " to peer : " < < destination_key_id < < std : : endl ;
std : : cerr < < " signing : " < < signing_key_id < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2013-08-31 17:10:04 -04:00
2015-01-11 17:18:28 -05:00
// The item is serialized and turned into a generic turtle item.
uint32_t msg_serialized_rssize = _serialiser - > size ( msgitem ) ;
unsigned char * msg_serialized_data = new unsigned char [ msg_serialized_rssize ] ;
if ( ! _serialiser - > serialise ( msgitem , msg_serialized_data , & msg_serialized_rssize ) )
{
std : : cerr < < " (EE) p3MsgService::sendTurtleData(): Serialization error. " < < std : : endl ;
delete [ ] msg_serialized_data ;
return ;
}
2013-08-31 17:10:04 -04:00
# ifdef DEBUG_DISTANT_MSG
2015-01-11 17:18:28 -05:00
std : : cerr < < " serialised size : " < < msg_serialized_rssize < < std : : endl ;
2013-08-31 17:10:04 -04:00
# endif
2014-03-29 10:18:05 -04:00
2015-01-11 17:18:28 -05:00
GRouterMsgPropagationId grouter_message_id ;
mGRouter - > sendData ( destination_key_id , GROUTER_CLIENT_ID_MESSAGES , msg_serialized_data , msg_serialized_rssize , signing_key_id , grouter_message_id ) ;
2015-01-23 10:16:04 -05:00
delete [ ] msg_serialized_data ;
2015-01-11 17:18:28 -05:00
// now store the grouter id along with the message id, so that we can keep track of received messages
{
RS_STACK_MUTEX ( mMsgMtx ) ;
_ongoing_messages [ grouter_message_id ] = msgitem - > msgId ;
}
2013-04-29 16:44:48 -04:00
}