21 #include <boost/lambda/lambda.hpp>    22 #include <boost/lambda/bind.hpp>    34 prefix_ void senf::emu::detail::EmulatedWirelessInterfaceTransmitFilter::request()
    37     if (iface_.basei::interface().modulationParameterIds().empty())
    40     h->modulationId() = iface_.basei::interface().transmitter().modulation();
    41     h->txPower() = iface_.basei::interface().transmitter().txPower() / 100;
    42     h->frequency() = iface_.basei::interface().frequency();
    43     h->bandwidth() = iface_.basei::interface().bandwidth();
    51 prefix_ void senf::emu::detail::EmulatedWirelessInterfaceReceiveFilter::request()
    56     if (iface_.basei::interface().frequency() != p->frequency() ||
    57         iface_.basei::interface().bandwidth() != p->bandwidth()) 
return;
    62     if (! senf::contains(iface_.basei::interface().modulationParameterIds(), p->modulationId())) {
    66     p.annotation<annotations::WirelessModulation>().
id = p->modulationId();
    67     if (! iface_.v_emulatedWirelessQuality(n, p.annotation<annotations::Quality>()))
    80     namespace l = boost::lambda;
    81     using boost::lambda::_1;
    83     checkCollisionOk(frequency, bandwidth);
    86         entries_.get<ByFrequency>().find(boost::make_tuple(frequency,bandwidth)));
    87     if (i == entries_.end()) {
    88         Entry e (frequency, bandwidth);
    94         i = entries_.insert(e).first;
    96     users_.insert(User(i, interfaceId, cb));
   103     if (! server_ && group_)
   109     namespace l = boost::lambda;
   110     using boost::lambda::_1;
   114                  "senf::emu::EmulatedFrequencyRegistry::release(): "   115                  "No registration for interface" );
   117     if (i->entry->nUsers > 0 && running_) {
   123         entries_.get<ByFrequency>().erase(i->entry);
   131 prefix_ senf::emu::EmulatedFrequencyRegistry::EmulatedFrequencyRegistry()
   132     : socket_ (), group_ (
"239.202.104.1:4701"), server_ (),
   133       schedulerStart_ (
"senf::emu::EmulatedFrequencyRegistry::schedulerStart",
   136       entries_ (), users_ (), running_ (
false)
   138     namespace fty = console::factory;
   140     console::sysdir().add(
"emu", dir_);
   142     dir_.
add(
"consoleGroup",
   145     dir_.
add(
"consoleGroup",
   149     typedef std::pair<INet4Network, unsigned> AddressPair;
   150     dir_.
add(
"addressRange",
   153     dir_.
add(
"addressRange",
   157     dir_.
add(
"list", fty::Command(&EmulatedFrequencyRegistry::consoleList, 
this));
   161     ipcdir.
add(
"add", fty::Command(&EmulatedFrequencyRegistry::add, 
this));
   162     ipcdir.add(
"del", fty::Command(&EmulatedFrequencyRegistry::del, 
this));
   163     ipcdir.add(
"join", fty::Command(&EmulatedFrequencyRegistry::join, 
this));
   164     ipcdir.add(
"leave", fty::Command(&EmulatedFrequencyRegistry::leave, 
this));
   165     ipcdir.add(
"poll", fty::Command(&EmulatedFrequencyRegistry::poll, 
this));
   175         server_->root(dir_[
"ipc"]).emptyReplies(
false);
   179 prefix_ void senf::emu::EmulatedFrequencyRegistry::consoleList(std::ostream & os)
   182     boost::format fmt (
"%10d %10d  %-21s%5d %10d ");
   183     os << fmt % 
"FREQUENCY" % 
"BANDWIDTH" % 
"ADDRESS" % 
"NODES" % 
"OWNER" << 
" USERS\n";
   185     for (EntriesRange::iterator i (e.begin()); i != e.end(); ++i) {
   193         for (UsersRange::iterator j (u.begin()); j != u.end(); ++j)
   197     os << (running_ ? 
" running\n" : 
" halted\n");
   200 prefix_ void senf::emu::EmulatedFrequencyRegistry::add(
unsigned nodeId, 
unsigned frequency,
   202                                                        UDPClientHandle::Address address)
   204     namespace l = boost::lambda;
   205     using boost::lambda::_1;
   211         entries_.get<ByFrequency>().find(boost::make_tuple(frequency,bandwidth)));
   214     if (fi != entries_.get<ByFrequency>().end()
   215         && ai != entries_.get<ByAddress>().end()
   218         if (nodeId < fi->ownerNodeId)
   223     if (ai != entries_.get<ByAddress>().end()) {
   228         if (nodeId < ai->ownerNodeId) {
   229             UDPClientHandle::Address newAddr;
   233                 newAddr = getAddress();
   236             entries_.get<ByAddress>().modify_key(ai, _1 = newAddr);
   243     if (fi != entries_.get<ByFrequency>().end()) {
   246         if (! fi->address || (fi->address != address && nodeId <= fi->ownerNodeId)) {
   247             entries_.get<ByFrequency>().modify(
   253         entries_.insert(
Entry(frequency, bandwidth, address, 0, nodeId));
   256 prefix_ void senf::emu::EmulatedFrequencyRegistry::del(
unsigned nodeId, 
unsigned frequency,
   259     namespace l = boost::lambda;
   260     using boost::lambda::_1;
   266         entries_.get<ByFrequency>().find(boost::make_tuple(frequency,bandwidth)));
   267     if (i == entries_.get<ByFrequency>().end())
   270     if (nodeId != i->ownerNodeId)
   272     if (users_.get<ByEntry>().count(i) > 0) {
   274                      "Active entry " << frequency << 
"," << bandwidth <<
   275                      " removed by " << nodeId));
   276         entries_.get<ByFrequency>().modify(
   282         entries_.get<ByFrequency>().erase(i);
   285 prefix_ void senf::emu::EmulatedFrequencyRegistry::join(
unsigned nodeId, 
unsigned frequency,
   288     namespace l = boost::lambda;
   289     using boost::lambda::_1;
   295         entries_.get<ByFrequency>().find(boost::make_tuple(frequency,bandwidth)));
   296     if (i == entries_.end()) {
   299         i = entries_.insert(
Entry(frequency, bandwidth, UDPClientHandle::Address(), 1, 0)).first;
   306 prefix_ void senf::emu::EmulatedFrequencyRegistry::leave(
unsigned nodeId, 
unsigned frequency,
   309     namespace l = boost::lambda;
   310     using boost::lambda::_1;
   316         entries_.get<ByFrequency>().find(boost::make_tuple(frequency,bandwidth)));
   317     if (i == entries_.end())
   323     if (i->nUsers == 0 && (i->ownerNodeId == 
Interface::nodeId() || i->ownerNodeId == 0)) {
   324         if (users_.get<ByEntry>().count(i) > 0) {
   326                          "Disabling active entry " << frequency << 
"," << bandwidth <<
   329                 entries_.get<ByFrequency>().modify(
   338             entries_.get<ByFrequency>().erase(i);
   343 prefix_ int senf::emu::EmulatedFrequencyRegistry::poll(
unsigned nodeId, 
unsigned frequency,
   350         entries_.get<ByFrequency>().find(boost::make_tuple(frequency,bandwidth)));
   351     if (i == entries_.end())
   354         users_.get<ByEntry>().equal_range(i));
   355     return std::distance(e.first, e.second);
   360     namespace l = boost::lambda;
   361     using boost::lambda::_1;
   363     if (! server_ && group_)
   368     for (Entries::iterator i (entries_.begin()), i_end (entries_.end()); i != i_end; ++i) {
   369         unsigned users (users_.get<ByEntry>().count(i));
   371             if (! i->ownerNodeId && ! i->address) {
   389     namespace l = boost::lambda;
   390     using boost::lambda::_1;
   395     if (entries_.empty()) {
   399     Entries::iterator i (entries_.begin());
   400     Entries::iterator i_next (boost::next(i));
   401     Entries::iterator 
const i_end (entries_.end());
   402     for (;i != i_end; i = i_next, ++ i_next) {
   403         entries_.modify(i, (l::bind(&
Entry::address,_1) = UDPClientHandle::Address(),
   407         if (users_.get<ByEntry>().count(i) == 0)
   415 prefix_ void senf::emu::EmulatedFrequencyRegistry::sendAdd(
unsigned nodeId, 
unsigned frequency,
   417                                                            UDPClientHandle::Address address)
   419     socket_.writeto(group_, (boost::format(
"add %d %d %d %s")
   420                              % nodeId % frequency % bandwidth % address).
str());
   423 prefix_ void senf::emu::EmulatedFrequencyRegistry::sendDel(
unsigned nodeId, 
unsigned frequency,
   426     socket_.writeto(group_, (boost::format(
"del %d %d %d")
   427                              % nodeId % frequency % bandwidth).
str());
   430 prefix_ void senf::emu::EmulatedFrequencyRegistry::sendJoin(
unsigned nodeId,
   434     socket_.writeto(group_, (boost::format(
"join %d %d %d")
   435                              % nodeId % frequency % bandwidth).
str());
   438 prefix_ void senf::emu::EmulatedFrequencyRegistry::sendLeave(
unsigned nodeId,
   442     socket_.writeto(group_, (boost::format(
"leave %d %d %d")
   443                              % nodeId % frequency % bandwidth).
str());
   446 prefix_ void senf::emu::EmulatedFrequencyRegistry::sendPoll(
unsigned nodeId,
   450     socket_.writeto(group_, (boost::format(
"poll %d %d %d")
   451                              % nodeId % frequency % bandwidth).
str());
   454 prefix_ senf::emu::UDPClientHandle::Address senf::emu::EmulatedFrequencyRegistry::getAddress()
   457         lastAddress_ = (lastAddress_+1) & ((1u<<(32-channelGroupRange_.
prefix_len()))-1);
   458         UDPClientHandle::Address addr (channelGroupRange_.
host(lastAddress_),
   459                                        portbase_ + lastAddress_);
   461             entries_.get<ByAddress>().find(addr));
   462         if (i == entries_.get<ByAddress>().end())
   465     return UDPClientHandle::Address();
   468 prefix_ void senf::emu::EmulatedFrequencyRegistry::updateAddress(
Entry const & entry)
   471     boost::tie(i, i_end) = users_.get<ByEntry>().equal_range(&entry);
   472     for (; i != i_end; ++i)
   478     inline bool frequencyOverlap(
unsigned f1, 
unsigned  b1, 
unsigned  f2, 
unsigned b2)
   480         return 2*f1-b1 <= 2*f2+b2 && 2*f2-b2 <= 2*f1+b1;
   485 prefix_ void senf::emu::EmulatedFrequencyRegistry::checkCollisionOk(
unsigned frequency,
   491              i_end (entries_.get<ByFrequency>().end()); i != i_end; ++i)
   492         if (frequencyOverlap(frequency, bandwidth, i->frequency, i->bandwidth)) {
   493             cb_(frequency, bandwidth);
   510                                                                      Ranges const & bandwidths)
   512     for (Ranges::const_iterator i (frequencies.begin()), i_end (frequencies.end()); i != i_end; ++i)
   513         for (Ranges::const_iterator j (bandwidths.begin()), j_end (bandwidths.end()); j != j_end; ++j)
   514             registerFrequency(i->lower, i->upper, j->lower, j->upper);
   521     namespace fty = console::factory;
   522     interface().consoleDir()
   523         .add(
"registerFrequency",
   526              .arg(
"frequencies",
"channel frequencies in kHz")
   527              .arg(
"bandwidths", 
"channel bandwidths in kHz")
   528              .doc(
"Register valid frequency/bandwidth combinations.\n"   529                   "Both parameters /frequencies/ and /bandwidths/ may be either a single value or\n"   530                   "range or a list of values or ranges.\n"   532                   "The statement will register all combinations of any frequency with any bandwidth.\n"   535                   "    registerFrequency 2412000 20000;\n"   536                   "        Register a single frequency/bandwidth combination.\n"   538                   "    registerFrequency 1000000:2000000 5000:20000;\n"   539                   "        Register a single frequency/bandwidth range combination.\n"   541                   "    registerFrequency (2412000 2417000 2422000) 20000;\n"   542                   "        Register 3 frequency/bandwidth combinations;\n"   544                   "    registerFrequency (1000000:2000000 3000000:4000000) (5000 10000:12000 20000);"   545                   "        Register 6 frequency/bandwidth combinations.") );
   551     frequency_ = frequency;
   552     bandwidth_ = bandwidth;
   554     index_ = interface().index();
   556         index_, frequency, bandwidth,
   558                         emulationAddress, (UDPClientHandle::Address 
const &)));
   573     namespace fty = console::factory;
   575     (*this).basei::interface().consoleDir()
   576         .add(
"rssiRandomnessRange",
   577                 fty::Variable(rssiRandomnessRange_)
   578         .doc(
"Set the range of the random variation of the RSSI value") );
   579     (*this).basei::interface().consoleDir()
   580         .add(
"noiseRandomnessRange",
   581                 fty::Variable(noiseRandomnessRange_)
   582         .doc(
"Set the range of the random variation of the Noise value") );
   591     if (!emui::interface().distanceCallback_) {
   599     double d = emui::interface().distanceCallback_(ph->nodeId());
   607     unsigned f = (*this).basei::interface().frequency();
   613     double fsl = 20 * log10( 4*d*M_PI*f/3.0e2);
   615     short rssi = short(ewph->txPower()-fsl);
   617     if (rssiRandomnessRange_ != 0)
   618         rssi += rand() % rssiRandomnessRange_; 
   620     if (rssi <= minRssi) {
   623                    "minRSSI " << minRssi  << 
"\n"   624                 << 
"txpower: " << ewph->txPower() << 
"\n"   625                 << 
"frequency (in KHz): " << f<< 
"\n"   626                 << 
"transmitter node:" << ph->nodeId() << 
"\n"   627                 << 
"distance " << emui::interface().distanceCallback_(ph->nodeId()) << 
" km\n"   628                 << 
"Free Space Loss: " << fsl << 
" dB\n"   629                 << 
"RSSI: " << rssi << 
" dB\n") );
   633     int defaultNoiseValue = -110;
   634     if (noiseRandomnessRange_ !=0)
   635         defaultNoiseValue=defaultNoiseValue + (rand()%noiseRandomnessRange_);
   639     quality.
noise = defaultNoiseValue;
   643     quality.
flags.
frameCorrupt = (rand() % ((rssi-minRssi)*(rssi-minRssi))) > 1 ? false : 
true;
   654     for (Ranges::const_iterator i (powers.begin()), i_end (powers.end()); i != i_end; ++i)
   655         registerTxPower(i->lower, i->upper);
   662     namespace fty = console::factory;
   664     basei::interface().consoleDir()
   665         .add(
"registerTxPower",
   667                                           registerTxPower, (
Ranges const &)))
   668              .arg(
"powers", 
"transmit power values or ranges")
   669              .doc(
"Register valid txpower values or ranges.\n"   670                   "The /powers/ parameter may be either a single value or range or a list of values\n"   672                   "    registerTxPower 4;\n"   673                   "        Register single txpower value\n\n"   674                   "    registerTxPower (-4:-1 1:10);\n"   675                   "        Register two txpower ranges\n") );
 void allocate(unsigned interfaceId, unsigned frequency, unsigned bandwidth, UserCallback cb)
Register for a wireless channel. 
 
boost::uint16_t perturb(boost::uint16_t value)
 
std::vector< console::ValueRange< int > > Ranges
 
#define SENF_FNP(ret, fn, args)
 
#define SENF_MEMBINDFNP(ret, cls, fn, args)
 
void registerFrequency(unsigned frequency, unsigned bandwidth)
Register single frequency/bandwidth combination. 
 
std::string str(T const &t)
 
boost::iterator_range< InterfaceIdIterator > UsersRange
Iterator range of interface id's using a channel. 
 
unsigned frameRetransmitted
 
OtherPacket rfind() const
 
Emulated wireless transmitter base-class. 
 
ModulationParameter const  & findModulationById(ModulationParameter::id_t id) const
 
unsigned nUsers
Number of active channel users. 
 
boost::function< R(Args)> membind(R(T::*fn)(Args), T *ob)
 
void registerTxPower(int power)
Register single txpower value. 
 
short minRssi
Minimum RSSI value. 
 
UDPClientHandle::Address consoleGroup() const
Get control channel multicast group/port. 
 
UDPClientHandle::Address address
Assigned multicast address. 
 
Wireless spectrum management. 
 
static unsigned nodeId()
Get unique node id. 
 
boost::iterator_range< Entries::index_iterator< ByFrequency >::type > EntriesRange
Iterator range of channel entries. 
 
NodeType & add(std::string const &name, boost::shared_ptr< NodeType > node)
 
EmulatedFrequencyRegistry & emulatedFrequencyRegistry()
 
Channel allocation entry. 
 
std::vector< console::ValueRange< unsigned > > Ranges
 
boost::signals2::signal< void(Entry const &, unsigned nodeId, ChangeType type)> channelPopulationChanged
Channel population changed signal. 
 
Annotation & annotation()
 
virtual bool v_emulatedWirelessQuality(Packet packet, annotations::Quality &quality)
Overload to define wireless characteristics. 
 
unsigned ownerNodeId
Channel master. 
 
ConcretePacket< EmulatedWirelessPacketHeaderType > EmulatedWirelessPacketHeader
 
std::pair< INet4Network, unsigned > addressRange() const
Get address/port range of channel multicast addresses. 
 
Emulated wireless interface base-class. 
 
void start()
Start multicast address/port allocation. 
 
#define SENF_ASSERT(x, comment)
 
unsigned emulatedFrequency() const
Get current emulated frequency. 
 
void release(unsigned interfaceId)
Release channel registration. 
 
unsigned prefix_len() const
 
UsersRange users(EntriesRange::iterator i) const
Get interface id's of local users of a given channel. 
 
static ModulationParameterRegistry & instance()
 
void stop()
Stop multicast address/port allocation. 
 
void emulatedCoverageRange(unsigned distance)
 
INet4Address host(boost::uint32_t number)
 
boost::function< void(UDPClientHandle::Address const &address)> UserCallback
Callback type called to set channel address. 
 
EmulatedWirelessInterface public header. 
 
EntriesRange entries() const
Get all channel entries. 
 
NodeType & add(std::string const &name, boost::shared_ptr< NodeType > node)
 
~EmulatedWirelessInterface()