6f7540d08e580172f40646238f7a18f8c5a0857f
[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
36 //#include "MultiMCLoop.mpp"
37 #define prefix_
38 ///////////////////////////////cc.p////////////////////////////////////////
39
40 typedef senf::UDPv4ClientSocketHandle UDPSocket;
41
42 class MCReader
43 {
44     std::string name;
45     UDPSocket socket;
46     senf::scheduler::FdEvent event;
47
48     void handler(int events);
49
50 public:
51     MCReader(unsigned n, std::string const & name, UDPSocket::Address const & group);
52 };
53
54 prefix_ MCReader::MCReader(unsigned n, std::string const & name_, 
55                            UDPSocket::Address const & group)
56     : name (name_), socket (),
57       event (name, senf::membind(&MCReader::handler, this), socket, 
58              senf::scheduler::FdEvent::EV_READ)
59 {
60     socket.protocol().reuseaddr(true);
61     socket.bind(group);
62     socket.protocol().bindInterface("dummy0");
63     socket.protocol().mcAddMembership(group.address(), "dummy0");
64 }
65
66 prefix_ void MCReader::handler(int events)
67 {
68     std::cout << "I " << name << ": " << socket.read() << "\n";
69 }
70
71 ///////////////////////////////////////////////////////////////////////////
72
73 class MCWriter
74 {
75     std::string name;
76     UDPSocket::Address group;
77     UDPSocket socket;
78     senf::ClockService::clock_type interval;
79     senf::scheduler::TimerEvent event;
80     unsigned count;
81
82     void handler();
83     
84 public:
85     MCWriter(std::string const & name, UDPSocket::Address const & group, 
86              senf::ClockService::clock_type interval);
87 };
88
89 prefix_ MCWriter::MCWriter(std::string const & name_, UDPSocket::Address const & group_,
90                            senf::ClockService::clock_type interval_)
91     : name (name_), group (group_), socket (), interval (interval_),
92       event (name, senf::membind(&MCWriter::handler, this), senf::ClockService::now() + interval),
93       count (0)
94 {}
95
96 prefix_ void MCWriter::handler()
97 {
98     std::stringstream ss;
99     ss << name << "-" << ++count;
100     std::cout << "O " << name << ": " << ss.str() << "\n";
101     socket.writeto(group, ss.str());
102     event.timeout(senf::scheduler::eventTime() + interval);
103 }
104
105 ///////////////////////////////////////////////////////////////////////////
106
107 class IfSetup
108 {
109     std::string iface;
110
111 public:
112     IfSetup(std::string const & iface_);
113     ~IfSetup();
114
115     void sys(std::string const & cmd);
116
117     struct SystemException : public senf::Exception
118     { SystemException() : senf::Exception("IfSetup::SystemException") {} };
119     
120 };
121
122 prefix_ IfSetup::IfSetup(std::string const & iface_)
123     : iface (iface_)
124 {
125     sys((boost::format("ifconfig %s up") % iface).str());
126     sys((boost::format("ifconfig %s 192.168.192.1") % iface).str());
127     sys((boost::format("ip route add 224.0.0.0/4 dev %s") % iface).str());
128 }
129
130 prefix_ IfSetup::~IfSetup()
131 {
132     try {
133         sys((boost::format("ifconfig %s down") % iface).str());
134     }
135     catch (SystemException & ex) {
136         std::cerr << ex.what() << "\n";
137     }
138 }
139
140 prefix_ void IfSetup::sys(std::string const & cmd)
141 {
142     int rv (system(cmd.c_str()));
143     if (rv != 0)
144         throw SystemException() << ": code " << rv << ": " << cmd;
145 }
146
147 ///////////////////////////////////////////////////////////////////////////
148
149 void sigintHandler(siginfo_t const &)
150 {
151     senf::scheduler::terminate();
152 }
153
154 ///////////////////////////////////////////////////////////////////////////
155
156 int main(int argc, char * argv[])
157 {
158     try {
159         IfSetup setup ("dummy0");
160         
161         senf::scheduler::SignalEvent sigint (SIGINT, &sigintHandler);
162
163         UDPSocket::Address g1 ("225.1:43434");
164         UDPSocket::Address g2 ("225.2:43434");
165
166         MCReader r1g1 (1u, "r1g1", g1);
167         MCReader r2g1 (2u, "r2g1", g1);
168         MCReader r1g2 (3u, "r1g2", g2);
169         MCReader r2g2 (4u, "r2g2", g2);
170
171         MCWriter w1g1 ("w1g1", g1, senf::ClockService::milliseconds(600));
172         MCWriter w2g1 ("w2g1", g1, senf::ClockService::milliseconds(800));
173         MCWriter w1g2 ("w1g2", g2, senf::ClockService::milliseconds(700));
174         MCWriter w2g2 ("w2g2", g2, senf::ClockService::milliseconds(900));
175
176         senf::scheduler::process();
177     }
178     catch (std::exception const & ex) {
179         std::cerr << ex.what() << "\n";
180         return 1;
181     }
182 };
183
184 ///////////////////////////////cc.e////////////////////////////////////////
185 #undef prefix_
186 //#include "MultiMCLoop.mpp"
187
188 \f
189 // Local Variables:
190 // mode: c++
191 // fill-column: 100
192 // comment-column: 40
193 // c-file-style: "senf"
194 // indent-tabs-mode: nil
195 // ispell-local-dictionary: "american"
196 // compile-command: "scons -u multimcloop"
197 // End: