1 /*
2  * This file is part of Wireless Display Software for Linux OS
3  *
4  * Copyright (C) 2014 Intel Corporation.
5  *
6  * Contact: Jussi Laako <jussi.laako@linux.intel.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23 
24 
25 #include <glib.h>
26 #include <glib-unix.h>
27 
28 #include <memory>
29 
30 #include "mirac-network.hpp"
31 
32 
_sig_handler(gpointer data_ptr)33 static gboolean _sig_handler (gpointer data_ptr)
34 {
35     GMainLoop *ml = (GMainLoop *) data_ptr;
36 
37     g_main_loop_quit(ml);
38 
39     return G_SOURCE_CONTINUE;
40 }
41 
42 
_send_cb(gint fd,GIOCondition condition,gpointer data_ptr)43 static gboolean _send_cb (gint fd, GIOCondition condition,
44     gpointer data_ptr)
45 {
46     MiracNetwork *ctx = reinterpret_cast<MiracNetwork *> (data_ptr);
47 
48     try
49     {
50         return ctx->Send() ? G_SOURCE_REMOVE : G_SOURCE_CONTINUE;
51     }
52     catch (std::exception &x)
53     {
54         g_warning("exception: %s", x.what());
55         delete ctx;
56     }
57     return G_SOURCE_REMOVE;
58 }
59 
60 
_receive_cb(gint fd,GIOCondition condition,gpointer data_ptr)61 static gboolean _receive_cb (gint fd, GIOCondition condition,
62     gpointer data_ptr)
63 {
64     MiracNetwork *ctx = reinterpret_cast<MiracNetwork *> (data_ptr);
65 
66     try
67     {
68         std::string msg;
69         if (ctx->Receive(msg))
70         {
71             g_message("message: %s", msg.c_str());
72             if (!ctx->Send(msg))
73                 g_unix_fd_add(ctx->GetHandle(), G_IO_OUT, _send_cb, ctx);
74         }
75     }
76     catch (std::exception &x)
77     {
78         g_warning("exception: %s", x.what());
79         delete ctx;
80         return G_SOURCE_REMOVE;
81     }
82     return G_SOURCE_CONTINUE;
83 }
84 
85 
_listen_cb(gint fd,GIOCondition condition,gpointer data_ptr)86 static gboolean _listen_cb (gint fd, GIOCondition condition, gpointer data_ptr)
87 {
88     try
89     {
90         MiracNetwork *listener = reinterpret_cast<MiracNetwork *> (data_ptr);
91         MiracNetwork *ctx;
92 
93         ctx = listener->Accept();
94         g_message("connection from: %s", ctx->GetPeerAddress().c_str());
95         g_unix_fd_add(ctx->GetHandle(), G_IO_IN, _receive_cb, ctx);
96     }
97     catch (std::exception &x)
98     {
99         g_warning("exception: %s", x.what());
100     }
101     return G_SOURCE_CONTINUE;
102 }
103 
104 
_sendmsg_cb(gint fd,GIOCondition condition,gpointer data_ptr)105 static gboolean _sendmsg_cb (gint fd, GIOCondition condition, gpointer data_ptr)
106 {
107     try
108     {
109         MiracNetwork *ctx = reinterpret_cast<MiracNetwork *> (data_ptr);
110 
111         if (!ctx->Send (std::string("Hello world!\r\n\r\n")))
112             g_unix_fd_add(ctx->GetHandle(), G_IO_OUT, _send_cb, ctx);
113 
114     }
115     catch (std::exception &x)
116     {
117         g_warning("exception %s", x.what());
118     }
119     return G_SOURCE_REMOVE;
120 }
121 
122 
_connect_cb(gint fd,GIOCondition condition,gpointer data_ptr)123 static gboolean _connect_cb (gint fd, GIOCondition condition, gpointer data_ptr)
124 {
125     try
126     {
127         MiracNetwork *ctx = reinterpret_cast<MiracNetwork *> (data_ptr);
128 
129         if (!ctx->Connect(NULL, NULL))
130             return G_SOURCE_CONTINUE;
131         g_message("connection success to: %s", ctx->GetPeerAddress().c_str());
132         g_unix_fd_add(ctx->GetHandle(), G_IO_OUT, _sendmsg_cb, ctx);
133     }
134     catch (std::exception &x)
135     {
136         g_warning("exception: %s", x.what());
137     }
138     return G_SOURCE_REMOVE;
139 }
140 
141 
main(int argc,char * argv[])142 int main (int argc, char *argv[])
143 {
144     GMainLoop *ml = NULL;
145 
146     try
147     {
148         ml = g_main_loop_new(NULL, TRUE);
149         g_unix_signal_add(SIGINT, _sig_handler, ml);
150         g_unix_signal_add(SIGTERM, _sig_handler, ml);
151 
152         std::unique_ptr<MiracNetwork> net_listen(new MiracNetwork);
153         std::unique_ptr<MiracNetwork> net_conn(new MiracNetwork);
154 
155         net_listen->Bind("127.0.0.1", "8080");
156         g_message("bound to port %hu", net_listen->GetHostPort());
157         g_unix_fd_add(net_listen->GetHandle(), G_IO_IN, _listen_cb,
158             net_listen.get());
159 
160         if (net_conn->Connect("127.0.0.1", "8080"))
161             g_unix_fd_add(net_conn->GetHandle(), G_IO_OUT, _sendmsg_cb,
162                 net_conn.get());
163         else
164             g_unix_fd_add(net_conn->GetHandle(), G_IO_OUT, _connect_cb,
165                 net_conn.get());
166 
167         g_main_loop_run(ml);
168     }
169     catch (std::exception &x)
170     {
171         g_error("exception: %s", x.what());
172     }
173 
174     if (ml)
175         g_main_loop_unref(ml);
176 
177     return 0;
178 }
179 
180