diff --git a/.gitignore b/.gitignore index cd7074d..3550c7e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,12 @@ NS3Mosaik/NS3MosaikSim # Ignore files generated by python *.pyc # Ignore files generated by macOS -.DS_Store \ No newline at end of file +.DS_Store +*.pcap +TapControl/monitor_udp.png +TapControl/monitor_tcp.png +TapControl/Monitor.png +TapControl/Monitor.png +NS3Mosaik/NS3MosaikSim +NS3Mosaik/NS3MosaikSim +NS3Mosaik/NS3MosaikSim diff --git a/IEEE13Node_BusXY.csv b/IEEE13Node_BusXY.csv new file mode 100644 index 0000000..ba14e1e --- /dev/null +++ b/IEEE13Node_BusXY.csv @@ -0,0 +1,16 @@ +SourceBus, 200, 400 +650, 200, 350 +RG60, 200, 300 +646, 0, 250 +645, 100, 250 +632, 200, 250 +633, 350, 250 +634, 400, 250 +670, 200, 200 +611, 0, 100 +684, 100, 100 +671, 200, 100 +692, 250, 100 +675, 400, 100 +652, 100, 0 +680, 200, 0 diff --git a/NS3Mosaik/Makefile b/NS3Mosaik/Makefile index 2166fb4..b12b046 100644 --- a/NS3Mosaik/Makefile +++ b/NS3Mosaik/Makefile @@ -73,7 +73,13 @@ LXFLAGS = -ljsoncpp\ ${NS3_LIB}/libns3.30.1-traffic-control-debug.so\ ${NS3_LIB}/libns3.30.1-stats-debug.so\ ${NS3_LIB}/libns3.30.1-mpi-debug.so\ - + ${NS3_LIB}/libns3.30.1-sixlowpan-debug.so\ + ${NS3_LIB}/libns3.30.1-lr-wpan-debug.so\ + ${NS3_LIB}/libns3.30.1-propagation-debug.so\ + ${NS3_LIB}/libns3.30.1-spectrum-debug.so\ + ${NS3_LIB}/libns3.30.1-antenna-debug.so\ + ${NS3_LIB}/libns3.30.1-wifi-debug.so\ + ${NS3_LIB}/libns3.30.1-energy-debug.so\ #------------------------# #--- Print Debug Info ---# diff --git a/NS3Mosaik/NS3MosaikSim b/NS3Mosaik/NS3MosaikSim index af2d0dd..b3fd38d 100755 Binary files a/NS3Mosaik/NS3MosaikSim and b/NS3Mosaik/NS3MosaikSim differ diff --git a/NS3Mosaik/mosaik_api/include/NS3Netsim.h b/NS3Mosaik/mosaik_api/include/NS3Netsim.h index 233745f..f284aad 100644 --- a/NS3Mosaik/mosaik_api/include/NS3Netsim.h +++ b/NS3Mosaik/mosaik_api/include/NS3Netsim.h @@ -63,7 +63,7 @@ struct DataXCHG { static vector dataXchgInput; ///< Input data exchange vector static vector dataXchgOutput; ///< Output data exchange vector static map mapIpv4NodeId; ///< Map from client Ipv4 to Node Id - +static map> wifiNetworks; ///< Map for the end-node in the primary network and the secondary network nodes class NS3Netsim { public: @@ -201,11 +201,11 @@ class NS3Netsim { /** * Set up a tcp or udp server depending on what has been passed in. * - * \param address The address that will be used to assigned addresses to both the server + * \param addressPrimary The address that will be used to assign addresses to both type of servers for the primary network * \param tcpOrUdp a string that is either set to tcp or udp, indicating which kind of server will be created * \param server holds the server id */ - void setUpServer(InetSocketAddress address, string protocol, string server); + void setUpServer(InetSocketAddress addressPrimary, string protocol, string server); /** * Sets up a tcp or udp client depending on what has been passed in @@ -215,7 +215,7 @@ class NS3Netsim { * \param server holds the server id * \param client holds the client id */ - void setUpClient(InetSocketAddress address, string protocol, string server, string client); + void setUpClient(AddressValue addressValue, string protocol, string server, string client); vector< vector> nodeAdjMatrix; ///< Node adjacency matrix string nodeAdjMatrixFilename; ///< Node adjacency matrix filename @@ -225,17 +225,12 @@ class NS3Netsim { vector> arrayNodeCoords; ///< Array of doubles with node coordinates NodeContainer nodes; ///< NS3 container with simulation nodes - PointToPointHelper pointToPoint; ///< Pointer to pointTopoint helper class string LinkRate; ///< Uniform link data rate string LinkDelay; ///< Uniform link delay string LinkErrorRate; ///< Uniform Link error rate uint32_t linkCount; ///< Network link count vector p2pDevices; ///< Vector with all link devices - InternetStackHelper internet; ///< Pointer to Internet helper class - Ipv4AddressHelper ipv4Address; ///< Pointer to Ipv4 Internet helper class - - MobilityHelper mobility; ///< Pointer to mobility (position) helper class Ptr nodePositionAlloc; ///< Pointer to node position allocation string appConnectionsFilename; ///< Application client-server connections filename @@ -245,10 +240,10 @@ class NS3Netsim { vector::iterator iList; ///< Application servers vector iterator uint16_t sinkPort; ///< Application port for all server nodes - MultiClientTcpServerHelper multiClientTcpServerHelper = MultiClientTcpServerHelper(Address()); ///< Application TCP server helper + MultiClientTcpServerHelper multiClientTcpServerHelper; ///< Application TCP server helper TcpClientHelper tcpClientHelper = TcpClientHelper(Address()); ///< Application TCP client helper - CustomUdpClientHelper customUdpClientHelper = CustomUdpClientHelper(Address()); ///< Application UDP server helper - CustomUdpServerHelper customUdpServerHelper = CustomUdpServerHelper(Address()); ///< Application UDP client helper + CustomUdpClientHelper customUdpClientHelper = CustomUdpClientHelper(Address()); ///< Application UDP client helper + CustomUdpServerHelper customUdpServerHelper; ///< Application UDP server helper double startTime; ///< Simulation start time int verbose; ///< Verbose level @@ -258,7 +253,6 @@ class NS3Netsim { Ptr sim; ///< Pointer to the smartgrid simulator implementation ApplicationContainer allApplications; - NodeContainer allNodes; string tcpOrUdp; ///< Which network protocol should be used }; diff --git a/NS3Mosaik/mosaik_api/include/ns3-helper.h b/NS3Mosaik/mosaik_api/include/ns3-helper.h index 34e6cd6..7f63e6e 100644 --- a/NS3Mosaik/mosaik_api/include/ns3-helper.h +++ b/NS3Mosaik/mosaik_api/include/ns3-helper.h @@ -114,4 +114,61 @@ void PrintIpAddresses(NodeContainer nodes); */ map CreateMapIpv4NodeId(NodeContainer nodes); +/** + * Checks the number of nodes. If the number does not match the number passed in, throws an error + * \param nodes, the node container which should be checked + * \param numberToCheck, the size nodes should equal this number + */ +void checkNumberOfNodesInContainer(NodeContainer nodes, int numberToCheck); + +/** + * Gets the address that starts with the string passed in. + * \param node, contains the node for which all the ipv4 addresses will be fetched + * \param starting, the string with which the address starts + * \return return the ipv4 address that starts with the starting string + */ +Ipv4Address getAddressForNodeStartingWith(NodeContainer node, std::string starting); + +/** + * Get a net-device of the type passed in + * \param node, the node which will be searched. + */ +template +Ptr GetNetDeviceOfType(NodeContainer node) { + checkNumberOfNodesInContainer(node, 1); + // Now iterate through the net devices + for (int i = 0; i < node.Get(0)->GetNDevices(); i++) { + // Try a dynamic cast + Ptr netDevice = DynamicCast (node.Get(0)->GetDevice(i)); + // If T is not null, successful, return the device + if (netDevice != 0) { + return netDevice; + } + } + + // If you've gotten to this point there is no net device of this type, throw an error + NS_FATAL_ERROR("NetDevice of correct type not found."); +} + +/** + * Get a application of the type passed in + * \param node, the node which will be searched + */ +template +Ptr GetApplicationOfType(NodeContainer node) { + checkNumberOfNodesInContainer(node, 1); + // Now iterate through the net devices + for (int i = 0; i < node.Get(0)->GetNApplications(); i++) { + // Try a dynamic cast + Ptr application = DynamicCast (node.Get(0)->GetApplication(i)); + // If T is not null, successful, return the device + if (application != 0) { + return application; + } + } + + // If you've gotten to this point there is no application of this type, throw an error + NS_FATAL_ERROR("Application of correct type not found."); +} + #endif /* SMARTGRID_NS3_HELPER_H_ */ diff --git a/NS3Mosaik/mosaik_api/src/MosaikSim.cpp b/NS3Mosaik/mosaik_api/src/MosaikSim.cpp index 84beb55..407ddac 100644 --- a/NS3Mosaik/mosaik_api/src/MosaikSim.cpp +++ b/NS3Mosaik/mosaik_api/src/MosaikSim.cpp @@ -553,12 +553,14 @@ MosaikSim::create(Json::Value args, Json::Value kwargs) std::string result; std::string entity; + std::cout << "CREATING" << std::endl; mosaikNum = args[0].asInt(); mosaikSimModel = args[1].asString(); if (verbose > 1) std::cout << "MosaikSim::create mosaikNum: " << mosaikNum << " - mosaikSimModel: " << mosaikSimModel << std::endl; + std::cout << kwargs << std::endl; //--- Store simulator parameters for (auto const& key : kwargs.getMemberNames()) { netsimParams[key] = (kwargs[key]).asString(); @@ -601,6 +603,7 @@ MosaikSim::create(Json::Value args, Json::Value kwargs) } return result; + exit(0); } diff --git a/NS3Mosaik/mosaik_api/src/NS3Netsim.cpp b/NS3Mosaik/mosaik_api/src/NS3Netsim.cpp index 2f532ea..6c4f17f 100644 --- a/NS3Mosaik/mosaik_api/src/NS3Netsim.cpp +++ b/NS3Mosaik/mosaik_api/src/NS3Netsim.cpp @@ -28,10 +28,14 @@ //--- Includes ---// #include +#include +#include +#include "ns3/core-module.h" +#include "ns3/internet-apps-module.h" +#include "ns3/wifi-module.h" +#include "ns3/smartgrid-default-simulator-impl.h" #include "NS3Netsim.h" #include "ns3-helper.h" -#include "ns3/smartgrid-default-simulator-impl.h" -#include using namespace std; using namespace ns3; @@ -64,11 +68,11 @@ ExtractInformationFromPacketAndSendToUpperLayer (Ptr socket) //--- print received msg NS_LOG_DEBUG( "Pkt Rcv at " << Simulator::Now ().GetMilliSeconds () - << " by nodeName: " << Names::FindName(socket->GetNode ()) + << " dstNodeName: " << Names::FindName(socket->GetNode ()) << " dstNodeId: " << socket->GetNode()->GetId() - << " dstAddr: " << socket->GetNode ()->GetObject()->GetAddress(1,0).GetLocal() + << " srcNodeName: " << Names::FindName(socket->GetNode ()) << " srcNodeId: " << srcNodeId - << " srcAddr: " << InetSocketAddress::ConvertFrom (from).GetIpv4() + << " from: " << InetSocketAddress::ConvertFrom (from).GetIpv4() << " Size: " << packet->GetSize() << " Payload: " << recMessage << endl; @@ -87,6 +91,19 @@ ExtractInformationFromPacketAndSendToUpperLayer (Ptr socket) stoll(val_time) }; dataXchgOutput.push_back(dataRcv); + + ofstream filePacketsSent; + filePacketsSent.open("packets_rec.pkt", std::ios_base::app); + filePacketsSent << "Pkt Rcv at " << Simulator::Now ().GetMilliSeconds () + << " dstNodeName: " << Names::FindName(socket->GetNode ()) + << " dstNodeId: " << socket->GetNode()->GetId() + << " srcNodeId: " << srcNodeId + << " from: " << InetSocketAddress::ConvertFrom (from).GetIpv4() + << " Size: " << packet->GetSize() + << " Payload: " << recMessage + << endl; + + filePacketsSent.close(); } NS3Netsim::NS3Netsim(): @@ -95,20 +112,10 @@ NS3Netsim::NS3Netsim(): //--- setup simulation type GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::SmartgridDefaultSimulatorImpl")); -// LogComponentEnable("Simulator", LOG_LEVEL_ALL); -// LogComponentEnable("SmartgridDefaultSimulatorImpl", LOG_LEVEL_ALL); -// LogComponentEnable("SmartgridNs3Main", LOG_LEVEL_ALL); +// LogComponentEnable ("SmartgridNs3Main", LOG_LEVEL_ALL); // LogComponentEnable ("MultiClientTcpServer", LOG_LEVEL_ALL); // LogComponentEnable ("TcpClient", LOG_LEVEL_ALL); -// LogComponentEnable ("Socket", LOG_LEVEL_ALL); -// LogComponentEnable ("SocketFactory", LOG_LEVEL_ALL); -// LogComponentEnable ("TcpSocket", LOG_LEVEL_ALL); // LogComponentEnable ("TcpSocketBase", LOG_LEVEL_ALL); -// LogComponentEnable ("TcpL4Protocol", LOG_LEVEL_ALL); -// LogComponentEnable ("IpL4Protocol", LOG_LEVEL_ALL); -// LogComponentEnable ("EventImpl", LOG_LEVEL_ALL); -// LogComponentEnable ("Node", LOG_LEVEL_ALL); -// LogComponentEnable ("Application", LOG_LEVEL_ALL); } @@ -129,6 +136,28 @@ NS3Netsim::init (string f_adjmat, int verb, string s_tcpOrUdp) { + // Point to point helper for point to point connections + PointToPointHelper pointToPoint; + // Internet stack helper to help with installation of internet + InternetStackHelper internet; + // Pointer to Ipv4 Internet helper class + Ipv4AddressHelper ipv4Address; + // Pointer to mobility (position) helper class + MobilityHelper mobility; + // Wifi network helper, meant to help install the wifi net device + WifiHelper wifi; + wifi.SetStandard (WIFI_PHY_STANDARD_80211g); + wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager"); + // Wifi mac helper + WifiMacHelper wifiMac; + // Wifi physical layer helper + YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default(); + // Wifi channel helper + YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default(); + // Set the properties of the wifi channel + wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); + wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel"); + allApplications = ApplicationContainer (); //--- verbose level verbose = verb; @@ -147,8 +176,9 @@ NS3Netsim::init (string f_adjmat, LinkErrorRate = s_linkErrorRate; linkCount = 0; - //--- set devices properties - ipv4Address.SetBase ("10.0.0.0", "255.255.255.252"); + //--- set address properties for ipv4 + // For the primary network, the address will start with 172 + ipv4Address.SetBase ("172.0.0.0", "255.255.255.252"); //--- set application destination port sinkPort = 3030; @@ -192,68 +222,6 @@ NS3Netsim::init (string f_adjmat, Ptr newNode = Names::Find(arrayNamesCoords[m][0]); } - //--- create network topology - NS_LOG_INFO ("Create Links Between Nodes."); - pointToPoint.SetDeviceAttribute ("DataRate", StringValue (LinkRate)); - pointToPoint.SetChannelAttribute ("Delay", StringValue (LinkDelay)); - for (size_t i = 0; i < nodeAdjMatrix.size (); i++) - { - for (size_t j = i; j < nodeAdjMatrix[i].size (); j++) - { - if (nodeAdjMatrix[i][j] == 1) - { - linkCount++; - NodeContainer n_links = NodeContainer (nodes.Get (i), nodes.Get (j)); - NetDeviceContainer n_devs = pointToPoint.Install (n_links); - p2pDevices.push_back(n_devs); - NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is 1"); - } - else - { - NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is 0"); - } - } - } - NS_LOG_INFO(""); - - //--- set link error rate - Ptr em = CreateObject (); - em->SetAttribute ("ErrorRate", DoubleValue (stod(LinkErrorRate))); - for (auto dev = p2pDevices.begin(); dev != p2pDevices.end(); ++dev) - { - (*dev).Get(1)->SetAttribute ("ReceiveErrorModel", PointerValue (em)); - if (verbose > 1) { - std::cout << "int(0) = " << (*dev).Get(0)->GetAddress() - << " int(1) = " << (*dev).Get(1)->GetAddress() - << " ID = " << (*dev).Get(1)->GetNode()->GetId() - << std::endl; - } - } - - - //--- set Internet stack and IP address to the p2p devices - NS_LOG_INFO ("Set internet stack and addresses."); - internet.Install (NodeContainer::GetGlobal ()); - for (auto dev = p2pDevices.begin(); dev != p2pDevices.end(); ++dev) - { - ipv4Address.Assign (*dev); - ipv4Address.NewNetwork (); - } - if (verbose > 1) { - PrintIpAddresses(nodes); - } - - //--- create map Ipv4 address to NodeId - mapIpv4NodeId = CreateMapIpv4NodeId(nodes); - - // --- Global routing protocol for IP version 4 stacks - NS_LOG_INFO ("Initialize Global Routing."); - Ipv4GlobalRoutingHelper::PopulateRoutingTables (); - - //--- Output topology summary - NS_LOG_INFO ("Number of links in the adjacency matrix is: " << linkCount); - NS_LOG_INFO ("Number of all nodes is: " << nodes.GetN ()); - // --- Allocate node positions NS_LOG_INFO ("Allocate Positions to Nodes."); nodePositionAlloc = CreateObject (); @@ -281,12 +249,107 @@ NS3Netsim::init (string f_adjmat, //--- resize list nodeServerList.resize(distance(nodeServerList.begin(), iList)); + // Set the internet stack on every node + internet.Install (NodeContainer::GetGlobal ()); + + //--- create network topology + NS_LOG_INFO ("Create p2p links and wifi networks between Nodes, then set internet stack and addresses"); + // Create the p2p links for the hard-wired links + pointToPoint.SetDeviceAttribute ("DataRate", StringValue (LinkRate)); + pointToPoint.SetChannelAttribute ("Delay", StringValue (LinkDelay)); + for (size_t i = 0; i < nodeAdjMatrix.size (); i++) + { + for (size_t j = i; j < nodeAdjMatrix[i].size (); j++) + { + if (nodeAdjMatrix[i][j] == 1) + { + // Create a point to point link + linkCount++; + NodeContainer n_links = NodeContainer (nodes.Get (i), nodes.Get (j)); + + uint32_t iId = nodes.Get(i)->GetId(); + uint32_t jId = nodes.Get(j)->GetId(); + + NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is " << nodeAdjMatrix[i][j]); + NetDeviceContainer n_devs = pointToPoint.Install (n_links); + p2pDevices.push_back(n_devs); + ipv4Address.Assign (n_devs); + ipv4Address.NewNetwork (); + } + else + { + NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is 0"); + } + } + } + + // For the wifi network, the address will start with 10 + ipv4Address.NewNetwork(); + ipv4Address.SetBase ("192.168.0.0", "255.255.255.0"); + // Create a WiFi network according to the nodes passed in, each set inside the vector is a network that needs to be created + for (auto network = wifiNetworks.begin(); network != wifiNetworks.end(); network++) { + // Grab the end node of the primary network + string primaryNodeName = (*network).first; + + // Find all the nodes in the network + NodeContainer networkNodes; + networkNodes.Add(Names::Find(primaryNodeName)); + for (auto nodeName = (*network).second.begin(); nodeName != (*network).second.end(); nodeName++) { + networkNodes.Add(Names::Find(*nodeName)); + } + + // Create a new channel for a new wi-fi network + wifiPhy.SetChannel(wifiChannel.Create()); + // New ssid with the name of the end node in the primary network + Ssid ssid = Ssid(primaryNodeName); + + // Set the type of mac network, with the correct ssid + wifiMac.SetType("ns3::AdhocWifiMac", + "Ssid", SsidValue(ssid)); + + // Connect all the devices + NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, networkNodes); + + wifiPhy.EnablePcapAll("pcapNS3Netsim.pcap"); + // Assign the addresses + ipv4Address.Assign(devices); + ipv4Address.NewNetwork(); + } + + //--- set link error rate + Ptr em = CreateObject (); + em->SetAttribute ("ErrorRate", DoubleValue (stod(LinkErrorRate))); + for (auto dev = p2pDevices.begin(); dev != p2pDevices.end(); ++dev) + { + (*dev).Get(1)->SetAttribute ("ReceiveErrorModel", PointerValue (em)); + if (verbose > 1) { + std::cout << "int(0) = " << (*dev).Get(0)->GetAddress() + << " int(1) = " << (*dev).Get(1)->GetAddress() + << " ID = " << (*dev).Get(1)->GetNode()->GetId() + << std::endl; + } + } + + if (verbose > 1) { + PrintIpAddresses(nodes); + } + + //--- create map Ipv4 address to NodeId + mapIpv4NodeId = CreateMapIpv4NodeId(nodes); + + // --- Global routing protocol for IP version 4 stacks + NS_LOG_INFO ("Initialize Global Routing."); + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + + //--- Output topology summary + NS_LOG_INFO ("Number of links in the adjacency matrix is: " << linkCount); + NS_LOG_INFO ("Number of all nodes is: " << nodes.GetN ()); //--- set regular trace file - AsciiTraceHelper ascii; - pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("traceNS3Netsim.tr")); - //pointToPoint.EnablePcapAll("pcapNS3Netsim.pcap"); - //pointToPoint.EnablePcap("dse", 0, 0, true); +// AsciiTraceHelper ascii; +// pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("pointToPointNS3.tr")); +// pointToPoint.EnablePcapAll("pcapNS3Netsim.pcap"); +// pointToPoint.EnablePcap("dse", 0, 0, true); } @@ -295,7 +358,6 @@ NS3Netsim::create (string client, string server) { NS_LOG_FUNCTION(this); bool found = false; - //--- //--- update list of application connections //--- @@ -316,43 +378,74 @@ NS3Netsim::create (string client, string server) //--- new connection, create entries if(found == false) { - arrayAppConnections.push_back(record); - - // create server socket - NS_LOG_INFO ("Create server."); - Ptr srvNode = Names::Find(server); - - // Check protocol - - //--- verify if server already exist - std::vector::iterator it = std::find(nodeServerList.begin(), nodeServerList.end(), server); - //--- if not found - if(it == nodeServerList.end()) { - // Create the server application - setUpServer(InetSocketAddress (Ipv4Address::GetAny (), sinkPort), tcpOrUdp, server); - NS_LOG_DEBUG ("NS3Netsim::create Server: " << *iList << endl); - } else { //--- end of server part - NS_LOG_DEBUG ("NS3Netsim::create Server already on the list: " << server << endl); - } + arrayAppConnections.push_back(record); + // create server socket + NS_LOG_INFO("Create server."); + Ptr srvNode = Names::Find(server); + + // Check protocol + //--- verify if server already exist + std::vector::iterator it = std::find(nodeServerList.begin(), nodeServerList.end(), server); + //--- if not found + if (it == nodeServerList.end()) { + // Create the server application + setUpServer(InetSocketAddress(Ipv4Address::GetAny(), sinkPort), tcpOrUdp, server); + NS_LOG_DEBUG("NS3Netsim::create Server: " << *iList << endl); + } else { //--- end of server part + NS_LOG_DEBUG("NS3Netsim::create Server already on the list: " << server << endl); + } - // create client socket - NS_LOG_INFO ("Create client."); - Ptr dstNode = Names::Find(server); - Ipv4InterfaceAddress sink_iaddr = dstNode->GetObject()->GetAddress (1,0); - InetSocketAddress remote = InetSocketAddress (sink_iaddr.GetLocal(), sinkPort); - setUpClient(remote, tcpOrUdp, server, client); - } + // Declared with a dummy address so that it can be initialized + InetSocketAddress serverAddr = InetSocketAddress("192.168.1.1"); + // At this point, the server has been created, check to see if the wifi socket needs to be enabled in the server + if (wifiNetworks.count(server) != 0 && wifiNetworks[server].count(client) != 0) { + // The wifi needs to be enabled in the server, fetch the application + if (tcpOrUdp == "tcp") { + // Fetch the multi-client-tcp-server + Ptr serverApp = GetApplicationOfType(NodeContainer(srvNode)); + // Get the wifi address + serverAddr = InetSocketAddress(getAddressForNodeStartingWith(NodeContainer(srvNode), "192.168"), sinkPort); + + // Check if the wifi socket has been enabled + if (serverApp->GetCreateWifiSocket() == false) { + // Now enabled enable it + serverApp->SetCreateWifiSocket(true); + serverApp->m_LocalWifi = serverAddr; + } + } else if (tcpOrUdp == "udp") { + // Fetch the custom-udp-server + Ptr serverApp = GetApplicationOfType(NodeContainer(srvNode)); + // Get the wifi address + serverAddr = InetSocketAddress(getAddressForNodeStartingWith(NodeContainer(srvNode), "192.168"), sinkPort); + + // Check if the wifi socket has been enabled + if (serverApp->GetCreateWifiSocket() == false) { + // Now enabled enable it + serverApp->SetCreateWifiSocket(true); + serverApp->m_LocalWifi = serverAddr; + } + } + } else { + serverAddr = InetSocketAddress(getAddressForNodeStartingWith(NodeContainer(srvNode), "172.0"), sinkPort); + } + + // create client socket + NS_LOG_INFO("Create client."); + + setUpClient(AddressValue(serverAddr), tcpOrUdp, server, client); + } } void -NS3Netsim::setUpServer(InetSocketAddress address, string protocol, string server) +NS3Netsim::setUpServer(InetSocketAddress addressPrimary, string protocol, string server) { + NS_LOG_FUNCTION(this); // Where the returned application will be stored ApplicationContainer serverAppContainer; // Switch on the protocol passed in if (protocol == "tcp") { // Set the address with which the application should be created - multiClientTcpServerHelper.SetAttribute("Local", AddressValue(address)); + multiClientTcpServerHelper.SetAttribute("LocalPrimary", AddressValue(addressPrimary)); serverAppContainer = multiClientTcpServerHelper.Install(server); // Set the call back to extract information from a packet and sent it to the upper layer Ptr serverAppAsCorrectType = DynamicCast (serverAppContainer.Get(0)); @@ -360,15 +453,13 @@ NS3Netsim::setUpServer(InetSocketAddress address, string protocol, string server serverAppAsCorrectType->SetPacketReceivedCallBack(ExtractInformationFromPacketAndSendToUpperLayer); } else if (protocol == "udp") { // Set the address with which the application should be created - customUdpServerHelper.SetAttribute("Local", AddressValue(InetSocketAddress (Ipv4Address::GetAny (), sinkPort))); + customUdpServerHelper.SetAttribute("LocalPrimary", AddressValue(addressPrimary)); // Create a tcp container serverAppContainer = customUdpServerHelper.Install(server); // Set the call back to extract information from a packet and sent it to the upper layer Ptr serverAppAsCorrectType = DynamicCast (serverAppContainer.Get(0)); // Set the function that should be called when the server receives a packet serverAppAsCorrectType->SetPacketReceivedCallBack(ExtractInformationFromPacketAndSendToUpperLayer); - // Set the function that should be called when the server receives a packet - serverAppAsCorrectType->SetPacketReceivedCallBack(ExtractInformationFromPacketAndSendToUpperLayer); } else { // If unknown protocol, stop and throw error NS_FATAL_ERROR("Invalid protocol passed in"); @@ -385,8 +476,9 @@ NS3Netsim::setUpServer(InetSocketAddress address, string protocol, string server } void -NS3Netsim::setUpClient(InetSocketAddress address, string protocol, string server, string client) +NS3Netsim::setUpClient(AddressValue addressValue, string protocol, string server, string client) { + NS_LOG_FUNCTION(this); // Get the server and the client nodes Ptr srcNode = Names::Find(client); Ptr dstNode = Names::Find(server); @@ -395,11 +487,11 @@ NS3Netsim::setUpClient(InetSocketAddress address, string protocol, string server // Switch on the protocol passed in if (protocol == "tcp") { // Create a tcp client - tcpClientHelper.SetAttribute("Remote", AddressValue(address)); + tcpClientHelper.SetAttribute("Remote", addressValue); clientAppContainer = tcpClientHelper.Install(client); } else if (protocol == "udp") { // Create a udp client - customUdpClientHelper.SetAttribute("Remote", AddressValue(address)); + customUdpClientHelper.SetAttribute("Remote", addressValue); clientAppContainer = customUdpClientHelper.Install(client); } else { // If unknown protocol, stop and throw error @@ -429,20 +521,17 @@ NS3Netsim::schedule (string src, string dst, string val, string val_time) << ")" << std::endl; } + Ptr srcNode = Names::Find(src); + // Try to get the correct type of application if (tcpOrUdp == "tcp") { - Ptr srcNode = Names::Find(src); - Ptr clientApp = DynamicCast (srcNode->GetApplication(0)); - if (clientApp == 0 ){ - clientApp = DynamicCast (srcNode->GetApplication(1)); - } + Ptr clientApp = GetApplicationOfType(NodeContainer(srcNode)); clientApp->ScheduleTransmit(val, val_time); } else if (tcpOrUdp == "udp") { - Ptr srcNode = Names::Find(src); - Ptr clientApp = DynamicCast (srcNode->GetApplication(0)); - if (clientApp == 0 ){ - clientApp = DynamicCast (srcNode->GetApplication(1)); - } + Ptr clientApp = GetApplicationOfType(NodeContainer(srcNode)); clientApp->ScheduleTransmit(val, val_time); + } else { + // If unknown protocol, stop and throw error + NS_FATAL_ERROR("Invalid protocol passed in"); } } @@ -471,10 +560,16 @@ NS3Netsim::runUntil (string nextStop) } } + if (stoi(nextStop) % 100 == 0){ + schedule ("6321", "632", to_string(20), to_string(stoi(nextStop) + 20)); + schedule ("6322", "632", to_string(20), to_string(stoi(nextStop) + 20)); + schedule ("6501", "650", to_string(30), to_string(stoi(nextStop) + 20)); + schedule ("6502", "650", to_string(30), to_string(stoi(nextStop) + 20)); + } + if (verbose > 1) { std::cout << "NS3Netsim::runUntil After_run NS3 time: " << Simulator::Now ().GetMilliSeconds () << std::endl; } - } diff --git a/NS3Mosaik/mosaik_api/src/ns3-helper.cpp b/NS3Mosaik/mosaik_api/src/ns3-helper.cpp index a9bba64..76db1a9 100644 --- a/NS3Mosaik/mosaik_api/src/ns3-helper.cpp +++ b/NS3Mosaik/mosaik_api/src/ns3-helper.cpp @@ -265,4 +265,28 @@ CreateMapIpv4NodeId(NodeContainer nodes) } return mapIpv4NodeId; +} + +void +checkNumberOfNodesInContainer(NodeContainer nodes, int numberToCheck) { + if (nodes.GetN() != numberToCheck) { + NS_FATAL_ERROR("Number of nodes passed in does not equal the desired number."); + } +} + +Ipv4Address +getAddressForNodeStartingWith(NodeContainer node, std::string starting) { + checkNumberOfNodesInContainer(node, 1); + + // Get all the ipv4 addresses + for (int i = 0; i < node.Get(0)->GetNDevices(); i++) { + // Convert the address into a string + std::ostringstream stream; + stream << node.Get(0)->GetObject()->GetAddress (i,0).GetLocal(); + std::string j = stream.str(); + if (j.rfind(starting, 0) == 0) { + return node.Get(0)->GetObject()->GetAddress (i,0).GetLocal(); + } + } + NS_FATAL_ERROR("Address not found."); } \ No newline at end of file diff --git a/NS3Mosaik/tcp-server-and-client/test/tcp-tester.cc b/NS3Mosaik/tcp-server-and-client/test/tcp-tester.cc deleted file mode 100644 index 2b70c97..0000000 --- a/NS3Mosaik/tcp-server-and-client/test/tcp-tester.cc +++ /dev/null @@ -1,172 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Add lines here - * Copyright (c) 2020 Amrinder S. Grewal - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Amrinder S. Grewal - * Date: 2020.05.18 - * Company: University of Alberta/Canada - Computing Science - * - * File modelled after star.cc - */ - -#include "ns3/core-module.h" -#include "ns3/network-module.h" -#include "ns3/netanim-module.h" -#include "ns3/internet-module.h" -#include "ns3/point-to-point-module.h" -#include "ns3/applications-module.h" -#include "ns3/point-to-point-layout-module.h" -#include "ns3/simulator.h" -#include -#include "ns3/Ptr.h" - -// Network topology (default) -// -// n2 n3 n4 . -// \ | / . -// \|/ . -// n1--- n0---n5 . -// /|\ . -// / | \ . -// n8 n7 n6 . -// n0 will always exist and be the server, n1....nk will be the number of clients -// Having 0 clients is a possibility - -using namespace ns3; - -NS_LOG_COMPONENT_DEFINE ("TESTER"); - - -void -ReceiveMessage (Ptr socket) -{ - Address from; - Ptr packet = socket->RecvFrom (from); - if (packet != 0) { - packet->RemoveAllPacketTags (); - packet->RemoveAllByteTags (); - - Ptr recvnode = socket->GetNode(); - uint8_t *buffer = new uint8_t[packet->GetSize()]; - packet->CopyData(buffer,packet->GetSize()); - std::string recMessage = std::string((char*)buffer); - recMessage = recMessage.substr (0,packet->GetSize()); - -// Ipv4Address srcIpv4Address = InetSocketAddress::ConvertFrom(from).GetIpv4(); -// uint32_t srcNodeId = mapIpv4NodeId[srcIpv4Address]; - - //--- print received msg - NS_LOG_DEBUG( - "Pkt Rcv at " << Simulator::Now ().GetMilliSeconds () - << " dstAddr: " << socket->GetNode ()->GetObject()->GetAddress(1,0).GetLocal() - << " srcAddr: " << InetSocketAddress::ConvertFrom (from).GetIpv4() - << " Size: " << packet->GetSize() - << " Payload: " << recMessage - ); - } -} - - -int -main (int argc, char *argv[]) -{ - // - // Default number of nodes in the star. Overridable by command line argument. - // - uint32_t nSpokes = 10; - - CommandLine cmd; - cmd.AddValue ("nSpokes", "Number of nodes to place in the star", nSpokes); - cmd.Parse (argc, argv); - - LogComponentEnable ("MultiClientTcpServer", LOG_LEVEL_ALL); - LogComponentEnable ("TESTER", LOG_LEVEL_DEBUG); - LogComponentEnable ("TcpClient", LOG_LEVEL_ALL); -// LogComponentEnable ("TcpL4Protocol", LOG_LEVEL_ALL); - - NS_LOG_INFO ("Build star topology."); - PointToPointHelper pointToPoint; - pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); - PointToPointStarHelper star (nSpokes, pointToPoint); - - NS_LOG_INFO ("Install internet stack on all nodes."); - InternetStackHelper internet; - star.InstallStack (internet); - - NS_LOG_INFO ("Assign IP Addresses."); - star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.1.0", "255.255.255.0")); - - NS_LOG_INFO ("Create applications."); - // - // Create a packet sink on the star "hub" to receive packets. - // - uint16_t port = 50000; - Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)); - MultiClientTcpServerHelper multiClientTcpServerHelper (hubLocalAddress); - ApplicationContainer hubApp = multiClientTcpServerHelper.Install (star.GetHub ()); - Ptr server = DynamicCast (hubApp.Get(0)); - server->SetPacketReceivedCallBack(&ReceiveMessage); - - hubApp.Start (Seconds (0.0)); - hubApp.Stop (Seconds (9.0)); - - // - // Create client applications to send TCP to the hub, one on each spoke node. - // - TcpClientHelper helper = TcpClientHelper(Address()); - ApplicationContainer spokeApps; - for (uint32_t i = 0; i < star.SpokeCount (); ++i) - { - AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address(i), port)); - helper.SetAttribute("Remote", remoteAddress); - helper.Install (star.GetSpokeNode (i)); - Ptr client = DynamicCast (star.GetSpokeNode(i)->GetApplication(0)); - - for (int j = 0; j < 10000; j++) { - Simulator::Schedule( - MilliSeconds(1000), - &TcpClient::ScheduleTransmit, - client, - std::to_string(i + 0.5), - std::to_string(i + 2000) - ); - } - spokeApps.Add (ApplicationContainer(client)); - } - spokeApps.Start (Seconds (0.0)); - spokeApps.Stop (Seconds (10.0)); - - NS_LOG_INFO ("Enable static global routing."); - // - // Turn on global static routing so we can actually be routed across the star. - // - Ipv4GlobalRoutingHelper::PopulateRoutingTables (); - - NS_LOG_INFO ("Enable pcap tracing."); - // - // Do pcap tracing on all point-to-point devices on all nodes. - // - pointToPoint.EnablePcapAll ("star"); - - NS_LOG_INFO ("Run Simulation."); - Simulator::Run (); - Simulator::Destroy (); - NS_LOG_INFO ("Done."); - - return 0; -} \ No newline at end of file diff --git a/TapControl/tapcontrol/data/ieee13.json b/TapControl/tapcontrol/data/ieee13.json new file mode 100644 index 0000000..9a749d2 --- /dev/null +++ b/TapControl/tapcontrol/data/ieee13.json @@ -0,0 +1,275 @@ +{ + "network": { + "nodes": [ + { + "id": "0", + "power_network_id": "SourceBus", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "1", + "power_network_id": "650", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "2", + "power_network_id": "RG60", + "location": { + "x": "200", + "y": "300" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "3", + "power_network_id": "646", + "location": { + "x": "0", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "4", + "power_network_id": "645", + "location": { + "x": "100", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "5", + "power_network_id": "632", + "location": { + "x": "200", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type":"wifi", + "access_point": true + }] + }, + { + "id": "6", + "power_network_id": "633", + "location": { + "x": "350", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "7", + "power_network_id": "634", + "location": { + "x": "400", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "8", + "power_network_id": "670", + "location": { + "x": "200", + "y": "200" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "9", + "power_network_id": "611", + "location": { + "x": "0", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "10", + "power_network_id": "684", + "location": { + "x": "100", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "11", + "power_network_id": "671", + "location": { + "x": "200", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "12", + "power_network_id": "692", + "location": { + "x": "250", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "13", + "power_network_id": "675", + "location": { + "x": "400", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "14", + "power_network_id": "652", + "location": { + "x": "100", + "y": "0" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "15", + "power_network_id": "680", + "location": { + "x": "200", + "y": "0" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + } + ], + "app_connections": [ + { + "receiver": "5", + "sender": "9", + "path_type": "control" + }, + { + "receiver": "1", + "sender": "5", + "path_type": "actuator" + }], + "network_layout": [ + { + "nodes":["0", "1"], + "type": "p2p" + }, + { + "nodes":["1", "2"], + "type": "p2p" + }, + { + "nodes":["6", "7"], + "type": "p2p" + }, + { + "nodes":["10", "11"], + "type": "p2p" + }, + { + "nodes":["4", "5"], + "type": "p2p" + }, + { + "nodes":["5", "6"], + "type": "p2p" + }, + { + "nodes":["8", "11"], + "type": "p2p" + }, + { + "nodes":["11", "12"], + "type": "p2p" + }, + { + "nodes":["12", "13"], + "type": "p2p" + }, + { + "nodes":["9", "10"], + "type": "p2p" + }, + { + "nodes":["10", "14"], + "type": "p2p" + }, + { + "nodes":["11", "15"], + "type": "p2p" + }, + { + "nodes":["2", "5"], + "type": "p2p" + }, + { + "nodes":["3", "4"], + "type": "p2p" + }, + { + "nodes":["5", "8"], + "type": "p2p" + } + ] + } +} diff --git a/TapControl/tapcontrol/simulator_demo.py b/TapControl/tapcontrol/simulator_demo.py index fa1f6d6..68e6787 100644 --- a/TapControl/tapcontrol/simulator_demo.py +++ b/TapControl/tapcontrol/simulator_demo.py @@ -192,12 +192,14 @@ def create_scenario( world, args ): #--- Transporter instances (Pktnet) transporters = [] for client, server, role in appconLinks: + print("TRANSPORTER") created_transporter = False for transporter in transporters: transporter_instance = 'Transp_' + str(client) + '-' + str(server) if (transporter_instance == transporter.eid): created_transporter = True if not created_transporter: + print(client, server) transporters.append(pktnetsim.Transporter(src=client, dst=server)) #--- Actuator instances @@ -249,19 +251,7 @@ def create_scenario( world, args ): for transporter in transporters: if (transporter_instance == transporter.eid): world.connect(transporter, controller, 'v', 't') - print('Connect', transporter.eid, 'to', controller.eid) - - #--- Sensor to Controller -# for client, server, role in appconLinks: -# if (role == 'sensing'): -# for sensor in sensors: -# sensor_instance = 'Sensor_' + str(client) -# if (sensor_instance == sensor.eid): -# for controller in controllers: -# controller_instance = 'Control_' + str(server) -# if (controller_instance == controller.eid): -# world.connect(sensor, controller, 'v', 't') -# print('Connect', sensor.eid, 'to', controller.eid) + print('Connect', transporter.eid, 'to', controller.eid) #--- Controller to PktNet for client, server, role in appconLinks: @@ -287,21 +277,7 @@ def create_scenario( world, args ): if (transporter_instance == transporter.eid): world.connect(transporter, actuator, 'v', 't', time_shifted=True, initial_data={'v': None, 't': None}) - print('Connect', transporter.eid, 'to', actuator.eid) - - #--- Controller to Actuator -# for client, server, role in appconLinks: -# if (role == 'acting'): -# for controller in controllers: -# controller_instance = 'Control_' + str(client) -# if (controller_instance == controller.eid): -# for actuator in actuators: -# actuator_instance = 'Actuator_' + str(server) -# if (actuator_instance == actuator.eid): -# print('Connect', controller.eid, 'to', actuator.eid) -# world.connect(controller, actuator, 'v', 't', -# time_shifted=True, initial_data={'v': None, 't': None}) - + print('Connect', transporter.eid, 'to', actuator.eid) #--- #--- Simulators to Monitor @@ -312,11 +288,6 @@ def create_scenario( world, args ): for sensor in sensors: print('Connect', sensor.eid, 'to', monitor.sid) - #--- PktNet(Transporter) to Monitor -# mosaik.util.connect_many_to_one(world, transporters, monitor, 'v', 't') -# for transporter in transporters: -# print('Connect', transporter.eid, 'to', monitor.sid) - #--- Controller to Monitor mosaik.util.connect_many_to_one(world, controllers, monitor, 'v', 't') for controller in controllers: diff --git a/ad_mat.csv b/ad_mat.csv new file mode 100644 index 0000000..1948966 --- /dev/null +++ b/ad_mat.csv @@ -0,0 +1,16 @@ +0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 +0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0 +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1 +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0 +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 diff --git a/config/reader/AppConnections.py b/config/reader/AppConnections.py new file mode 100644 index 0000000..4f998b2 --- /dev/null +++ b/config/reader/AppConnections.py @@ -0,0 +1,71 @@ +""" +Created on August 05, 2020 +File contains the app connections class, will be used to hold connections between senders and receivers. + +@file AppConnections.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.08.05 +@version 0.1 +@company University of Alberta - Computing Science +""" + +from config.reader.ValidationFunctions import check_non_empty_non_none_string, check_app_connection_types + + +class AppConnections: + """ + Holds the connection between the server and the receiver and the type of connection + """ + # The node sending the data + sender = "" + # The node receiving the data + receiver = "" + # The type of connection + path_type = None + + def __init__(self, sender, receiver, path_type): + """ + Just validates the sender, the receiver and the path type, then assigns it to the members. + :param sender: + :param receiver: + :param path_type: + """ + # Check that the sender and the receiver ids are valid + check_non_empty_non_none_string(sender) + check_non_empty_non_none_string(receiver) + # Check that the path type is valid + check_app_connection_types(path_type) + + super(AppConnections, self).__setattr__('sender', sender) + super(AppConnections, self).__setattr__('receiver', receiver) + super(AppConnections, self).__setattr__('path_type', path_type) + + def __setattr__(self, key, value): + """ + Overridden to ensure that nothing in the class is mutable after creation + :param key: + :param value: + :return: + """ + raise ImmutableObjectError + + def __eq__(self, other): + """ + Compare and make sure the the app connections are equal by comparing sender, receiver and path_type + :param other: + :return: + """ + if isinstance(other, AppConnections): + return (self.sender == other.sender + and self.receiver == other.receiver + and self.path_type == other.path_type) + return False + + def __ne__(self, other): + """ + Returns the opposite of eq. + :param other: + :return: + """ + return not self.__eq__(other) \ No newline at end of file diff --git a/config/reader/AppConnectionsTypes.py b/config/reader/AppConnectionsTypes.py new file mode 100644 index 0000000..4bc8362 --- /dev/null +++ b/config/reader/AppConnectionsTypes.py @@ -0,0 +1,60 @@ +""" +Created on August 05, 2020 +File contains the types of network connections + +@file AppConnectionsTypes.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.08.05 +@version 0.1 +@company University of Alberta - Computing Science +""" + + +class BaseAppConnectionPathType: + """ + The base app connection type. + """ + # Stores the type of the network connection + app_conn_type = "base" + + def __setattr__(self, key, value): + """ + Overridden to ensure that nothing in the class is mutable after creation + :param key: + :param value: + :return: + """ + raise ImmutableObjectError + + def __eq__(self, other): + """ + If the app_conn_type is equal, return true, otherwise false. + :param other: + :return: + """ + if isinstance(other, BaseAppConnectionPathType): + return self.app_conn_type == other.app_conn_type + return False + + def __ne__(self, other): + """ + If the app_conn_type is equal, return true, otherwise false. + :param other: + :return: + """ + return not self.__eq__(other) + + +class ControlAppConnectionPathType(BaseAppConnectionPathType): + """ + A control app connection path type + """ + app_conn_type = "control" + + +class ActuatorAppConnectionPathType(BaseAppConnectionPathType): + """ + A actuator app connection path type + """ + app_conn_type = "actuator" diff --git a/config/reader/Config.py b/config/reader/Config.py new file mode 100644 index 0000000..7114251 --- /dev/null +++ b/config/reader/Config.py @@ -0,0 +1,346 @@ +""" +Created on July 30, 2020 +File contains the classes that will read and verify the config files. + +@file Config.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.07.30 +@version 0.1 +@company University of Alberta - Computing Science +""" +import json + +from config.reader.ConfigErrors import InvalidNetworkType, NodeWithNetworkIdAlreadyExistsInNetwork, \ + NodeWithPowerIdAlreadyExistsInNetwork, NodeInNetworkConnectionDoesNotExist, NetworkConnectionAlreadyExists, \ + InvalidNetworkConnectionType, NoAccessPointFoundInNetworkConnection, NoNonAccessPointFoundInNetworkConnection, \ + NodeInNetworkConnectionDoesHaveCorrectNIC, NodeInAppConnectionDoesNotExist, InvalidAppConnectionType, \ + NodeTooFarAwayFromAccessPoint +from config.reader.NetworkConnection import NetworkConnection +from config.reader.AppConnections import AppConnections +from config.reader.AppConnectionsTypes import ControlAppConnectionPathType, ActuatorAppConnectionPathType +from config.reader.NetworkConnectionTypes import NetworkConnectionP2P, NetworkConnectionWiFi +from config.reader.NICs import P2PNIC, WiFiNIC +from config.reader.Node import Node +from config.reader.ValidationFunctions import check_distance_between_wifi_access_point_and_node + + +class Config: + """ + Class was created read, verify and store the verified config file. + """ + # Stores the files passed in + file = None + # Stores all the nodes + nodes = [] + # Store all the ids of the network nodes, used for verification purposes + __network_node_ids = set() + # Store all the ids of the power nodes, used for verification purposes + __power_node_ids = set() + # Stores the Network connection + network_connections = [] + # Stores all the ids of the network connections in a set, used for verification purposes + __network_connection_ids = set() + # Stores the app connections + app_connections = [] + + def __init__(self, file): + """ + Stores the file pointer passed in. Nothing else is done. + :param file: + """ + # Just save the file pointer + self.file = file + + def __setattr__(self, key, value): + """ + Overridden, once file changes, wipe all the other members + :param key: + :param value: + :return: + """ + # Call super to change the value of the members + super(Config, self).__setattr__(key, value) + # If the changed key was file, then set all the others to their default value + if key == "file": + self.nodes = [] + self.__node_ids = dict() + self.network_connections = [] + self.__network_connections = set() + self.app_connections = [] + self.__app_connections = [] + + def get_nodes_as_json(self): + """ + Returns all the nodes as json. + :return: + """ + # The list that will hold all the nodes + nodes_to_ret = [] + for node in self.nodes: + node_dict = {"power_id": node.power_id, "network_id": node.network_id, "x": node.location["x"], + "y": node.location["y"]} + + nics = [] + + for nic in node.nic_types: + if isinstance(nic, P2PNIC): + nics.append("p2p") + elif isinstance(nic, WiFiNIC): + nics.append("wifi") + else: + raise TypeError("NIC type invalid") + + node_dict["nics"] = nics + + nodes_to_ret.append(node_dict) + + return json.dumps(nodes_to_ret) + + def get_network_connections_as_json(self): + """ + Returns network connections as json. + :return: + """ + # The list that will hold all the network connections + ncs_to_ret = [] + for nc in self.network_connections: + nc_dict = {"src": nc.nodes[0], "dst": nc.nodes[1], "conn_type": nc.conn_type} + + if isinstance(nc.conn_type, NetworkConnectionP2P): + nc_dict["conn_type"] = "p2p" + elif isinstance(nc.conn_type, NetworkConnectionWiFi): + nc_dict["conn_type"] = "wifi" + else: + raise TypeError("Invalid Network Connection Type") + + ncs_to_ret.append(nc_dict) + + return json.dumps(ncs_to_ret) + + def get_app_connections_as_json(self): + """ + Returns app connections as json. + :return: + """ + # The list that will hold all the app connections. + acs_to_ret = [] + for ac in self.app_connections: + ac_dict = {"sender": ac.sender, "receiver": ac.receiver} + + if isinstance(ac.path_type, ActuatorAppConnectionPathType): + ac_dict["path_type"] = "actuator" + elif isinstance(ac.path_type, ControlAppConnectionPathType): + ac_dict["conn_type"] = "control" + else: + raise TypeError("Invalid App Connection Type") + + acs_to_ret.append(ac_dict) + + return json.dumps(acs_to_ret) + + def read_config(self): + """ + Reads the config files and the file. + :return: + """ + # Load the config file + data = json.load(self.file) + # Get the primary network out + network_dict = data["network"] + + # Load the nodes + nodes_dict = network_dict["nodes"] + self.__read_nodes_from_network(nodes_dict) + + # Loads the network connections in the primary network + network_layout_dict = network_dict["network_layout"] + self.__read_network_connections(network_layout_dict) + + # Loads the app connections + app_connections_dict = network_dict["app_connections"] + self.__read_app_connections(app_connections_dict) + + def __read_nodes_from_network(self, data): + """ + Reads the nodes from the primary network, parses them, then verifies them. + - No duplicates + :return: + """ + # Go through every node and create a node from it + for node_dict in data: + node = self.__read_and_create_node(node_dict) + self.__network_node_ids.add(node.network_id) + self.__power_node_ids.add(node.power_id) + self.nodes.append(node) + + def __read_and_create_node(self, node_dict): + """ + Reads a dict, creates a node and returns it. + :param node_dict: + :return: + """ + # Just get the values that can be easily fetched + power_id = node_dict["power_network_id"] + network_id = node_dict["id"] + location = node_dict["location"] + + nics = [] + # Convert the NIC strings to NICs + for nic_type in node_dict["nic_card_types"]: + nic = None + if nic_type["type"] == "p2p": + nic = P2PNIC() + elif nic_type["type"] == "wifi": + nic = WiFiNIC(nic_type["access_point"]) + else: + raise InvalidNetworkType(nic_type) + # Add the nic to end + nics.append(nic) + + node = Node(power_id, network_id, location, nics) + # Check that the node creates no duplicates + if network_id in self.__network_node_ids: + raise NodeWithNetworkIdAlreadyExistsInNetwork(node) + if power_id in self.__power_node_ids: + raise NodeWithPowerIdAlreadyExistsInNetwork(node) + + return node + + def __read_network_connections(self, network_layout_dict): + """ + Reads the network connections between nodes, parses them and then verifies them. + - No duplicates + - Both nodes exist + - Both nodes have correct type of NIC + :return: + """ + # Go through each connection + for network_conn_dict in network_layout_dict: + network_connection = self.__read_and_create_network_connections(network_conn_dict) + self.network_connections.append(network_connection) + self.__network_connection_ids.add(tuple(sorted([network_connection.nodes[0], network_connection.nodes[1]]))) + + def __read_app_connections(self, app_connections_dict): + """ + Reads the app connections between nodes, parses them and verifies them. + - Both nodes exist in the app connection + :param app_connections_dict: + :return: + """ + # Go through each app connection + for app_conn_dict in app_connections_dict: + app_conn = self.__read_application_connections(app_conn_dict) + self.app_connections.append(app_conn) + + def __read_and_create_network_connections(self, network_conn_dict): + """ + Reads a network connection, the nodes and the type, converts it to a NetworkConnection class, and verifies the + type connection. + :param self: + :param network_conn_dict: + :return: + """ + # Get the nodes + node_one = network_conn_dict["nodes"][0] + node_two = network_conn_dict["nodes"][1] + + # Check the nodes exist + if node_one not in self.__network_node_ids: + raise NodeInNetworkConnectionDoesNotExist(node_one) + if node_two not in self.__network_node_ids: + raise NodeInNetworkConnectionDoesNotExist(node_two) + + node_one_found = self.__get_node_with_network_id(node_one) + node_two_found = self.__get_node_with_network_id(node_two) + + # Now check if the connection already exists + if tuple(sorted([node_one, node_two])) in self.__network_connection_ids: + raise NetworkConnectionAlreadyExists(node_one_found, node_two_found) + + # Now check if the network connection type is valid + if network_conn_dict["type"] == "p2p": + conn_type = NetworkConnectionP2P() + if not node_one_found.has_p2p_card(): + raise NodeInNetworkConnectionDoesHaveCorrectNIC(node_one_found) + + if not node_two_found.has_p2p_card(): + raise NodeInNetworkConnectionDoesHaveCorrectNIC(node_two_found) + # No additional validation required + elif network_conn_dict["type"] == "wifi": + if not node_one_found.has_wifi_card(): + raise NodeInNetworkConnectionDoesHaveCorrectNIC(node_one_found) + + if not node_two_found.has_wifi_card(): + raise NodeInNetworkConnectionDoesHaveCorrectNIC(node_two_found) + + conn_type = NetworkConnectionWiFi() + found_access_point = False + found_non_access_point = False + # In this case, we need to verify that at least one of the wifi nodes is an access point and the other is + # not + + if not node_one_found.is_wifi_access_point() or not node_two_found.is_wifi_access_point(): + found_non_access_point = True + + if node_one_found.is_wifi_access_point() or node_two_found.is_wifi_access_point(): + found_access_point = True + + # Now check if access point and non-access point node in the network connection has been found + if not found_non_access_point: + raise NoNonAccessPointFoundInNetworkConnection(str(node_one_found), str(node_two_found)) + + if not found_access_point: + raise NoAccessPointFoundInNetworkConnection(str(node_one_found), str(node_two_found)) + + if not check_distance_between_wifi_access_point_and_node([node_one_found, node_two_found]): + raise NodeTooFarAwayFromAccessPoint + else: + raise InvalidNetworkConnectionType(network_conn_dict["type"]) + + # Create a conn and return it + return NetworkConnection([node_one, node_two], conn_type) + + def __read_application_connections(self, app_conn_dict): + """ + Reads the application connections, validates the connections by making sure the nodes exist. It does not however + validate the network connection to determine reachability. + :return: + """ + # Get the nodes + sender = app_conn_dict["sender"] + receiver = app_conn_dict["receiver"] + + # Check the nodes exist + if sender not in self.__network_node_ids: + raise NodeInAppConnectionDoesNotExist(sender) + if receiver not in self.__network_node_ids: + raise NodeInAppConnectionDoesNotExist(receiver) + + # Get the nodes if they exist, or it'll never get to this point + sender_found = self.__get_node_with_network_id(sender) + receiver_found = self.__get_node_with_network_id(receiver) + + # Check if the connection path type is valid + path_type = None + if app_conn_dict["path_type"] == "control": + path_type = ControlAppConnectionPathType() + elif app_conn_dict["path_type"] == "actuator": + path_type = ActuatorAppConnectionPathType() + else: + raise InvalidAppConnectionType + + # Return an app connection type + return AppConnections(sender_found.network_id, receiver_found.network_id, path_type) + + def __get_node_with_network_id(self, network_id): + """ + Returns the node with the passed in network id if found, else return None + :param network_id: + :return: + """ + for node in self.nodes: + if node.network_id == network_id: + return node + + return None diff --git a/config/reader/ConfigErrors.py b/config/reader/ConfigErrors.py new file mode 100644 index 0000000..9ab54ea --- /dev/null +++ b/config/reader/ConfigErrors.py @@ -0,0 +1,94 @@ +""" +Created on July 30, 2020 +File was created to store all the errors created for Config reading + +@file ConfigErrors.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.07.30 +@version 0.1 +@company University of Alberta - Computing Science +""" + + +class ImmutableObjectError(Exception): + """Raised when an Immutable object is being edited""" + pass + + +class InvalidNetworkType(Exception): + """Raised when an invalid type of NIC is passed in""" + pass + + +class InvalidNetworkConnectionType(Exception): + """Raised when an invalid type of network connection is passed in""" + pass + + +class InvalidAppConnectionType(Exception): + """Raised when an invalid type of app connection is passed in""" + pass + + +class InvalidAccessPointValueForNICType(Exception): + """Raised when: + - the value of access point is None or not a bool if NIC is of type wifi + - the value of access point in not None when the NIC is not wifi + """ + pass + + +class NetworkConnectionNumberOfNodesNotCorrect(Exception): + """Raised when a network connection does not have 2 nodes passed in.""" + pass + + +class NetworkConnectionHasNodesWithConnectionToSelf(Exception): + """Raised when a node is connected to itself in the network connection.""" + pass + + +class NodeWithNetworkIdAlreadyExistsInNetwork(Exception): + """Raised when a node with a network id is being created that is already taken.""" + pass + + +class NodeWithPowerIdAlreadyExistsInNetwork(Exception): + """Raised when a node with a power id is being created that is already taken.""" + pass + + +class NodeInNetworkConnectionDoesNotExist(Exception): + """Raised when a node in a network connection does not exist in nodes part of the file.""" + pass + + +class NodeInAppConnectionDoesNotExist(Exception): + """Raised when a node in a applications connection does not exist part of the file.""" + pass + + +class NodeInNetworkConnectionDoesHaveCorrectNIC(Exception): + """Raised when a node in a network connection does not have the correct nic.""" + pass + + +class NetworkConnectionAlreadyExists(Exception): + """Raised when a network connection between two nodes already exists.""" + pass + + +class NoAccessPointFoundInNetworkConnection(Exception): + """Raised when two wifi nodes are connected but an access point has not been found.""" + pass + + +class NoNonAccessPointFoundInNetworkConnection(Exception): + """Raised when two wifi nodes are connected but a non-access-point has not been found.""" + pass + + +class NodeTooFarAwayFromAccessPoint(Exception): + """Raised when a wifi node and an access point are too far away, for now that is 50m or more.""" + pass diff --git a/config/reader/ConfigHelpers.py b/config/reader/ConfigHelpers.py new file mode 100644 index 0000000..d4d9d6b --- /dev/null +++ b/config/reader/ConfigHelpers.py @@ -0,0 +1,69 @@ +""" +Created on August 12, 2020 +File contains helper for the config readers/validators. + +@file ConfigHelpers.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.08.12 +@version 0.1 +@company University of Alberta - Computing Science +""" +from config.reader.NICs import WiFiNIC + + +def find_access_point_in_wifi_nodes(nodes): + """ + Find and return the access point in the wifi nodes. + :param nodes: + :return: + """ + return get_wifi_node(True, nodes) + + +def find_non_access_point_in_wifi_nodes(nodes): + """ + Find and return the non access point in the wifi nodes. + :param nodes: + :return: + """ + return get_wifi_node(False, nodes) + + +def get_wifi_node(access_point, nodes): + """ + If access point is true, returns the access point from the nodes, if access point is false, returns the non access + point from the nodes. + :param access_point: + :param nodes: + :return: + """ + for node in nodes: + wifi_nic = get_nic_of_type(node.nic_types, WiFiNIC) + if wifi_nic.access_point == access_point: + return node + + return None + + +def get_nic_of_type(nics, nic_type): + """ + Go through nics and find the nic that is of type nic_type, otherwise throw a type error. + :param nics: + :param nic_type: + :return: + """ + for nic in nics: + if isinstance(nic, nic_type): + return nic + + raise TypeError(str(nic_type) + " not found in " + str(nics)) + + +def check_if_node_is_of_type(node, node_type): + """ + Check if a node is of type passed in. + :return: + """ + if not isinstance(node, node_type): + raise TypeError(str(node) + " is not of type " + str(node_type)) diff --git a/config/reader/NICs.py b/config/reader/NICs.py new file mode 100644 index 0000000..b91458c --- /dev/null +++ b/config/reader/NICs.py @@ -0,0 +1,113 @@ +""" +Created on August 5, 2020 +File contains all NIC type classes. + +@file NICs.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.08.05 +@version 0.1 +@company University of Alberta - Computing Science +""" +from config.reader.ConfigErrors import ImmutableObjectError + + +class NIC: + """ + Created to store the base type of NIC, where its not specified to be p2p or wifi, etc. + """ + # Stores the type of card, this cannot be set, each class has its own type that is set but cannot be changed + nic_type = "base" + + def __str__(self): + """ + Returns a description of the nic + :return: + """ + return self.nic_type + + def __eq__(self, other): + """ + Method checks to see if the type of other is correct and if type var is equal in self and other. + :param other: + :return: + """ + if isinstance(other, NIC): + return self.nic_type == other.nic_type + return False + + def __ne__(self, other): + """ + Returns the opposite value of __eq__, compares type + :param other: + :return: + """ + return not self.__eq__(other) + + +class P2PNIC(NIC): + """ + Created to store the p2p NIC card. + """ + # Stores the type of card, this cannot be set, each class has its own type that is set but cannot be changed + nic_type = "p2p" + + def __setattr__(self, key, value): + """ + Overridden to ensure that nothing in the class is mutable after creation + :param key: + :param value: + :return: + """ + raise ImmutableObjectError + + +class WiFiNIC(NIC): + """ + Created to store the Wifi NIC card. + """ + # Stores the type of card, this cannot be set, each class has its own type that is set but cannot be changed + nic_type = "wifi" + # Indicates if the wifi card is an access-point or not, by default its not + access_point = False + + def __init__(self, access_point=False): + """ + Created so that the value of access point can be set on creation of the class + :param access_point: + """ + super(WiFiNIC, self).__setattr__('access_point', access_point) + + def __setattr__(self, key, value): + """ + Overridden to ensure that nothing in the class is mutable after creation + :param key: + :param value: + :return: + """ + raise ImmutableObjectError + + def __str__(self): + """ + Returns a description of the nic + :return: + """ + return self.nic_type + ", access_point: " + str(self.access_point) + + def __eq__(self, other): + """ + Method checks to see if the type of other is correct and if type var is equal in self and other. + :param other: + :return: + """ + if super(WiFiNIC, self).__eq__(other): + return self.access_point == other.access_point + return False + + def __ne__(self, other): + """ + Returns the opposite value of __eq__, compares type + :param other: + :return: + """ + return not self.__eq__(other) diff --git a/config/reader/NetworkConnection.py b/config/reader/NetworkConnection.py new file mode 100644 index 0000000..e28669a --- /dev/null +++ b/config/reader/NetworkConnection.py @@ -0,0 +1,73 @@ +""" +Created on July 30, 2020 +File contains the class that will store network connections. + +@file NetworkConnection.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.07.30 +@version 0.1 +@company University of Alberta - Computing Science +""" + +from config.reader.ConfigErrors import ImmutableObjectError +from config.reader.ValidationFunctions import check_network_connection_nodes, check_network_connection_types + + +class NetworkConnection: + """ + Class was created to store the network connections. This includes connections between machines, but not connections + between applications, ie Server/Client connections will not be stored here. + """ + # Stores the nodes in the connection + nodes = [] + # Stores the type of connection + conn_type = "" + + def __init__(self, nodes, conn_type): + """ + Validates all the information passed in and stores it within itself. Meaning there should be two nodes passed in + . Each node should be a string, which will be the id of the string + :param nodes: + :param type: + """ + check_network_connection_nodes(nodes) + check_network_connection_types(conn_type) + + super(NetworkConnection, self).__setattr__('nodes', nodes) + super(NetworkConnection, self).__setattr__('conn_type', conn_type) + + def __setattr__(self, key, value): + """ + Overridden to ensure that nothing in the class is mutable after creation + :param key: + :param value: + :return: + """ + raise ImmutableObjectError + + def __eq__(self, other): + """ + Make sure the nodes are equal and the conn type is equal, return true + :param other: + :return: + """ + if isinstance(other, NetworkConnection): + # Sort the nodes in both + sorted_nodes = sorted(self.nodes) + sorted_nodes_other = sorted(other.nodes) + # Make sure the nodes are equal, and the type is equal + return ( + sorted_nodes[0] == sorted_nodes_other[0] and + sorted_nodes[1] == sorted_nodes_other[1] and + self.conn_type == other.conn_type + ) + return False + + def __ne__(self, other): + """ + Return the opposite of eq. If nodes are not equal or the conn type is not equal, return true + :param other: + :return: + """ + return not self.__eq__(other) diff --git a/config/reader/NetworkConnectionTypes.py b/config/reader/NetworkConnectionTypes.py new file mode 100644 index 0000000..901962d --- /dev/null +++ b/config/reader/NetworkConnectionTypes.py @@ -0,0 +1,60 @@ +""" +Created on August 05, 2020 +File contains the types of network connections + +@file NetworkConnectionTypes.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.08.05 +@version 0.1 +@company University of Alberta - Computing Science +""" + + +class NetworkConnectionTypeBase: + """ + The base network connection type. + """ + # Stores the type of the network connection + conn_type = "base" + + def __setattr__(self, key, value): + """ + Overridden to ensure that nothing in the class is mutable after creation + :param key: + :param value: + :return: + """ + raise ImmutableObjectError + + def __eq__(self, other): + """ + Checks to see if conn_type of two NetworkConnections is the same + :param other: + :return: + """ + if isinstance(other, NetworkConnectionTypeBase): + return self.conn_type == other.conn_type + return False + + def __ne__(self, other): + """ + Checks to see if conn_type of two NetworkConnections is not the same, opposite of eq + :param other: + :return: + """ + return not self.__eq__(other) + + +class NetworkConnectionP2P(NetworkConnectionTypeBase): + """ + A p2p network connection type + """ + conn_type = "p2p" + + +class NetworkConnectionWiFi(NetworkConnectionTypeBase): + """ + A WiFi network connection type + """ + conn_type = "wifi" diff --git a/config/reader/Node.py b/config/reader/Node.py new file mode 100644 index 0000000..a748646 --- /dev/null +++ b/config/reader/Node.py @@ -0,0 +1,184 @@ +""" +Created on July 30, 2020 +File contains the class that will store nodes. + +@file Node.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.07.30 +@version 0.1 +@company University of Alberta - Computing Science +""" + +from config.reader.ConfigErrors import ImmutableObjectError +from config.reader.ValidationFunctions import check_location_coordinates, check_non_empty_non_none_string, \ + check_nic_types +from config.reader.NICs import P2PNIC, WiFiNIC + +class Node: + """ + Class was created to store the information on a node. Solely meant to be used by ConfigReader + """ + # Stores the id of the node in the power system + power_id = "" + # Stores the id of the node in the network + network_id = "" + # Stores the network of the system + location = {} + # Stores the NIC card type, should be nic objects that are passed in + nic_types = [] + + def __init__(self, power_id, network_id, location, nic_types): + """ + Validates that all the data necessary is present and is of the correct type and then saves it + :param power_id: + :param network_id: + :param location: + """ + self.__check_power_id_type(power_id) + self.__check_network_id_type(network_id) + check_location_coordinates(location) + check_nic_types(nic_types) + + super(Node, self).__setattr__('power_id', power_id) + super(Node, self).__setattr__('network_id', network_id) + super(Node, self).__setattr__('location', {'x': float(location['x']), 'y': float(location['y'])}) + super(Node, self).__setattr__('nic_types', nic_types) + + def has_p2p_card(self): + """ + Check the nics to see if it has a p2p card. + :return: + """ + return self.__has_type_of_card(P2PNIC) + + def has_wifi_card(self): + """ + Check the nics to see if it has a wifi card. + :return: + """ + return self.__has_type_of_card(WiFiNIC) + + def is_wifi_access_point(self): + """ + Check the nics to see if it has a wifi card. + :return: + """ + # Get wifi cards + wifi_cards = self.__get_type_of_cards(WiFiNIC) + if len(wifi_cards) > 0: + for card in wifi_cards: + if card.access_point: + return True + + return False + + def __setattr__(self, key, value): + """ + Overridden to ensure that nothing in the class is mutable after creation + :param key: + :param value: + :return: + """ + raise ImmutableObjectError + + def __has_type_of_card(self, card_type): + """ + Check to see if Node has a type of card in nic_types + :param card_type: + :return: + """ + if len(self.__get_type_of_cards(card_type)) > 0: + return True + else: + return False + + def __get_type_of_cards(self, card_type): + """ + Gets and returns all the cards of type, well type + :param card_type: + :return: + """ + to_return = [] + for card in self.nic_types: + if isinstance(card, card_type): + to_return.append(card) + + return to_return + + def __check_power_id_type(self, power_id): + """ + Checks that the power id passed in is a non-empty string. + :param power_id: + :return: + """ + check_non_empty_non_none_string(power_id) + + def __check_network_id_type(self, network_id): + """ + Checks that the network id passed in is a non-empty string. + :param network_id: + :return: + """ + check_non_empty_non_none_string(network_id) + + def __eq__(self, other): + """ + Over-ridden to make it easier to compare two nodes and see if they are equal + :param other: + :return: + """ + # Check type of node + if isinstance(other, Node): + return (other.power_id == self.power_id) and \ + (other.network_id == self.network_id) and \ + (other.location["x"] == self.location["x"]) and \ + (other.location["y"] == self.location["y"]) and \ + (self.__compare_nic_types(other.nic_types)) + return False + + def __ne__(self, other): + """ + Over-ridden to make it easier to compare two nodes and see if they are not equal. Just inverts the bool returned + by other. + :param other: + :return: + """ + return not self.__eq__(other) + + def __compare_nic_types(self, other_nics): + """ + Compare's NICs. They need to be in the same order for this to be successful. + :param other_nics: + :return: + """ + # If the length is not the same, return false + if len(self.nic_types) != len(other_nics): + return False + + # If the length if the same, start comparing the NIC types + for i in range(0, len(self.nic_types)): + if self.nic_types[i] != other_nics[i]: + return False + + # Everything matches, return true + return True + + def __str__(self): + """ + Returns a string describing the node. + :return: + """ + string_to_return = "\nNode Object: \n" \ + "\t power_id: " + self.power_id + "\n" \ + "\t network_id: " + self.network_id + "\n" \ + "\t location: " + self.network_id + "\n" \ + "\t nics: " + + for nic in self.nic_types: + string_to_return += ("(" + str(nic) + "), ") + + string_to_return = string_to_return[:-2] + string_to_return += "\n" + + return string_to_return diff --git a/config/reader/ValidationFunctions.py b/config/reader/ValidationFunctions.py new file mode 100644 index 0000000..0079b6e --- /dev/null +++ b/config/reader/ValidationFunctions.py @@ -0,0 +1,152 @@ +""" +Created on July 30, 2020 +File contains all the validation tests needed to make sure the values stored in the Classes are valid. + +@file ValidationFunctions.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.07.30 +@version 0.1 +@company University of Alberta - Computing Science +""" + +from config.reader.ConfigErrors import InvalidNetworkType, InvalidAccessPointValueForNICType, \ + NetworkConnectionNumberOfNodesNotCorrect, NetworkConnectionHasNodesWithConnectionToSelf, \ + InvalidNetworkConnectionType, InvalidAppConnectionType +from config.reader.NICs import P2PNIC, WiFiNIC +from config.reader.NetworkConnectionTypes import NetworkConnectionWiFi, NetworkConnectionP2P +from config.reader.AppConnectionsTypes import ControlAppConnectionPathType, ActuatorAppConnectionPathType +from math import sqrt +from config.reader.ConfigHelpers import find_access_point_in_wifi_nodes, find_non_access_point_in_wifi_nodes + +# Stores the valid types of nics +valid_nic_types = [P2PNIC, WiFiNIC] +valid_network_connection_types = [NetworkConnectionP2P, NetworkConnectionWiFi] +valid_app_connection_types = [ActuatorAppConnectionPathType, ControlAppConnectionPathType] + + +def check_non_empty_non_none_string(to_check): + """ + Created to check that to_check is not None, is not an empty string and is not of some other type + :param to_check: + :return: + """ + if isinstance(to_check, str) and to_check == "": + raise ValueError + elif not isinstance(to_check, str) or to_check is None: + raise TypeError + + +def check_location_coordinates(location_to_check): + """ + Check the location to make sure that it has both x and y parts, then checks that both x and y can be converted + into doubles. + :param location_to_check: + :return: + """ + if 'x' not in location_to_check or 'y' not in location_to_check: + raise KeyError + + float(location_to_check['x']) + float(location_to_check['y']) + + +def check_nic_types(nics_to_check): + """ + Check to make sure that all the nics in nics_to_check are of type valid_nic_types and that there are not duplicated. + :param nics_to_check: + :return: + """ + types_found = [] + # Iterate through every type and make sure there are no duplicated + for nic in nics_to_check: + found = False + + for valid_nic in valid_nic_types: + if isinstance(nic, valid_nic): + found = True + break + + if not found: + raise InvalidNetworkType + + types_found.append(nic.nic_type) + + +def check_if_passed_in_is_of_valid_type(passed_in, valid_types): + """ + Iterates through valid_types to check if passed_in is of that type. + :param passed_in: + :param valid_types: + :return: + """ + found = False + for valid_type in valid_types: + if isinstance(passed_in, valid_type): + found = True + break + + return found + + +def check_network_connection_types(network_connection_type): + """ + Check to see if the network connection type is of a valid type. + :param network_connection_type: + :return: + """ + found = check_if_passed_in_is_of_valid_type(network_connection_type, valid_network_connection_types) + + if not found: + raise InvalidNetworkConnectionType + + +def check_app_connection_types(app_connection_type): + """ + Check if the app connection type is of a valid type + :param app_connection_type: + :return: + """ + found = check_if_passed_in_is_of_valid_type(app_connection_type, valid_app_connection_types) + + if not found: + raise InvalidAppConnectionType + + +def check_network_connection_nodes(nodes): + """ + Method checks to make sure there are only two nodes passed into the connection. Also checks to make sure that each + node is valid using check_non_empty_non_none_string. + :param nodes: + :return: + """ + if len(nodes) != 2: + raise NetworkConnectionNumberOfNodesNotCorrect + + if len(set(nodes)) != len(nodes): + raise NetworkConnectionHasNodesWithConnectionToSelf + + # Now make sure every node is valid + for node in nodes: + check_non_empty_non_none_string(node) + + +def check_distance_between_wifi_access_point_and_node(nodes): + """ + Check the distance between ap and node to make sure it is less than 50m. + :param nodes: + :return: + """ + # Make sure there are only two nodes in nodes + if len(nodes) != 2: + raise NetworkConnectionNumberOfNodesNotCorrect + + ap = find_access_point_in_wifi_nodes(nodes) + node = find_non_access_point_in_wifi_nodes(nodes) + + distance = sqrt(((ap.location['x'] - node.location['x']) ** 2) + ((ap.location['y'] - node.location['y']) ** 2)) + + if distance < 50: + return True + else: + return False diff --git a/config/reader/tests/AppConnectionsTestCases.py b/config/reader/tests/AppConnectionsTestCases.py new file mode 100644 index 0000000..1e4c8a7 --- /dev/null +++ b/config/reader/tests/AppConnectionsTestCases.py @@ -0,0 +1,185 @@ +""" +Created on August 05, 2020 +File contains the types of network connections + +@file AppConnectionsTestCases.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.08.05 +@version 0.1 +@company University of Alberta - Computing Science +""" + +import unittest +from config.reader.AppConnections import AppConnections +from config.reader.AppConnectionsTypes import ControlAppConnectionPathType, ActuatorAppConnectionPathType, \ + BaseAppConnectionPathType +from config.reader.ConfigErrors import InvalidAppConnectionType + + +class AppConnectionsTestCases(unittest.TestCase): + """ + Tests were created to test the AppConnections class + """ + + def test_sender_none(self): + """ + Create a app connection where the sender is none, should throw an error + :return: + """ + with self.assertRaises(TypeError): + app_conn = AppConnections(None, "123", ControlAppConnectionPathType()) + + def test_sender_empty(self): + """ + Create a app connection where the sender is empty, should throw an error + :return: + """ + with self.assertRaises(ValueError): + app_conn = AppConnections("", "123", ControlAppConnectionPathType()) + + def test_sender_type(self): + """ + Create a app connection where the sender is non-string, should throw an error + :return: + """ + with self.assertRaises(TypeError): + app_conn = AppConnections(1, "123", ControlAppConnectionPathType()) + + def test_receiver_none(self): + """ + Create a app connection where the receiver is none, should throw an error + :return: + """ + with self.assertRaises(TypeError): + app_conn = AppConnections("123", None, ControlAppConnectionPathType()) + + def test_receiver_empty(self): + """ + Create a app connection where the receiver is empty, should throw an error + :return: + """ + with self.assertRaises(ValueError): + app_conn = AppConnections("123", "", ControlAppConnectionPathType()) + + def test_receiver_type(self): + """ + Create a app connection where the receiver is non-string, should throw an error + :return: + """ + with self.assertRaises(TypeError): + app_conn = AppConnections("123", 1, ControlAppConnectionPathType()) + + def test_app_connections_base_type(self): + """ + Create a app connection where the path type is base, should throw an error + :return: + """ + with self.assertRaises(InvalidAppConnectionType): + app_conn = AppConnections("123", "123", BaseAppConnectionPathType()) + + def test_app_connections_actuator_type(self): + """ + Create a app connection where the path type is actuator, no error + :return: + """ + app_conn = AppConnections("123", "123", ActuatorAppConnectionPathType()) + + def test_app_connections_control_type(self): + """ + Create a app connection where the path type is control, no error + :return: + """ + app_conn = AppConnections("123", "123", ControlAppConnectionPathType()) + + def test_eq_equal(self): + """ + Compare two app cons that have the sender, receiver and path type being equal. + :return: + """ + ac1 = AppConnections("123", "123", ControlAppConnectionPathType()) + ac2 = AppConnections("123", "123", ControlAppConnectionPathType()) + self.assertTrue(ac1 == ac2) + + ac1 = AppConnections("321", "123", ActuatorAppConnectionPathType()) + ac2 = AppConnections("321", "123", ActuatorAppConnectionPathType()) + self.assertTrue(ac1 == ac2) + + def test_eq_not_equal_sender(self): + """ + Compare two app conns that do not have the same sender and test eq operator. + :return: + """ + ac1 = AppConnections("123", "123", ControlAppConnectionPathType()) + ac2 = AppConnections("321", "123", ControlAppConnectionPathType()) + self.assertFalse(ac1 == ac2) + + def test_eq_not_equal_receiver(self): + """ + Compare two app conns that do not have the same receiver and test eq operator. + :return: + """ + ac1 = AppConnections("123", "123", ControlAppConnectionPathType()) + ac2 = AppConnections("123", "321", ControlAppConnectionPathType()) + self.assertFalse(ac1 == ac2) + + def test_eq_not_equal_path_type(self): + """ + Compare two app conns that do not have the same path type and test eq operator. + :return: + """ + ac1 = AppConnections("123", "123", ControlAppConnectionPathType()) + ac2 = AppConnections("123", "123", ActuatorAppConnectionPathType()) + self.assertFalse(ac1 == ac2) + + ac1 = AppConnections("123", "123", ActuatorAppConnectionPathType()) + ac2 = AppConnections("123", "123", ControlAppConnectionPathType()) + self.assertFalse(ac1 == ac2) + + def test_ne_equal(self): + """ + Compare two equal app cons using not equal operator. + :return: + """ + ac1 = AppConnections("123", "123", ControlAppConnectionPathType()) + ac2 = AppConnections("123", "123", ControlAppConnectionPathType()) + self.assertFalse(ac1 != ac2) + + ac1 = AppConnections("321", "123", ActuatorAppConnectionPathType()) + ac2 = AppConnections("321", "123", ActuatorAppConnectionPathType()) + self.assertFalse(ac1 != ac2) + + def test_ne_not_equal_sender(self): + """ + Compare two not equal sender using the not equal operator. + :return: + """ + ac1 = AppConnections("123", "123", ControlAppConnectionPathType()) + ac2 = AppConnections("321", "123", ControlAppConnectionPathType()) + self.assertTrue(ac1 != ac2) + + def test_ne_not_equal_receiver(self): + """ + Compare two not equal receiver using the not equal operator. + :return: + """ + ac1 = AppConnections("123", "123", ControlAppConnectionPathType()) + ac2 = AppConnections("123", "321", ControlAppConnectionPathType()) + self.assertTrue(ac1 != ac2) + + def test_ne_not_equal_path_type(self): + """ + Compare two app conns that do not have the same path type and test != operator. + :return: + """ + ac1 = AppConnections("123", "123", ControlAppConnectionPathType()) + ac2 = AppConnections("123", "123", ActuatorAppConnectionPathType()) + self.assertTrue(ac1 != ac2) + + ac1 = AppConnections("123", "123", ActuatorAppConnectionPathType()) + ac2 = AppConnections("123", "123", ControlAppConnectionPathType()) + self.assertTrue(ac1 != ac2) + + +if __name__ == '__main__': + unittest.main() diff --git a/config/reader/tests/ConfigTestCases.py b/config/reader/tests/ConfigTestCases.py new file mode 100644 index 0000000..a8a967b --- /dev/null +++ b/config/reader/tests/ConfigTestCases.py @@ -0,0 +1,320 @@ +""" +Created on July 30, 2020 +File contains tests that will test the reading/verification of config files that are being read by Config + +@file ConfigTestCases.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.07.30 +@version 0.1 +@company University of Alberta - Computing Science +""" +import unittest +from config.reader.Config import Config +from config.reader.Node import Node +from config.reader.NICs import P2PNIC, WiFiNIC +from config.reader.NetworkConnection import NetworkConnection +from config.reader.AppConnections import AppConnections +from config.reader.AppConnectionsTypes import ControlAppConnectionPathType, ActuatorAppConnectionPathType +from config.reader.ConfigErrors import NodeWithNetworkIdAlreadyExistsInNetwork, NodeWithPowerIdAlreadyExistsInNetwork, \ + InvalidNetworkType, NetworkConnectionAlreadyExists, NodeInNetworkConnectionDoesHaveCorrectNIC, \ + NoAccessPointFoundInNetworkConnection, NoNonAccessPointFoundInNetworkConnection, \ + NodeInNetworkConnectionDoesNotExist, NodeInAppConnectionDoesNotExist, InvalidAppConnectionType, \ + NodeTooFarAwayFromAccessPoint +from config.reader.NetworkConnectionTypes import NetworkConnectionP2P, NetworkConnectionWiFi + + +class ConfigTestCases(unittest.TestCase): + def test_valid_file(self): + """ + Testing a valid file with ieee13.json. Should produce no errors. + :return: + """ + file = open("TestFiles/ieee13.json") + config = Config(file) + config.read_config() + print(config.get_network_connections_as_json()) + file.close() + + def test_valid_nodes(self): + """ + Passes a file which has valid nodes into Config, no error + :return: + """ + valid_nodes_list = [ + Node("622", "3", {"x": "100", "y": "120"}, [P2PNIC(), WiFiNIC(True)]), + Node("612", "4", {"x": "110", "y": "130"}, [P2PNIC()]), + Node("632", "5", {"x": "120", "y": "140"}, [WiFiNIC()]) + ] + + # Read the file + file = open("TestFiles/valid_nodes.json") + config = Config(file) + config.read_config() + # Should have read 3 nodes + self.assertEqual(len(config.nodes), len(valid_nodes_list)) + + # Iterate through the nodes to check their properties + for i in range(0, len(valid_nodes_list)): + self.assertTrue(valid_nodes_list[i] == config.nodes[i]) + + # Everything else should be empty + self.assertEqual(len(config.network_connections), 0) + self.assertEqual(len(config.app_connections), 0) + # Close the file + file.close() + + def __open_file_and_wait_to_raise(self, file_to_open, exception_type): + """ + Opens the file passed in, then check if the exception with type is is raised + :return: + """ + file = open(file_to_open) + config = Config(file) + + with self.assertRaises(exception_type): + config.read_config() + + file.close() + + def __compare_valid_network_connections(self, file_to_open, connections_to_check): + """ + Open the file, create the connections, then check against connections_to_check + :param file_to_open: + :param connections_to_check: + :return: + """ + # Read the file + file = open(file_to_open) + config = Config(file) + config.read_config() + # Check the number of connections is correct + self.assertEqual(len(connections_to_check), len(config.network_connections)) + + # Now iterate and check the network connections + for i in range(0, len(connections_to_check)): + self.assertTrue(connections_to_check[i] == config.network_connections[i]) + + # Close the file + file.close() + + def test_duplicate_power_id_nodes(self): + """ + Passes a file with duplicate power id nodes into Config, should produce an error + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/duplicate_power_id_nodes.json", + NodeWithPowerIdAlreadyExistsInNetwork) + + def test_duplicate_network_id_nodes(self): + """ + Passes a file with duplicate network id nodes into Config, should produce an error + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/duplicate_network_id_nodes.json", + NodeWithNetworkIdAlreadyExistsInNetwork) + + def test_nic_wrong_type(self): + """ + Read a file where the NIC type is not valid + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/wrong_type_nic.json", + InvalidNetworkType) + + def test_valid_p2p_network_connections(self): + """ + Read a file where the network connections are all p2p and are valid. + :return: + """ + # Network connections that should be created + network_conns = [ + NetworkConnection(["11111", "11112"], NetworkConnectionP2P()), + NetworkConnection(["11112", "11113"], NetworkConnectionP2P()), + NetworkConnection(["11113", "11115"], NetworkConnectionP2P()), + NetworkConnection(["11115", "11114"], NetworkConnectionP2P()), + NetworkConnection(["11114", "11113"], NetworkConnectionP2P()), + ] + + self.__compare_valid_network_connections("TestFiles/valid_network_connections_p2p.json", network_conns) + + def test_valid_wifi_network_connections(self): + """ + Read a file where the network connections are all wifi and are valid. + :return: + """ + network_conns = [ + NetworkConnection(["21", "22"], NetworkConnectionWiFi()), + NetworkConnection(["21", "25"], NetworkConnectionWiFi()), + NetworkConnection(["23", "24"], NetworkConnectionWiFi()) + ] + self.__compare_valid_network_connections("TestFiles/valid_network_connections_wifi.json", network_conns) + + def test_valid_mixed_network_connections(self): + """ + Read a file where the network connections are wifi and p2p mixed and are valid. + :return: + """ + # Network connections that should be created + network_conns = [ + NetworkConnection(["1111", "1112"], NetworkConnectionP2P()), + NetworkConnection(["1112", "1113"], NetworkConnectionP2P()), + NetworkConnection(["1113", "1115"], NetworkConnectionP2P()), + NetworkConnection(["1115", "1114"], NetworkConnectionP2P()), + NetworkConnection(["1114", "1113"], NetworkConnectionP2P()), + NetworkConnection(["1111", "1115"], NetworkConnectionWiFi()), + ] + # Read the file + self.__compare_valid_network_connections("TestFiles/valid_network_connections_mixed.json", network_conns) + + def test_not_valid_duplicate_p2p(self): + """ + Read a file where the network connections are all p2p, but are not valid because there are duplicates. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_network_duplicate_p2p.json", + NetworkConnectionAlreadyExists) + + def test_not_valid_duplicate_wifi(self): + """ + Read a file where the network connections are all wifi, but are not valid because there are duplicates. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_network_duplicate_wifi.json", + NetworkConnectionAlreadyExists) + + def test_not_valid_duplicate_mixed(self): + """ + Read a file where the network connections are wifi and p2p, but are not valid because there are duplicates. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_network_duplicate_mixed.json", + NetworkConnectionAlreadyExists) + + def test_not_valid_missing_nic_p2p(self): + """ + Read a file where the network connections p2p, but one of the nodes does not have a p2p nic card. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_network_missing_nic_p2p.json", + NodeInNetworkConnectionDoesHaveCorrectNIC) + + def test_not_valid_missing_nic_wifi(self): + """ + Read a file where the network connections wifi, but one of the nodes does not have a wifi nic card. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_network_missing_nic_wifi.json", + NodeInNetworkConnectionDoesHaveCorrectNIC) + + def test_not_valid_wifi_no_access_point(self): + """ + Read a file where the network connections wifi, the connections are valid except there are no access points. So, + there should be an error. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_network_wifi_no_access_point.json", + NoAccessPointFoundInNetworkConnection) + + def test_not_valid_wifi_only_access_point(self): + """ + Read a file where the network connections wifi, the connections are valid except there are only access points. + So, there should be an error. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_network_wifi_no_non_access_point.json", + NoNonAccessPointFoundInNetworkConnection) + + def test_missing_network_id(self): + """ + Create valid network connections, but the nodes on one of the connections is missing. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_network_missing_node.json", + NodeInNetworkConnectionDoesNotExist) + + def test_node_one_missing(self): + """ + Check to see if config reader will fail if node one in an app connection is missing. Error should be thrown. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_app_conn_node_one_missing.json", + NodeInAppConnectionDoesNotExist) + + def test_node_two_missing(self): + """ + Check to see if config reader will fail if node two in an app connection is missing. Error should be thrown. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_app_conn_node_two_missing.json", + NodeInAppConnectionDoesNotExist) + + def test_wrong_connection_types(self): + """ + Will pass in invalid path type of app connections, errors should be thrown. + :return: + """ + self.__open_file_and_wait_to_raise("TestFiles/not_valid_app_conn_wrong_path_type_one.json", + InvalidAppConnectionType) + self.__open_file_and_wait_to_raise("TestFiles/not_valid_app_conn_wrong_path_type_two.json", + InvalidAppConnectionType) + + def test_valid_app_connection(self): + """ + Will pass in valid app connections of different types. Should work. + :return: + """ + valid_app_conns_list = [ + AppConnections("-111", "-222", ControlAppConnectionPathType()), + AppConnections("-333", "-444", ActuatorAppConnectionPathType()) + ] + # Read the file + file = open("TestFiles/valid_app_conns.json") + config = Config(file) + config.read_config() + # Should have read 3 nodes + self.assertEqual(len(config.app_connections), len(valid_app_conns_list)) + + # Iterate through the nodes to check their properties + for i in range(0, len(valid_app_conns_list)): + self.assertTrue(valid_app_conns_list[i] == config.app_connections[i]) + + # Close the file + file.close() + + def test_distance_too_far_p2p(self): + """ + In this case, the distance should not matter. The layout should be valid. + :return: + """ + file = open("TestFiles/valid_network_connections_distance_p2p.json") + config = Config(file) + config.read_config() + file.close() + + def test_distance_too_far_wifi(self): + """ + In this case, distance should matter, should get an exception. + :return: + """ + file = open("TestFiles/invalid_network_connections_distance_wifi.json") + config = Config(file) + + with self.assertRaises(NodeTooFarAwayFromAccessPoint): + config.read_config() + + file.close() + + def test_distance_close_enough_wifi(self): + """ + In this case, distance should matter, but should be valid. + :return: + """ + file = open("TestFiles/valid_network_connections_distance_wifi.json") + config = Config(file) + config.read_config() + file.close() + + +if __name__ == '__main__': + unittest.main() diff --git a/config/reader/tests/NICTestCases.py b/config/reader/tests/NICTestCases.py new file mode 100644 index 0000000..7bfe918 --- /dev/null +++ b/config/reader/tests/NICTestCases.py @@ -0,0 +1,123 @@ +""" +Created on August 5, 2020 +File contains the class that will test NIC class. Super simple in this case. + +@file NICTestCases.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.08.05 +@version 0.1 +@company University of Alberta - Computing Science +""" + +import unittest + +from config.reader.NICs import NIC, P2PNIC, WiFiNIC +from config.reader.ConfigErrors import ImmutableObjectError + + +class AllNICTestCases(unittest.TestCase): + """ + Tests were created to test the NIC class and its sub-classes + """ + + def test_type_of_nic_base(self): + """ + Tests the type of NIC base class. No error + :return: + """ + nic = NIC() + self.assertEqual("base", nic.nic_type, "TYPE FOR BASE NIC CLASS IS NOT base") + + def test_type_of_nic_p2p(self): + """ + Tests the type of NIC p2p class. No Error + :return: + """ + nic = P2PNIC() + self.assertEqual("p2p", nic.nic_type, "TYPE FOR BASE NIC CLASS IS NOT p2p") + + def test_change_of_type_in_nic_p2p(self): + """ + Tries to change the type of the P2P NIC card. Should throw an error. + :return: + """ + with self.assertRaises(ImmutableObjectError): + nic = P2PNIC() + nic.nic_type = "another_type" + + def test_type_of_nic_wifi(self): + """ + Tests the type of NIC wifi class. No Error + :return: + """ + nic = WiFiNIC() + self.assertEqual("wifi", nic.nic_type, "TYPE FOR BASE NIC CLASS IS NOT wifi") + + def test_change_of_type_in_nic_wifi(self): + """ + Tries to change the type of the P2P NIC card. Should throw an error. + :return: + """ + with self.assertRaises(ImmutableObjectError): + nic = WiFiNIC() + nic.nic_type = "another_type" + + def test_access_point_setting_at_init_in_wifi_nic(self): + """ + Checks that the wifi access point can be set to false/true at the init of WifiNIC + :return: + """ + # Create a NIC without setting access_point + nic = WiFiNIC() + self.assertEqual(False, nic.access_point, "WIFI NIC ACCESS POINT NOW FALSE WHEN NOT SET IN INIT") + nic = WiFiNIC(access_point=False) + self.assertEqual(False, nic.access_point, "WIFI NIC ACCESS POINT NOW FALSE WHEN SET IN INIT") + nic = WiFiNIC(access_point=True) + self.assertEqual(True, nic.access_point, "WIFI NIC ACCESS POINT NOW TRUE WHEN SET IN INIT") + + def test_eq_for_all_types(self): + """ + Check the equality operator for each type. + :return: + """ + nic1 = WiFiNIC() + nic2 = WiFiNIC() + self.assertTrue(nic1 == nic2) + + nic1 = P2PNIC() + nic2 = P2PNIC() + self.assertTrue(nic1 == nic2) + + nic1 = WiFiNIC(access_point=True) + nic2 = WiFiNIC(access_point=True) + self.assertTrue(nic1 == nic2) + + nic1 = WiFiNIC(access_point=True) + nic2 = WiFiNIC(access_point=False) + self.assertFalse(nic1 == nic2) + + def test_ne_for_all_types(self): + """ + Check if the __ne__ operator is working correctly. + :return: + """ + nic1 = WiFiNIC() + nic2 = WiFiNIC() + self.assertFalse(nic1 != nic2) + + nic1 = P2PNIC() + nic2 = P2PNIC() + self.assertFalse(nic1 != nic2) + + nic1 = WiFiNIC(access_point=True) + nic2 = WiFiNIC(access_point=True) + self.assertFalse(nic1 != nic2) + + nic1 = WiFiNIC(access_point=True) + nic2 = WiFiNIC(access_point=False) + self.assertTrue(nic1 != nic2) + + +if __name__ == '__main__': + unittest.main() diff --git a/config/reader/tests/NetworkConnectionTestCases.py b/config/reader/tests/NetworkConnectionTestCases.py new file mode 100644 index 0000000..3dd7745 --- /dev/null +++ b/config/reader/tests/NetworkConnectionTestCases.py @@ -0,0 +1,207 @@ +""" +Created on July 30, 2020 +Test cases for testing NetworkConnections + +@file NetworkConnectionTestCases.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.07.30 +@version 0.1 +@company University of Alberta - Computing Science +""" + +import unittest +from config.reader.ConfigErrors import NetworkConnectionNumberOfNodesNotCorrect, \ + NetworkConnectionHasNodesWithConnectionToSelf, InvalidNetworkConnectionType +from config.reader.NetworkConnection import NetworkConnection +from config.reader.NetworkConnectionTypes import NetworkConnectionP2P, NetworkConnectionTypeBase, NetworkConnectionWiFi + + +class NetworkConnectionTestCases(unittest.TestCase): + """ + Tests were created to test the NetworkConnection class + """ + def test_too_many_nodes(self): + """ + Creates a NetworkConnection with too many nodes, should throw an error + :return: + """ + with self.assertRaises(NetworkConnectionNumberOfNodesNotCorrect): + nc = NetworkConnection(["123", "321", "5432"], NetworkConnectionP2P()) + + def test_too_few_nodes(self): + """ + Create a NetworkConnection with too few nodes, should throw an error + :return: + """ + with self.assertRaises(NetworkConnectionNumberOfNodesNotCorrect): + nc = NetworkConnection(["123", "321", "5432"], NetworkConnectionWiFi()) + + def test_network_connection_to_self(self): + """ + Create a NetworkConnection where a node is connected to itself, should throw an error + :return: + """ + with self.assertRaises(NetworkConnectionHasNodesWithConnectionToSelf): + nc = NetworkConnection(["123", "123"], NetworkConnectionWiFi()) + + def test_correct_number_of_nodes(self): + """ + Creates a NetworkConnection with the correct number of nodes, should not throw an error + :return: + """ + nc = NetworkConnection(["123", "312"], NetworkConnectionWiFi()) + + def test_correct_network_type_wifi(self): + """ + Creates a NetworkConnection with an correct type of network ie, wifi + :return: + """ + nc = NetworkConnection(["123", "321"], NetworkConnectionWiFi()) + + def test_correct_network_type_p2p(self): + """ + Creates a NetworkConnection with an correct type of network ie, p2p + :return: + """ + nc = NetworkConnection(["123", "321"], NetworkConnectionP2P()) + + def test_incorrect_network_type(self): + """ + Creates a NetworkConnection with an incorrect type of network ie, not wifi and not p2p, should throw an error + :return: + """ + with self.assertRaises(InvalidNetworkConnectionType): + nc = NetworkConnection(["123", "321"], NetworkConnectionTypeBase()) + + def test_eq_is_equal_network_connection(self): + """ + Test network connections that are equal with the == operator. + :return: + """ + nc1 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + nc2 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + self.assertTrue(nc1 == nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + nc2 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + self.assertTrue(nc1 == nc2) + + def test_eq_not_equal_network_connection(self): + """ + Test network connections that are not equal with the == operator. + :return: + """ + nc1 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + nc2 = NetworkConnection(["3", "2"], NetworkConnectionP2P()) + self.assertFalse(nc1 == nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + nc2 = NetworkConnection(["1", "3"], NetworkConnectionP2P()) + self.assertFalse(nc1 == nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + nc2 = NetworkConnection(["3", "2"], NetworkConnectionWiFi()) + self.assertFalse(nc1 == nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + nc2 = NetworkConnection(["1", "3"], NetworkConnectionWiFi()) + self.assertFalse(nc1 == nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + nc2 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + self.assertFalse(nc1 == nc2) + + def test_ne_is_equal_network_connection(self): + """ + Test network connections that are equal with the != operator. + :return: + """ + nc1 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + nc2 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + self.assertFalse(nc1 != nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + nc2 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + self.assertFalse(nc1 != nc2) + + def test_ne_not_equal_network_connection(self): + """ + Test network connections that are not equal with the != operator. + :return: + """ + nc1 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + nc2 = NetworkConnection(["3", "2"], NetworkConnectionP2P()) + self.assertTrue(nc1 != nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + nc2 = NetworkConnection(["1", "3"], NetworkConnectionP2P()) + self.assertTrue(nc1 != nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + nc2 = NetworkConnection(["3", "2"], NetworkConnectionWiFi()) + self.assertTrue(nc1 != nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + nc2 = NetworkConnection(["1", "3"], NetworkConnectionWiFi()) + self.assertTrue(nc1 != nc2) + + nc1 = NetworkConnection(["1", "2"], NetworkConnectionWiFi()) + nc2 = NetworkConnection(["1", "2"], NetworkConnectionP2P()) + self.assertTrue(nc1 != nc2) + + def test_eq_is_equal_network_connection_type(self): + """ + Check the connection type with == when they are both equal + :return: + """ + nct1 = NetworkConnectionWiFi() + nct2 = NetworkConnectionWiFi() + self.assertTrue(nct1 == nct2) + + nct1 = NetworkConnectionP2P() + nct2 = NetworkConnectionP2P() + self.assertTrue(nct1 == nct2) + + def test_eq_not_equal_network_connection_type(self): + """ + Check the connection type with == when they are not equal + :return: + """ + nct1 = NetworkConnectionWiFi() + nct2 = NetworkConnectionP2P() + self.assertFalse(nct1 == nct2) + + nct1 = NetworkConnectionP2P() + nct2 = NetworkConnectionWiFi() + self.assertFalse(nct1 == nct2) + + def test_ne_is_equal_network_connection_type(self): + """ + Check the connection type with != when they are both equal + :return: + """ + nct1 = NetworkConnectionWiFi() + nct2 = NetworkConnectionWiFi() + self.assertFalse(nct1 != nct2) + + nct1 = NetworkConnectionP2P() + nct2 = NetworkConnectionP2P() + self.assertFalse(nct1 != nct2) + + def test_ne_not_equal_network_connection_type(self): + """ + Check the connection type with != when they are not equal + :return: + """ + nct1 = NetworkConnectionWiFi() + nct2 = NetworkConnectionP2P() + self.assertTrue(nct1 != nct2) + + nct1 = NetworkConnectionP2P() + nct2 = NetworkConnectionWiFi() + self.assertTrue(nct1 != nct2) + + +if __name__ == '__main__': + unittest.main() diff --git a/config/reader/tests/NodeTestCases.py b/config/reader/tests/NodeTestCases.py new file mode 100644 index 0000000..3fefa19 --- /dev/null +++ b/config/reader/tests/NodeTestCases.py @@ -0,0 +1,287 @@ +""" +Created on July 30, 2020 +File contains the class that will store nodes. + +@file NodeTestCases.py +@author Amrinder S. Grewal +@email asgrewal@ualberta.ca +@date 2020.07.30 +@version 0.1 +@company University of Alberta - Computing Science +""" +import unittest + +from config.reader.Node import Node +from config.reader.NICs import P2PNIC, WiFiNIC, NIC +from config.reader.ConfigErrors import InvalidNetworkType, InvalidAccessPointValueForNICType + + +class NodeTestCases(unittest.TestCase): + """ + Tests were created to test the Node class + """ + + def test_power_id_none(self): + """ + Create a power id that is None, should throw an error + :return: + """ + with self.assertRaises(TypeError): + node = Node(None, "test", {"x": "123", "y": "321"}, [P2PNIC()]) + + def test_power_id_empty(self): + """ + Create a power id that is an empty string, should throw an error + :return: + """ + with self.assertRaises(ValueError): + node = Node("", "test", {"x": "123", "y": "321"}, [P2PNIC()]) + + def test_power_id_type(self): + """ + Create a non-empty and non-None power id, should not throw an error + :return: + """ + with self.assertRaises(TypeError): + node = Node(1, "test", {"x": "123", "y": "321"}, [P2PNIC()]) + + def test_network_id_none(self): + """ + Create a network id that is None, should throw an error + :return: + """ + with self.assertRaises(TypeError): + node = Node("test", None, {"x": "123", "y": "321"}, [P2PNIC()]) + + def test_network_id_empty(self): + """ + Create a network id that is an empty string, should throw an error + :return: + """ + with self.assertRaises(ValueError): + node = Node("test", "", {"x": "123", "y": "321"}, [P2PNIC()]) + + def test_network_id_type(self): + """ + Create a non-empty and non-None network id, should not throw an error + :return: + """ + with self.assertRaises(TypeError): + node = Node("test", 1, {"x": "123", "y": "321"}, [P2PNIC()]) + + def test_missing_location_x(self): + """ + Create a location with the x missing, should throw an error + :return: + """ + with self.assertRaises(KeyError): + node = Node("test", "test", {"y", "123"}, [P2PNIC()]) + + def test_missing_location_y(self): + """ + Create a location with the y missing, should throw an error + :return: + """ + with self.assertRaises(KeyError): + node = Node("test", "test", {"x": "123"}, [P2PNIC()]) + + def test_non_num_location_x(self): + """ + Create a non num location for x in node location, should throw an error + :return: + """ + with self.assertRaises(ValueError): + node = Node("test", "test", {"x": "a", "y": "123.1"}, [P2PNIC()]) + + def test_non_num_location_y(self): + """ + Create a non num location for y in node location, should throw an error + :return: + """ + with self.assertRaises(ValueError): + node = Node("test", "test", {"x": "321", "y": "b"}, [P2PNIC()]) + + def test_none_location_x(self): + """ + Create a none location for x in node location, should throw an error + :return: + """ + with self.assertRaises(TypeError): + node = Node("test", "test", {"x": None, "y": "123"}, [P2PNIC()]) + + def test_none_location_y(self): + """ + Create a none location for y in node location, should throw an error + :return: + """ + with self.assertRaises(TypeError): + node = Node("test", "test", {"x": "321", "y": None}, [P2PNIC()]) + + def test_no_nic(self): + """ + Create a Node with no NIC, should produce no error + :return: + """ + node = Node("test", "test", {"x": "321", "y": "321"}, []) + + def test_incorrect_type_nic(self): + """ + Create a base type of NIC and a string, should create an error. + :return: + """ + with self.assertRaises(InvalidNetworkType): + node = Node("test", "test", {"x": "321", "y": "321"}, [NIC()]) + + with self.assertRaises(InvalidNetworkType): + node = Node("test", "test", {"x": "321", "y": "321"}, ["p2p"]) + + def test_correct(self): + """ + Everything is correct, no error should be raised. + :return: + """ + node = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + node = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC()]) + node = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC(access_point=True)]) + + def test_eq_incorrect_type(self): + """ + Create two identical nodes and check if they are equal. They should not be equal. + :return: + """ + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = "123" + self.assertFalse(n1 == n2) + + def test_eq_is_equal(self): + """ + Create two identical nodes and check if they are equal. They should be equal. + :return: + """ + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + self.assertTrue(n1 == n2) + + def test_eq_not_equal(self): + """ + Create two non-identical nodes and check if they are equal. They should not be equal. + :return: + """ + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test1", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + self.assertFalse(n1 == n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test1", {"x": "321", "y": "321"}, [P2PNIC()]) + self.assertFalse(n1 == n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "3211", "y": "321"}, [P2PNIC()]) + self.assertFalse(n1 == n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "321", "y": "3211"}, [P2PNIC()]) + self.assertFalse(n1 == n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC()]) + self.assertFalse(n1 == n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC(), P2PNIC()]) + self.assertFalse(n1 == n2) + + def test_ne_incorrect_type(self): + """ + Create two identical nodes and check if they are equal. Should be true, they are not equal + :return: + """ + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = "123" + self.assertTrue(n1 != n2) + + def test_ne_is_equal(self): + """ + Create two identical nodes check if they are not equal. Should be false, since they are equal. + :return: + """ + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + self.assertFalse(n1 != n2) + + def test_ne_not_equal(self): + """ + Create two non-identical nodes to check if they are not equal. Should be true, since they are not equal. + :return: + """ + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test1", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + self.assertTrue(n1 != n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test1", {"x": "321", "y": "321"}, [P2PNIC()]) + self.assertTrue(n1 != n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "3211", "y": "321"}, [P2PNIC()]) + self.assertTrue(n1 != n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "321", "y": "3211"}, [P2PNIC()]) + self.assertTrue(n1 != n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC()]) + self.assertTrue(n1 != n2) + + n1 = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + n2 = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC(), P2PNIC()]) + self.assertTrue(n1 != n2) + + def test_has_p2p_card(self): + """ + Check to see if has_p2p_card method is working properly + :return: + """ + n = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + self.assertTrue(n.has_p2p_card()) + + n = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC()]) + self.assertFalse(n.has_p2p_card()) + + n = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC(), WiFiNIC()]) + self.assertTrue(n.has_p2p_card()) + + def test_has_wifi_card(self): + """ + Check to see if has_wifi_card method is working properly + :return: + """ + n = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + self.assertFalse(n.has_wifi_card()) + + n = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC()]) + self.assertTrue(n.has_wifi_card()) + + n = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC(), WiFiNIC()]) + self.assertTrue(n.has_wifi_card()) + + def test_is_wifi_access_point(self): + """ + Check to see if is_wifi_access_point method is working properly + :return: + """ + n = Node("test", "test", {"x": "321", "y": "321"}, [P2PNIC()]) + self.assertFalse(n.is_wifi_access_point()) + + n = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC()]) + self.assertFalse(n.is_wifi_access_point()) + + n = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC(access_point=False)]) + self.assertFalse(n.is_wifi_access_point()) + + n = Node("test", "test", {"x": "321", "y": "321"}, [WiFiNIC(access_point=True)]) + self.assertTrue(n.is_wifi_access_point()) + +if __name__ == '__main__': + unittest.main() diff --git a/config/reader/tests/TestFiles/duplicate_network_id_nodes.json b/config/reader/tests/TestFiles/duplicate_network_id_nodes.json new file mode 100644 index 0000000..67d2755 --- /dev/null +++ b/config/reader/tests/TestFiles/duplicate_network_id_nodes.json @@ -0,0 +1,48 @@ +{ + "network": { + "nodes": [ + { + "id": "6", + "power_network_id": "623", + "location": { + "x": "100", + "y": "120" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + }] + }, + { + "id": "6", + "power_network_id": "613", + "location": { + "x": "110", + "y": "130" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "7", + "power_network_id": "633", + "location": { + "x": "120", + "y": "140" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + }] + } + ], + "network_layout": [] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/duplicate_power_id_nodes.json b/config/reader/tests/TestFiles/duplicate_power_id_nodes.json new file mode 100644 index 0000000..9ae4a12 --- /dev/null +++ b/config/reader/tests/TestFiles/duplicate_power_id_nodes.json @@ -0,0 +1,48 @@ +{ + "network": { + "nodes": [ + { + "id": "0", + "power_network_id": "621", + "location": { + "x": "100", + "y": "120" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + }] + }, + { + "id": "1", + "power_network_id": "621", + "location": { + "x": "110", + "y": "130" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "2", + "power_network_id": "631", + "location": { + "x": "120", + "y": "140" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + }] + } + ], + "network_layout": [] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/ieee13.json b/config/reader/tests/TestFiles/ieee13.json new file mode 100644 index 0000000..9a749d2 --- /dev/null +++ b/config/reader/tests/TestFiles/ieee13.json @@ -0,0 +1,275 @@ +{ + "network": { + "nodes": [ + { + "id": "0", + "power_network_id": "SourceBus", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "1", + "power_network_id": "650", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "2", + "power_network_id": "RG60", + "location": { + "x": "200", + "y": "300" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "3", + "power_network_id": "646", + "location": { + "x": "0", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "4", + "power_network_id": "645", + "location": { + "x": "100", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "5", + "power_network_id": "632", + "location": { + "x": "200", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type":"wifi", + "access_point": true + }] + }, + { + "id": "6", + "power_network_id": "633", + "location": { + "x": "350", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "7", + "power_network_id": "634", + "location": { + "x": "400", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "8", + "power_network_id": "670", + "location": { + "x": "200", + "y": "200" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "9", + "power_network_id": "611", + "location": { + "x": "0", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "10", + "power_network_id": "684", + "location": { + "x": "100", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "11", + "power_network_id": "671", + "location": { + "x": "200", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "12", + "power_network_id": "692", + "location": { + "x": "250", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "13", + "power_network_id": "675", + "location": { + "x": "400", + "y": "100" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "14", + "power_network_id": "652", + "location": { + "x": "100", + "y": "0" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "15", + "power_network_id": "680", + "location": { + "x": "200", + "y": "0" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + } + ], + "app_connections": [ + { + "receiver": "5", + "sender": "9", + "path_type": "control" + }, + { + "receiver": "1", + "sender": "5", + "path_type": "actuator" + }], + "network_layout": [ + { + "nodes":["0", "1"], + "type": "p2p" + }, + { + "nodes":["1", "2"], + "type": "p2p" + }, + { + "nodes":["6", "7"], + "type": "p2p" + }, + { + "nodes":["10", "11"], + "type": "p2p" + }, + { + "nodes":["4", "5"], + "type": "p2p" + }, + { + "nodes":["5", "6"], + "type": "p2p" + }, + { + "nodes":["8", "11"], + "type": "p2p" + }, + { + "nodes":["11", "12"], + "type": "p2p" + }, + { + "nodes":["12", "13"], + "type": "p2p" + }, + { + "nodes":["9", "10"], + "type": "p2p" + }, + { + "nodes":["10", "14"], + "type": "p2p" + }, + { + "nodes":["11", "15"], + "type": "p2p" + }, + { + "nodes":["2", "5"], + "type": "p2p" + }, + { + "nodes":["3", "4"], + "type": "p2p" + }, + { + "nodes":["5", "8"], + "type": "p2p" + } + ] + } +} diff --git a/config/reader/tests/TestFiles/invalid_network_connections_distance_wifi.json b/config/reader/tests/TestFiles/invalid_network_connections_distance_wifi.json new file mode 100644 index 0000000..ae09911 --- /dev/null +++ b/config/reader/tests/TestFiles/invalid_network_connections_distance_wifi.json @@ -0,0 +1,44 @@ +{ + "network": { + "nodes": [ + { + "id": "-1111819", + "power_network_id": "-11118009", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "-1111829", + "power_network_id": "-11181019", + "location": { + "x": "200", + "y": "349" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "-1111819", + "-1111829" + ], + "type": "wifi" + } + ], + "app_connections": [] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_app_conn_node_one_missing.json b/config/reader/tests/TestFiles/not_valid_app_conn_node_one_missing.json new file mode 100644 index 0000000..244098c --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_app_conn_node_one_missing.json @@ -0,0 +1,52 @@ +{ + "network": { + "nodes": [ + { + "id": "1111111111", + "power_network_id": "11111111100", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "1111111112", + "power_network_id": "11111111101", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "1111111111", + "1111111112" + ], + "type": "p2p" + } + ], + "app_connections": [ + { + "receiver": "1111111111", + "sender": "1111111113", + "path_type": "control" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_app_conn_node_two_missing.json b/config/reader/tests/TestFiles/not_valid_app_conn_node_two_missing.json new file mode 100644 index 0000000..fc4f238 --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_app_conn_node_two_missing.json @@ -0,0 +1,52 @@ +{ + "network": { + "nodes": [ + { + "id": "1111111", + "power_network_id": "11111100", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "1111112", + "power_network_id": "11111101", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "1111111", + "1111112" + ], + "type": "p2p" + } + ], + "app_connections": [ + { + "receiver": "1111113", + "sender": "1111112", + "path_type": "control" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_app_conn_wrong_path_type_one.json b/config/reader/tests/TestFiles/not_valid_app_conn_wrong_path_type_one.json new file mode 100644 index 0000000..170a0bd --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_app_conn_wrong_path_type_one.json @@ -0,0 +1,52 @@ +{ + "network": { + "nodes": [ + { + "id": "11111112222", + "power_network_id": "222211111100", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "11111122222", + "power_network_id": "222211111101", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "11111112222", + "11111122222" + ], + "type": "p2p" + } + ], + "app_connections": [ + { + "receiver": "11111112222", + "sender": "11111122222", + "path_type": "controller" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_app_conn_wrong_path_type_two.json b/config/reader/tests/TestFiles/not_valid_app_conn_wrong_path_type_two.json new file mode 100644 index 0000000..83359fe --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_app_conn_wrong_path_type_two.json @@ -0,0 +1,52 @@ +{ + "network": { + "nodes": [ + { + "id": "111111122222", + "power_network_id": "2222111111002", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "111111222222", + "power_network_id": "2222111111012", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "111111122222", + "111111222222" + ], + "type": "p2p" + } + ], + "app_connections": [ + { + "receiver": "111111122222", + "sender": "111111222222", + "path_type": "actuatorr" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_network_duplicate_mixed.json b/config/reader/tests/TestFiles/not_valid_network_duplicate_mixed.json new file mode 100644 index 0000000..0cee1a2 --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_network_duplicate_mixed.json @@ -0,0 +1,56 @@ +{ + "network": { + "nodes": [ + { + "id": "111145", + "power_network_id": "1111145", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": true + }, + { + "type": "p2p" + } + ] + }, + { + "id": "111146", + "power_network_id": "1111146", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + }, + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "111145", + "111146" + ], + "type": "p2p" + }, + { + "nodes": [ + "111146", + "111145" + ], + "type": "wifi" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_network_duplicate_p2p.json b/config/reader/tests/TestFiles/not_valid_network_duplicate_p2p.json new file mode 100644 index 0000000..2d177b8 --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_network_duplicate_p2p.json @@ -0,0 +1,48 @@ +{ + "network": { + "nodes": [ + { + "id": "43", + "power_network_id": "100", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "44", + "power_network_id": "101", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "43", + "44" + ], + "type": "p2p" + }, + { + "nodes": [ + "43", + "44" + ], + "type": "p2p" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_network_duplicate_wifi.json b/config/reader/tests/TestFiles/not_valid_network_duplicate_wifi.json new file mode 100644 index 0000000..177f67e --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_network_duplicate_wifi.json @@ -0,0 +1,50 @@ +{ + "network": { + "nodes": [ + { + "id": "45", + "power_network_id": "145", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "46", + "power_network_id": "146", + "location": { + "x": "200", + "y": "410" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "45", + "46" + ], + "type": "wifi" + }, + { + "nodes": [ + "46", + "45" + ], + "type": "wifi" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_network_missing_nic_p2p.json b/config/reader/tests/TestFiles/not_valid_network_missing_nic_p2p.json new file mode 100644 index 0000000..8186a6e --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_network_missing_nic_p2p.json @@ -0,0 +1,37 @@ +{ + "network": { + "nodes": [ + { + "id": "43123213", + "power_network_id": "10123421340", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [] + }, + { + "id": "44123123", + "power_network_id": "10123412341", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "43123213", + "44123123" + ], + "type": "p2p" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_network_missing_nic_wifi.json b/config/reader/tests/TestFiles/not_valid_network_missing_nic_wifi.json new file mode 100644 index 0000000..c3a83d7 --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_network_missing_nic_wifi.json @@ -0,0 +1,38 @@ +{ + "network": { + "nodes": [ + { + "id": "434321321", + "power_network_id": "10sdafada0", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [] + }, + { + "id": "444321321423", + "power_network_id": "1dasfsasd01", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": true + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "434321321", + "444321321423" + ], + "type": "wifi" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_network_missing_node.json b/config/reader/tests/TestFiles/not_valid_network_missing_node.json new file mode 100644 index 0000000..c0b3ae8 --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_network_missing_node.json @@ -0,0 +1,28 @@ +{ + "network": { + "nodes": [ + { + "id": "430000", + "power_network_id": "10000000", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "430000", + "440000" + ], + "type": "p2p" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_network_wifi_no_access_point.json b/config/reader/tests/TestFiles/not_valid_network_wifi_no_access_point.json new file mode 100644 index 0000000..4e9284b --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_network_wifi_no_access_point.json @@ -0,0 +1,43 @@ +{ + "network": { + "nodes": [ + { + "id": "21111", + "power_network_id": "110000", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + } + ] + }, + { + "id": "22111", + "power_network_id": "111000", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "21111", + "22111" + ], + "type": "wifi" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/not_valid_network_wifi_no_non_access_point.json b/config/reader/tests/TestFiles/not_valid_network_wifi_no_non_access_point.json new file mode 100644 index 0000000..1206093 --- /dev/null +++ b/config/reader/tests/TestFiles/not_valid_network_wifi_no_non_access_point.json @@ -0,0 +1,43 @@ +{ + "network": { + "nodes": [ + { + "id": "211143211", + "power_network_id": "110431234000", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "221143214511", + "power_network_id": "1110034211310", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": true + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "211143211", + "221143214511" + ], + "type": "wifi" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/valid_app_conns.json b/config/reader/tests/TestFiles/valid_app_conns.json new file mode 100644 index 0000000..498f7eb --- /dev/null +++ b/config/reader/tests/TestFiles/valid_app_conns.json @@ -0,0 +1,94 @@ +{ + "network": { + "nodes": [ + { + "id": "-111", + "power_network_id": "-1111", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "-222", + "power_network_id": "-2222", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "-333", + "power_network_id": "-3333", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "-444", + "power_network_id": "-4444", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "-111", + "-222" + ], + "type": "p2p" + }, + { + "nodes": [ + "-333", + "-444" + ], + "type": "p2p" + } + ], + "app_connections": [ + { + "sender": "-111", + "receiver": "-222", + "path_type": "control" + }, + { + "sender": "-333", + "receiver": "-444", + "path_type": "actuator" + } + ] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/valid_network_connections_distance_p2p.json b/config/reader/tests/TestFiles/valid_network_connections_distance_p2p.json new file mode 100644 index 0000000..e9c196d --- /dev/null +++ b/config/reader/tests/TestFiles/valid_network_connections_distance_p2p.json @@ -0,0 +1,42 @@ +{ + "network": { + "nodes": [ + { + "id": "-11111", + "power_network_id": "-111100", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "-11112", + "power_network_id": "-111101", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "-11111", + "-11112" + ], + "type": "p2p" + } + ], + "app_connections": [] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/valid_network_connections_distance_wifi.json b/config/reader/tests/TestFiles/valid_network_connections_distance_wifi.json new file mode 100644 index 0000000..e837892 --- /dev/null +++ b/config/reader/tests/TestFiles/valid_network_connections_distance_wifi.json @@ -0,0 +1,44 @@ +{ + "network": { + "nodes": [ + { + "id": "-111181", + "power_network_id": "-1111800", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "-111182", + "power_network_id": "-1118101", + "location": { + "x": "200", + "y": "351" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "-111181", + "-111182" + ], + "type": "wifi" + } + ], + "app_connections": [] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/valid_network_connections_mixed.json b/config/reader/tests/TestFiles/valid_network_connections_mixed.json new file mode 100644 index 0000000..b167829 --- /dev/null +++ b/config/reader/tests/TestFiles/valid_network_connections_mixed.json @@ -0,0 +1,124 @@ +{ + "network": { + "nodes": [ + { + "id": "1111", + "power_network_id": "11100", + "location": { + "x": "0", + "y": "0" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "1112", + "power_network_id": "11101", + "location": { + "x": "10", + "y": "10" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "1113", + "power_network_id": "11102", + "location": { + "x": "20", + "y": "20" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "1114", + "power_network_id": "11103", + "location": { + "x": "30", + "y": "30" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "1115", + "power_network_id": "11104", + "location": { + "x": "40", + "y": "10" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": false + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "1111", + "1112" + ], + "type": "p2p" + }, + { + "nodes": [ + "1112", + "1113" + ], + "type": "p2p" + }, + { + "nodes": [ + "1113", + "1115" + ], + "type": "p2p" + }, + { + "nodes": [ + "1115", + "1114" + ], + "type": "p2p" + }, + { + "nodes": [ + "1114", + "1113" + ], + "type": "p2p" + }, + { + "nodes": [ + "1111", + "1115" + ], + "type": "wifi" + } + ], + "app_connections": [] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/valid_network_connections_p2p.json b/config/reader/tests/TestFiles/valid_network_connections_p2p.json new file mode 100644 index 0000000..72df21c --- /dev/null +++ b/config/reader/tests/TestFiles/valid_network_connections_p2p.json @@ -0,0 +1,109 @@ +{ + "network": { + "nodes": [ + { + "id": "11111", + "power_network_id": "111100", + "location": { + "x": "200", + "y": "400" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "11112", + "power_network_id": "111101", + "location": { + "x": "200", + "y": "350" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "11113", + "power_network_id": "111102", + "location": { + "x": "200", + "y": "300" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "11114", + "power_network_id": "111103", + "location": { + "x": "0", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + }, + { + "id": "11115", + "power_network_id": "111104", + "location": { + "x": "100", + "y": "250" + }, + "nic_card_types": [ + { + "type": "p2p" + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "11111", + "11112" + ], + "type": "p2p" + }, + { + "nodes": [ + "11112", + "11113" + ], + "type": "p2p" + }, + { + "nodes": [ + "11113", + "11115" + ], + "type": "p2p" + }, + { + "nodes": [ + "11115", + "11114" + ], + "type": "p2p" + }, + { + "nodes": [ + "11114", + "11113" + ], + "type": "p2p" + } + ], + "app_connections": [] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/valid_network_connections_wifi.json b/config/reader/tests/TestFiles/valid_network_connections_wifi.json new file mode 100644 index 0000000..e10f8de --- /dev/null +++ b/config/reader/tests/TestFiles/valid_network_connections_wifi.json @@ -0,0 +1,100 @@ +{ + "network": { + "nodes": [ + { + "id": "21", + "power_network_id": "110", + "location": { + "x": "0", + "y": "0" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "22", + "power_network_id": "111", + "location": { + "x": "10", + "y": "10" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + } + ] + }, + { + "id": "23", + "power_network_id": "112", + "location": { + "x": "20", + "y": "20" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": true + } + ] + }, + { + "id": "24", + "power_network_id": "113", + "location": { + "x": "30", + "y": "30" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + } + ] + }, + { + "id": "25", + "power_network_id": "114", + "location": { + "x": "40", + "y": "10" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + } + ] + } + ], + "network_layout": [ + { + "nodes": [ + "21", + "22" + ], + "type": "wifi" + }, + { + "nodes": [ + "21", + "25" + ], + "type": "wifi" + }, + { + "nodes": [ + "24", + "23" + ], + "type": "wifi" + } + ], + "app_connections": [] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/valid_nodes.json b/config/reader/tests/TestFiles/valid_nodes.json new file mode 100644 index 0000000..cdf81a4 --- /dev/null +++ b/config/reader/tests/TestFiles/valid_nodes.json @@ -0,0 +1,49 @@ +{ + "network": { + "nodes": [ + { + "id": "3", + "power_network_id": "622", + "location": { + "x": "100", + "y": "120" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + }] + }, + { + "id": "4", + "power_network_id": "612", + "location": { + "x": "110", + "y": "130" + }, + "nic_card_types": [ + { + "type": "p2p" + }] + }, + { + "id": "5", + "power_network_id": "632", + "location": { + "x": "120", + "y": "140" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + }] + } + ], + "network_layout": [], + "app_connections": [] + } +} \ No newline at end of file diff --git a/config/reader/tests/TestFiles/wrong_type_nic.json b/config/reader/tests/TestFiles/wrong_type_nic.json new file mode 100644 index 0000000..41d3dc9 --- /dev/null +++ b/config/reader/tests/TestFiles/wrong_type_nic.json @@ -0,0 +1,47 @@ +{ + "network": { + "nodes": [ + { + "id": "8", + "power_network_id": "624", + "location": { + "x": "100", + "y": "120" + }, + "nic_card_types": [ + { + "type": "p2p" + }, + { + "type": "wifi", + "access_point": true + }] + }, + { + "id": "9", + "power_network_id": "614", + "location": { + "x": "110", + "y": "130" + }, + "nic_card_types": [ + { + "type": "nil" + }] + }, + { + "id": "10", + "power_network_id": "634", + "location": { + "x": "120", + "y": "140" + }, + "nic_card_types": [ + { + "type": "wifi", + "access_point": false + }] + } + ] + } +} \ No newline at end of file diff --git a/NS3Mosaik/tcp-server-and-client/include/multi-client-tcp-server-helper.h b/tcp-server-and-client/include/multi-client-tcp-server-helper.h similarity index 86% rename from NS3Mosaik/tcp-server-and-client/include/multi-client-tcp-server-helper.h rename to tcp-server-and-client/include/multi-client-tcp-server-helper.h index 54e64b3..783e7e3 100644 --- a/NS3Mosaik/tcp-server-and-client/include/multi-client-tcp-server-helper.h +++ b/tcp-server-and-client/include/multi-client-tcp-server-helper.h @@ -22,14 +22,14 @@ * Modelled after packet-sink-helper.h */ +#ifndef _MULTI_CLIENT_TCP_SERVER_HELPER_H_ +#define _MULTI_CLIENT_TCP_SERVER_HELPER_H_ + #include "ns3/object-factory.h" #include "ns3/ipv4-address.h" #include "ns3/node-container.h" #include "ns3/application-container.h" -#ifndef _MULTI_CLIENT_TCP_SERVER_HELPER_H_ -#define _MULTI_CLIENT_TCP_SERVER_HELPER_H_ - using namespace ns3; /** @@ -41,14 +41,14 @@ class MultiClientTcpServerHelper { * \brief constructor * \param address The address for the client that will be created */ - MultiClientTcpServerHelper(Address address); + MultiClientTcpServerHelper(); /** * Sets an attribute to the value passed in * \param name The name of the attribute * \param value The value to which the attribute should be set to */ - void SetAttribute(std::string name, const AttributeValue &value); + void SetAttribute (std::string name, const AttributeValue &value); /** * \brief Installs TcpClient on every node in the NodeContainer @@ -57,7 +57,7 @@ class MultiClientTcpServerHelper { * * \return An application container with all the applications */ - ApplicationContainer Install(NodeContainer c) const; + ApplicationContainer Install (NodeContainer c) const; /** * \brief Installs TcpClient on the given node @@ -66,7 +66,7 @@ class MultiClientTcpServerHelper { * * \return An application container with the installed application */ - ApplicationContainer Install(Ptr node) const; + ApplicationContainer Install (Ptr node) const; /** * \brief Installs TcpClient on a node with nodeName @@ -75,10 +75,10 @@ class MultiClientTcpServerHelper { * * \return An application container with the installed application */ - ApplicationContainer Install(std::string nodeName) const; + ApplicationContainer Install (std::string nodeName) const; private: - Ptr InstallPriv(Ptr node) const; - ObjectFactory m_factory; + Ptr InstallPriv (Ptr node) const; + ObjectFactory m_factory; }; #endif //_MULTI_CLIENT_TCP_SERVER_HELPER_H_ diff --git a/NS3Mosaik/tcp-server-and-client/include/multi-client-tcp-server.h b/tcp-server-and-client/include/multi-client-tcp-server.h similarity index 58% rename from NS3Mosaik/tcp-server-and-client/include/multi-client-tcp-server.h rename to tcp-server-and-client/include/multi-client-tcp-server.h index d1aed83..75afd7a 100644 --- a/NS3Mosaik/tcp-server-and-client/include/multi-client-tcp-server.h +++ b/tcp-server-and-client/include/multi-client-tcp-server.h @@ -1,4 +1,4 @@ - +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2020 Amrinder S. Grewal * @@ -22,15 +22,15 @@ * Modelled after packet-sink.h */ +#ifndef _MULTI_CLIENT_TCP_SERVER_H_ +#define _MULTI_CLIENT_TCP_SERVER_H_ + #include "ns3/core-module.h" #include "ns3/socket.h" #include "ns3/application.h" #include "ns3/address.h" #include "ns3/ptr.h" -#ifndef _MULTI_CLIENT_TCP_SERVER_H_ -#define _MULTI_CLIENT_TCP_SERVER_H_ - using namespace ns3; /** * \brief Application server that allows multiple simultaneous TCP connection. @@ -44,53 +44,89 @@ using namespace ns3; * * Modelled after packet-sink.h */ -class MultiClientTcpServer : public Application { +class MultiClientTcpServer: public Application +{ public: /** * \brief Get the type ID. * \return the object TypeID */ - static TypeId GetTypeId(void); + static TypeId GetTypeId (void); - MultiClientTcpServer(); - virtual ~MultiClientTcpServer(); + MultiClientTcpServer (); + virtual ~MultiClientTcpServer (); /** - * \return pointer to the listening socket. + * \return pointer to the listening socket in the primary network */ - Ptr GetListeningSocket(void) const; + Ptr GetListeningSocketPrimary (void) const; + + /** + * \return pointer to the listening socket with the wifi network + */ + Ptr GetListeningSocketWifi (void) const; /** * \return list of pointer to accepted sockets */ - std::list> GetAcceptedSockets(void) const; + std::list > GetAcceptedSockets(void) const; /** * \brief set the callback function that is called when a packet is received * \param callback the function to which the callback is set. */ void SetPacketReceivedCallBack(void (*callback)(Ptr socket)); + + /** + * \brief Created to control the creation of the wifi-socket. This needs to be done before the application is started. + * After the application is started, calling this method will have no effect. Default is no-wifi socket creation. + * + * \param the bool value which will enable/disable the wifi creation + */ + void SetCreateWifiSocket(bool enable); + + /** + * \brief Fetch the value of the wifi socket creation bool + * \return bool indicating if the wifi socket will be created or not + */ + bool GetCreateWifiSocket(void); + + Address m_LocalPrimary; //!< The primary network ipv4 address + Address m_LocalWifi; //!< The secondary network ipv4 address, this is the wifi network address protected: - virtual void DoDispose(void); + virtual void DoDispose (void); private: // inherited from Application base class. - virtual void StartApplication(void); // Called at time specified by Start - virtual void StopApplication(void); // Called at time specified by Stop + virtual void StartApplication (void); // Called at time specified by Start + virtual void StopApplication (void); // Called at time specified by Stop + + /** + * \brief Created to set up the listening socket with all the callbacks set. + * \param address of type Address, the address which will bind to the socket + * \return Ptr, the socket with the address bound + */ + Ptr CreateListeningSocket(const Address bindTo); + + /** + * \breif Closes the listening sockets. + * \param The socket to close + */ + void CloseListeningSocket(Ptr socket); /** * \brief Handle a connection request received by the application. * \param socket the incoming connection socket * \param from the address the connection is from */ - bool HandleRequest(Ptr socket, const Address &from); + bool HandleRequest(Ptr socket, const Address& from); /** * \brief Handle an incoming connection that has been accepted * \param socket the incoming connection socket * \param from the address the connection is from */ - void HandleAccept(Ptr socket, const Address &from); + void HandleAccept(Ptr socket, const Address& from); /** * \brief Handle a packet received by the application @@ -102,21 +138,20 @@ class MultiClientTcpServer : public Application { * \brief Handle an connection close * \param socket the connected socket */ - void HandlePeerClose(Ptr socket); + void HandlePeerClose (Ptr socket); /** * \brief Handle an connection error * \param socket the connected socket */ - void HandlePeerError(Ptr socket); + void HandlePeerError (Ptr socket); // When a connection is accepted in TCP, a new socket is returned // So we need to store a listening socket for this class - Ptr m_listeningSocket; //!< Listening socket + Ptr m_listeningPrimary; //!< Listening socket for the primary network + Ptr m_listeningWifi; //!< Listening socket for the wifi network // And a list of sockets that have been accepted - std::list> m_acceptedSocketList; //!< the accepted sockets - - Address m_local; //!< Local address to bind to + std::list > m_acceptedSocketList; //!< the accepted sockets /// Traced Callback: received packets, source address. TracedCallback, const Address &> m_rxTrace; @@ -126,6 +161,9 @@ class MultiClientTcpServer : public Application { /// The function that will be called when a packet is received void (*m_packetReceivedCallback)(Ptr socket); + + /// The creation of a wifi-socket will depend on the value of this member + bool m_createWifiSocket; }; #endif //_MULTI_CLIENT_TCP_SERVER_H_ diff --git a/NS3Mosaik/tcp-server-and-client/include/tcp-client-helper.h b/tcp-server-and-client/include/tcp-client-helper.h similarity index 100% rename from NS3Mosaik/tcp-server-and-client/include/tcp-client-helper.h rename to tcp-server-and-client/include/tcp-client-helper.h index a8e0f17..f39db28 100644 --- a/NS3Mosaik/tcp-server-and-client/include/tcp-client-helper.h +++ b/tcp-server-and-client/include/tcp-client-helper.h @@ -22,13 +22,13 @@ * Modelled after udp-client-server-helper.h */ +#ifndef _TCP_CLIENT_HELPER_H_ +#define _TCP_CLIENT_HELPER_H_ + #include "ns3/node-container.h" #include "ns3/application-container.h" #include "ns3/core-module.h" -#ifndef _TCP_CLIENT_HELPER_H_ -#define _TCP_CLIENT_HELPER_H_ - using namespace ns3; /** diff --git a/NS3Mosaik/tcp-server-and-client/include/tcp-client.h b/tcp-server-and-client/include/tcp-client.h similarity index 98% rename from NS3Mosaik/tcp-server-and-client/include/tcp-client.h rename to tcp-server-and-client/include/tcp-client.h index 0120f90..04eea5b 100644 --- a/NS3Mosaik/tcp-server-and-client/include/tcp-client.h +++ b/tcp-server-and-client/include/tcp-client.h @@ -22,15 +22,15 @@ * Modelled after udp-echo-client.h */ +#ifndef _TCP_CLIENT_H_ +#define _TCP_CLIENT_H_ + #include "ns3/socket.h" #include "ns3/application.h" #include "ns3/address.h" #include "ns3/ptr.h" #include "ns3/traced-callback.h" -#ifndef _TCP_SENSOR_H_ -#define _TCP_SENSOR_H_ - using namespace ns3; /** @@ -107,4 +107,4 @@ class TcpClient : public Application TracedCallback, const Address &, const Address &> m_rxTraceWithAddresses; }; -#endif //_TCP_SENSOR_H_ +#endif //_TCP_CLIENT_H_ diff --git a/NS3Mosaik/tcp-server-and-client/src/multi-client-tcp-server-helper.cc b/tcp-server-and-client/src/multi-client-tcp-server-helper.cc similarity index 94% rename from NS3Mosaik/tcp-server-and-client/src/multi-client-tcp-server-helper.cc rename to tcp-server-and-client/src/multi-client-tcp-server-helper.cc index 397f75a..82bd68f 100644 --- a/NS3Mosaik/tcp-server-and-client/src/multi-client-tcp-server-helper.cc +++ b/tcp-server-and-client/src/multi-client-tcp-server-helper.cc @@ -29,10 +29,9 @@ using namespace ns3; -MultiClientTcpServerHelper::MultiClientTcpServerHelper(Address address) +MultiClientTcpServerHelper::MultiClientTcpServerHelper() { m_factory.SetTypeId ("ns3::MultiClientTcpServer"); - m_factory.Set ("Local", AddressValue (address)); } void diff --git a/NS3Mosaik/tcp-server-and-client/src/multi-client-tcp-server.cc b/tcp-server-and-client/src/multi-client-tcp-server.cc similarity index 60% rename from NS3Mosaik/tcp-server-and-client/src/multi-client-tcp-server.cc rename to tcp-server-and-client/src/multi-client-tcp-server.cc index f7f7681..bdaa71f 100644 --- a/NS3Mosaik/tcp-server-and-client/src/multi-client-tcp-server.cc +++ b/tcp-server-and-client/src/multi-client-tcp-server.cc @@ -26,7 +26,6 @@ #include "ns3/address-utils.h" #include "ns3/socket-factory.h" #include "multi-client-tcp-server.h" -#include "multi-use-code.h" using namespace ns3; @@ -40,11 +39,16 @@ MultiClientTcpServer::GetTypeId (void) .SetParent () .SetGroupName("Applications") .AddConstructor () - .AddAttribute("Local", + .AddAttribute("LocalPrimary", "The value on which to Bind the rx socket.", AddressValue (), - MakeAddressAccessor (&MultiClientTcpServer::m_local), + MakeAddressAccessor (&MultiClientTcpServer::m_LocalPrimary), MakeAddressChecker()) + .AddAttribute("LocalWifi", + "The value on which to Bind the rx socket.", + AddressValue (), + MakeAddressAccessor (&MultiClientTcpServer::m_LocalWifi), + MakeAddressChecker()) .AddTraceSource("Rx", "A packet has been received", MakeTraceSourceAccessor (&MultiClientTcpServer::m_rxTrace), @@ -61,8 +65,10 @@ MultiClientTcpServer::MultiClientTcpServer() { NS_LOG_FUNCTION(this); // Set the socket to null - m_listeningSocket = 0; + m_listeningPrimary = 0; + m_listeningWifi = 0; m_packetReceivedCallback = 0; + m_createWifiSocket = false; } MultiClientTcpServer::~MultiClientTcpServer() @@ -71,10 +77,17 @@ MultiClientTcpServer::~MultiClientTcpServer() } Ptr -MultiClientTcpServer::GetListeningSocket (void) const +MultiClientTcpServer::GetListeningSocketPrimary (void) const { NS_LOG_FUNCTION (this); - return m_listeningSocket; + return m_listeningPrimary; +} + +Ptr +MultiClientTcpServer::GetListeningSocketWifi (void) const +{ + NS_LOG_FUNCTION (this); + return m_listeningWifi; } std::list > @@ -89,7 +102,8 @@ MultiClientTcpServer::DoDispose (void) { NS_LOG_FUNCTION (this); // Clear the listening socket - m_listeningSocket = 0; + m_listeningPrimary = 0; + m_listeningWifi = 0; // Clear the accepted socket m_acceptedSocketList.clear (); @@ -108,36 +122,50 @@ void MultiClientTcpServer::StartApplication() { NS_LOG_FUNCTION(this); - // Create the socket if it does not already exist - if (m_listeningSocket == 0) { - TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory"); - m_listeningSocket = Socket::CreateSocket(GetNode(), tid); - if (m_listeningSocket->Bind(m_local) == -1) - { - NS_FATAL_ERROR ("Failed to bind socket"); - } - - m_listeningSocket->Listen(); - m_listeningSocket->ShutdownSend (); - // No need to worry about multi-cast, not appropriate for TCP - } + // Create ipv4 primary listening socket if it does not exist + if (m_listeningPrimary == 0) { + m_listeningPrimary = CreateListeningSocket(m_LocalPrimary); + } + + // Create ipv4 wifi listening socket if it does not exist + if (m_listeningWifi == 0 && m_createWifiSocket) { + m_listeningWifi = CreateListeningSocket(m_LocalWifi); + } +} + +Ptr +MultiClientTcpServer::CreateListeningSocket(const Address bindTo) +{ + NS_LOG_FUNCTION(this); + // Create the socket + TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory"); + Ptr socket = Socket::CreateSocket(GetNode(), tid); + // Bind the socket + if (socket->Bind(bindTo) == -1) + { + NS_FATAL_ERROR ("Failed to bind socket"); + } + + // Tell the socket to start listening + socket->Listen(); + socket->ShutdownSend (); // Set the callback funcs for connection request and connection accept - m_listeningSocket->SetAcceptCallback( - MakeCallback (&MultiClientTcpServer::HandleRequest, this), - MakeCallback (&MultiClientTcpServer::HandleAccept, this) + socket->SetAcceptCallback( + MakeCallback (&MultiClientTcpServer::HandleRequest, this), + MakeCallback (&MultiClientTcpServer::HandleAccept, this) ); - // Set the callback funcs for connection close for the listening socket - m_listeningSocket->SetCloseCallbacks( - MakeCallback (&MultiClientTcpServer::HandlePeerClose, this), - MakeCallback (&MultiClientTcpServer::HandlePeerError, this) + socket->SetCloseCallbacks( + MakeCallback (&MultiClientTcpServer::HandlePeerClose, this), + MakeCallback (&MultiClientTcpServer::HandlePeerError, this) ); - // Set the call back for packet reception for the listening socket - m_listeningSocket->SetRecvCallback( - MakeCallback(&MultiClientTcpServer::HandleRead, this) + socket->SetRecvCallback( + MakeCallback(&MultiClientTcpServer::HandleRead, this) ); + + return socket; } void @@ -146,18 +174,35 @@ MultiClientTcpServer::StopApplication() NS_LOG_FUNCTION (this); // Iterate thorough and close all sockets that are still active. while(!m_acceptedSocketList.empty ()) //these are accepted sockets, close them - { - Ptr acceptedSocket = m_acceptedSocketList.front (); - m_acceptedSocketList.pop_front (); - acceptedSocket->Close (); - } + { + Ptr acceptedSocket = m_acceptedSocketList.front (); + m_acceptedSocketList.pop_front (); + acceptedSocket->Close (); + } - // Close the listening socket - if (m_listeningSocket != 0) - { - m_listeningSocket->Close (); - m_listeningSocket->SetRecvCallback (MakeNullCallback > ()); - } + // Close the listening sockets + if (m_listeningPrimary != 0) + { + CloseListeningSocket(m_listeningPrimary); + } + if (m_listeningWifi != 0) + { + CloseListeningSocket(m_listeningWifi); + } +} + +void +MultiClientTcpServer::CloseListeningSocket(Ptr socket) +{ + NS_LOG_FUNCTION(this); + socket->Close (); + socket->SetAcceptCallback ( + MakeNullCallback, const Address& > (), + MakeNullCallback, const Address & > ()); + socket->SetCloseCallbacks ( + MakeNullCallback > (), + MakeNullCallback > ()); + socket->SetRecvCallback (MakeNullCallback > ()); } bool MultiClientTcpServer::HandleRequest(Ptr socket, const Address& from) @@ -191,11 +236,26 @@ MultiClientTcpServer::HandleAccept (Ptr socket, const Address& from) } void -MultiClientTcpServer::HandleRead(Ptr socket) { +MultiClientTcpServer::HandleRead(Ptr socket) +{ NS_LOG_FUNCTION (this); // Call the callback in the simulator to let it know that a message has been received if (m_packetReceivedCallback != NULL) { m_packetReceivedCallback(socket); } +} + +void +MultiClientTcpServer::SetCreateWifiSocket(bool enable) +{ + NS_LOG_FUNCTION(this); + m_createWifiSocket = enable; +} + +bool +MultiClientTcpServer::GetCreateWifiSocket(void) +{ + NS_LOG_FUNCTION(this); + return m_createWifiSocket; } \ No newline at end of file diff --git a/NS3Mosaik/tcp-server-and-client/src/tcp-client-helper.cc b/tcp-server-and-client/src/tcp-client-helper.cc similarity index 100% rename from NS3Mosaik/tcp-server-and-client/src/tcp-client-helper.cc rename to tcp-server-and-client/src/tcp-client-helper.cc diff --git a/NS3Mosaik/tcp-server-and-client/src/tcp-client.cc b/tcp-server-and-client/src/tcp-client.cc similarity index 88% rename from NS3Mosaik/tcp-server-and-client/src/tcp-client.cc rename to tcp-server-and-client/src/tcp-client.cc index 0c9b89b..79fe208 100644 --- a/NS3Mosaik/tcp-server-and-client/src/tcp-client.cc +++ b/tcp-server-and-client/src/tcp-client.cc @@ -35,6 +35,8 @@ #include "ns3/uinteger.h" #include "ns3/trace-source-accessor.h" #include "ns3/ipv4.h" +#include "ns3/ipv6.h" +#include "ns3/names.h" #include "tcp-client.h" #include @@ -118,29 +120,12 @@ void TcpClient::StartApplication (void) { NS_LOG_FUNCTION(this); - // Make a socket if empty if (m_socket == 0) { TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory"); m_socket = Socket::CreateSocket (GetNode (), tid); - if (Ipv4Address::IsMatchingType(m_peerAddress) == true) - { - if (m_socket->Bind () == -1) - { - NS_FATAL_ERROR ("Failed to bind socket"); - } - m_socket->Connect (InetSocketAddress (Ipv4Address::ConvertFrom(m_peerAddress), m_peerPort)); - } - else if (Ipv6Address::IsMatchingType(m_peerAddress) == true) - { - if (m_socket->Bind6 () == -1) - { - NS_FATAL_ERROR ("Failed to bind socket"); - } - m_socket->Connect (Inet6SocketAddress (Ipv6Address::ConvertFrom(m_peerAddress), m_peerPort)); - } - else if (InetSocketAddress::IsMatchingType (m_peerAddress) == true) + if (InetSocketAddress::IsMatchingType (m_peerAddress) == true) { if (m_socket->Bind () == -1) { @@ -185,6 +170,14 @@ TcpClient::SendMessage (string message) Ptr sendPacket = Create ((uint8_t*)message.c_str(),message.size()); m_socket->Send (sendPacket); + + ofstream filePacketsSent; + filePacketsSent.open("packets_sent.pkt", std::ios_base::app); + filePacketsSent << "time: " << Simulator::Now ().GetMilliSeconds () + << " nodeId: " << m_socket->GetNode()->GetId() + << " by nodeName: " << Names::FindName(m_socket->GetNode ()) + << " MsgSize: " << message.size() << std::endl; + filePacketsSent.close(); } } @@ -198,7 +191,6 @@ TcpClient::ScheduleTransmit(std::string val, std::string valTime) { << " Event_Val_Time: " << valTime << " val " << val << " socket " << m_socket); NS_LOG_DEBUG("TcpClient:schedule(" -// << "source=" << m_socket->GetNode () << ", value=" << val << ", delay=" << schDelay << ")"); diff --git a/NS3Mosaik/udp-server-client/include/custom-udp-client-helper.h b/udp-server-client/include/custom-udp-client-helper.h similarity index 100% rename from NS3Mosaik/udp-server-client/include/custom-udp-client-helper.h rename to udp-server-client/include/custom-udp-client-helper.h index eb1cb48..5c20dfb 100644 --- a/NS3Mosaik/udp-server-client/include/custom-udp-client-helper.h +++ b/udp-server-client/include/custom-udp-client-helper.h @@ -22,14 +22,14 @@ * Modelled after packet-sink-helper.h */ +#ifndef _CUSTOM_UDP_CLIENT_HELPER_H_ +#define _CUSTOM_UDP_CLIENT_HELPER_H_ + #include "ns3/object-factory.h" #include "ns3/ipv4-address.h" #include "ns3/node-container.h" #include "ns3/application-container.h" -#ifndef _CUSTOM_UDP_CLIENT_HELPER_H_ -#define _CUSTOM_UDP_CLIENT_HELPER_H_ - using namespace ns3; /** diff --git a/NS3Mosaik/udp-server-client/include/custom-udp-client.h b/udp-server-client/include/custom-udp-client.h similarity index 100% rename from NS3Mosaik/udp-server-client/include/custom-udp-client.h rename to udp-server-client/include/custom-udp-client.h index f973e6a..d1261ea 100644 --- a/NS3Mosaik/udp-server-client/include/custom-udp-client.h +++ b/udp-server-client/include/custom-udp-client.h @@ -21,15 +21,15 @@ * */ +#ifndef _CUSTOM_UDP_CLIENT_H_ +#define _CUSTOM_UDP_CLIENT_H_ + #include "ns3/socket.h" #include "ns3/application.h" #include "ns3/address.h" #include "ns3/ptr.h" #include "ns3/traced-callback.h" -#ifndef _CUSTOM_UDP_CLIENT_H_ -#define _CUSTOM_UDP_CLIENT_H_ - using namespace ns3; using namespace std; diff --git a/NS3Mosaik/udp-server-client/include/custom-udp-server-helper.h b/udp-server-client/include/custom-udp-server-helper.h similarity index 98% rename from NS3Mosaik/udp-server-client/include/custom-udp-server-helper.h rename to udp-server-client/include/custom-udp-server-helper.h index ebd6dbc..6c71407 100644 --- a/NS3Mosaik/udp-server-client/include/custom-udp-server-helper.h +++ b/udp-server-client/include/custom-udp-server-helper.h @@ -22,14 +22,14 @@ * Modelled after packet-sink-helper.h */ +#ifndef _CUSTOM_UDP_SERVER_HELPER_H_ +#define _CUSTOM_UDP_SERVER_HELPER_H_ + #include "ns3/object-factory.h" #include "ns3/ipv4-address.h" #include "ns3/node-container.h" #include "ns3/application-container.h" -#ifndef _CUSTOM_UDP_SERVER_HELPER_H_ -#define _CUSTOM_UDP_SERVER_HELPER_H_ - using namespace ns3; /** @@ -41,7 +41,7 @@ class CustomUdpServerHelper { * \brief constructor * \param address The address for the client that will be created */ - CustomUdpServerHelper(Address address); + CustomUdpServerHelper(); /** * Sets an attribute to the value passed in diff --git a/NS3Mosaik/udp-server-client/include/custom-udp-server.h b/udp-server-client/include/custom-udp-server.h similarity index 57% rename from NS3Mosaik/udp-server-client/include/custom-udp-server.h rename to udp-server-client/include/custom-udp-server.h index 518d374..ee3004a 100644 --- a/NS3Mosaik/udp-server-client/include/custom-udp-server.h +++ b/udp-server-client/include/custom-udp-server.h @@ -21,15 +21,15 @@ * */ +#ifndef _CUSTOM_UDP_SERVER_H_ +#define _CUSTOM_UDP_SERVER_H_ + #include "ns3/core-module.h" #include "ns3/socket.h" #include "ns3/application.h" #include "ns3/address.h" #include "ns3/ptr.h" -#ifndef _CUSTOM_UDP_SERVER_H_ -#define _CUSTOM_UDP_SERVER_H_ - using namespace ns3; using namespace std; @@ -43,14 +43,58 @@ class CustomUdpServer: public Application { * \brief Configures the server */ static TypeId GetTypeId (void); + + CustomUdpServer (); + virtual ~CustomUdpServer (); + /** * \brief set the callback function that is called when a packet is received * \param callback the function to which the callback is set. */ void SetPacketReceivedCallBack(void (*callback)(Ptr socket)); + + /** + * \return pointer to the listening socket in the primary network + */ + Ptr GetListeningSocketPrimary (void) const; + + /** + * \return pointer to the listening socket with the wifi network + */ + Ptr GetListeningSocketWifi (void) const; + + /** + * \brief Created to control the creation of the wifi-socket. This needs to be done before the application is started. + * After the application is started, calling this method will have no effect. Default is no-wifi socket creation. + * + * \param the bool value which will enable/disable the wifi creation + */ + void SetCreateWifiSocket(bool enable); + + /** + * \brief Fetch the value of the wifi socket creation bool + * \return bool indicating if the wifi socket will be created or not + */ + bool GetCreateWifiSocket(void); + + Address m_LocalPrimary; //!< The primary network ipv4 address + Address m_LocalWifi; //!< The secondary network ipv4 address, this is the wifi network address private: virtual void StartApplication (void); virtual void StopApplication (void); + + /** + * \Brief, create a udp socket and bind it to the address + * \param bindTo, the address to which the udp packet should be bound to + * \return socket, the created udp socket + */ + Ptr CreateSocket(const Address bindTo); + + /** + * Close a udp socket. + * \param socket, the udp socket to close + */ + void CloseSocket(Ptr socket); /** * The over-written read callback function that calls ExtractInformationFromPacketAndSendToUpperLayer to send * a message that a new packet has been received. @@ -58,11 +102,15 @@ class CustomUdpServer: public Application { virtual void HandleRead (Ptr socket); /// The function that will be called when a packet is received void (*m_packetReceivedCallback)(Ptr socket); - Ptr m_socket; //!< Socket that will be used to send the messages - Address m_local; //!< Local address to bind to + + Ptr m_socketPrimary; //!< Socket for the primary network + Ptr m_socketWifi; //!< Socket for the wifi network TracedCallback > m_rxTrace; TracedCallback, const Address &, const Address &> m_rxTraceWithAddresses; + + /// The creation of a wifi-socket will depend on the value of this member + bool m_createWifiSocket; }; #endif //_CUSTOM_UDP_SERVER_H_ diff --git a/NS3Mosaik/udp-server-client/src/custom-udp-client-helper.cc b/udp-server-client/src/custom-udp-client-helper.cc similarity index 100% rename from NS3Mosaik/udp-server-client/src/custom-udp-client-helper.cc rename to udp-server-client/src/custom-udp-client-helper.cc diff --git a/NS3Mosaik/udp-server-client/src/custom-udp-client.cc b/udp-server-client/src/custom-udp-client.cc similarity index 93% rename from NS3Mosaik/udp-server-client/src/custom-udp-client.cc rename to udp-server-client/src/custom-udp-client.cc index 1e93103..aa94f93 100644 --- a/NS3Mosaik/udp-server-client/src/custom-udp-client.cc +++ b/udp-server-client/src/custom-udp-client.cc @@ -35,6 +35,7 @@ #include "ns3/uinteger.h" #include "ns3/trace-source-accessor.h" #include "ns3/ipv4.h" +#include "ns3/names.h" #include "ns3/log.h" #include @@ -85,6 +86,14 @@ CustomUdpClient::SendMessage (string message) Ptr sendPacket = Create ((uint8_t *) message.c_str (), message.size ()); m_socket->Send (sendPacket); + + ofstream filePacketsSent; + filePacketsSent.open("packets_sent.pkt", std::ios_base::app); + filePacketsSent << "time: " << Simulator::Now ().GetMilliSeconds () + << " nodeId: " << m_socket->GetNode()->GetId() + << " by nodeName: " << Names::FindName(m_socket->GetNode ()) + << " MsgSize: " << message.size() << std::endl; + filePacketsSent.close(); } } diff --git a/NS3Mosaik/udp-server-client/src/custom-udp-server-helper.cc b/udp-server-client/src/custom-udp-server-helper.cc similarity index 94% rename from NS3Mosaik/udp-server-client/src/custom-udp-server-helper.cc rename to udp-server-client/src/custom-udp-server-helper.cc index 0cc8d89..5b73087 100644 --- a/NS3Mosaik/udp-server-client/src/custom-udp-server-helper.cc +++ b/udp-server-client/src/custom-udp-server-helper.cc @@ -29,10 +29,9 @@ using namespace ns3; -CustomUdpServerHelper::CustomUdpServerHelper(Address address) +CustomUdpServerHelper::CustomUdpServerHelper() { m_factory.SetTypeId ("ns3::CustomUdpServer"); - m_factory.Set ("Local", AddressValue (address)); } void diff --git a/NS3Mosaik/udp-server-client/src/custom-udp-server.cc b/udp-server-client/src/custom-udp-server.cc similarity index 58% rename from NS3Mosaik/udp-server-client/src/custom-udp-server.cc rename to udp-server-client/src/custom-udp-server.cc index e03f285..f782902 100644 --- a/NS3Mosaik/udp-server-client/src/custom-udp-server.cc +++ b/udp-server-client/src/custom-udp-server.cc @@ -49,11 +49,16 @@ CustomUdpServer::GetTypeId (void) .SetParent () .SetGroupName("Applications") .AddConstructor () - .AddAttribute("Local", - "The value on which to Bind the rx socket.", - AddressValue (), - MakeAddressAccessor (&CustomUdpServer::m_local), - MakeAddressChecker()) + .AddAttribute("LocalPrimary", + "The value on which to Bind the rx socket.", + AddressValue (), + MakeAddressAccessor (&CustomUdpServer::m_LocalPrimary), + MakeAddressChecker()) + .AddAttribute("LocalWifi", + "The value on which to Bind the rx socket.", + AddressValue (), + MakeAddressAccessor (&CustomUdpServer::m_LocalWifi), + MakeAddressChecker()) .AddTraceSource ("Rx", "A packet has been received", MakeTraceSourceAccessor (&CustomUdpServer::m_rxTrace), "ns3::Packet::TracedCallback") @@ -64,6 +69,20 @@ CustomUdpServer::GetTypeId (void) return tid; } +CustomUdpServer::CustomUdpServer() +{ + NS_LOG_FUNCTION(this); + // Set the socket to null + m_socketPrimary = 0; + m_socketWifi = 0; + m_createWifiSocket = false; +} + +CustomUdpServer::~CustomUdpServer() +{ + NS_LOG_FUNCTION (this); +} + void CustomUdpServer::HandleRead(Ptr socket) { NS_LOG_FUNCTION (this); @@ -85,32 +104,77 @@ CustomUdpServer::StartApplication (void) { NS_LOG_FUNCTION(this); // Create the socket if it does not already exist - if (m_socket == 0) { - TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory"); - m_socket = Socket::CreateSocket(GetNode(), tid); - if (m_socket->Bind(m_local) == -1) - { - NS_FATAL_ERROR ("Failed to bind socket"); - } - - m_socket->Listen(); - m_socket->ShutdownSend (); - // No need to worry about multi-cast, not appropriate for TCP - } + if (m_socketPrimary == 0) + { + m_socketPrimary = CreateSocket(m_LocalPrimary); + } + + if (m_socketWifi == 0 && m_createWifiSocket == true) + { + m_socketWifi = CreateSocket(m_LocalWifi); + } +} + +Ptr +CustomUdpServer::CreateSocket(const Address bindTo) +{ + NS_LOG_FUNCTION(this); + Ptr socket; + // Create a socket + TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory"); + socket = Socket::CreateSocket(GetNode(), tid); + // Bind teh socket + if (socket->Bind(bindTo) == -1) + { + NS_FATAL_ERROR ("Failed to bind socket"); + } + + // Tell the socket to listen + socket->Listen(); + socket->ShutdownSend (); + // No need to worry about multi-cast, not appropriate for TCP // Set the call back for packet reception for the listening socket - m_socket->SetRecvCallback( - MakeCallback(&CustomUdpServer::HandleRead, this) + socket->SetRecvCallback( + MakeCallback(&CustomUdpServer::HandleRead, this) ); + + return socket; } void CustomUdpServer::StopApplication (void) { // Close the socket - if (m_socket != 0) - { - m_socket->Close (); - m_socket->SetRecvCallback (MakeNullCallback > ()); - } + if (m_socketPrimary != 0) + { + CloseSocket(m_socketPrimary); + } + + if (m_socketWifi != 0) + { + CloseSocket(m_socketWifi); + } +} + +void +CustomUdpServer::CloseSocket(Ptr socket) +{ + NS_LOG_FUNCTION(this); + socket->Close (); + socket->SetRecvCallback (MakeNullCallback > ()); +} + +void +CustomUdpServer::SetCreateWifiSocket(bool enable) +{ + NS_LOG_FUNCTION(this); + m_createWifiSocket = enable; +} + +bool +CustomUdpServer::GetCreateWifiSocket(void) +{ + NS_LOG_FUNCTION(this); + return m_createWifiSocket; } \ No newline at end of file