]> git.tdb.fi Git - xinema.git/blob - source/networkinterface.cpp
e5283b6ff96791c068b334e0a42ea1a0d102ad91
[xinema.git] / source / networkinterface.cpp
1 #include <msp/net/inet6.h>
2 #include <msp/net/resolve.h>
3 #include "client.h"
4 #include "networkinterface.h"
5
6 using namespace std;
7 using namespace Msp;
8
9 NetworkInterface::NetworkInterface(Xinema &x):
10         xinema(x)
11 {
12         Net::SockAddr *addr = Net::resolve("::", "34588", Net::INET6);
13         server_sock = new Net::StreamServerSocket(addr->get_family());
14         server_sock->listen(*addr);
15         discover_sock = new Net::DatagramSocket(addr->get_family());
16         discover_sock->bind(*addr);
17         delete addr;
18
19         server_sock->signal_data_available.connect(sigc::mem_fun(this, &NetworkInterface::connection_available));
20         discover_sock->signal_data_available.connect(sigc::mem_fun(this, &NetworkInterface::discover_request));
21
22         event_disp.add(*server_sock);
23         event_disp.add(*discover_sock);
24
25         thread = new NetworkThread(*this);
26 }
27
28 NetworkInterface::~NetworkInterface()
29 {
30         thread->terminate();
31         delete thread;
32         delete server_sock;
33 }
34
35 void NetworkInterface::connection_available()
36 {
37         Net::StreamSocket *sock = server_sock->accept();
38         event_disp.add(*sock);
39         clients.push_back(new Client(xinema, sock));
40 }
41
42 void NetworkInterface::discover_request()
43 {
44         Net::SockAddr *peer_addr;
45         char rbuf[1024];
46         discover_sock->recvfrom(rbuf, sizeof(rbuf), peer_addr);
47         discover_sock->sendto("xinema", 6, *peer_addr);
48         delete peer_addr;
49 }
50
51
52 NetworkInterface::NetworkThread::NetworkThread(NetworkInterface &n):
53         network(n),
54         done(false)
55 {
56         network.event_disp.add(wakeup_pipe);
57         launch();
58 }
59
60 void NetworkInterface::NetworkThread::terminate()
61 {
62         done = true;
63         wakeup_pipe.put('w');
64         join();
65 }
66
67 void NetworkInterface::NetworkThread::main()
68 {
69         while(!done)
70         {
71                 network.event_disp.tick();
72
73                 for(list<Client *>::iterator i=network.clients.begin(); i!=network.clients.end(); )
74                 {
75                         if((*i)->is_stale())
76                         {
77                                 delete *i;
78                                 network.clients.erase(i++);
79                         }
80                         else
81                                 ++i;
82                 }
83         }
84 }