1 /*
2  * Copyright 2017 CodiLime
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 #pragma once
18 
19 #include <cstdint>
20 #include <iostream>
21 #include <map>
22 #include <memory>
23 #include <random>
24 #include <set>
25 #include <unordered_map>
26 #include <unordered_set>
27 
28 #include <QSslSocket>
29 #include <QString>
30 
31 #include "data/nodeid.h"
32 #include "network/msgpackwrapper.h"
33 
34 namespace veles {
35 namespace client {
36 
37 const QString SCHEME_UNIX("veles+unix");
38 const QString SCHEME_TCP("veles");
39 const QString SCHEME_SSL("veles+ssl");
40 
41 class NodeTree;
42 
43 using pair_str = std::pair<bool, std::shared_ptr<std::string>>;
44 using msg_ptr = std::shared_ptr<proto::MsgpackMsg>;
45 
46 /*****************************************************************************/
47 /* NetworkClient */
48 /*****************************************************************************/
49 
50 class NetworkClient : public QObject {
51   Q_OBJECT
52 
53  public:
54   enum class ConnectionStatus { NotConnected, Connecting, Connected };
55   static QString connStatusStr(ConnectionStatus status);
56 
57   explicit NetworkClient(QObject* parent = nullptr);
58   ~NetworkClient() override;
59   ConnectionStatus connectionStatus();
60   void connect(const QString& server_url, const QString& client_name,
61                const QString& client_version, const QString& client_description,
62                const QString& client_type, bool quit_on_close);
63   void disconnect();
64   std::unique_ptr<NodeTree> const& nodeTree();
65   uint64_t nextQid();
66 
67   QString serverHostName();
68   int serverPort();
69   QString clientInterfaceName();
70   unsigned int protocolVersion();
71   QString clientName();
72   QString clientVersion();
73   QString clientDescription();
74   QString clientType();
75   QString authenticationKey();
76 
77   QTextStream* output();
78   void setOutput(QTextStream* stream);
79 
80   void sendMsgConnect();
81   virtual void registerMessageHandlers();
82   virtual void handleNodeTreeRelatedMessage(const msg_ptr& msg);
83   virtual void handleConnectedMessage(const msg_ptr& msg);
84   virtual void handleProtoErrorMessage(const msg_ptr& msg);
85   virtual void handleConnectionsMessage(const msg_ptr& msg);
86   virtual void handleRegistryReplyMessage(const msg_ptr& msg);
87   virtual void handleMthdResMessage(const msg_ptr& msg);
88   virtual void handlePluginTriggerRunMessage(const msg_ptr& msg);
89   virtual void handleConnErrorMessage(const msg_ptr& msg);
90   virtual void handlePluginMethodRunMessage(const msg_ptr& msg);
91   virtual void handlePluginQueryGetMessage(const msg_ptr& msg);
92   virtual void handleBroadcastRunMessage(const msg_ptr& msg);
93   virtual void handlePluginHandlerUnregisteredMessage(const msg_ptr& msg);
94 
95   using MessageHandler = void (NetworkClient::*)(const msg_ptr&);
96 
97  signals:
98   void connectionStatusChanged(ConnectionStatus connection_status);
99   void messageReceived(const msg_ptr& message);
100 
101  public slots:
102   void sendMessage(const msg_ptr& msg);
103   void setConnectionStatus(ConnectionStatus connection_status);
104   void socketConnected();
105   void socketDisconnected();
106   void newDataAvailable();
107   void socketError(QAbstractSocket::SocketError socketError);
108   void checkFingerprint(const QList<QSslError>& errors);
109 
110  private:
111   QSslSocket* client_socket_ = nullptr;
112   std::unique_ptr<NodeTree> node_tree_;
113   ConnectionStatus status_;
114 
115   QString server_name_;
116   uint16_t server_port_;
117 
118   unsigned int protocol_version_;
119   QString client_name_;
120   QString client_version_;
121   QString client_description_;
122   QString client_type_;
123   QByteArray authentication_key_;
124   QString fingerprint_;
125   bool quit_on_close_;
126   bool ssl_enabled_;
127 
128   messages::MsgpackWrapper msgpack_wrapper_;
129   std::unordered_map<std::string, MessageHandler> message_handlers_;
130 
131   QTextStream* output_stream_ = nullptr;
132   uint64_t qid_;
133 };
134 
135 }  // namespace client
136 }  // namespace veles
137 
138 Q_DECLARE_METATYPE(veles::client::NetworkClient::ConnectionStatus)
139