/******************************************************************************* * libretroshare/src/retroshare: rsgxsifacehelper.h * * * * libretroshare: retroshare core library * * * * Copyright 2011 by Christopher Evi-Parker * * Copyright (C) 2018-2019 Gioacchino Mazzurco * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * * * This program 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 Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see . * * * *******************************************************************************/ #pragma once #include #include #include "retroshare/rsgxsiface.h" #include "retroshare/rsreputations.h" #include "rsgxsflags.h" #include "util/rsdeprecate.h" /*! * This class only make method of internal members visible tu upper level to * offer a more friendly API. * This is just a workaround to awkward GXS API design, do not take it as an * example for your coding. * To properly fix the API design many changes with the implied chain reactions * are necessary, so at this point this workaround seems acceptable. */ struct RsGxsIfaceHelper { /*! * @param gxs handle to RsGenExchange instance of service (Usually the * service class itself) */ RsGxsIfaceHelper(RsGxsIface& gxs) : mGxs(gxs), mTokenService(*gxs.getTokenService()) {} ~RsGxsIfaceHelper(){} /*! * Gxs services should call this for automatic handling of * changes, send * @param changes */ void receiveChanges(std::vector &changes) { mGxs.receiveChanges(changes); } /* Generic Lists */ /*! * Retrieve list of group ids associated to a request token * @param token token to be redeemed for this request * @param groupIds the ids return for given request token * @return false if request token is invalid, check token status for error report */ bool getGroupList(const uint32_t &token, std::list &groupIds) { return mGxs.getGroupList(token, groupIds); } /*! * Retrieves list of msg ids associated to a request token * @param token token to be redeemed for this request * @param msgIds the ids return for given request token * @return false if request token is invalid, check token status for error report */ bool getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds) { return mGxs.getMsgList(token, msgIds); } /*! * Retrieves list of msg related ids associated to a request token * @param token token to be redeemed for this request * @param msgIds the ids return for given request token * @return false if request token is invalid, check token status for error report */ bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds) { return mGxs.getMsgRelatedList(token, msgIds); } /*! * @param token token to be redeemed for group summary request * @param groupInfo the ids returned for given request token * @return false if request token is invalid, check token status for error report */ bool getGroupSummary(const uint32_t &token, std::list &groupInfo) { return mGxs.getGroupMeta(token, groupInfo); } /*! * @param token token to be redeemed for message summary request * @param msgInfo the message metadata returned for given request token * @return false if request token is invalid, check token status for error report */ bool getMsgSummary(const uint32_t &token, GxsMsgMetaMap &msgInfo) { return mGxs.getMsgMeta(token, msgInfo); } /*! * @param token token to be redeemed for message related summary request * @param msgInfo the message metadata returned for given request token * @return false if request token is invalid, check token status for error report */ bool getMsgRelatedSummary(const uint32_t &token, GxsMsgRelatedMetaMap &msgInfo) { return mGxs.getMsgRelatedMeta(token, msgInfo); } /*! * subscribes to group, and returns token which can be used * to be acknowledged to get group Id * @param token token to redeem for acknowledgement * @param grpId the id of the group to subscribe to */ bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) { return mGxs.subscribeToGroup(token, grpId, subscribe); } /*! * This allows the client service to acknowledge that their msgs has * been created/modified and retrieve the create/modified msg ids * @param token the token related to modification/create request * @param msgIds map of grpid->msgIds of message created/modified * @return true if token exists false otherwise */ bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) { return mGxs.acknowledgeTokenMsg(token, msgId); } /*! * This allows the client service to acknowledge that their grps has * been created/modified and retrieve the create/modified grp ids * @param token the token related to modification/create request * @param msgIds vector of ids of groups created/modified * @return true if token exists false otherwise */ bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) { return mGxs.acknowledgeTokenGrp(token, grpId); } /*! * Gets service statistic for a given services * @param token value to to retrieve requested stats * @param stats the status * @return true if token exists false otherwise */ bool getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats) { return mGxs.getServiceStatistic(token, stats); } /*! * * @param token to be redeemed * @param stats the stats associated to token request * @return true if token is false otherwise */ bool getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats) { return mGxs.getGroupStatistic(token, stats); } /*! * This determines the reputation threshold messages need to surpass in order * for it to be accepted by local user from remote source * NOTE: threshold only enforced if service require author signature * @param token value set to be redeemed with acknowledgement * @param grpId group id for cutoff value to be set * @param CutOff The cut off value to set */ void setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff) { return mGxs.setGroupReputationCutOff(token, grpId, CutOff); } /*! * @return storage/sync time of messages in secs */ uint32_t getDefaultStoragePeriod() { return mGxs.getDefaultStoragePeriod(); } uint32_t getStoragePeriod(const RsGxsGroupId& grpId) { return mGxs.getStoragePeriod(grpId); } void setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) { mGxs.setStoragePeriod(grpId,age_in_secs); } uint32_t getDefaultSyncPeriod() { return mGxs.getDefaultSyncPeriod(); } uint32_t getSyncPeriod(const RsGxsGroupId& grpId) { return mGxs.getSyncPeriod(grpId); } void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) { mGxs.setSyncPeriod(grpId,age_in_secs); } RsReputationLevel minReputationForForwardingMessages( uint32_t group_sign_flags, uint32_t identity_flags ) { return mGxs.minReputationForForwardingMessages(group_sign_flags,identity_flags); } /// @see RsTokenService::requestGroupInfo bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list &groupIds ) { return mTokenService.requestGroupInfo(token, 0, opts, groupIds); } /// @see RsTokenService::requestGroupInfo bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts) { return mTokenService.requestGroupInfo(token, 0, opts); } /// @see RsTokenService::requestMsgInfo bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const GxsMsgReq& msgIds ) { return mTokenService.requestMsgInfo(token, 0, opts, msgIds); } /// @see RsTokenService::requestMsgInfo bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list& grpIds ) { return mTokenService.requestMsgInfo(token, 0, opts, grpIds); } /// @see RsTokenService::requestMsgRelatedInfo bool requestMsgRelatedInfo( uint32_t& token, const RsTokReqOptions& opts, const std::vector& msgIds ) { return mTokenService.requestMsgRelatedInfo(token, 0, opts, msgIds); } /** * @jsonapi{development} * @param[in] token */ RsTokenService::GxsRequestStatus requestStatus(uint32_t token) { return mTokenService.requestStatus(token); } /// @see RsTokenService::requestServiceStatistic void requestServiceStatistic(uint32_t& token) { mTokenService.requestServiceStatistic(token); } /// @see RsTokenService::requestGroupStatistic void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId) { mTokenService.requestGroupStatistic(token, grpId); } /// @see RsTokenService::cancelRequest bool cancelRequest(uint32_t token) { return mTokenService.cancelRequest(token); } /** * @deprecated * Token service methods are already exposed by this helper, so you should * not need to get token service pointer directly anymore. */ RS_DEPRECATED RsTokenService* getTokenService() { return &mTokenService; } protected: /** * Block caller while request is being processed. * Useful for blocking API implementation. * @param[in] token token associated to the request caller is waiting for * @param[in] maxWait maximum waiting time in milliseconds * @param[in] checkEvery time in millisecond between status checks */ RsTokenService::GxsRequestStatus waitToken( uint32_t token, std::chrono::milliseconds maxWait = std::chrono::milliseconds(500), std::chrono::milliseconds checkEvery = std::chrono::milliseconds(2)) { #if defined(__ANDROID__) && (__ANDROID_API__ < 24) auto wkStartime = std::chrono::steady_clock::now(); int maxWorkAroundCnt = 10; LLwaitTokenBeginLabel: #endif auto timeout = std::chrono::steady_clock::now() + maxWait; auto st = requestStatus(token); while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) { std::this_thread::sleep_for(checkEvery); st = requestStatus(token); } #if defined(__ANDROID__) && (__ANDROID_API__ < 24) /* Work around for very slow/old android devices, we don't expect this * to be necessary on newer devices. If it take unreasonably long * something worser is already happening elsewere amd we return anyway. */ if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE && maxWorkAroundCnt-- > 0 ) { maxWait *= 10; checkEvery *= 3; std::cerr << __PRETTY_FUNCTION__ << " Slow Android device " << " workaround st: " << st << " maxWorkAroundCnt: " << maxWorkAroundCnt << " maxWait: " << maxWait.count() << " checkEvery: " << checkEvery.count() << std::endl; goto LLwaitTokenBeginLabel; } std::cerr << __PRETTY_FUNCTION__ << " lasted: " << std::chrono::duration_cast( std::chrono::steady_clock::now() - wkStartime ).count() << "ms" << std::endl; #endif return st; } private: RsGxsIface& mGxs; RsTokenService& mTokenService; };