EmulatedWirelessInterface.hh
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #ifndef HH_SENF_Ext_NetEmu_EmulatedWirelessInterface_
18 #define HH_SENF_Ext_NetEmu_EmulatedWirelessInterface_ 1
19 
20 // Custom includes
21 #include <boost/signals2.hpp>
22 #include <boost/multi_index_container.hpp>
23 #include <boost/multi_index/ordered_index.hpp>
24 #include <boost/multi_index/composite_key.hpp>
29 #include <senf/Utils/singleton.hh>
30 #include "WirelessInterfaceAPI.hh"
31 #include "EmulatedInterface.hh"
32 #include "Annotations.hh"
33 
35 //-/////////////////////////////////////////////////////////////////////////////////////////////////
36 
37 namespace senf {
38 namespace emu {
39 
73  : public senf::singleton<EmulatedFrequencyRegistry>
74  {
76 
77  public:
78  typedef boost::function<void (UDPClientHandle::Address const & address)> UserCallback;
80  typedef boost::function<void (unsigned frequency, unsigned bandwidth)> CollisionCallback;
82 
84  struct Entry
85  {
86  unsigned frequency;
87  unsigned bandwidth;
88  UDPClientHandle::Address address;
89  unsigned nUsers;
90  unsigned ownerNodeId;
91 
92  private:
93  Entry();
94  Entry(unsigned frequency_, unsigned bandwidth_);
95  Entry(unsigned frequency_, unsigned bandwidth_, UDPClientHandle::Address address_,
96  unsigned nUsers_, unsigned ownerNodeId_);
97 
99  };
100 
101  private:
102  struct ByFrequency {};
103  struct ByAddress {};
104 
105  // The ByAddress index really is unique except for the 'None' address, which may occur
106  // more than once
107  struct EntryIndices
108  : public boost::multi_index::indexed_by<
109  boost::multi_index::ordered_unique<
110  boost::multi_index::tag<ByFrequency>,
111  boost::multi_index::composite_key<
112  Entry,
113  boost::multi_index::member<Entry, unsigned, &Entry::frequency>,
114  boost::multi_index::member<Entry, unsigned, &Entry::bandwidth> > >,
115  boost::multi_index::ordered_non_unique<
116  boost::multi_index::tag<ByAddress>,
117  boost::multi_index::member<Entry, UDPClientHandle::Address, &Entry::address> >
118  >
119  {};
120 
121  typedef boost::multi_index_container<Entry, EntryIndices> Entries;
122 
123  struct User
124  {
126  unsigned interfaceId;
127  mutable UserCallback callback;
128 
129  User();
130  User(Entries::index_iterator<ByFrequency>::type entry_, unsigned interfaceId_,
131  UserCallback callback_);
132  };
133 
134  struct ByInterfaceId {};
135  struct ByEntry {};
136 
137  // Since the multi_index_container iterators are not comparable, we sort the ByEntry index
138  // using the address of the Entry referenced by the 'entry' iterator. Additional overloads
139  // allow searching either by iterator or by Entry address.
140  struct AddrCompare
141  {
145  Entry const * b) const;
146  bool operator()(Entry const * a,
148  };
149 
150  struct UserIndices
151  : public boost::multi_index::indexed_by<
152  boost::multi_index::ordered_unique<
153  boost::multi_index::tag<ByInterfaceId>,
154  boost::multi_index::member<User, unsigned, &User::interfaceId> >,
155  boost::multi_index::ordered_non_unique<
156  boost::multi_index::tag<ByEntry>,
157  boost::multi_index::member<
158  User, Entries::index_iterator<ByFrequency>::type, &User::entry>,
159  AddrCompare>
160  >
161  {};
162 
163  typedef boost::multi_index_container<User, UserIndices> Users;
164 
165  typedef boost::multi_index::member<User, unsigned, &User::interfaceId> GetInterfaceId;
166  typedef boost::transform_iterator<
167  GetInterfaceId, Users::index_iterator<ByEntry>::type> InterfaceIdIterator;
168 
169  public:
172  typedef boost::iterator_range<InterfaceIdIterator> UsersRange;
174 
177 
178  UDPClientHandle::Address consoleGroup() const;
180  void consoleGroup(UDPClientHandle::Address const & group);
182 
183  std::pair<INet4Network, unsigned> addressRange() const;
185 
193  void addressRange(INet4Network const & range, unsigned portbase);
195 
196  void nextAddress(unsigned index);
197 
201  void allocate(unsigned interfaceId, unsigned frequency, unsigned bandwidth, UserCallback cb);
203 
211  void release(unsigned interfaceId);
213 
215  void collisionCallback(CollisionCallback cb);
217 
224  void schedulerStart();
225  void start();
226  void stop();
227 
230  EntriesRange entries() const;
231  UsersRange users(EntriesRange::iterator i) const;
233 
234  enum ChangeType { JOIN, LEAVE, STOP };
236  Entry const &, unsigned nodeId, ChangeType type)> channelPopulationChanged;
238 
241  protected:
242 
243  private:
245 
246  // User console commands
247  void consoleList(std::ostream & os) const;
248 
249  // IPC console commands
250  void add(unsigned nodeId, unsigned frequency, unsigned bandwidth,
251  UDPClientHandle::Address address);
252  void del(unsigned nodeId, unsigned frequency, unsigned bandwidth);
253  void join(unsigned nodeId, unsigned frequency, unsigned bandwidth);
254  void leave(unsigned nodeId, unsigned frequency, unsigned bandwidth);
255  int poll(unsigned nodeId, unsigned frequency, unsigned bandwidth);
256 
257  // Sending console commands to other nodes
258  void sendAdd(unsigned nodeId, unsigned frequency, unsigned bandwidth,
259  UDPClientHandle::Address address);
260  void sendDel(unsigned nodeId, unsigned frequency, unsigned bandwidth);
261  void sendJoin(unsigned nodeId, unsigned frequency, unsigned bandwidth);
262  void sendLeave(unsigned nodeId, unsigned frequency, unsigned bandwidth);
263  void sendPoll(unsigned nodeId, unsigned frequency, unsigned bandwidth);
264 
265  UDPClientHandle::Address getAddress();
266  void updateAddress(Entry const & entry);
267  void checkCollisionOk(unsigned frequency, unsigned bandwidth);
268 
270  UDPClientHandle socket_;
271  UDPClientHandle::Address group_;
272  boost::scoped_ptr<console::UDPServer> server_;
273  scheduler::IdleEvent schedulerStart_;
274  INet4Network channelGroupRange_;
275  unsigned portbase_;
276  unsigned lastAddress_;
277  Entries entries_;
278  Users users_;
279  bool running_;
280  CollisionCallback cb_;
281 
283  };
284 
285  EmulatedFrequencyRegistry & emulatedFrequencyRegistry();
286 
287  //-////////////////////////////////////////////////////////////////////////
288 
291 
303  : public EmulatedInterface,
304  public detail::InterfaceAccess<WirelessInterface>,
305  public detail::CommfaceAccess<EmulatedWirelessReceiver, EmulatedWirelessTransmitter>
306  {
307  public:
308  using detail::InterfaceAccess<WirelessInterface>::interface;
309  using detail::CommfaceAccess<EmulatedWirelessReceiver, EmulatedWirelessTransmitter>::receiver;
310  using detail::CommfaceAccess<EmulatedWirelessReceiver, EmulatedWirelessTransmitter>::transmitter;
311 
312  typedef std::vector<console::ValueRange<unsigned> > Ranges;
313  typedef boost::function<double (unsigned nodeId)> DistanceCallback;
314 
316 
317  void registerFrequency(unsigned frequency, unsigned bandwidth);
319  void registerFrequency(unsigned frequencyLower, unsigned frequencyUpper,
320  unsigned bandwidthLower,unsigned bandwidthUpper);
322  void registerFrequency(Ranges const & frequencies, Ranges const & bandwidths);
324 
329  void distanceCallback(DistanceCallback cb); //register the distance cb
330 
331  protected:
333  void init();
334 
335  unsigned emulatedFrequency() const;
336  unsigned emulatedBandwidth() const;
337  void emulatedFrequency(unsigned frequency, unsigned bandwidth);
339 
341  void emulatedCoverageRange(unsigned distance);
342 
343  private:
344  unsigned frequency_;
345  unsigned bandwidth_;
346  unsigned index_;
347 
349  DistanceCallback distanceCallback_;
351  };
352 
358  : public EmulatedReceiver,
359  public detail::InterfaceAccess<WirelessInterface>,
360  public detail::InterfaceAccess<EmulatedWirelessInterface>
361  {
362  public:
363  typedef detail::InterfaceAccess<EmulatedWirelessInterface> emui;
364  typedef detail::InterfaceAccess<WirelessInterface> basei;
365 
366  protected:
368 
370  void init();
371 
372  virtual bool v_emulatedWirelessQuality(Packet packet, annotations::Quality & quality);
374 
384  private:
385  detail::EmulatedWirelessInterfaceReceiveFilter filter_;
386 
387  unsigned rssiRandomnessRange_;
388  unsigned noiseRandomnessRange_;
389 
390  friend class detail::EmulatedWirelessInterfaceReceiveFilter;
391  };
392 
398  : public EmulatedTransmitter,
399  public detail::InterfaceAccess<WirelessInterface>,
400  public detail::InterfaceAccess<EmulatedWirelessInterface>
401  {
402  public:
403  typedef detail::InterfaceAccess<EmulatedWirelessInterface> emui;
404  typedef detail::InterfaceAccess<WirelessInterface> basei;
405 
406  typedef std::vector< console::ValueRange<int> > Ranges;
407 
408  void registerTxPower(int power);
409  void registerTxPower(int powerLow, int powerHigh);
410  void registerTxPower(Ranges const & powers);
411 
413  protected:
415 
417  void init();
418 
419  private:
420  detail::EmulatedWirelessInterfaceTransmitFilter filter_;
421  };
422 
423 }}
424 
425 //-/////////////////////////////////////////////////////////////////////////////////////////////////
427 //#include "EmulatedWirelessInterface.ct"
428 //#include "EmulatedWirelessInterface.cti"
429 #endif
430 
431 
432 // Local Variables:
433 // mode: c++
434 // fill-column: 100
435 // comment-column: 40
436 // c-file-style: "senf"
437 // indent-tabs-mode: nil
438 // ispell-local-dictionary: "american"
439 // compile-command: "scons -u test"
440 // End:
void allocate(unsigned interfaceId, unsigned frequency, unsigned bandwidth, UserCallback cb)
Register for a wireless channel.
WirelessInterfaceAPI public header.
void init()
std::vector< console::ValueRange< int > > Ranges
Emulated interface base-class for transmit capable interfaces.
detail::InterfaceAccess< EmulatedWirelessInterface > emui
detail::InterfaceAccess< EmulatedWirelessInterface > emui
boost::iterator_range< InterfaceIdIterator > UsersRange
Iterator range of interface id&#39;s using a channel.
u8 type
#define SENF_LOG_CLASS_AREA()
Emulated wireless receiver base-class.
Emulated wireless transmitter base-class.
void nextAddress(unsigned index)
Set next address index to use (if free)
EmulatedInterface public header.
unsigned nUsers
Number of active channel users.
detail::InterfaceAccess< WirelessInterface > basei
Annotations public header.
Emulated interface base-class.
UDPClientHandle::Address consoleGroup() const
Get control channel multicast group/port.
UDPClientHandle::Address address
Assigned multicast address.
StatsDataCollectorKernel signal
boost::iterator_range< Entries::index_iterator< ByFrequency >::type > EntriesRange
Iterator range of channel entries.
ppi::connector::ActiveOutputJack receiverJack
EmulatedFrequencyRegistry & emulatedFrequencyRegistry()
std::vector< console::ValueRange< unsigned > > Ranges
Emulated interface base-class for receive capable interfaces.
boost::signals2::signal< void(Entry const &, unsigned nodeId, ChangeType type)> channelPopulationChanged
Channel population changed signal.
std::pair< INet4Network, unsigned > addressRange() const
Get address/port range of channel multicast addresses.
Emulated wireless interface base-class.
boost::function< void(unsigned frequency, unsigned bandwidth)> CollisionCallback
Callback type called for channel collisions.
void start()
Start multicast address/port allocation.
ppi::connector::PassiveInputJack transmitterJack
void release(unsigned interfaceId)
Release channel registration.
UsersRange users(EntriesRange::iterator i) const
Get interface id&#39;s of local users of a given channel.
senf::UDPv4ClientSocketHandle UDPClientHandle
void stop()
Stop multicast address/port allocation.
void collisionCallback(CollisionCallback cb)
Change collision callback.
boost::function< double(unsigned nodeId)> DistanceCallback
boost::function< void(UDPClientHandle::Address const &address)> UserCallback
Callback type called to set channel address.
EntriesRange entries() const
Get all channel entries.
detail::InterfaceAccess< WirelessInterface > basei