mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-09 03:18:41 -05:00
Removed most of the interface for RsGNP as it mostly makes calls to other components
Added final comments before review git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-new_cache_system@4928 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
3ab62f147e
commit
25fbf771a7
@ -40,6 +40,8 @@ typedef std::map<std::string, std::set<RsGxsSignedMessage*> > SignedMsgGrp;
|
|||||||
/*!
|
/*!
|
||||||
* The main role of GDP is the preparation and handing out of messages requested from
|
* The main role of GDP is the preparation and handing out of messages requested from
|
||||||
* RsGeneralExchangeService and RsGeneralExchangeService
|
* RsGeneralExchangeService and RsGeneralExchangeService
|
||||||
|
* It is important to note that no actual messages are passed by this interface as its is expected
|
||||||
|
* architecturally to pass messages to the service via a call back
|
||||||
*
|
*
|
||||||
* It also acts as a layer between RsGeneralStorageService and its parent RsGeneralExchangeService
|
* It also acts as a layer between RsGeneralStorageService and its parent RsGeneralExchangeService
|
||||||
* thus allowing for non-blocking requests, etc.
|
* thus allowing for non-blocking requests, etc.
|
||||||
@ -49,6 +51,12 @@ typedef std::map<std::string, std::set<RsGxsSignedMessage*> > SignedMsgGrp;
|
|||||||
* Caching feature:
|
* Caching feature:
|
||||||
* - A cache index should be maintained which is faster than normal message request
|
* - A cache index should be maintained which is faster than normal message request
|
||||||
* - This should allow fast retrieval of message based on grp id or msg id
|
* - This should allow fast retrieval of message based on grp id or msg id
|
||||||
|
*
|
||||||
|
* Identity Exchange Service:
|
||||||
|
* - As this is the point where data is accessed by both the GNP and GXS the identities
|
||||||
|
* used to decrypt, encrypt and verify is handle here.
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class RsGeneralDataService
|
class RsGeneralDataService
|
||||||
{
|
{
|
||||||
@ -59,17 +67,17 @@ public:
|
|||||||
* @param msgGrp this contains grp and the message to retrieve
|
* @param msgGrp this contains grp and the message to retrieve
|
||||||
* @return request code to be redeemed later
|
* @return request code to be redeemed later
|
||||||
*/
|
*/
|
||||||
virtual int request(const MsgGrpId& msgGrp, SignedMsgGrp& result, bool decrypted) = 0;
|
virtual int request(const MsgGrpId& msgGrp, bool decrypted) = 0;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* allows for more complex queries specific to the service
|
* allows for more complex queries specific to the service
|
||||||
* Service should implement method taking case
|
* Service should implement its own specific filter
|
||||||
* @param filter generally stores parameters needed for query
|
* @param filter generally stores parameters needed for query
|
||||||
* @param cacheRequest set to true to cache the messages requested
|
* @param cacheRequest set to true to cache the messages requested
|
||||||
* @return request code to be redeemed later
|
* @return request code to be redeemed later
|
||||||
*/
|
*/
|
||||||
virtual int request(RequestFilter* filter, SignedMsgGrp& msgs, bool cacheRequest) = 0;
|
virtual int request(RequestFilter* filter, bool cacheRequest) = 0;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -79,13 +87,14 @@ public:
|
|||||||
virtual bool store(SignedMsgGrp& msgs) = 0;
|
virtual bool store(SignedMsgGrp& msgs) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @param grpIds set with grpIds available from storage
|
* Gets group and any associated meta data
|
||||||
|
* @param grpIds set with group Ids available from storage
|
||||||
* @return request code to be redeemed later
|
* @return request code to be redeemed later
|
||||||
*/
|
*/
|
||||||
virtual int getGroups(std::set<std::string>& grpIds) = 0;
|
virtual int getGroups(const std::set<std::string>& grpIds) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
* Gets list of message ids in storage
|
||||||
* @param msgIds gets message ids in storage
|
* @param msgIds gets message ids in storage
|
||||||
* @return request code to be redeemed later
|
* @return request code to be redeemed later
|
||||||
*/
|
*/
|
||||||
|
@ -59,159 +59,172 @@
|
|||||||
* 7) Data will be stored encrypted.
|
* 7) Data will be stored encrypted.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class GixsKey
|
|
||||||
{
|
|
||||||
KeyRef mKeyId;
|
|
||||||
|
|
||||||
/// public key
|
/*!
|
||||||
EVP_PKEY *mPubKey;
|
* Storage class for private and public publish keys
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class GixsKey
|
||||||
|
{
|
||||||
|
KeyRef mKeyId;
|
||||||
|
|
||||||
/// NULL if non-existant */
|
/// public key
|
||||||
EVP_PKEY *mPrivKey;
|
EVP_PKEY *mPubKey;
|
||||||
};
|
|
||||||
|
|
||||||
class KeyRef {
|
/// NULL if non-existant */
|
||||||
|
EVP_PKEY *mPrivKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class KeyRef {
|
||||||
|
|
||||||
|
std::string refId;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class KeyRefSet {
|
||||||
|
std::set<KeyRef> mKeyRefSet;
|
||||||
|
};
|
||||||
|
|
||||||
};
|
class SignatureSet {
|
||||||
|
std::set<Signature> mSignatureSet;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Signature {
|
||||||
|
|
||||||
class KeyRefSet {
|
KeyRef mKeyRef;
|
||||||
std::set<KeyRef> mKeyRefSet;
|
Signature mSignature;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SignatureSet {
|
/*!
|
||||||
std::set<Signature> mSignatureSet;
|
* This is the actual identity \n
|
||||||
};
|
* In a sense the group description with the GixsKey the "message"
|
||||||
|
*/
|
||||||
|
class RsGixsProfile {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
class Signature {
|
KeyRef mKeyRef;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
KeyRef mKeyRef;
|
/// may be superseded by newer timestamps
|
||||||
Signature mSignature;
|
time_t mTimeStamp;
|
||||||
};
|
uint32_t mProfileType;
|
||||||
|
|
||||||
|
// TODO: add permissions members
|
||||||
|
|
||||||
|
Signature mSignature;
|
||||||
|
|
||||||
class RsGixsProfile {
|
};
|
||||||
|
|
||||||
public:
|
/*!
|
||||||
|
* Retroshare general identity exchange service
|
||||||
|
*
|
||||||
|
* Purpose: \n
|
||||||
|
* Provides a means to distribute identities among peers \n
|
||||||
|
* Also provides encyption, decryption, verification, \n
|
||||||
|
* and signing functionality using any created or received identities \n
|
||||||
|
*
|
||||||
|
* This may best be implemented as a singleton like current AuthGPG? \n
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class RsIdentityExchangeService : RsGeneralExchangeService
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
KeyRef mKeyRef;
|
RsGixs();
|
||||||
std::string mPseudonym;
|
|
||||||
|
|
||||||
/// may be superseded by newer timestamps
|
|
||||||
time_t mTimeStamp;
|
|
||||||
uint32_t mProfileType;
|
|
||||||
|
|
||||||
// TODO: add permissions members
|
|
||||||
|
|
||||||
Signature mSignature;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Retroshare general identity exchange service
|
* creates gixs profile and shares it
|
||||||
*
|
* @param profile
|
||||||
* Purpose: \n
|
* @param type the type of profile to create, self signed, anonymous, and GPG signed
|
||||||
* Provides a means to distribute identities among peers \n
|
*/
|
||||||
* also provides encyption, decryption, verification, \n
|
virtual bool createKey(RsGixsProfile& profile, uint32_t type) = 0; /* fills in mKeyId, and signature */
|
||||||
* and signing functionality using any created or received identities \n
|
|
||||||
*
|
/*!
|
||||||
* This may best be implemented as a singleton like current AuthGPG? \n
|
* Use to query a whether given key is available by its key reference
|
||||||
|
* @param keyref the keyref of key that is being checked for
|
||||||
|
* @return true if available, false otherwise
|
||||||
|
*/
|
||||||
|
virtual bool haveKey(const KeyRef& keyref) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Use to query whether private key member of the given key reference is available
|
||||||
|
* @param keyref the KeyRef of the key being checked for
|
||||||
|
* @return true if private key is held here, false otherwise
|
||||||
|
*/
|
||||||
|
virtual bool havePrivateKey(const KeyRef& keyref) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Use to request a given key reference
|
||||||
|
* @param keyref the KeyRef of the key being requested
|
||||||
|
* @return will
|
||||||
|
*/
|
||||||
|
virtual bool requestKey(const KeyRef& keyref) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Retrieves a key identity
|
||||||
|
* @param keyref
|
||||||
|
* @return a pointer to a valid profile if successful, otherwise NULL
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class RsIdentityExchangeService : RsGeneralExchangeService
|
virtual RsGixsProfile* getProfile(const KeyRef& keyref) = 0;
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
RsGixs();
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* creates gixs profile and shares it
|
|
||||||
* @param profile
|
|
||||||
*/
|
|
||||||
virtual bool createKey(RsGixsProfile& profile) = 0; /* fills in mKeyId, and signature */
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Use to query a whether given key is available by its key reference
|
|
||||||
* @param keyref the keyref of key that is being checked for
|
|
||||||
* @return true if available, false otherwise
|
|
||||||
*/
|
|
||||||
virtual bool haveKey(const KeyRef& keyref) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Use to query whether private key member of the given key reference is available
|
|
||||||
* @param keyref the KeyRef of the key being checked for
|
|
||||||
* @return true if private key is held here, false otherwise
|
|
||||||
*/
|
|
||||||
virtual bool havePrivateKey(const KeyRef& keyref) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Use to request a given key reference
|
|
||||||
* @param keyref the KeyRef of the key being requested
|
|
||||||
* @return will
|
|
||||||
*/
|
|
||||||
virtual bool requestKey(const KeyRef& keyref) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Retrieves a key identity
|
|
||||||
* @param keyref
|
|
||||||
* @return a pointer to a valid profile if successful, otherwise NULL
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
virtual RsGixsProfile* getProfile(const KeyRef& keyref) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*** process data ***/
|
/*** process data ***/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Use to sign data with a given key
|
* Use to sign data with a given key
|
||||||
* @param keyref the key to sign the data with
|
* @param keyref the key to sign the data with
|
||||||
* @param data the data to be signed
|
* @param data the data to be signed
|
||||||
* @param dataLen the length of the data
|
* @param dataLen the length of the data
|
||||||
* @param signature is set with the signature from signing with keyref
|
* @param signature is set with the signature from signing with keyref
|
||||||
* @return false if signing failed, true otherwise
|
* @return false if signing failed, true otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool sign(const KeyRef& keyref, unsigned char* data, uint32_t dataLen, std::string& signature) = 0;
|
virtual bool sign(const KeyRef& keyref, unsigned char* data, uint32_t dataLen, std::string& signature) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Verify that the data is signed by the key owner
|
* Verify that the data is signed by the key owner
|
||||||
* @param keyref
|
* @param keyref
|
||||||
* @param data
|
* @param data
|
||||||
* @param dataLen
|
* @param dataLen
|
||||||
* @param signature
|
* @param signature
|
||||||
* @return false if verification failed, false otherwise
|
* @return false if verification failed, false otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool verify(const KeyRef& keyref, unsigned char* data, int dataLen, std::string& signature) = 0;
|
virtual bool verify(const KeyRef& keyref, unsigned char* data, int dataLen, std::string& signature) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Attempt to decrypt data with a given key
|
* Attempt to decrypt data with a given key
|
||||||
* @param keyref
|
* @param keyref
|
||||||
* @param data data to be decrypted
|
* @param data data to be decrypted
|
||||||
* @param dataLen length of data
|
* @param dataLen length of data
|
||||||
* @param decryptedData decrypted data
|
* @param decryptedData decrypted data
|
||||||
* @param decryptDataLen length of decrypted data
|
* @param decryptDataLen length of decrypted data
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
virtual bool decrypt(const KeyRef& keyref, unsigned char* data, int dataLen,
|
virtual bool decrypt(const KeyRef& keyref, unsigned char* data, int dataLen,
|
||||||
unsigned char*& decryptedData, uint32_t& decyptDataLen) = 0;
|
unsigned char*& decryptedData, uint32_t& decyptDataLen) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Attempt to encrypt data with a given key
|
* Attempt to encrypt data with a given key
|
||||||
* @param keyref
|
* @param keyref
|
||||||
* @param data data to be encrypted
|
* @param data data to be encrypted
|
||||||
* @param dataLen length of data
|
* @param dataLen length of data
|
||||||
* @param encryptedData encrypted data
|
* @param encryptedData encrypted data
|
||||||
* @param encryptDataLen length of encrypted data
|
* @param encryptDataLen length of encrypted data
|
||||||
*/
|
*/
|
||||||
virtual bool encrypt(const KeyRef& keyref, unsigned char* data, int dataLen,
|
virtual bool encrypt(const KeyRef& keyref, unsigned char* data, int dataLen,
|
||||||
unsigned char*& encryptedData, uint32_t& encryptDataLen) = 0;
|
unsigned char*& encryptedData, uint32_t& encryptDataLen) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // RSGIXS_H
|
#endif // RSGIXS_H
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "gxs/rsgxs.h"
|
#include "gxs/rsgxs.h"
|
||||||
|
#include "services/p3service.h"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -75,75 +75,35 @@ typedef std::map<std::string, std::set<std::string> > PeerGrp;
|
|||||||
/*!
|
/*!
|
||||||
* Retroshare General Network Exchange Service: \n
|
* Retroshare General Network Exchange Service: \n
|
||||||
* Interface:
|
* Interface:
|
||||||
* - This provides a module to service peers requests for GXS message \n
|
* - This provides a module to service peer's requests for GXS messages \n
|
||||||
* and also request GXS messages from other peers. \n
|
* and also request GXS messages from other peers. \n
|
||||||
* - Users can make a general request for message under a grp id for a peer, all grp ids held \n
|
* - The general mode of operation is to sychronise all messages/grps between
|
||||||
* by a set of peers. And can also apply to timerange to them
|
* peers
|
||||||
* - An interface is provided for the observer pattern so clients of this class
|
*
|
||||||
* can check if their requests have been served
|
* The interface is sparse as this service is mostly making the requests to other GXS components
|
||||||
|
*
|
||||||
|
* Groups:
|
||||||
|
* - As this is where exchanges occur between peers, this is also where groups relationships
|
||||||
|
* should get resolved as far as
|
||||||
|
* - Per implemented GXS there are a set of rules which will determine whether data is transferred
|
||||||
|
* between any set of groups
|
||||||
|
*
|
||||||
|
* 1 allow transfers to any group
|
||||||
|
* 2 transfers only between group
|
||||||
|
* - the also group matrix settings which is by default everyone can transfer to each other
|
||||||
*/
|
*/
|
||||||
class RsNetworktExchangeService
|
class RsNetworktExchangeService : public p3Service
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RsNetworkExchangeService();
|
RsNetworkExchangeService(uint16_t subtype);
|
||||||
|
|
||||||
/*!
|
|
||||||
* Queries peers for a set of grp ids
|
|
||||||
* @param pg a map of peer to a set of grp ids to query message from
|
|
||||||
* @param from start range of time
|
|
||||||
* @param to end range of time
|
|
||||||
* @return a request code to be kept to redeem query later
|
|
||||||
*/
|
|
||||||
virtual int requestAvailableMsgs(PeerGrp& pg, time_t from, time_t to) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Queries peer for msgs of peer grp id pairs
|
|
||||||
* @param pg peer, grp id peers
|
|
||||||
* @param from start range of time
|
|
||||||
* @param to end range of time
|
|
||||||
* @return a request code to be kept to redeem query later
|
|
||||||
*/
|
|
||||||
virtual int requestMsgs(PeerGrp& pg, time_t from, time_t to) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Queries peers in list for groups avaialble
|
|
||||||
*
|
|
||||||
* @param peers the peers to query
|
|
||||||
* @param from start range of time
|
|
||||||
* @param to end range of time
|
|
||||||
* @return a request code to be kept to redeem query later
|
|
||||||
*/
|
|
||||||
int requestAvailableGrps(const std::set<std::string>& peers, time_t from, time_t to) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* When messages are received this function should be call containing the messages
|
* Use this to set how far back synchronisation of messages should take place
|
||||||
* @param msgs the messages received from peers
|
* @param range how far back from current time to synchronise with other peers
|
||||||
*/
|
*/
|
||||||
void messageFromPeers(std::list<RsGxsSignedMessage*>& msgs) = 0;
|
virtual void setTimeRange(uint64_t range) = 0;
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* attempt to retrieve requested messages
|
|
||||||
* @param requestCode
|
|
||||||
* @param msgs
|
|
||||||
* @return false if not received, true is requestCode has been redeemed
|
|
||||||
* @see RsGeneralNetExchangeService::requestAvailableGrps()
|
|
||||||
*/
|
|
||||||
bool getRequested(uint32_t requestCode, std::list<RsGxsSignedMessage*>& msgs) = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Allows observer pattern for checking if a request has been satisfied
|
|
||||||
*
|
|
||||||
* @param requestCode the code returned msg request functions
|
|
||||||
* @return false if not ready, true otherwise
|
|
||||||
* @see RsGeneralNetExchangeService::requestAvailableGrps()
|
|
||||||
* @see RsGeneralNetExchangeService::requestAvailableMsgs()
|
|
||||||
*/
|
|
||||||
bool requestCodeReady(uint32_t reuqestCode);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@
|
|||||||
// Relay connexions:
|
// Relay connexions:
|
||||||
// * allow relay connexions between people of group A and group B.
|
// * allow relay connexions between people of group A and group B.
|
||||||
//
|
//
|
||||||
|
// General Exchange Services:
|
||||||
|
// * Allow data exchanged from one peers of one group to peers of another group
|
||||||
|
//
|
||||||
// We need per-group permission flags for:
|
// We need per-group permission flags for:
|
||||||
//
|
//
|
||||||
// File download permission:
|
// File download permission:
|
||||||
|
@ -33,12 +33,16 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "serialiser/rsbaseitems.h"
|
#include "serialiser/rsbaseitems.h"
|
||||||
#include "rsgnp.h"
|
#include "rsgnp.h"
|
||||||
#include "rsgdp.h"
|
#include "rsgdp.h"
|
||||||
#include "rsgixs.h"
|
#include "rsgixs.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::map<uint32_t, std::string> requestMsgMap;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* Brief explanation of how RsGeneralExchange service would work \n
|
* Brief explanation of how RsGeneralExchange service would work \n
|
||||||
@ -82,18 +86,43 @@ public:
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* get the RsGeneralDataService instance serving this \n
|
* get the RsGeneralDataService instance serving this \n
|
||||||
* RsGeneralExchangeService
|
* @see RsGeneralExchangeService
|
||||||
* @return data service
|
* @return data service
|
||||||
*/
|
*/
|
||||||
virtual RsGeneralDataService* getDataService() = 0;
|
virtual RsGeneralDataService* getDataService() = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* get the RsNetworktExchangeService instance serving this \n
|
* get the RsNetworktExchangeService instance serving this \n
|
||||||
* RsGeneralExchangeService
|
* @see RsGeneralExchangeService
|
||||||
* @return network exchange service
|
* @return network exchange service
|
||||||
*/
|
*/
|
||||||
virtual RsNetworktExchangeService* getNetworkService() = 0;
|
virtual RsNetworktExchangeService* getNetworkService() = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Requests by this service for messages can be satisfied calling \n
|
||||||
|
* this method with a map containing id to msg map
|
||||||
|
*/
|
||||||
|
virtual void receiveMessages(requestMsgMap&) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* This allows non blocking requests to be made to this service
|
||||||
|
*/
|
||||||
|
virtual void tick();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Implementations of general exchange service can be added \n
|
||||||
|
* to this service runner which ticks the service's general data service \n
|
||||||
|
* and the service itself
|
||||||
|
*/
|
||||||
|
class RsGxServiceRunner : public RsThread {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void addGxService() = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user