mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-08-02 11:16:34 -04:00
Merge branch 'master' into TheWire-rework-ui
This commit is contained in:
commit
bcaef29d49
145 changed files with 4041 additions and 3647 deletions
|
@ -658,7 +658,8 @@ public:
|
|||
* @brief Get file details
|
||||
* @jsonapi{development}
|
||||
* @param[in] hash file identifier
|
||||
* @param[in] hintflags filtering hint (RS_FILE_HINTS_EXTRA|...|RS_FILE_HINTS_LOCAL)
|
||||
* @param[in] hintflags filtering hint ( RS_FILE_HINTS_UPLOAD|...|
|
||||
* RS_FILE_HINTS_EXTRA|RS_FILE_HINTS_LOCAL )
|
||||
* @param[out] info storage for file information
|
||||
* @return true if file found, false otherwise
|
||||
*/
|
||||
|
|
|
@ -310,11 +310,13 @@ public:
|
|||
* @param[in] channelId id of the channel of which the content is requested
|
||||
* @param[out] posts storage for posts
|
||||
* @param[out] comments storage for the comments
|
||||
* @param[out] votes storage for votes
|
||||
* @return false if something failed, true otherwhise
|
||||
*/
|
||||
virtual bool getChannelAllContent( const RsGxsGroupId& channelId,
|
||||
std::vector<RsGxsChannelPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) = 0;
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get channel messages and comments corresponding to the given IDs.
|
||||
|
@ -326,12 +328,14 @@ public:
|
|||
* @param[in] contentsIds ids of requested contents
|
||||
* @param[out] posts storage for posts
|
||||
* @param[out] comments storage for the comments
|
||||
* @param[out] votes storage for the votes
|
||||
* @return false if something failed, true otherwhise
|
||||
*/
|
||||
virtual bool getChannelContent( const RsGxsGroupId& channelId,
|
||||
const std::set<RsGxsMessageId>& contentsIds,
|
||||
std::vector<RsGxsChannelPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) = 0;
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get channel comments corresponding to the given IDs.
|
||||
|
@ -571,6 +575,9 @@ public:
|
|||
RS_DEPRECATED_FOR(getChannelsInfo)
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getChannelContent)
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts, std::vector<RsGxsVote> &votes) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getChannelContent)
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
|
||||
|
||||
|
|
|
@ -45,25 +45,23 @@ extern RsGxsCircles* rsGxsCircles;
|
|||
|
||||
enum class RsGxsCircleType : uint32_t // 32 bit overkill, just for retrocompat
|
||||
{
|
||||
UNKNOWN = 0, /// Used to detect uninizialized values.
|
||||
PUBLIC = 1, /// Public distribution
|
||||
EXTERNAL = 2, /// Restricted to an external circle
|
||||
UNKNOWN = 0, /// Used to detect uninizialized values.
|
||||
PUBLIC = 1, /// Public distribution, based on GxsIds
|
||||
EXTERNAL = 2, /// Restricted to an external circle, based on GxsIds
|
||||
|
||||
/** Restricted to a group of friend nodes, the administrator of the circle
|
||||
* behave as a hub for them */
|
||||
NODES_GROUP = 3,
|
||||
NODES_GROUP = 3, /// Restricted to a group of friend nodes, the administrator of the circle behave as a hub for them
|
||||
/// Based on PGP nodes ids.
|
||||
|
||||
LOCAL = 4, /// not distributed at all
|
||||
|
||||
/** Self-restricted. Used only at creation time of self-restricted circles
|
||||
* when the circle id isn't known yet. Once the circle id is known the type
|
||||
* is set to EXTERNAL, and the external circle id is set to the id of the
|
||||
* circle itself.
|
||||
* circle itself. Based on GxsIds.
|
||||
*/
|
||||
EXT_SELF = 5,
|
||||
|
||||
/// distributed to nodes signed by your own PGP key only.
|
||||
YOUR_EYES_ONLY = 6
|
||||
YOUR_EYES_ONLY = 6 /// distributed to nodes signed by your own PGP key only.
|
||||
};
|
||||
|
||||
// TODO: convert to enum class
|
||||
|
@ -98,22 +96,32 @@ struct RsGxsCircleGroup : RsSerializable
|
|||
~RsGxsCircleGroup() override;
|
||||
};
|
||||
|
||||
enum class RsGxsCircleSubscriptionType:uint8_t {
|
||||
UNKNOWN = 0x00,
|
||||
SUBSCRIBE = 0x01,
|
||||
UNSUBSCRIBE = 0x02
|
||||
};
|
||||
|
||||
struct RsGxsCircleMsg : RsSerializable
|
||||
{
|
||||
RsMsgMetaData mMeta;
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
// This item is actually totally unused, so we can change it no problem
|
||||
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED
|
||||
/* This is horrible and should be changed into yet to be defined something
|
||||
* reasonable in next non-retrocompatible version */
|
||||
std::string stuff;
|
||||
#endif
|
||||
#endif
|
||||
RsGxsCircleSubscriptionType mSubscriptionType;
|
||||
|
||||
/// @see RsSerializable
|
||||
void serial_process( RsGenericSerializer::SerializeJob j,
|
||||
RsGenericSerializer::SerializeContext& ctx) override
|
||||
{
|
||||
RS_SERIAL_PROCESS(mMeta);
|
||||
RS_SERIAL_PROCESS(stuff);
|
||||
RS_SERIAL_PROCESS(mSubscriptionType);
|
||||
}
|
||||
|
||||
~RsGxsCircleMsg() override;
|
||||
|
@ -121,15 +129,29 @@ struct RsGxsCircleMsg : RsSerializable
|
|||
|
||||
struct RsGxsCircleDetails : RsSerializable
|
||||
{
|
||||
RsGxsCircleDetails() :
|
||||
mCircleType(static_cast<uint32_t>(RsGxsCircleType::EXTERNAL)),
|
||||
mAmIAllowed(false),mAmIAdmin(false) {}
|
||||
RsGxsCircleDetails() : mCircleType(RsGxsCircleType::EXTERNAL), mAmIAllowed(false),mAmIAdmin(false) {}
|
||||
~RsGxsCircleDetails() override;
|
||||
|
||||
// helper functions.
|
||||
bool isIdInCircle(const RsGxsId& id) const { return mAllowedGxsIds.find(id) != mAllowedGxsIds.end(); }
|
||||
bool isIdInInviteeList(const RsGxsId& id) const
|
||||
{
|
||||
auto it = mSubscriptionFlags.find(id);
|
||||
return (it != mSubscriptionFlags.end()) && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST );
|
||||
}
|
||||
bool isIdRequestingMembership(const RsGxsId& id) const
|
||||
{
|
||||
auto it = mSubscriptionFlags.find(id);
|
||||
return it != mSubscriptionFlags.end() && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED );
|
||||
}
|
||||
bool isGxsIdBased() const { return mCircleType==RsGxsCircleType::PUBLIC || mCircleType==RsGxsCircleType::EXTERNAL || mCircleType==RsGxsCircleType::EXT_SELF; }
|
||||
|
||||
// Members
|
||||
|
||||
RsGxsCircleId mCircleId;
|
||||
std::string mCircleName;
|
||||
|
||||
uint32_t mCircleType;
|
||||
RsGxsCircleType mCircleType;
|
||||
RsGxsCircleId mRestrictedCircleId;
|
||||
|
||||
/** true when one of load GXS ids belong to the circle allowed list (admin
|
||||
|
@ -165,32 +187,54 @@ struct RsGxsCircleDetails : RsSerializable
|
|||
|
||||
enum class RsGxsCircleEventCode: uint8_t
|
||||
{
|
||||
// Notifications be only have 4 different possibilities:
|
||||
//
|
||||
// invitee list join/leave and
|
||||
// membership request / leave request
|
||||
//
|
||||
// From there, depending on what the client displays, it is possible to interpret these
|
||||
// as "some user joined the circle", or "membership pending for that Id", etc, depending
|
||||
// on whether the current node owns the circle, or the admin is or is not yours.
|
||||
//
|
||||
// These should be decided in the UI based on what the circle cache is displaying.
|
||||
//
|
||||
UNKNOWN = 0x00,
|
||||
|
||||
/** mCircleId contains the circle id and mGxsId is the id requesting
|
||||
* membership */
|
||||
CIRCLE_MEMBERSHIP_REQUEST = 0x01,
|
||||
/**
|
||||
* Sent when we receive a membership request msg for a particular circle.
|
||||
*
|
||||
* mCircleId contains the circle id and mGxsId is the id requesting membership */
|
||||
CIRCLE_MEMBERSHIP_REQUEST = 0x01,
|
||||
|
||||
/** mCircleId is the circle that invites me, and mGxsId is my own Id that is
|
||||
* invited */
|
||||
CIRCLE_MEMBERSHIP_INVITE = 0x02,
|
||||
/**
|
||||
* Sent when the ID has been added to the circle invitee list.
|
||||
*
|
||||
* mCircleId is the circle that invites me, and mGxsId is my own Id that is invited */
|
||||
CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST = 0x02,
|
||||
|
||||
/** mCircleId contains the circle id and mGxsId is the id dropping
|
||||
* membership */
|
||||
CIRCLE_MEMBERSHIP_LEAVE = 0x03,
|
||||
/**
|
||||
* Sent when a GxsId annouces its will to not be in the circle.
|
||||
*
|
||||
* mCircleId contains the circle id and mGxsId is the id dropping membership */
|
||||
CIRCLE_MEMBERSHIP_LEAVE = 0x03,
|
||||
|
||||
/// mCircleId contains the circle id and mGxsId is the id of the new member
|
||||
CIRCLE_MEMBERSHIP_JOIN = 0x04,
|
||||
/**
|
||||
* Sent when the Id has been removed from the invitee list.
|
||||
*
|
||||
* mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */
|
||||
CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST = 0x04,
|
||||
|
||||
/** mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */
|
||||
CIRCLE_MEMBERSHIP_REVOQUED= 0x05,
|
||||
|
||||
/** mCircleId contains the circle id */
|
||||
NEW_CIRCLE = 0x06,
|
||||
|
||||
/** no additional information. Simply means that the info previously from the cache has changed. */
|
||||
CACHE_DATA_UPDATED = 0x07,
|
||||
/**
|
||||
* Means a new circle has been received.
|
||||
*
|
||||
* mCircleId contains the circle id */
|
||||
NEW_CIRCLE = 0x05,
|
||||
|
||||
/**
|
||||
* Means that the circle cache has updated, and membership status that is displayed should probably be updated to.
|
||||
*
|
||||
* no additional information. Simply means that the info previously from the cache has changed. */
|
||||
CACHE_DATA_UPDATED = 0x06,
|
||||
};
|
||||
|
||||
struct RsGxsCircleEvent: RsEvent
|
||||
|
|
|
@ -112,6 +112,7 @@ enum class RsForumEventCode: uint8_t
|
|||
SUBSCRIBE_STATUS_CHANGED = 0x05, /// forum was subscribed or unsubscribed
|
||||
READ_STATUS_CHANGED = 0x06, /// msg was read or marked unread
|
||||
STATISTICS_CHANGED = 0x07, /// suppliers and how many messages they have changed
|
||||
MODERATOR_LIST_CHANGED = 0x08, /// forum moderation list has changed.
|
||||
};
|
||||
|
||||
struct RsGxsForumEvent: RsEvent
|
||||
|
@ -123,6 +124,8 @@ struct RsGxsForumEvent: RsEvent
|
|||
RsForumEventCode mForumEventCode;
|
||||
RsGxsGroupId mForumGroupId;
|
||||
RsGxsMessageId mForumMsgId;
|
||||
std::list<RsGxsId> mModeratorsAdded;
|
||||
std::list<RsGxsId> mModeratorsRemoved;
|
||||
|
||||
///* @see RsEvent @see RsSerializable
|
||||
void serial_process(
|
||||
|
@ -133,6 +136,9 @@ struct RsGxsForumEvent: RsEvent
|
|||
RS_SERIAL_PROCESS(mForumEventCode);
|
||||
RS_SERIAL_PROCESS(mForumGroupId);
|
||||
RS_SERIAL_PROCESS(mForumMsgId);
|
||||
RS_SERIAL_PROCESS(mForumMsgId);
|
||||
RS_SERIAL_PROCESS(mModeratorsAdded);
|
||||
RS_SERIAL_PROCESS(mModeratorsRemoved);
|
||||
}
|
||||
|
||||
~RsGxsForumEvent() override;
|
||||
|
|
|
@ -116,12 +116,14 @@ struct RsGxsIface
|
|||
*/
|
||||
virtual uint16_t serviceType() const =0;
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
/*!
|
||||
* Gxs services should call this for automatic handling of
|
||||
* changes, send
|
||||
* @param changes
|
||||
*/
|
||||
virtual void receiveChanges(std::vector<RsGxsNotify*>& changes) = 0;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @return handle to token service for this GXS service
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
|
||||
~RsGxsIfaceHelper() = default;
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
/*!
|
||||
* Gxs services should call this for automatic handling of
|
||||
* changes, send
|
||||
|
@ -81,6 +82,7 @@ public:
|
|||
{
|
||||
mGxs.receiveChanges(changes);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Generic Lists */
|
||||
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "serialiser/rstypeserializer.h"
|
||||
#include "util/rstime.h"
|
||||
|
||||
typedef Sha1CheckSum RsGxsMessageId;
|
||||
|
||||
typedef std::map<RsGxsGroupId, std::set<RsGxsMessageId> > GxsMsgIdResult;
|
||||
typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair;
|
||||
typedef std::map<RsGxsGrpMsgIdPair, std::set<RsGxsMessageId> > MsgRelatedIdResult;
|
||||
|
|
|
@ -32,69 +32,6 @@ typedef uint32_t TurtleRequestId;
|
|||
typedef std::map<RsGxsGroupId, std::vector<RsMsgMetaData> > GxsMsgMetaMap;
|
||||
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsMsgMetaData> > GxsMsgRelatedMetaMap;
|
||||
|
||||
/*!
|
||||
* The aim of this class is to abstract how changes are represented so they can
|
||||
* be determined outside the client API without explcitly enumerating all
|
||||
* possible changes at the interface
|
||||
*/
|
||||
struct RsGxsNotify
|
||||
{
|
||||
enum NotifyType
|
||||
{
|
||||
TYPE_UNKNOWN = 0x00,
|
||||
TYPE_PUBLISHED = 0x01,
|
||||
TYPE_RECEIVED_NEW = 0x02,
|
||||
TYPE_PROCESSED = 0x03,
|
||||
TYPE_RECEIVED_PUBLISHKEY = 0x04,
|
||||
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
|
||||
TYPE_STATISTICS_CHANGED = 0x06
|
||||
};
|
||||
|
||||
virtual ~RsGxsNotify() {}
|
||||
virtual NotifyType getType() = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Relevant to group changes
|
||||
*/
|
||||
class RsGxsGroupChange : public RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsGroupChange(NotifyType type, bool metaChange) : NOTIFY_TYPE(type), mMetaChange(metaChange) {}
|
||||
std::list<RsGxsGroupId> mGrpIdList;
|
||||
NotifyType getType(){ return NOTIFY_TYPE;}
|
||||
bool metaChange() { return mMetaChange; }
|
||||
private:
|
||||
const NotifyType NOTIFY_TYPE;
|
||||
bool mMetaChange;
|
||||
};
|
||||
|
||||
class RsGxsDistantSearchResultChange: public RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsDistantSearchResultChange(TurtleRequestId id,const RsGxsGroupId& group_id) : mRequestId(id),mGroupId(group_id){}
|
||||
|
||||
NotifyType getType() { return TYPE_RECEIVED_DISTANT_SEARCH_RESULTS ; }
|
||||
|
||||
TurtleRequestId mRequestId ;
|
||||
RsGxsGroupId mGroupId;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Relevant to message changes
|
||||
*/
|
||||
class RsGxsMsgChange : public RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsMsgChange(NotifyType type, bool metaChange) : NOTIFY_TYPE(type), mMetaChange(metaChange) {}
|
||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > msgChangeMap;
|
||||
NotifyType getType(){ return NOTIFY_TYPE;}
|
||||
bool metaChange() { return mMetaChange; }
|
||||
private:
|
||||
const NotifyType NOTIFY_TYPE;
|
||||
bool mMetaChange;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // RSGXSSERVICE_H
|
||||
|
|
|
@ -328,6 +328,7 @@ using Sha256CheckSum = t_RsGenericIdType<_RsIdSize::SHA256 , false, R
|
|||
using RsPgpFingerprint = t_RsGenericIdType<_RsIdSize::PGP_FINGERPRINT, true, RsGenericIdType::PGP_FINGERPRINT>;
|
||||
using Bias20Bytes = t_RsGenericIdType<_RsIdSize::SHA1 , true, RsGenericIdType::BIAS_20_BYTES >;
|
||||
using RsGxsGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_GROUP >;
|
||||
using RsGxsMessageId = t_RsGenericIdType<_RsIdSize::SHA1 , false, RsGenericIdType::GXS_MSG >;
|
||||
using RsGxsId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_ID >;
|
||||
using RsGxsCircleId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_CIRCLE >;
|
||||
using RsGxsTunnelId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::GXS_TUNNEL >;
|
||||
|
|
|
@ -115,11 +115,13 @@ const uint32_t RS_FEED_ITEM_CHAT_NEW = RS_FEED_TYPE_CHAT | 0x0001;
|
|||
const uint32_t RS_FEED_ITEM_MESSAGE = RS_FEED_TYPE_MSG | 0x0001;
|
||||
const uint32_t RS_FEED_ITEM_FILES_NEW = RS_FEED_TYPE_FILES | 0x0001;
|
||||
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_INVIT_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED = RS_FEED_TYPE_CIRCLE | 0x0005;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED = RS_FEED_TYPE_CIRCLE | 0x0005;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOKED = RS_FEED_TYPE_CIRCLE | 0x0006;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_CANCELLED= RS_FEED_TYPE_CIRCLE | 0x0007;
|
||||
|
||||
const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001;
|
||||
|
||||
|
|
|
@ -154,13 +154,15 @@ public:
|
|||
virtual bool getBoardAllContent(
|
||||
const RsGxsGroupId& boardId,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) = 0;
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) = 0;
|
||||
|
||||
virtual bool getBoardContent(
|
||||
const RsGxsGroupId& boardId,
|
||||
const std::set<RsGxsMessageId>& contentsIds,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) = 0;
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) = 0;
|
||||
|
||||
virtual bool editBoard(RsPostedGroup& board) =0;
|
||||
|
||||
|
@ -176,6 +178,11 @@ public:
|
|||
virtual bool getGroupData( const uint32_t& token,
|
||||
std::vector<RsPostedGroup> &groups ) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getBoardsContent)
|
||||
virtual bool getPostData(
|
||||
const uint32_t& token, std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& cmts, std::vector<RsGxsVote>& vots) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getBoardsContent)
|
||||
virtual bool getPostData(
|
||||
const uint32_t& token, std::vector<RsPostedPost>& posts,
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#define USE_NEW_CHUNK_CHECKING_CODE
|
||||
|
||||
typedef Sha1CheckSum RsFileHash ;
|
||||
typedef Sha1CheckSum RsMessageId ;
|
||||
|
||||
const uint32_t FT_STATE_FAILED = 0x0000 ;
|
||||
const uint32_t FT_STATE_OKAY = 0x0001 ;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue