From 9eef412b4441939a047aa3e1f97f8f6075e5077c Mon Sep 17 00:00:00 2001 From: Gio Date: Wed, 7 Dec 2016 20:09:14 +0100 Subject: [PATCH] Expose libresapi for distant chat Added macro to deprecate symbols usage in a crossplatform way. Deprecated Request::mMethod and related stuff that make implementation more complex without advantage. Added /chat/{initiate_distant_chat, distant_chat_status, close_distant_chat} to libresapi. Solved subtle bug in ChatId::ChatId(std::string str) that caused zeroed DistantChatPeerId being created. --- libresapi/src/api/ApiTypes.h | 45 ++++++------- libresapi/src/api/ChatHandler.cpp | 77 ++++++++++++++++++++-- libresapi/src/api/ChatHandler.h | 8 ++- libretroshare/src/chat/distantchat.cc | 39 ++++++----- libretroshare/src/chat/p3chatservice.cc | 28 ++++---- libretroshare/src/gxstunnel/p3gxstunnel.cc | 2 +- libretroshare/src/libretroshare.pro | 5 +- libretroshare/src/rsserver/p3msgs.cc | 23 ++++--- libretroshare/src/util/rsdeprecate.h | 34 ++++++++++ 9 files changed, 179 insertions(+), 82 deletions(-) create mode 100644 libretroshare/src/util/rsdeprecate.h diff --git a/libresapi/src/api/ApiTypes.h b/libresapi/src/api/ApiTypes.h index 98ad44cd9..c443eb170 100644 --- a/libresapi/src/api/ApiTypes.h +++ b/libresapi/src/api/ApiTypes.h @@ -6,6 +6,8 @@ #include #include +#include "util/rsdeprecate.h" + namespace resource_api { // things to clean up: @@ -181,18 +183,20 @@ private: class Request { public: - Request(StreamBase& stream): mStream(stream), mMethod(GET){} + Request(StreamBase& stream) : mStream(stream), mMethod(GET){} - bool isGet(){ return mMethod == GET;} - bool isPut(){ return mMethod == PUT;} - bool isDelete(){ return mMethod == DELETE_AA;} - bool isExec(){ return mMethod == EXEC;} + RS_DEPRECATED bool isGet(){ return mMethod == GET;} + RS_DEPRECATED bool isPut(){ return mMethod == PUT;} + RS_DEPRECATED bool isDelete(){ return mMethod == DELETE_AA;} + RS_DEPRECATED bool isExec(){ return mMethod == EXEC;} - // path is the adress to the resource - // if the path has multiple parts which get handled by different handlers, - // then each handler should pop the top element - std::stack mPath; - std::string mFullPath; + /** + * Path is the adress to the resource if the path has multiple parts which + * get handled by different handlers, then each handler should pop the top + * element + */ + std::stack mPath; + std::string mFullPath; bool setPath(const std::string &reqPath) { std::string str; @@ -213,19 +217,16 @@ public: return true; } - // parameters should be used to influence the result - // for example include or exclude some information - // question: when to use parameters, and when to use the data field? - // it would be easier to have only one thing... - // UNUSED: was never implemented - //std::vector > mParameters; + /// Contains data for new resources + StreamBase& mStream; - // contains data for new resources - StreamBase& mStream; - - // use the is*() methods to query the method type: - enum Method { GET, PUT, DELETE_AA, EXEC};// something is wrong with DELETE, it won't compile with it - Method mMethod; + /** + * @deprecated + * Method and derivated stuff usage is deprecated as it make implementation + * more complex and less readable without advantage + */ + enum Method { GET, PUT, DELETE_AA, EXEC}; + RS_DEPRECATED Method mMethod; }; // new notes on responses diff --git a/libresapi/src/api/ChatHandler.cpp b/libresapi/src/api/ChatHandler.cpp index 1f10351a8..3944032fb 100644 --- a/libresapi/src/api/ChatHandler.cpp +++ b/libresapi/src/api/ChatHandler.cpp @@ -155,6 +155,9 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs, addResourceHandler("receive_status", this, &ChatHandler::handleReceiveStatus); addResourceHandler("send_status", this, &ChatHandler::handleSendStatus); addResourceHandler("unread_msgs", this, &ChatHandler::handleUnreadMsgs); + addResourceHandler("initiate_distant_chat", this, &ChatHandler::handleInitiateDistantChatConnexion); + addResourceHandler("distant_chat_status", this, &ChatHandler::handleDistantChatStatus); + addResourceHandler("close_distant_chat", this, &ChatHandler::handleCloseDistantChatConnexion); } ChatHandler::~ChatHandler() @@ -928,12 +931,14 @@ void ChatHandler::handleMessages(Request &req, Response &resp) return; } std::map >::iterator mit = mMsgs.find(id); - if(mit == mMsgs.end()) - { - resp.mStateToken = mMsgStateToken; // even set state token, if not found yet, maybe later messages arrive and then the chat id will be found - resp.setFail("chat with id=\""+req.mPath.top()+"\" not found"); - return; - } + if(mit == mMsgs.end()) + { + /* set state token, even if not found yet, maybe later messages arrive + * and then the chat id will be found */ + resp.mStateToken = mMsgStateToken; + resp.setFail("chat with id=\""+req.mPath.top()+"\" not found"); + return; + } resp.mStateToken = mMsgStateToken; handlePaginationRequest(req, resp, mit->second); } @@ -954,7 +959,6 @@ void ChatHandler::handleSendMessage(Request &req, Response &resp) resp.setOk(); else resp.setFail("failed to send message"); - } void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp) @@ -1125,4 +1129,63 @@ void ChatHandler::handleUnreadMsgs(Request &/*req*/, Response &resp) resp.mStateToken = mUnreadMsgsStateToken; } +void ChatHandler::handleInitiateDistantChatConnexion(Request& req, Response& resp) +{ + std::string own_gxs_hex, remote_gxs_hex; + + req.mStream << makeKeyValueReference("own_gxs_hex", own_gxs_hex) + << makeKeyValueReference("remote_gxs_hex", remote_gxs_hex); + + RsGxsId sender_id(own_gxs_hex); + if(sender_id.isNull()) + { + resp.setFail("own_gxs_hex is invalid"); + return; + } + + RsGxsId receiver_id(remote_gxs_hex); + if(receiver_id.isNull()) + { + resp.setFail("remote_gxs_hex is invalid"); + return; + } + + DistantChatPeerId distant_chat_id; + uint32_t error_code; + + if(mRsMsgs->initiateDistantChatConnexion(receiver_id, sender_id, distant_chat_id, error_code)) + resp.setOk(); + else resp.setFail("Failed to initiate distant chat"); + + ChatId chat_id(distant_chat_id); + resp.mDataStream << makeKeyValue("chat_id", chat_id.toStdString()) + << makeKeyValueReference("error_code", error_code); +} + +void ChatHandler::handleDistantChatStatus(Request& req, Response& resp) +{ + std::string distant_chat_hex; + req.mStream << makeKeyValueReference("chat_id", distant_chat_hex); + + ChatId id(distant_chat_hex); + DistantChatPeerInfo info; + if(mRsMsgs->getDistantChatStatus(id.toDistantChatId(), info)) resp.setOk(); + else resp.setFail("Failed to get status for distant chat"); + + resp.mDataStream << makeKeyValue("own_gxs_hex", info.own_id.toStdString()) + << makeKeyValue("remote_gxs_hex", info.to_id.toStdString()) + << makeKeyValue("chat_id", info.peer_id.toStdString()) + << makeKeyValue("status", info.status); +} + +void ChatHandler::handleCloseDistantChatConnexion(Request& req, Response& resp) +{ + std::string distant_chat_hex; + req.mStream << makeKeyValueReference("distant_chat_hex", distant_chat_hex); + + DistantChatPeerId chat_id(distant_chat_hex); + if (mRsMsgs->closeDistantChatConnexion(chat_id)) resp.setOk(); + else resp.setFail("Failed to close distant chat"); +} + } // namespace resource_api diff --git a/libresapi/src/api/ChatHandler.h b/libresapi/src/api/ChatHandler.h index 3068302f7..dc075c77f 100644 --- a/libresapi/src/api/ChatHandler.h +++ b/libresapi/src/api/ChatHandler.h @@ -11,9 +11,10 @@ class RsIdentity; namespace resource_api { -class UnreadMsgNotify{ +class UnreadMsgNotify +{ public: - virtual void notifyUnreadMsgCountChanged(const RsPeerId& peer, uint32_t count) = 0; + virtual void notifyUnreadMsgCountChanged(const RsPeerId& peer, uint32_t count) = 0; }; class ChatHandler: public ResourceRouter, NotifyClient, Tickable @@ -128,6 +129,9 @@ private: ResponseTask *handleReceiveStatus(Request& req, Response& resp); void handleSendStatus(Request& req, Response& resp); void handleUnreadMsgs(Request& req, Response& resp); + void handleInitiateDistantChatConnexion(Request& req, Response& resp); + void handleDistantChatStatus(Request& req, Response& resp); + void handleCloseDistantChatConnexion(Request& req, Response& resp); void getPlainText(const std::string& in, std::string &out, std::vector &links); // last parameter is only used for lobbies! diff --git a/libretroshare/src/chat/distantchat.cc b/libretroshare/src/chat/distantchat.cc index 805728905..70fb88d8c 100644 --- a/libretroshare/src/chat/distantchat.cc +++ b/libretroshare/src/chat/distantchat.cc @@ -275,31 +275,30 @@ bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id, bool DistantChatService::getDistantChatStatus(const DistantChatPeerId& tunnel_id, DistantChatPeerInfo& cinfo) { - RsStackMutex stack(mDistantChatMtx); /********** STACK LOCKED MTX ******/ + RS_STACK_MUTEX(mDistantChatMtx); - RsGxsTunnelService::GxsTunnelInfo tinfo ; + RsGxsTunnelService::GxsTunnelInfo tinfo; - if(!mGxsTunnels->getTunnelInfo(RsGxsTunnelId(tunnel_id),tinfo)) - return false; + if(!mGxsTunnels->getTunnelInfo(RsGxsTunnelId(tunnel_id),tinfo)) return false; - cinfo.to_id = tinfo.destination_gxs_id; - cinfo.own_id = tinfo.source_gxs_id; - cinfo.peer_id = tunnel_id; + cinfo.to_id = tinfo.destination_gxs_id; + cinfo.own_id = tinfo.source_gxs_id; + cinfo.peer_id = tunnel_id; - switch(tinfo.tunnel_status) - { - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_CAN_TALK : cinfo.status = RS_DISTANT_CHAT_STATUS_CAN_TALK; - break ; - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_TUNNEL_DN: cinfo.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN ; - break ; - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED: cinfo.status = RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED ; - break ; - default: - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_UNKNOWN: cinfo.status = RS_DISTANT_CHAT_STATUS_UNKNOWN; - break ; - } + switch(tinfo.tunnel_status) + { + case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_CAN_TALK : + cinfo.status = RS_DISTANT_CHAT_STATUS_CAN_TALK; break; + case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_TUNNEL_DN: + cinfo.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN; break; + case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED: + cinfo.status = RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED; break; + case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_UNKNOWN: + default: + cinfo.status = RS_DISTANT_CHAT_STATUS_UNKNOWN; break; + } - return true ; + return true; } bool DistantChatService::closeDistantChatConnexion(const DistantChatPeerId &tunnel_id) diff --git a/libretroshare/src/chat/p3chatservice.cc b/libretroshare/src/chat/p3chatservice.cc index 72fc3fde5..eb421ac31 100644 --- a/libretroshare/src/chat/p3chatservice.cc +++ b/libretroshare/src/chat/p3chatservice.cc @@ -292,14 +292,11 @@ void p3ChatService::checkSizeAndSendMessage(RsChatMsgItem *msg) bool p3ChatService::isOnline(const RsPeerId& pid) { - // check if the id is a tunnel id or a peer id. - - DistantChatPeerInfo dcpinfo; - - if(getDistantChatStatus(DistantChatPeerId(pid),dcpinfo)) - return dcpinfo.status == RS_DISTANT_CHAT_STATUS_CAN_TALK ; - else - return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid); + // check if the id is a tunnel id or a peer id. + DistantChatPeerInfo dcpinfo; + if(getDistantChatStatus(DistantChatPeerId(pid),dcpinfo)) + return dcpinfo.status == RS_DISTANT_CHAT_STATUS_CAN_TALK; + else return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid); } bool p3ChatService::sendChat(ChatId destination, std::string msg) @@ -318,8 +315,7 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg) } // destination is peer or distant #ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sendChat()"; - std::cerr << std::endl; + std::cerr << "p3ChatService::sendChat()" << std::endl; #endif RsPeerId vpid; @@ -341,12 +337,12 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg) message.online = true; if(!isOnline(vpid)) - { - /* peer is offline, add to outgoing list */ - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - privateOutgoingList.push_back(ci); - } + { + /* peer is offline, add to outgoing list */ + { + RS_STACK_MUTEX(mChatMtx); + privateOutgoingList.push_back(ci); + } message.online = false; RsServer::notify()->notifyChatMessage(message); diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index 092c8e533..0838bef50 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -1464,7 +1464,7 @@ RsGxsId p3GxsTunnelService::destinationGxsIdFromHash(const TurtleFileHash& sum) bool p3GxsTunnelService::getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info) { - RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ + RS_STACK_MUTEX(mGxsTunnelMtx); std::map::const_iterator it = _gxs_tunnel_contacts.find(tunnel_id) ; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index db7066c9d..1d5817e9a 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -527,7 +527,8 @@ HEADERS += util/folderiterator.h \ util/rstickevent.h \ util/rsrecogn.h \ util/rsscopetimer.h \ - util/stacktrace.h + util/stacktrace.h \ + util/rsdeprecate.h SOURCES += ft/ftchunkmap.cc \ ft/ftcontroller.cc \ @@ -540,7 +541,7 @@ SOURCES += ft/ftchunkmap.cc \ ft/fttransfermodule.cc \ ft/ftturtlefiletransferitem.cc -SOURCES += crypto/chacha20.cpp +SOURCES += crypto/chacha20.cpp SOURCES += chat/distantchat.cc \ chat/p3chatservice.cc \ diff --git a/libretroshare/src/rsserver/p3msgs.cc b/libretroshare/src/rsserver/p3msgs.cc index 38b6c5455..6b8ec7cc8 100644 --- a/libretroshare/src/rsserver/p3msgs.cc +++ b/libretroshare/src/rsserver/p3msgs.cc @@ -79,22 +79,21 @@ ChatId::ChatId(ChatLobbyId id): lobby_id = id; } -ChatId::ChatId(std::string str): - lobby_id(0) +ChatId::ChatId(std::string str) : lobby_id(0) { - type = TYPE_NOT_SET; - if(str.empty()) - return; + type = TYPE_NOT_SET; + if(str.empty()) return; + if(str[0] == 'P') { type = TYPE_PRIVATE; peer_id = RsPeerId(str.substr(1)); - } - else if(str[0] == 'D') - { - type = TYPE_PRIVATE_DISTANT; - distant_chat_id == DistantChatPeerId(str.substr(1)); - } + } + else if(str[0] == 'D') + { + type = TYPE_PRIVATE_DISTANT; + distant_chat_id = DistantChatPeerId(str.substr(1)); + } else if(str[0] == 'L') { if(sizeof(ChatLobbyId) != 8) @@ -401,7 +400,7 @@ bool p3Msgs::resetMessageStandardTagTypes(MsgTagType& tags) /****************************************/ bool p3Msgs::sendChat(ChatId destination, std::string msg) { - return mChatSrv->sendChat(destination, msg); + return mChatSrv->sendChat(destination, msg); } uint32_t p3Msgs::getMaxMessageSecuritySize(int type) diff --git a/libretroshare/src/util/rsdeprecate.h b/libretroshare/src/util/rsdeprecate.h new file mode 100644 index 000000000..4d44e208e --- /dev/null +++ b/libretroshare/src/util/rsdeprecate.h @@ -0,0 +1,34 @@ +#pragma once +/* + * RetroShare deprecation macros + * Copyright (C) 2016 Gioacchino Mazzurco + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +# define RS_DEPRECATED __attribute__((__deprecated__)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1300) +# define RS_DEPRECATED __declspec(deprecated) +#else +# define RS_DEPRECATED +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +# define RS_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead"))) +#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) +# define RS_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead")) +#else +# define RS_DEPRECATED_FOR(f) RS_DEPRECATED +#endif