1 // Copyright (C) 2008 Ole Laursen
2 // Copyright (C) 2011, 2014, 2015, 2017 Ben Asselstine
3 //
4 //  This program is free software; you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation; either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU Library General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 //  02110-1301, USA.
18 
19 #pragma once
20 #ifndef NETWORK_CONNECTION_H
21 #define NETWORK_CONNECTION_H
22 
23 #include <config.h>
24 
25 #include <queue>
26 #include <sigc++/signal.h>
27 #include <glibmm.h>
28 #include <giomm.h>
29 #include <gtkmm.h>
30 #include <glibmm/threads.h>
31 #include "network-common.h"
32 #include <mutex>
33 #include <condition_variable>
34 
35 //! A simple network connection for sending messages, encapsulates the protocol
36 class NetworkConnection
37 {
38 public:
39 
40   NetworkConnection(const Glib::RefPtr<Gio::SocketConnection> &conn);
41   NetworkConnection();
42   ~NetworkConnection();
43 
44   void connectToHost(Glib::ustring host, int port);
45 
46   sigc::signal<void> connected;
47   sigc::signal<void> connection_lost;
48   sigc::signal<void> connection_failed;
49   sigc::signal<void> connection_received_data;
50   sigc::signal<bool, int, Glib::ustring> got_message;
51   sigc::signal<void> queue_flushed;
52   sigc::signal<void> torn_down;
53 
54   void send(int type, const Glib::ustring &payload);
55   void sendFile(int type, const Glib::ustring &filename);
56   Glib::ustring get_peer_hostname();
57 
58   void tear_down_connection(bool lockit = false);
59   void disconnect();
getHost()60   Glib::ustring getHost() const {return d_host;};
getPort()61   guint32 getPort() const {return d_port;};
62 
63   void send_queued_messages();
64 
65 private:
66   Glib::RefPtr<Gio::SocketClient> client; //this is client-side connections.
67   Glib::RefPtr<Gio::SocketConnection> conn;
68   Glib::RefPtr<Gio::DataInputStream> in;
69   Glib::RefPtr<Gio::DataOutputStream> out;
70   Glib::RefPtr<Gio::SocketSource> source;
71   sigc::connection d_connect_timer;
72   sigc::connection d_in_cb;
73   char *payload;
74   int payload_left;
75   int payload_size;
76   char header[MESSAGE_SIZE_BYTES];
77   int header_left;
78   int header_size;
79   Glib::ustring d_host;
80   guint32 d_port;
81 
82   std::mutex mutex;
83   std::condition_variable cond_push;
84   std::condition_variable cond_pop;
85 
86   bool d_stop;
87   bool d_bail;
88   Glib::RefPtr<Gio::Cancellable> d_cancellable;
89 
90   struct Message
91     {
92       int type;
93       Glib::ustring payload;
94     };
95   std::queue<struct Message> messages;
96 
97   void setup_connection();
98   void on_connect_connected(Glib::RefPtr<Gio::AsyncResult> &result);
99   gssize on_header_received(gssize len);
100   gssize on_payload_received(gssize len);
101   bool on_got_input(Glib::IOCondition cond);
102   bool on_connect_timeout();
103 
104   void queue_message(int type, const Glib::ustring &payload);
105   bool sendMessage(int type, const Glib::ustring &payload);
106   void sendFileMessage(int type, Glib::ustring filename);
107 
108 };
109 
110 #endif
111