diff --git a/src/inet/node/leach/LeachBS.ned b/src/inet/node/leach/LeachBS.ned new file mode 100644 index 00000000000..8f45fc83e45 --- /dev/null +++ b/src/inet/node/leach/LeachBS.ned @@ -0,0 +1,30 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +package inet.node.leach; + +import inet.node.inet.AdhocHost; +import inet.routing.leach.LeachBS; + +module LeachBS extends AdhocHost { + submodules: + LeachBS: LeachBS { + @display("p=825,226"); + } + connections: + LeachBS.ipOut --> tn.in++; + LeachBS.ipIn <-- tn.out++; + +} diff --git a/src/inet/node/leach/LeachNode.ned b/src/inet/node/leach/LeachNode.ned new file mode 100644 index 00000000000..824c31cec42 --- /dev/null +++ b/src/inet/node/leach/LeachNode.ned @@ -0,0 +1,30 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +package inet.node.leach; + +import inet.node.inet.AdhocHost; +import inet.routing.leach.Leach; + +module LeachNode extends AdhocHost { + submodules: + LeachNode: Leach { + @display("p=825,226"); + } + connections: + LeachNode.ipOut --> tn.in++; + LeachNode.ipIn <-- tn.out++; + +} \ No newline at end of file diff --git a/src/inet/routing/leach/Leach.cc b/src/inet/routing/leach/Leach.cc new file mode 100644 index 00000000000..27a005b31eb --- /dev/null +++ b/src/inet/routing/leach/Leach.cc @@ -0,0 +1,480 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +#include "Leach.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "inet/common/IProtocolRegistrationListener.h" +#include "inet/common/ModuleAccess.h" +#include "inet/common/ProtocolTag_m.h" +#include "inet/linklayer/common/InterfaceTag_m.h" +#include "inet/networklayer/common/L3AddressTag_m.h" +#include "inet/physicallayer/wireless/common/contract/packetlevel/SignalTag_m.h" +#include "inet/networklayer/common/L3AddressResolver.h" +#include "inet/common/lifecycle/LifecycleOperation.h" +#include "inet/common/lifecycle/ModuleOperations.h" +#include "inet/common/lifecycle/NodeStatus.h" +#include "inet/common/lifecycle/LifecycleController.h" + +namespace inet { + +Register_Enum(inet::Leach, (Leach::ch, Leach::nch)); +Define_Module(Leach); + +Leach::Leach() { + +} + +Leach::~Leach() { + stop(); + delete event; +} + +void Leach::initialize(int stage) { + RoutingProtocolBase::initialize(stage); + + //reads from omnetpp.ini + if (stage == INITSTAGE_LOCAL) { + sequencenumber = 0; + host = getContainingNode(this); + ift = getModuleFromPar(par("interfaceTableModule"), + this); + + clusterHeadPercentage = par("clusterHeadPercentage"); + numNodes = par("numNodes"); + + roundDuration = dblrand(0) * 10; + TDMADelayCounter = 1; + event = new cMessage("event"); + roundDuration = dblrand(0) * 10; + wasCH = false; + + vector nodeMemory(numNodes); // Localized NCH node memory with CH data + vector nodeCHMemory(numNodes); // Localized CH memory + vector extractedTDMASchedule(numNodes); // Localized NCH node memory with extracted TDMA data + + } else if (stage == INITSTAGE_ROUTING_PROTOCOLS) { + registerService(Protocol::manet, nullptr, gate("ipIn")); + registerProtocol(Protocol::manet, gate("ipOut"), nullptr); + } +} + +void Leach::start() { + // Search the 802154 interface + int num_802154 = 0; + NetworkInterface *ie; + NetworkInterface *i_face; + const char *name; + + for (int i = 0; i < ift->getNumInterfaces(); i++) { + ie = ift->getInterface(i); + name = ie->getInterfaceName(); + if (strstr(name, "wlan") != nullptr) { + i_face = ie; + num_802154++; + interfaceId = i; + } + } + + // One enabled network interface (in total) + if (num_802154 == 1) + interface80211ptr = i_face; + else + throw cRuntimeError("DSDV has found %i 80211 interfaces", num_802154); + CHK(interface80211ptr->getProtocolDataForUpdate())->joinMulticastGroup( + Ipv4Address::LL_MANET_ROUTERS); + + // schedules a random periodic event + event->setKind(SELF); + scheduleAt(simTime() + uniform(0.0, par("maxVariance").doubleValue()), + event); +} + +void Leach::stop() { + cancelEvent(event); + nodeMemory.clear(); + nodeCHMemory.clear(); + extractedTDMASchedule.clear(); + TDMADelayCounter = 1; +} + +void Leach::handleMessageWhenUp(cMessage *msg) { + // if node is sending message + if (msg->isSelfMessage()) { + double randNo = dblrand(1); + double threshold = generateThresholdValue(round); + + if (randNo < threshold && wasCH == false) { + setLeachState(ch); // Set state for GUI visualization + wasCH = true; + handleSelfMessage(msg); + } + + round += 1; + int intervalLength = 1.0 / clusterHeadPercentage; + if (fmod(round, intervalLength) == 0) { // reset values at end of number of subintervals + wasCH = false; + nodeMemory.clear(); + nodeCHMemory.clear(); + extractedTDMASchedule.clear(); + TDMADelayCounter = 1; + } + + // schedule another self message every time new one is received by node + event->setKind(SELF); + scheduleAt(simTime() + roundDuration, event); + // if node is receiving message + } else if (check_and_cast(msg)->getTag()->getProtocol() + == &Protocol::manet) { + processMessage(msg); + } else { + throw cRuntimeError("Message not supported %s", msg->getName()); + } +} + +void Leach::handleMessageWhenDown(cMessage *msg) { + delete msg; + OperationalBase::handleMessageWhenDown(msg); +} + +void Leach::handleSelfMessage(cMessage *msg) { + if (msg == event) { + if (event->getKind() == SELF) { + auto ctrlPkt = makeShared(); + + // Filling the LeachControlPkt fields + ctrlPkt->setPacketType(CH); + Ipv4Address source = (interface80211ptr->getProtocolData< + Ipv4InterfaceData>()->getIPAddress()); + ctrlPkt->setChunkLength(b(128)); ///size of Hello message in bits + ctrlPkt->setSrcAddress(source); + + //new control info for LeachControlPkt + auto packet = new Packet("LEACHControlPkt", ctrlPkt); + auto addressReq = packet->addTag(); + addressReq->setDestAddress(Ipv4Address(255, 255, 255, 255)); + addressReq->setSrcAddress(source); //let's try the limited broadcast + packet->addTag()->setInterfaceId( + interface80211ptr->getInterfaceId()); + packet->addTag()->setProtocol(&Protocol::manet); + packet->addTag()->setProtocol(&Protocol::ipv4); + + //broadcast to other nodes the hello message + send(packet, "ipOut"); + packet = nullptr; + ctrlPkt = nullptr; + } + } else { + delete msg; + } +} + +void Leach::processMessage(cMessage *msg) { + Ipv4Address selfAddr = + (interface80211ptr->getProtocolData()->getIPAddress()); + auto receivedCtrlPkt = + staticPtrCast( + check_and_cast(msg)->peekData()->dupShared()); + Packet *receivedPkt = check_and_cast(msg); + auto &leachControlPkt = receivedPkt->popAtFront(); + auto packetType = leachControlPkt->getPacketType(); + + // filter packet based on type and run specific functions + if (msg->arrivedOn("ipIn")) { + // first broadcast from CH to NCH nodes + if (packetType == 1) { + Ipv4Address CHAddr = receivedCtrlPkt->getSrcAddress(); + + auto signalPowerInd = receivedPkt->getTag(); + double rxPower = signalPowerInd->getPower().get(); + + addToNodeMemory(selfAddr, CHAddr, rxPower); + sendAckToCH(selfAddr, CHAddr); + + // ACK packet from NCH node to CH + } else if (packetType == 2 && leachState == ch) { + Ipv4Address nodeAddr = receivedCtrlPkt->getSrcAddress(); + + addToNodeCHMemory(nodeAddr); + if (nodeCHMemory.size() > 2) { + sendSchToNCH(selfAddr); + } + + // TDMA schedule from CH to NCH + } else if (packetType == 3) { + Ipv4Address CHAddr = receivedCtrlPkt->getSrcAddress(); + + int scheduleArraySize = receivedCtrlPkt->getScheduleArraySize(); + // Traverses through schedule array in packets and sets values into a vector in local node memory + for (int counter = 0; counter < scheduleArraySize; counter++) { + ScheduleEntry tempScheduleEntry = receivedCtrlPkt->getSchedule( + counter); + TDMAScheduleEntry extractedTDMAScheduleEntry; + extractedTDMAScheduleEntry.nodeAddress = + tempScheduleEntry.getNodeAddress(); + extractedTDMAScheduleEntry.TDMAdelay = + tempScheduleEntry.getTDMAdelay(); + extractedTDMASchedule.push_back(extractedTDMAScheduleEntry); + } + + // Finds TDMA slot for self by traversing through earlier generated vector + double receivedTDMADelay = -1; + for (auto &it : extractedTDMASchedule) { + if (it.nodeAddress == selfAddr) { + receivedTDMADelay = it.TDMAdelay; + break; + } + } + + if (receivedTDMADelay > -1) { // Only sends data to CH if self address is included in schedule + sendDataToCH(selfAddr, CHAddr, receivedTDMADelay); + } + // Data packet from NCH to CH + } else if (packetType == 4) { + Ipv4Address NCHAddr = receivedCtrlPkt->getSrcAddress(); + + sendDataToBS(selfAddr); + + // BS packet from CH to BS - deleted in the case of standard nodes + } else if (packetType == 5) { + delete msg; + } + } else { + throw cRuntimeError("Message arrived on unknown gate %s", + msg->getArrivalGate()->getName()); + } +} + +// Runs during node shutdown events +void Leach::handleStopOperation(LifecycleOperation *operation) { + cancelAndDelete(event); + +} + +// Runs during node crash events +void Leach::handleCrashOperation(LifecycleOperation *operation) { + cancelAndDelete(event); +} + +// Threshold value for CH selection +double Leach::Leach::generateThresholdValue(int round) { + int intervalLength = 1.0 / clusterHeadPercentage; + double threshold = (clusterHeadPercentage + / (1 - clusterHeadPercentage * (fmod(round, intervalLength)))); + + return threshold; +} + +// Add CH to non CH node memory +void Leach::addToNodeMemory(Ipv4Address nodeAddr, Ipv4Address CHAddr, + double energy) { + if (!isCHAddedInMemory(CHAddr)) { + nodeMemoryObject node; + node.nodeAddr = nodeAddr; + node.CHAddr = CHAddr; + node.energy = energy; + nodeMemory.push_back(node); + } +} + +// Add non CH to CH node memory for TDMA schedule generation +void Leach::addToNodeCHMemory(Ipv4Address NCHAddr) { + if (!isNCHAddedInCHMemory(NCHAddr)) { + TDMAScheduleEntry scheduleEntry; + scheduleEntry.nodeAddress = NCHAddr; + scheduleEntry.TDMAdelay = TDMADelayCounter; + nodeCHMemory.push_back(scheduleEntry); + TDMADelayCounter++; // Counter increases and sets slots for NCH transmission time + } +} + +// Checks non CH nodes memory for CH records +bool Leach::isCHAddedInMemory(Ipv4Address CHAddr) { + for (auto &it : nodeMemory) { + if (it.CHAddr == CHAddr) { + return true; + } + } + return false; +} + +// Checks CH nodes memory to generate TDMA schedule +bool Leach::isNCHAddedInCHMemory(Ipv4Address NCHAddr) { + for (auto &it : nodeCHMemory) { + if (it.nodeAddress == NCHAddr) { + return true; + } + } + return false; +} + +void Leach::generateTDMASchedule() { + for (auto &it : nodeCHMemory) { + ScheduleEntry scheduleEntry; + scheduleEntry.setNodeAddress(it.nodeAddress); + scheduleEntry.setTDMAdelay(it.TDMAdelay); + } +} + +// Set CH/non CH states for GUI visualization - optional +void Leach::setLeachState(LeachState ls) { + leachState = ls; +} + +// Send broadcast acknowledgement to CH from non CH nodes +void Leach::sendAckToCH(Ipv4Address nodeAddr, Ipv4Address CHAddr) { + auto ackPkt = makeShared(); + ackPkt->setPacketType(ACK); + ackPkt->setChunkLength(b(128)); ///size of Hello message in bits + ackPkt->setSrcAddress(nodeAddr); + + auto ackPacket = new Packet("LeachAckPkt", ackPkt); + auto addressReq = ackPacket->addTag(); + + addressReq->setDestAddress(getIdealCH(nodeAddr, CHAddr)); + addressReq->setSrcAddress(nodeAddr); + ackPacket->addTag()->setInterfaceId( + interface80211ptr->getInterfaceId()); + ackPacket->addTag()->setProtocol(&Protocol::manet); + ackPacket->addTag()->setProtocol(&Protocol::ipv4); + + send(ackPacket, "ipOut"); +} + +// Sends TDMA schedule to non CH nodes +void Leach::sendSchToNCH(Ipv4Address selfAddr) { + auto schedulePkt = makeShared(); + schedulePkt->setPacketType(SCH); + schedulePkt->setChunkLength(b(128)); ///size of Hello message in bits + schedulePkt->setSrcAddress(selfAddr); + + for (auto &it : nodeCHMemory) { + ScheduleEntry scheduleEntry; + scheduleEntry.setNodeAddress(it.nodeAddress); + scheduleEntry.setTDMAdelay(it.TDMAdelay); + schedulePkt->insertSchedule(scheduleEntry); + } + + auto schedulePacket = new Packet("LeachSchedulePkt", schedulePkt); + auto scheduleReq = schedulePacket->addTag(); + + scheduleReq->setDestAddress(Ipv4Address(255, 255, 255, 255)); + scheduleReq->setSrcAddress(selfAddr); + schedulePacket->addTag()->setInterfaceId( + interface80211ptr->getInterfaceId()); + schedulePacket->addTag()->setProtocol(&Protocol::manet); + schedulePacket->addTag()->setProtocol(&Protocol::ipv4); + + send(schedulePacket, "ipOut"); +} + +// Sends data to CH node +void Leach::sendDataToCH(Ipv4Address nodeAddr, Ipv4Address CHAddr, + double TDMAslot) { + auto dataPkt = makeShared(); + dataPkt->setPacketType(DATA); + double temperature = (double) rand() / RAND_MAX; + double humidity = (double) rand() / RAND_MAX; + + dataPkt->setChunkLength(b(128)); + dataPkt->setTemperature(temperature); + dataPkt->setHumidity(humidity); + dataPkt->setSrcAddress(nodeAddr); + + auto dataPacket = new Packet("LEACHDataPkt", dataPkt); + auto addressReq = dataPacket->addTag(); + + addressReq->setDestAddress(getIdealCH(nodeAddr, CHAddr)); + addressReq->setSrcAddress(nodeAddr); + dataPacket->addTag()->setInterfaceId( + interface80211ptr->getInterfaceId()); + dataPacket->addTag()->setProtocol(&Protocol::manet); + dataPacket->addTag()->setProtocol(&Protocol::ipv4); + + sendDelayed(dataPacket, TDMAslot, "ipOut"); +} + +// CH sends data to BS +void Leach::sendDataToBS(Ipv4Address CHAddr) { + auto bsPkt = makeShared(); + bsPkt->setPacketType(BS); + + bsPkt->setChunkLength(b(128)); + bsPkt->setCHAddr(CHAddr); + + auto bsPacket = new Packet("LEACHBsPkt", bsPkt); + auto addressReq = bsPacket->addTag(); + + addressReq->setDestAddress(Ipv4Address(10, 0, 0, 1)); + addressReq->setSrcAddress(CHAddr); + bsPacket->addTag()->setInterfaceId( + interface80211ptr->getInterfaceId()); + bsPacket->addTag()->setProtocol(&Protocol::manet); + bsPacket->addTag()->setProtocol(&Protocol::ipv4); + + sendDelayed(bsPacket, TDMADelayCounter, "ipOut"); + setLeachState(nch); // Set state for GUI visualization +} + +// Selects the ideal CH based on RSSI signal +Ipv4Address Leach::getIdealCH(Ipv4Address nodeAddr, Ipv4Address CHAddr) { + Ipv4Address tempIdealCHAddr = CHAddr; + double tempRxPower = 0.0; + if (nodeMemory.size() > 0) { + for (auto &it : nodeMemory) { + if (it.nodeAddr == nodeAddr) { + if (it.energy > tempRxPower) { + tempRxPower = it.energy; + tempIdealCHAddr = it.CHAddr; + continue; + } + } else { + continue; + } + } + } + return tempIdealCHAddr; +} + +void Leach::refreshDisplay() const { + const char *icon; + switch (leachState) { + case nch: + icon = ""; + break; + case ch: + icon = "status/green"; + break; + default: + throw cRuntimeError("Unknown LEACH status"); + } + auto &displayString = getDisplayString(); + if (*icon) { + displayString.setTagArg("i2", 0, icon); + host->getDisplayString().setTagArg("i2", 0, icon); + } else { + displayString.removeTag("i2"); + host->getDisplayString().removeTag("i2"); + } +} +} /* namespace inet */ diff --git a/src/inet/routing/leach/Leach.h b/src/inet/routing/leach/Leach.h new file mode 100644 index 00000000000..92157fd754a --- /dev/null +++ b/src/inet/routing/leach/Leach.h @@ -0,0 +1,140 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +#ifndef INET_ROUTING_LEACH_LEACH_H_ +#define INET_ROUTING_LEACH_LEACH_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "inet/common/INETDefs.h" +#include "inet/common/packet/Packet.h" +#include "inet/networklayer/contract/IInterfaceTable.h" +#include "inet/networklayer/contract/ipv4/Ipv4Address.h" +#include "inet/networklayer/ipv4/IIpv4RoutingTable.h" +#include "inet/networklayer/ipv4/Ipv4Header_m.h" +#include "inet/networklayer/ipv4/Ipv4InterfaceData.h" +#include "inet/networklayer/ipv4/Ipv4RoutingTable.h" +#include "inet/routing/base/RoutingProtocolBase.h" +#include "LeackPkts_m.h" +#include "inet/mobility/contract/IMobility.h" +#include "inet/common/geometry/common/Coord.h" +#include "inet/mobility/base/StationaryMobilityBase.h" +#include "inet/power/contract/ICcEnergyStorage.h" +#include "inet/common/lifecycle/LifecycleController.h" + +using namespace std; + +namespace inet { + +class INET_API Leach: public RoutingProtocolBase { + +private: + + NetworkInterface *interface80211ptr = nullptr; + int interfaceId = -1; + unsigned int sequencenumber = 0; + cModule *host = nullptr; + Ipv4Address idealCH; + cMessage *event = nullptr; + int round; + +protected: + IInterfaceTable *ift = nullptr; + simtime_t dataPktSendDelay; + simtime_t CHPktSendDelay; + simtime_t roundDuration; + + int numNodes = 0; + double clusterHeadPercentage = 0.0; + + // object for storing CH data per node in vector array + struct nodeMemoryObject { + Ipv4Address nodeAddr; + Ipv4Address CHAddr; + double energy; + }; + + struct TDMAScheduleEntry { + Ipv4Address nodeAddress; + double TDMAdelay; + }; + + vector nodeMemory; // NCH nodes store data about CH broadcasts + vector nodeCHMemory; // CH store data about CH acknowledgements + vector extractedTDMASchedule; + bool wasCH; + +public: + Leach(); + virtual ~Leach(); + + enum LeachState { + nch, ch + }; // written in lower caps as it conflicts with enum in LeachPkts.msg file + + LeachState leachState; + double TDMADelayCounter; + + virtual int numInitStages() const override { + return NUM_INIT_STAGES; + } + virtual void initialize(int stage) override; + virtual void handleMessageWhenUp(cMessage *msg) override; + virtual void handleMessageWhenDown(cMessage *msg) override; + + void handleSelfMessage(cMessage *msg); + void processMessage(cMessage *msg); + + // lifecycle + virtual void handleStartOperation(LifecycleOperation *operation) override { + start(); + } + virtual void handleStopOperation(LifecycleOperation *operation) override; + virtual void handleCrashOperation(LifecycleOperation *operation) override; + void start(); + void stop(); + virtual void refreshDisplay() const override; + enum SelfMsgKinds { + SELF = 1, DATA2CH, DATA2BS + }; + + double generateThresholdValue(int subInterval); + + void sendDataToCH(Ipv4Address nodeAddr, Ipv4Address CHAddr, + double TDMAslot); + void sendDataToBS(Ipv4Address CHAddr); + void sendAckToCH(Ipv4Address nodeAddr, Ipv4Address CHAddr); + void sendSchToNCH(Ipv4Address selfAddr); + + void addToNodeMemory(Ipv4Address nodeAddr, Ipv4Address CHAddr, + double energy); + void addToNodeCHMemory(Ipv4Address NCHAddr); + bool isCHAddedInMemory(Ipv4Address CHAddr); + bool isNCHAddedInCHMemory(Ipv4Address NCHAddr); + void generateTDMASchedule(); + + virtual void setLeachState(LeachState ls); + Ipv4Address getIdealCH(Ipv4Address nodeAddr, Ipv4Address CHAddr); +}; + +} /* namespace inet */ + +#endif /* INET_ROUTING_LEACH_LEACH_H_ */ diff --git a/src/inet/routing/leach/Leach.ned b/src/inet/routing/leach/Leach.ned new file mode 100644 index 00000000000..0074d52b0ba --- /dev/null +++ b/src/inet/routing/leach/Leach.ned @@ -0,0 +1,31 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +package inet.routing.leach; + +import inet.routing.contract.IManetRouting; + +simple Leach like IManetRouting +{ + parameters: + @display("i=block/routing"); + string interfaceTableModule; // The path to the InterfaceTable module + double maxVariance = default(1); + int numNodes = default(10); + double clusterHeadPercentage = default(0.5); + gates: + input ipIn; + output ipOut; +} diff --git a/src/inet/routing/leach/LeachBS.cc b/src/inet/routing/leach/LeachBS.cc new file mode 100644 index 00000000000..a87378edc62 --- /dev/null +++ b/src/inet/routing/leach/LeachBS.cc @@ -0,0 +1,126 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +#include +#include +#include + +#include "inet/common/IProtocolRegistrationListener.h" +#include "inet/common/ModuleAccess.h" +#include "inet/common/ProtocolTag_m.h" +#include "inet/linklayer/common/InterfaceTag_m.h" +#include "inet/networklayer/common/L3AddressTag_m.h" +#include "inet/routing/leach/Leach.h" +#include "inet/physicallayer/wireless/common/contract/packetlevel/SignalTag_m.h" +#include "LeachBS.h" + +using namespace std; + +namespace inet { + +Define_Module(LeachBS); + +LeachBS::LeachBS() { + +} + +LeachBS::~LeachBS() { + // TODO Auto-generated destructor stub +} + +void LeachBS::initialize(int stage) { + RoutingProtocolBase::initialize(stage); + + //reads from omnetpp.ini + if (stage == INITSTAGE_LOCAL) { + sequencenumber = 0; + host = getContainingNode(this); + ift = getModuleFromPar(par("interfaceTableModule"), + this); + + bsPktReceived = 0; + + } else if (stage == INITSTAGE_ROUTING_PROTOCOLS) { + registerService(Protocol::manet, nullptr, gate("ipIn")); + registerProtocol(Protocol::manet, gate("ipOut"), nullptr); + } +} + +void LeachBS::start() { + /* Search the 80211 interface */ + int num_80211 = 0; + NetworkInterface *ie; + NetworkInterface *i_face; + const char *name; + + for (int i = 0; i < ift->getNumInterfaces(); i++) { + ie = ift->getInterface(i); + name = ie->getInterfaceName(); + if (strstr(name, "wlan") != nullptr) { + i_face = ie; + num_80211++; + interfaceId = i; + } + } + + // One enabled network interface (in total) + if (num_80211 == 1) + interface80211ptr = i_face; + else + throw cRuntimeError("DSDV has found %i 80211 interfaces", num_80211); + + CHK(interface80211ptr->getProtocolDataForUpdate())->joinMulticastGroup( + Ipv4Address::LL_MANET_ROUTERS); +} + +void LeachBS::stop() { + +} + +void LeachBS::handleMessageWhenUp(cMessage *msg) { + Ipv4Address nodeAddr = + (interface80211ptr->getProtocolData()->getIPAddress()); + // if node is sending message + if (msg->isSelfMessage()) { + delete msg; + } + // if node is receiving message + else if (check_and_cast(msg)->getTag()->getProtocol() + == &Protocol::manet) { + auto receivedCtrlPkt = + staticPtrCast( + check_and_cast(msg)->peekData()->dupShared()); + Packet *receivedPkt = check_and_cast(msg); + auto &leachControlPkt = receivedPkt->popAtFront(); + + auto packetType = leachControlPkt->getPacketType(); + + // filter packet based on type and run specific functions + if (msg->arrivedOn("ipIn")) { + if (packetType == 5) { + bsPktReceived += 1; + } else { + delete msg; + } + } else { + throw cRuntimeError("Message arrived on unknown gate %s", + msg->getArrivalGate()->getName()); + } + } else { + throw cRuntimeError("Message not supported %s", msg->getName()); + } +} + +} /* namespace inet */ diff --git a/src/inet/routing/leach/LeachBS.h b/src/inet/routing/leach/LeachBS.h new file mode 100644 index 00000000000..767fd3b340c --- /dev/null +++ b/src/inet/routing/leach/LeachBS.h @@ -0,0 +1,70 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +#ifndef INET_ROUTING_LEACH_LEACHBS_H_ +#define INET_ROUTING_LEACH_LEACHBS_H_ + +#include "inet/common/INETDefs.h" +#include "inet/common/packet/Packet.h" +#include "inet/networklayer/contract/IInterfaceTable.h" +#include "inet/networklayer/contract/ipv4/Ipv4Address.h" +#include "inet/networklayer/ipv4/IIpv4RoutingTable.h" +#include "inet/networklayer/ipv4/Ipv4Header_m.h" +#include "inet/networklayer/ipv4/Ipv4InterfaceData.h" +#include "inet/networklayer/ipv4/Ipv4RoutingTable.h" +#include "inet/routing/base/RoutingProtocolBase.h" +#include "LeackPkts_m.h" +#include "Leach.h" + +namespace inet { + +// Base Station of network which acts as data sink +class INET_API LeachBS: public RoutingProtocolBase { +private: + int bsPktReceived; // number of packets received at BS + +public: + LeachBS(); + virtual ~LeachBS(); + + int interfaceId = -1; + NetworkInterface *interface80211ptr = nullptr; + IInterfaceTable *ift = nullptr; + unsigned int sequencenumber = 0; + cModule *host = nullptr; + +protected: + virtual int numInitStages() const override { + return NUM_INIT_STAGES; + } + virtual void initialize(int stage) override; + virtual void handleMessageWhenUp(cMessage *msg) override; + + virtual void handleStartOperation(LifecycleOperation *operation) override { + start(); + } + virtual void handleStopOperation(LifecycleOperation *operation) override { + stop(); + } + virtual void handleCrashOperation(LifecycleOperation *operation) override { + stop(); + } + void start(); + void stop(); +}; + +} /* namespace inet */ + +#endif /* INET_ROUTING_LEACH_LEACHBS_H_ */ diff --git a/src/inet/routing/leach/LeachBS.ned b/src/inet/routing/leach/LeachBS.ned new file mode 100644 index 00000000000..aaccbe08e71 --- /dev/null +++ b/src/inet/routing/leach/LeachBS.ned @@ -0,0 +1,29 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +package inet.routing.leach; + +import inet.routing.contract.IManetRouting; + +simple LeachBS like IManetRouting +{ + parameters: + @display("i=block/routing"); + string interfaceTableModule; // The path to the InterfaceTable module + string routingTableModule; + gates: + input ipIn; + output ipOut; +} diff --git a/src/inet/routing/leach/LeackPkts.msg b/src/inet/routing/leach/LeackPkts.msg new file mode 100644 index 00000000000..79fd0dc9e8c --- /dev/null +++ b/src/inet/routing/leach/LeackPkts.msg @@ -0,0 +1,73 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +import inet.common.INETDefs; +import inet.common.packet.chunk.Chunk; +import inet.networklayer.contract.ipv4.Ipv4Address; + +cplusplus {{ + #include + #include "inet/common/INETDefs.h" + #include "Leach.h" + #include "inet/networklayer/contract/ipv4/Ipv4Address.h" + using namespace std; + using namespace inet; + +}} + +namespace inet; + +enum LeachPktType { + CH = 1; + ACK = 2; + SCH = 3; + DATA = 4; + BS = 5; +} + +class ScheduleEntry extends cObject { + Ipv4Address nodeAddress; + double TDMAdelay; +} + +// Base packet including all fields used across other packet variants +class LeachControlPkt extends FieldsChunk { + LeachPktType packetType = static_cast(-1); + Ipv4Address srcAddress; + string fingerprint; + + ScheduleEntry schedule[]; +} + +// Data packet including fields for mock data +class LeachDataPkt extends LeachControlPkt { + double temperature; + double humidity; +} + +// Packet sent to BS from CH +class LeachBSPkt extends LeachControlPkt { + Ipv4Address CHAddr; +} + +// CH broadcast reception acknowledgement from NCH nodes +class LeachAckPkt extends LeachControlPkt { + +} + +// Packet with TDMA schedule from CH +class LeachSchedulePkt extends LeachControlPkt { + +}