Fix documentation build under maverick (doxygen 1.7.1)
[senf.git] / Examples / MultiMCLoop / MultiMCLoop.cc
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program 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
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief MultiMCLoop non-inline non-template implementation */
25
26 //#include "MultiMCLoop.hh"
27 //#include "MultiMCLoop.ih"
28
29 // Custom includes
30 #include <senf/Scheduler/ClockService.hh>
31 #include <senf/Scheduler/Scheduler.hh>
32 #include <senf/Utils/membind.hh>
33 #include <senf/Socket/Protocols/INet.hh>
34 #include <boost/format.hpp>
35 #include <boost/scoped_ptr.hpp>
36
37 //#include "MultiMCLoop.mpp"
38 #define prefix_
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
40
41 typedef senf::UDPv4ClientSocketHandle UDPSocket;
42
43 class MCReader
44 {
45     std::string name;
46     UDPSocket socket;
47     senf::scheduler::FdEvent event;
48
49     void handler(int events);
50
51 public:
52     MCReader(unsigned n, std::string const & name, UDPSocket::Address const & group);
53 };
54
55 prefix_ MCReader::MCReader(unsigned n, std::string const & name_,
56                            UDPSocket::Address const & group)
57     : name (name_), socket (),
58       event (name, senf::membind(&MCReader::handler, this), socket,
59              senf::scheduler::FdEvent::EV_READ)
60 {
61     socket.protocol().reuseaddr(true);
62     socket.bind(group);
63     socket.protocol().bindInterface("dummy0");
64     socket.protocol().mcAddMembership(group.address(), "dummy0");
65 }
66
67 prefix_ void MCReader::handler(int events)
68 {
69     std::cout << "I " << name << ": " << socket.read() << "\n";
70 }
71
72 //-/////////////////////////////////////////////////////////////////////////////////////////////////
73
74 class MCWriter
75 {
76     std::string name;
77     UDPSocket::Address group;
78     UDPSocket socket;
79     senf::ClockService::clock_type interval;
80     senf::scheduler::TimerEvent event;
81     unsigned count;
82
83     void handler();
84
85 public:
86     MCWriter(std::string const & name, UDPSocket::Address const & group,
87              senf::ClockService::clock_type interval);
88 };
89
90 prefix_ MCWriter::MCWriter(std::string const & name_, UDPSocket::Address const & group_,
91                            senf::ClockService::clock_type interval_)
92     : name (name_), group (group_), socket (), interval (interval_),
93       event (name, senf::membind(&MCWriter::handler, this), senf::ClockService::now() + interval),
94       count (0)
95 {}
96
97 prefix_ void MCWriter::handler()
98 {
99     std::stringstream ss;
100     ss << name << "-" << ++count;
101     std::cout << "O " << name << ": " << ss.str() << "\n";
102     socket.writeto(group, ss.str());
103     event.timeout(senf::scheduler::eventTime() + interval);
104 }
105
106 //-/////////////////////////////////////////////////////////////////////////////////////////////////
107
108 class IfSetup
109 {
110     std::string iface;
111
112 public:
113     IfSetup(std::string const & iface_);
114     ~IfSetup();
115
116     void sys(std::string const & cmd);
117
118     struct SystemException : public senf::Exception
119     { SystemException() : senf::Exception("IfSetup::SystemException") {} };
120
121 };
122
123 prefix_ IfSetup::IfSetup(std::string const & iface_)
124     : iface (iface_)
125 {
126     sys((boost::format("ifconfig %s up") % iface).str());
127     sys((boost::format("ifconfig %s 192.168.192.1") % iface).str());
128     sys((boost::format("ip route add 224.0.0.0/4 dev %s") % iface).str());
129 }
130
131 prefix_ IfSetup::~IfSetup()
132 {
133     try {
134         sys((boost::format("ifconfig %s down") % iface).str());
135     }
136     catch (SystemException & ex) {
137         std::cerr << ex.what() << "\n";
138     }
139 }
140
141 prefix_ void IfSetup::sys(std::string const & cmd)
142 {
143     int rv (system(cmd.c_str()));
144     if (rv != 0)
145         throw SystemException() << ": code " << rv << ": " << cmd;
146 }
147
148 //-/////////////////////////////////////////////////////////////////////////////////////////////////
149
150 void sigintHandler(siginfo_t const &)
151 {
152     senf::scheduler::terminate();
153 }
154
155 //-/////////////////////////////////////////////////////////////////////////////////////////////////
156
157 int main(int argc, char * argv[])
158 {
159     try {
160         boost::scoped_ptr<IfSetup> setup (
161             (argc != 2 || std::string(argv[1]) != "-n") ? new IfSetup("dummy0") : 0);
162
163         senf::scheduler::SignalEvent sigint (SIGINT, &sigintHandler);
164
165         UDPSocket::Address g1 ("225.1:43434");
166         UDPSocket::Address g2 ("225.2:43434");
167
168         MCReader r1g1 (1u, "r1g1", g1);
169         MCReader r2g1 (2u, "r2g1", g1);
170         MCReader r1g2 (3u, "r1g2", g2);
171         MCReader r2g2 (4u, "r2g2", g2);
172
173         MCWriter w1g1 ("w1g1", g1, senf::ClockService::milliseconds(600));
174         MCWriter w2g1 ("w2g1", g1, senf::ClockService::milliseconds(800));
175         MCWriter w1g2 ("w1g2", g2, senf::ClockService::milliseconds(700));
176         MCWriter w2g2 ("w2g2", g2, senf::ClockService::milliseconds(900));
177
178         senf::scheduler::process();
179     }
180     catch (std::exception const & ex) {
181         std::cerr << ex.what() << "\n";
182         return 1;
183     }
184 };
185
186 //-/////////////////////////////////////////////////////////////////////////////////////////////////
187 #undef prefix_
188 //#include "MultiMCLoop.mpp"
189
190 \f
191 // Local Variables:
192 // mode: c++
193 // fill-column: 100
194 // comment-column: 40
195 // c-file-style: "senf"
196 // indent-tabs-mode: nil
197 // ispell-local-dictionary: "american"
198 // compile-command: "scons -u multimcloop"
199 // End: