From 929f824db986b0c01f214162e9d5cc247c8092b7 Mon Sep 17 00:00:00 2001 From: alfonso Date: Fri, 22 Jun 2012 12:31:40 +0200 Subject: [PATCH] merge with inet-framework, integration --- .oppfeatures | 112 +- etc/OSPF.xsd | 242 +- etc/OSPF_old.xsd | 463 +++ etc/OSPFold_to_OSPFnew.xsl | 282 ++ etc/plugins/contextmenu.tcl | 7 + etc/sumo-launchd.py | 677 ++++ misc/gdb/README | 44 + misc/gdb/inet/__init__.py | 0 misc/gdb/inet/printers.py | 121 + src/applications/dhcp/ChangeLog | 8 + src/applications/dhcp/DHCPClient.cc | 5 +- src/applications/dhcp/package.ned | 2 - src/applications/traci/TraCIDemo.cc | 91 +- src/applications/traci/TraCIDemo.h | 48 +- src/applications/traci/TraCITestApp.cc | 382 +-- src/applications/traci/TraCITestApp.h | 50 +- src/linklayer/IWirelessNicMulti.ned | 28 + src/linklayer/ieee80211/ChangeLog | 6 + src/linklayer/ieee80211/Ieee80211NewNic.ned | 100 - src/linklayer/ieee80211/Ieee80211Nic.ned | 13 +- src/linklayer/ieee80211/mac/Ieee80211Mac.cc | 2548 ++++++++++++-- src/linklayer/ieee80211/mac/Ieee80211Mac.h | 399 ++- src/linklayer/ieee80211/mac/Ieee80211Mac.ned | 82 +- .../ieee80211/mac/Ieee80211NewMac.cc | 3036 ----------------- src/linklayer/ieee80211/mac/Ieee80211NewMac.h | 682 ---- .../ieee80211/mac/Ieee80211NewMac.ned | 123 - .../ieee80211/mgmt/Ieee80211MgmtAP.cc | 51 - .../ieee80211/radio/Ieee80211NewRadio.ned | 45 - .../ieee80211/radio/Ieee80211NewRadioModel.cc | 356 -- .../ieee80211/radio/Ieee80211NewRadioModel.h | 82 - .../ieee80211/radio/Ieee80211Radio.ned | 23 +- .../ieee80211/radio/Ieee80211RadioModel.cc | 298 +- .../ieee80211/radio/Ieee80211RadioModel.h | 45 +- .../ieee80211mesh/Ieee80211NewNicMesh.ned | 114 - .../ieee80211mesh/Ieee80211NicMesh.ned | 72 +- ...eshMulti.ned => Ieee80211NicMeshMulti.ned} | 10 +- .../ieee80211mesh/nodes/ApMeshNode.ned | 6 +- .../ieee80211mesh/nodes/ApMeshRelay.ned | 6 +- .../nodes/BasicMobileManetMesh.ned | 6 +- .../ieee80211mesh/nodes/gateWayMesh.ned | 6 +- src/mobility/ChangeLog | 6 +- ...y.cc => LinearNodeDistributionMobility.cc} | 12 +- ...ity.h => LinearNodeDistributionMobility.h} | 4 +- ...ned => LinearNodeDistributionMobility.ned} | 12 +- src/mobility/models/TraCIMobility.cc | 348 +- src/mobility/models/TraCIMobility.h | 37 +- src/mobility/models/TraCIMobility.ned | 16 +- src/networklayer/autorouting/ipv4/ChangeLog | 7 + .../autorouting/ipv4/HostAutoConfigurator.cc | 189 +- .../autorouting/ipv4/HostAutoConfigurator.h | 60 +- .../autorouting/ipv4/HostAutoConfigurator.ned | 16 +- src/networklayer/manetrouting/ChangeLog | 13 + .../manetrouting/base/ManetRoutingBase.cc | 56 +- .../manetrouting/base/ManetRoutingBase.h | 4 + .../manetrouting/dsr/dsr-pkt_omnet.cc | 2 + .../manetrouting/dsr/dsr-uu-omnetpp.cc | 4 +- .../manetrouting/dsr/dsr-uu/dsr-pkt.cc | 2 + .../manetrouting/dymo/dymo_um_omnet.cc | 7 +- .../ospfv2/router/OSPFRoutingTableEntry.cc | 1 + src/transport/contract/ChangeLog | 6 + src/transport/contract/UDPSocket.h | 4 +- src/transport/udp/ChangeLog | 5 + src/transport/udp/UDP.cc | 32 +- .../ieee80211/mgmt/Ieee80211NicExtended.ned | 8 +- .../nodes/wireless/WirelessRouterExtended.ned | 2 +- src/world/traci/ChangeLog | 12 + src/world/traci/TraCIScenarioManager.cc | 71 +- src/world/traci/TraCIScenarioManager.h | 53 +- src/world/traci/TraCIScenarioManager.ned | 23 +- .../traci/TraCIScenarioManagerLaunchd.cc | 2 +- src/world/traci/TraCIScenarioManagerLaunchd.h | 18 +- .../traci/TraCIScenarioManagerLaunchd.ned | 29 +- tests/fingerprint/examples-TODO.csv_off | 6 - tests/fingerprint/examples-quick.csv | 17 +- tests/fingerprint/examples.csv | 99 +- tests/fingerprint/examples.csv.unstable | 2 +- tests/fingerprint/gen_runallexamples.pl | 0 tests/fingerprint/manet.csv | 56 +- tests/module/ospf_1_area.test | 239 ++ tests/module/ospf_1_area_HostInterface.test | 239 ++ tests/module/ospf_backbone_and_2_areas.test | 294 ++ ...pf_backbone_and_2_areas_HostInterface.test | 294 ++ tests/module/ospf_backbone_and_2_stub.test | 274 ++ ...and_3_areas_VirtualLink_HostInterface.test | 331 ++ ...ackbone_and_3_areas_with_virtual_link.test | 331 ++ tests/module/ospf_fig6_simple_fail.test | 293 ++ tests/smoke/examples-TODO.csv_off | 11 +- tests/smoke/examples.csv | 46 +- .../EtherMACs_compare_twohosts_speed.test | 2 +- .../EtherMacFullDuplex_twohosts_speed.test | 4 +- .../EtherMac_bus_reconnect_speed.test | 4 +- tests/statistical/EtherMac_bus_speed.test | 4 +- .../EtherMac_fullduplex_twohosts_speed.test | 4 +- .../EtherMac_halfduplex_twohosts_speed.test | 4 +- .../EtherMac_hub_reconnect_speed.test | 4 +- tests/statistical/EtherMac_hub_speed.test | 4 +- tests/statistical/EtherMac_switch_speed.test | 4 +- ...esspoint_tenhost_congestion_speed_BAD.test | 4 +- .../ieee80211_accesspoint_tenhost_speed.test | 4 +- ..._accesspoint_twohost_congestion_speed.test | 4 +- .../ieee80211_accesspoint_twohost_speed.test | 4 +- ...e80211_adhoc_tenhost_congestion_speed.test | 4 +- .../ieee80211_adhoc_tenhost_speed.test | 4 +- .../ieee80211_adhoc_twohost_speed.test | 4 +- tests/statistical/manetrouting_transmit1.test | 4 +- .../statistical/manetrouting_transmit10.test | 4 +- tests/statistical/ospf_1_area_Dynamic.test | 297 ++ tests/statistical/ospf_1_area_Dynamic2.test | 296 ++ .../tcp_nosack_moreclients_speed.test | 8 +- .../tcp_nosack_moreclients_speed_strict.test | 8 +- .../tcp_nosack_twohosts_bytestream_speed.test | 8 +- .../tcp_nosack_twohosts_object_speed.test | 8 +- .../tcp_nosack_twohosts_speed.test | 8 +- .../tcp_nosack_twohosts_speed_strict.test | 8 +- .../tcp_sack_moreclients_speed.test | 8 +- .../tcp_sack_moreclients_speed_strict.test | 8 +- .../statistical/tcp_sack_twohosts_speed.test | 8 +- .../tcp_sack_twohosts_speed_strict.test | 8 +- tests/statistical/udp_twohosts_speed.test | 17 +- tests/traci/Car.ned | 89 + tests/traci/Highway.ned | 41 + tests/traci/net.edg.xml | 71 + tests/traci/net.net.xml | 1298 +++++++ tests/traci/net.netconvert.cfg | 17 + tests/traci/net.nod.xml | 38 + tests/traci/omnetpp.ini | 63 + tests/traci/package.ned | 1 + tests/traci/polys.poly.xml | 3 + tests/traci/routes.rou.xml | 5 + tests/traci/runTest.sh | 3 + tests/traci/sumo-launchd.launch.xml | 10 + tests/traci/sumo.sumo.cfg | 15 + tests/traci/tls.tls.xml | 18 + 133 files changed, 10554 insertions(+), 6142 deletions(-) create mode 100644 etc/OSPF_old.xsd create mode 100644 etc/OSPFold_to_OSPFnew.xsl create mode 100755 etc/sumo-launchd.py create mode 100644 misc/gdb/README create mode 100644 misc/gdb/inet/__init__.py create mode 100644 misc/gdb/inet/printers.py create mode 100644 src/applications/dhcp/ChangeLog delete mode 100644 src/applications/dhcp/package.ned create mode 100644 src/linklayer/IWirelessNicMulti.ned delete mode 100644 src/linklayer/ieee80211/Ieee80211NewNic.ned delete mode 100644 src/linklayer/ieee80211/mac/Ieee80211NewMac.cc delete mode 100644 src/linklayer/ieee80211/mac/Ieee80211NewMac.h delete mode 100644 src/linklayer/ieee80211/mac/Ieee80211NewMac.ned delete mode 100644 src/linklayer/ieee80211/radio/Ieee80211NewRadio.ned delete mode 100644 src/linklayer/ieee80211/radio/Ieee80211NewRadioModel.cc delete mode 100644 src/linklayer/ieee80211/radio/Ieee80211NewRadioModel.h delete mode 100644 src/linklayer/ieee80211mesh/Ieee80211NewNicMesh.ned rename src/linklayer/ieee80211mesh/{Ieee80211NewNicMeshMulti.ned => Ieee80211NicMeshMulti.ned} (94%) rename src/mobility/models/{LinealNodeDistributionMobility.cc => LinearNodeDistributionMobility.cc} (85%) rename src/mobility/models/{LinealNodeDistributionMobility.h => LinearNodeDistributionMobility.h} (93%) rename src/mobility/models/{LinealNodeDistributionMobility.ned => LinearNodeDistributionMobility.ned} (79%) create mode 100644 src/world/traci/ChangeLog mode change 100644 => 100755 tests/fingerprint/gen_runallexamples.pl create mode 100644 tests/module/ospf_1_area.test create mode 100644 tests/module/ospf_1_area_HostInterface.test create mode 100644 tests/module/ospf_backbone_and_2_areas.test create mode 100644 tests/module/ospf_backbone_and_2_areas_HostInterface.test create mode 100644 tests/module/ospf_backbone_and_2_stub.test create mode 100644 tests/module/ospf_backbone_and_3_areas_VirtualLink_HostInterface.test create mode 100644 tests/module/ospf_backbone_and_3_areas_with_virtual_link.test create mode 100644 tests/module/ospf_fig6_simple_fail.test create mode 100644 tests/statistical/ospf_1_area_Dynamic.test create mode 100644 tests/statistical/ospf_1_area_Dynamic2.test create mode 100644 tests/traci/Car.ned create mode 100644 tests/traci/Highway.ned create mode 100644 tests/traci/net.edg.xml create mode 100644 tests/traci/net.net.xml create mode 100644 tests/traci/net.netconvert.cfg create mode 100644 tests/traci/net.nod.xml create mode 100644 tests/traci/omnetpp.ini create mode 100644 tests/traci/package.ned create mode 100644 tests/traci/polys.poly.xml create mode 100644 tests/traci/routes.rou.xml create mode 100755 tests/traci/runTest.sh create mode 100644 tests/traci/sumo-launchd.launch.xml create mode 100644 tests/traci/sumo.sumo.cfg create mode 100644 tests/traci/tls.tls.xml diff --git a/.oppfeatures b/.oppfeatures index d3d858f1d..83eece176 100644 --- a/.oppfeatures +++ b/.oppfeatures @@ -229,6 +229,34 @@ compileFlags = "" linkerFlags = "" /> + + + + /> - + /> - - - diff --git a/etc/OSPF.xsd b/etc/OSPF.xsd index 14ad183af..1ff6fae64 100644 --- a/etc/OSPF.xsd +++ b/etc/OSPF.xsd @@ -1,7 +1,7 @@ - + A string containing an IPv4 address in dotted decimal notation. @@ -13,6 +13,39 @@ + + + + A string containing a string which resolvable by IPvXAddressResolver class in INET. + + + + + + + + + + + A string containing a node path, for example "Area1.Router2". + + + + + + + + + + + A string containing an interface name. + + + + + + + @@ -95,6 +128,13 @@ + + + + + + + @@ -103,11 +143,9 @@ - - - - - + + + @@ -121,9 +159,7 @@ - - - + @@ -140,7 +176,7 @@ - + @@ -148,24 +184,22 @@ Describes the parameters of a point-to-point interface. It is identified - in the router by its ifIndex value. + in the router by its ifName value, or name of toward module. HelloInterval and RouterDeadInterval must be the same for all router interfaces attached to the same network. - - - - - - - - - - - + + + + + + + + + @@ -173,25 +207,23 @@ Describes the parameters of a broadcast interface. It is identified in - the router by its ifIndex value. + the router by its ifName value, or name of toward module. HelloInterval and RouterDeadInterval must be the same for all router interfaces attached to the same network. - - - - - - - - - - - - + + + + + + + + + + @@ -203,10 +235,8 @@ - - - - + + @@ -228,7 +258,7 @@ Describes the parameters of an NBMA interface. It is identified in the - router by its ifIndex value. + router by its ifName value, or name of toward module. HelloInterval and RouterDeadInterval must be the same for all router interfaces attached to the same network. @@ -236,19 +266,19 @@ - - - - - - - - - - - + + + + + + + + + + + @@ -261,7 +291,7 @@ - + @@ -270,7 +300,7 @@ Describes the parameters of a point-to-multipoint interface. It is - identified in the router by its ifIndex value. + identified in the router by its ifName value, or name of toward module. HelloInterval and RouterDeadInterval must be the same for all router interfaces attached to the same network. @@ -278,47 +308,17 @@ - - - - - - - - - - - - - - - - The address of an external network to advertise in AS External LSAs. - - - - - - - - - - - - - - - The output cost parameters of an external interface. - - - - - - - - + + + + + + + + + @@ -327,18 +327,18 @@ Describes the parameters of an external interface. These parameters will be advertised in the AS External LSA for this external route. The - interface is identified in the router by its ifIndex value. + interface is identified in the router by its ifName value, or name of toward module. - - - - - - - + + + + + + + @@ -347,17 +347,15 @@ Describes the parameters of a host interface (an interface to which a single host is attached). The interface is identified in the router by - its ifIndex value. + its ifName value, or name of toward module. - - - - - - + + + + @@ -372,23 +370,21 @@ - - - - - - - - - - + + + + + + + + - Describes an OSPF router with its interfaces. Interface ifIndex values + Describes an OSPF router with its interfaces. Interface 'ifName' and 'toward' module name values must be unique within the same router. A router is identified by its Router ID, which is given as an IPv4 address (but isn't necessarily one). @@ -396,7 +392,6 @@ - @@ -407,11 +402,16 @@ - + + - + + + + + diff --git a/etc/OSPF_old.xsd b/etc/OSPF_old.xsd new file mode 100644 index 000000000..07baf4df2 --- /dev/null +++ b/etc/OSPF_old.xsd @@ -0,0 +1,463 @@ + + + + + + + A string containing an IPv4 address in dotted decimal notation. + + + + + + + + + + + + A string containing an interface name. + + + + + + + + + + + A value type which decides whether an address range will be advertised + in Summary LSAs. + + + + + + + + + + + + + Link cost metric datatype. Should be less then 1000. + + + + + + + + + + + + Possible OSPF packet authentication protocols. + + + + + + + + + + + + + + Key value for the chosen authentication protocol. A string of at most 8 + bytes given in hexadecimal form. It starts with the '0x' string and + continues with 1 to 8 pairs of hexadecimal digits. + + + + + + + + + + + + 4 bytes describing the external route tag propagated for an external + route in AS External LSAs. A string of at most 4 bytes given in + hexadecimal form. It starts with the '0x' string and continues with 1 to + 4 pairs of hexadecimal digits. + + + + + + + + + + + The output cost type of an external link. + + + + + + + + + + + + + + Describes an address range of an OSPF area. + + + + + + + + + + + + + + + + An OSPF area (except the backbone) can be configured as a stub area. This + element signals this occurrence and defines the default route cost + advertised for that area. + + + + + + + + + + + + + + The definition of an OSPF area. It has to have an Area ID given in the + form of an IPv4 address. (The backbone is '0.0.0.0'.) + + + + + + + + + + + + + + + + Describes the parameters of a point-to-point interface. It is identified + in the router by its ifName value. + HelloInterval and RouterDeadInterval must be the same for all router + interfaces attached to the same network. + + + + + + + + + + + + + + + + + + + + + + Describes the parameters of a broadcast interface. It is identified in + the router by its ifName value. + HelloInterval and RouterDeadInterval must be the same for all router + interfaces attached to the same network. + + + + + + + + + + + + + + + + + + + + + + + Describes the preconfigured parameters of one of an NBMA router's neighbor. + + + + + + + + + + + + + + + A list of the available neighbors on an NBMA network. + + + + + + + + + + + + + + Describes the parameters of an NBMA interface. It is identified in the + router by its ifName value. + HelloInterval and RouterDeadInterval must be the same for all router + interfaces attached to the same network. + + + + + + + + + + + + + + + + + + + + + + + + + A list of the available neighbors on a PointToMultiPoint network. + + + + + + + + + + + + + + Describes the parameters of a point-to-multipoint interface. It is + identified in the router by its ifName value. + HelloInterval and RouterDeadInterval must be the same for all router + interfaces attached to the same network. + + + + + + + + + + + + + + + + + + + + + + + The address of an external network to advertise in AS External LSAs. + + + + + + + + + + + + + + + The output cost parameters of an external interface. + + + + + + + + + + + + + + + Describes the parameters of an external interface. These parameters will + be advertised in the AS External LSA for this external route. The + interface is identified in the router by its ifName value. + + + + + + + + + + + + + + + + + + Describes the parameters of a host interface (an interface to which a + single host is attached). The interface is identified in the router by + its ifName value. + + + + + + + + + + + + + + + + + Describes a virtual link between two backbone routers. + RetransmissionInterval should be well over the expected round-trip delay + between the two routers. The virtual link is identified by its end + point's router ID. + + + + + + + + + + + + + + + + + + + + + Describes an OSPF router with its interfaces. Interface ifName values + must be unique within the same router. A router is identified by its + Router ID, which is given as an IPv4 address (but isn't necessarily one). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Describes an OSPF autonomous system with its areas and its routers. The + Area IDs, Router IDs and area Address Ranges must be unique within the + autonomous system. + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/etc/OSPFold_to_OSPFnew.xsl b/etc/OSPFold_to_OSPFnew.xsl new file mode 100644 index 000000000..016dbf11c --- /dev/null +++ b/etc/OSPFold_to_OSPFnew.xsl @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/etc/plugins/contextmenu.tcl b/etc/plugins/contextmenu.tcl index 4877ad925..f7bbba737 100644 --- a/etc/plugins/contextmenu.tcl +++ b/etc/plugins/contextmenu.tcl @@ -18,5 +18,12 @@ extendContextMenu { {"INET: TCP connections" "**.tcp" "tcpAppConnMap" "*map*" } {"INET: TED database" "**.ted" "ted" "*vector*"} {"INET: LIB table" "**.libTable" "lib" "*vector*"} + + {"INET: OSPF areas" "**" "**ospf.areas" "*vector*"} + {"INET: OSPF areas" "**.ospf" "areas" "*vector*"} + {"INET: OSPF ASExternalLSA" "**" "**ospf.asExternalLSAs" "*vector*"} + {"INET: OSPF ASExternalLSA" "**.ospf" "asExternalLSAs" "*vector*"} + {"INET: OSPF RoutingTable" "**" "**ospf.routingTable" "*vector*"} + {"INET: OSPF RoutingTable" "**.ospf" "routingTable" "*vector*"} } diff --git a/etc/sumo-launchd.py b/etc/sumo-launchd.py new file mode 100755 index 000000000..394e18621 --- /dev/null +++ b/etc/sumo-launchd.py @@ -0,0 +1,677 @@ +#!/usr/bin/env python + +# +# sumo-launchd.py -- SUMO launcher daemon for use with TraCI clients +# Copyright (C) 2006-2012 Christoph Sommer +# +# Documentation for these modules is at http://veins.car2x.org/ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU 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 +# + +""" +For each incoming TCP connection the daemon receives a launch configuration. +It starts SUMO accordingly, then proxies all TraCI Messages. + +The launch configuration must be sent in the very first TraCI message. +This message must contain a single command, CMD_FILE_SEND and be used to +send a file named "sumo-launchd.launch.xml", which has the following +structure: + + + + + + + + + +""" + +import os +import sys +import tempfile +import shutil +import socket +import struct +import subprocess +import time +import signal +import exceptions +import thread +import xml.dom.minidom +import select +import logging +import atexit +from optparse import OptionParser + +_API_VERSION = 1 +_LAUNCHD_VERSION = 'sumo-launchd.py 1.00' +_CMD_GET_VERSION = 0x00 +_CMD_FILE_SEND = 0x75 + +class UnusedPortLock: + lock = thread.allocate_lock() + + def __init__(self): + self.acquired = False + + def __enter__(self): + self.acquire() + + def __exit__(self): + self.release() + + def acquire(self): + if not self.acquired: + logging.debug("Claiming lock on port") + UnusedPortLock.lock.acquire() + self.acquired = True + + def release(self): + if self.acquired: + logging.debug("Releasing lock on port") + UnusedPortLock.lock.release() + self.acquired = False + +def find_unused_port(): + """ + Return an unused port number. + """ + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) + sock.bind(('127.0.0.1', 0)) + sock.listen(socket.SOMAXCONN) + ipaddr, port = sock.getsockname() + sock.close() + return port + + +def forward_connection(client_socket, server_socket, process): + """ + Proxy connections until either socket runs out of data or process terminates. + """ + + logging.debug("Starting proxy mode") + + client_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + server_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + + do_exit = False + while not do_exit: + + (r, w, e) = select.select([client_socket, server_socket], [], [client_socket, server_socket], 1) + if client_socket in e: + do_exit = True + break + if server_socket in e: + do_exit = True + break + if client_socket in r: + try: + data = client_socket.recv(65535) + if data == "": + do_exit = True + except: + do_exit = True + finally: + server_socket.send(data) + if server_socket in r: + try: + data = server_socket.recv(65535) + if data == "": + do_exit = True + except: + do_exit = True + finally: + client_socket.send(data) + + rc = process.poll() + if (rc != None): + do_exit = True + break + + logging.debug("Done with proxy mode") + + +def parse_launch_configuration(launch_xml_string): + """ + Returns tuple of options set in launch configuration + """ + + p = xml.dom.minidom.parseString(launch_xml_string) + + # get root node "launch" + launch_node = p.documentElement + if (launch_node.tagName != "launch"): + raise RuntimeError("launch config root element not , but <%s>" % launch_node.tagName) + + # get "launch.basedir" + basedir = "" + basedir_nodes = [x for x in launch_node.getElementsByTagName("basedir") if x.parentNode==launch_node] + if len(basedir_nodes) > 1: + raise RuntimeError('launch config contains %d nodes, expected at most 1' % (len(basedir_nodes))) + elif len(basedir_nodes) == 1: + basedir = basedir_nodes[0].getAttribute("path") + logging.debug("Base dir is %s" % basedir) + + # get "launch.seed" + seed = 23423 + seed_nodes = [x for x in launch_node.getElementsByTagName("seed") if x.parentNode==launch_node] + if len(seed_nodes) > 1: + raise RuntimeError('launch config contains %d nodes, expected at most 1' % (len(seed_nodes))) + elif len(seed_nodes) == 1: + seed = int(seed_nodes[0].getAttribute("value")) + logging.debug("Seed is %d" % seed) + + # get list of "launch.copy" entries + copy_nodes = [x for x in launch_node.getElementsByTagName("copy") if x.parentNode==launch_node] + + return (basedir, copy_nodes, seed) + + +def run_sumo(runpath, sumo_command, shlex, config_file_name, remote_port, seed, client_socket, unused_port_lock, keep_temp): + """ + Actually run SUMO. + """ + + # create log files + sumoLogOut = open(os.path.join(runpath, 'sumo-launchd.out.log'), 'w') + sumoLogErr = open(os.path.join(runpath, 'sumo-launchd.err.log'), 'w') + + # start SUMO + sumo_start = int(time.time()) + sumo_end = None + sumo_returncode = -1 + sumo_status = None + try: + cmd = [] + if shlex: + import shlex + cmd = shlex.split(sumo_command.replace('{}', '-c ' + unicode(config_file_name).encode())) + else: + cmd = [sumo_command, "-c", config_file_name] + logging.info("Starting SUMO (%s) on port %d, seed %d" % (" ".join(cmd), remote_port, seed)) + sumo = subprocess.Popen(cmd, cwd=runpath, stdin=None, stdout=sumoLogOut, stderr=sumoLogErr) + + sumo_socket = None + + connected = False + tries = 1 + while not connected: + try: + logging.debug("Connecting to SUMO (%s) on port %d (try %d)" % (" ".join(cmd), remote_port, tries)) + sumo_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sumo_socket.connect(('127.0.0.1', remote_port)) + break + except socket.error, e: + logging.debug("Error (%s)" % e) + if tries >= 10: + raise + time.sleep(tries * 0.25) + tries += 1 + + unused_port_lock.release() + forward_connection(client_socket, sumo_socket, sumo) + + client_socket.close() + sumo_socket.close() + + logging.debug("Done with proxy mode, killing SUMO") + + thread.start_new_thread(subprocess.Popen.wait, (sumo, )) + time.sleep(0.5) + if sumo.returncode == None: + logging.debug("SIGTERM") + os.kill(sumo.pid, signal.SIGTERM) + time.sleep(0.5) + if sumo.returncode == None: + logging.debug("SIGKILL") + os.kill(sumo.pid, signal.SIGKILL) + time.sleep(1) + if sumo.returncode == None: + logging.debug("Warning: SUMO still not dead. Waiting 10 more seconds...") + time.sleep(10) + + logging.info("Done running SUMO") + sumo_returncode = sumo.returncode + if sumo_returncode == 0: + sumo_status = "Done." + elif sumo_returncode != None: + sumo_status = "Exited with error code %d" % sumo_returncode + else: + sumo_returncode = -1 + sumo_status = "Undef" + + except OSError, e: + sumo_status = "Could not start SUMO (%s): %s" % (" ".join(cmd), e) + + except exceptions.SystemExit: + sumo_status = "Premature launch script exit" + + except exceptions.KeyboardInterrupt: + sumo_status = "Keyboard interrupt." + + except socket.error, e: + sumo_status = "Could not connect to SUMO (%s). Might be protected by a personal firewall or crashed before a connection could be established." % e + + except: + raise + + # statistics + sumo_end = int(time.time()) + + # close log files + sumoLogOut.close() + sumoLogErr.close() + + # read log files + sumoLogOut = open(os.path.join(runpath, 'sumo-launchd.out.log'), 'r') + sumoLogErr = open(os.path.join(runpath, 'sumo-launchd.err.log'), 'r') + sumo_stdout = sumoLogOut.read() + sumo_stderr = sumoLogErr.read() + sumoLogOut.close() + sumoLogErr.close() + + # prepare result XML + CDATA_START = '' + result_xml = '\n' + result_xml += '\n' + result_xml += '\t<%s>%s\n' % ("exit-code", sumo_returncode, "exit-code") + if sumo_start: + result_xml += '\t<%s>%s\n' % ("start", sumo_start, "start") + if sumo_end: + result_xml += '\t<%s>%s\n' % ("end", sumo_end, "end") + if sumo_status: + result_xml += '\t<%s>%s\n' % ("status", sumo_status, "status") + result_xml += '\t<%s>%s\n' % ("stdout", CDATA_START + sumo_stdout.replace(CDATA_END, CDATA_END + CDATA_END + CDATA_START) + CDATA_END, "stdout") + result_xml += '\t<%s>%s\n' % ("stderr", CDATA_START + sumo_stderr.replace(CDATA_END, CDATA_END + CDATA_END + CDATA_START) + CDATA_END, "stderr") + result_xml += '\n' + + return result_xml + + +def set_sumoconfig_option(config_parser, config_xml, section, key, value): + """ + Add or replace named config option (currently ignores given section) + """ + + key_nodes = config_xml.getElementsByTagName(key) + if len(key_nodes) > 1: + raise RuntimeError('config file "%s" contains %d <%s> nodes, expected at most 1' % (file_dst_name, key, len(key_nodes))) + elif len(key_nodes) < 1: + key_node = config_parser.createElement(key) + key_node.setAttribute("value", str(value)) + config_xml.appendChild(key_node) + else: + key_node = key_nodes[0] + for n in key_node.childNodes: + key_node.removeChild(n) + key_node.setAttribute("value", str(value)) + + +def copy_and_modify_files(basedir, copy_nodes, runpath, remote_port, seed): + """ + Copy (and modify) files, return config file name + """ + + config_file_name = None + for copy_node in copy_nodes: + + file_src_name = None + file_dst_name = None + file_contents = None + + # Read from disk? + if copy_node.hasAttribute("file"): + file_src_name = copy_node.getAttribute("file") + file_src_path = os.path.join(basedir, file_src_name) + + # Sanity check + if file_src_name.find("/") != -1: + raise RuntimeError('name of file to copy "%s" contains a "/"' % file_src_name) + if not os.path.exists(file_src_path): + raise RuntimeError('file "%s" does not exist' % file_src_path) + + # Read contents + file_handle = open(file_src_path, 'rb') + file_contents = file_handle.read() + file_handle.close() + + # By now we need a destination name and contents + if copy_node.hasAttribute("name"): + file_dst_name = copy_node.getAttribute("name") + elif file_src_name: + file_dst_name = file_src_name + else: + raise RuntimeError(' node with no destination name: %s' % copy_node.toxml()) + if file_contents == None: + raise RuntimeError(' node with no contents: %s' % copy_node.toxml()) + + # Is this our config file? + if copy_node.getAttribute("type") == "config": + config_file_name = file_dst_name + + config_parser = xml.dom.minidom.parseString(file_contents) + config_xml = config_parser.documentElement + + set_sumoconfig_option(config_parser, config_xml, "traci_server", "remote-port", remote_port) + set_sumoconfig_option(config_parser, config_xml, "random_number", "seed", seed) + set_sumoconfig_option(config_parser, config_xml, "random_number", "random", "false") + + file_contents = config_xml.toxml() + + # Write file into rundir + file_dst_path = os.path.join(runpath, file_dst_name) + file_handle = open(file_dst_path, "wb") + file_handle.write(file_contents) + file_handle.close() + + # make sure that we copied a config file + if not config_file_name: + raise RuntimeError('launch config contained no node with type="config"') + + return config_file_name + + +def handle_launch_configuration(sumo_command, shlex, launch_xml_string, client_socket, keep_temp): + """ + Process launch configuration in launch_xml_string. + """ + + # create temporary directory + logging.debug("Creating temporary directory...") + runpath = tempfile.mkdtemp(prefix="sumo-launchd-tmp-") + if not runpath: + raise RuntimeError("Could not create temporary directory") + if not os.path.exists(runpath): + raise RuntimeError('Temporary directory "%s" does not exist, even though it should have been created' % runpath) + logging.debug("Temporary dir is %s" % runpath) + + result_xml = None + unused_port_lock = UnusedPortLock() + try: + # parse launch configuration + (basedir, copy_nodes, seed) = parse_launch_configuration(launch_xml_string) + + # find remote_port + logging.debug("Finding free port number...") + unused_port_lock.__enter__() + remote_port = find_unused_port() + logging.debug("...found port %d" % remote_port) + + # copy (and modify) files + config_file_name = copy_and_modify_files(basedir, copy_nodes, runpath, remote_port, seed) + + # run SUMO + result_xml = run_sumo(runpath, sumo_command, shlex, config_file_name, remote_port, seed, client_socket, unused_port_lock, keep_temp) + + finally: + unused_port_lock.__exit__() + + # clean up + if not keep_temp: + logging.debug("Cleaning up") + shutil.rmtree(runpath) + else: + logging.debug("Not cleaning up %s" % runpath) + + logging.debug('Result: "%s"' % result_xml) + + return result_xml + +def handle_get_version(conn): + """ + process a "get version" command received on the connection + """ + + logging.debug('Got CMD_GETVERSION') + + # Send OK response and version info + response = struct.pack("!iBBBiBBii", 4+1+1+1+4 + 1+1+4+4+len(_LAUNCHD_VERSION), 1+1+1+4, _CMD_GET_VERSION, 0x00, 0x00, 1+4+4+len(_LAUNCHD_VERSION), _CMD_GET_VERSION, _API_VERSION, len(_LAUNCHD_VERSION)) + _LAUNCHD_VERSION + conn.send(response) + + +def read_launch_config(conn): + """ + Read (and return) launch configuration from socket + """ + + # Get TraCI message length + msg_len_buf = "" + while len(msg_len_buf) < 4: + msg_len_buf += conn.recv(4 - len(msg_len_buf)) + msg_len = struct.unpack("!i", msg_len_buf)[0] - 4 + + logging.debug("Got TraCI message of length %d" % msg_len) + + # Get TraCI command length + cmd_len_buf = "" + cmd_len_buf += conn.recv(1) + cmd_len = struct.unpack("!B", cmd_len_buf)[0] - 1 + if cmd_len == -1: + cmd_len_buf = "" + while len(cmd_len_buf) < 4: + cmd_len_buf += conn.recv(4 - len(cmd_len_buf)) + cmd_len = struct.unpack("!i", cmd_len_buf)[0] - 5 + + logging.debug("Got TraCI command of length %d" % cmd_len) + + # Get TraCI command ID + cmd_id_buf = "" + cmd_id_buf += conn.recv(1) + cmd_id = struct.unpack("!B", cmd_id_buf)[0] + + logging.debug("Got TraCI command 0x%x" % cmd_id) + + if cmd_id == _CMD_GET_VERSION: + # handle get version command + handle_get_version(conn) + # ...and try reading the launch config again + return read_launch_config(conn) + elif cmd_id != _CMD_FILE_SEND: + raise RuntimeError("Expected CMD_FILE_SEND (0x%x), but got 0x%x" % (_CMD_FILE_SEND, cmd_id)) + + # Get File name + fname_len_buf = "" + while len(fname_len_buf) < 4: + fname_len_buf += conn.recv(4 - len(fname_len_buf)) + fname_len = struct.unpack("!i", fname_len_buf)[0] + fname = conn.recv(fname_len) + if fname != "sumo-launchd.launch.xml": + raise RuntimeError('Launch configuration must be named "sumo-launchd.launch.xml", got "%s" instead.' % fname) + + logging.debug('Got CMD_FILE_SEND for "%s"' % fname) + + # Get File contents + data_len_buf = "" + while len(data_len_buf) < 4: + data_len_buf += conn.recv(4 - len(data_len_buf)) + data_len = struct.unpack("!i", data_len_buf)[0] + data = conn.recv(data_len) + + logging.debug('Got CMD_FILE_SEND with data "%s"' % data) + + # Send OK response + response = struct.pack("!iBBBi", 4+1+1+1+4, 1+1+1+4, _CMD_FILE_SEND, 0x00, 0x00) + conn.send(response) + + return data + + +def handle_connection(sumo_command, shlex, conn, addr, keep_temp): + """ + Handle incoming connection. + """ + + logging.debug("Handling connection from %s on port %d" % addr) + + try: + data = read_launch_config(conn) + handle_launch_configuration(sumo_command, shlex, data, conn, keep_temp) + + except Exception, e: + logging.error("Aborting on error: %s" % e) + + finally: + logging.debug("Closing connection from %s on port %d" % addr) + conn.close() + + +def wait_for_connections(sumo_command, shlex, sumo_port, bind_address, do_daemonize, do_kill, pidfile, keep_temp): + """ + Open TCP socket, wait for connections, call handle_connection for each + """ + + if do_kill: + check_kill_daemon(pidfile) + + listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + listener.bind((bind_address, sumo_port)) + listener.listen(5) + logging.info("Listening on port %d" % sumo_port) + + if do_daemonize: + logging.info("Detaching to run as daemon") + daemonize(pidfile) + + try: + while True: + conn, addr = listener.accept() + logging.debug("Connection from %s on port %d" % addr) + thread.start_new_thread(handle_connection, (sumo_command, shlex, conn, addr, keep_temp)) + + except exceptions.SystemExit: + logging.warning("Killed.") + + except exceptions.KeyboardInterrupt: + logging.warning("Keyboard interrupt.") + + except: + raise + + finally: + # clean up + logging.info("Shutting down.") + listener.close() + + +def check_kill_daemon(pidfile): + # check pidfile, see if the daemon is still running + try: + pidfileh = open(pidfile, 'r') + old_pid = int(pidfileh.readline()) + if old_pid: + logging.info("There might already be a daemon running with PID %d. Sending SIGTERM." % old_pid) + try: + os.kill(old_pid, signal.SIGTERM) + time.sleep(1) + except OSError, e: + pass + + pidfileh.close() + except IOError, e: + pass + + +def daemonize(pidfile): + """ + detach process, keep it running in the background + """ + + # fork and exit parent process + try: + child_pid = os.fork() + if child_pid > 0: + # parent can exit + sys.exit(0) + elif child_pid == 0: + # child does nothing + pass + else: + logging.error("Aborting. Failed to fork: %s" % e.strerror) + sys.exit(1); + except OSError, e: + logging.error("Aborting. Failed to fork: %s" % e.strerror) + sys.exit(1) + + # get rid of any outside influence + os.setsid() + + # fork again to prevent zombies + try: + child_pid = os.fork() + if child_pid > 0: + # parent can exit + sys.exit(0) + elif child_pid == 0: + # child creates PIDFILE + logging.info("Fork successful. PID is %d" % os.getpid()) + if pidfile: + pidfileh = open(pidfile, 'w') + pidfileh.write('%d\n' % os.getpid()) + pidfileh.close() + atexit.register(os.remove, pidfile) + else: + logging.error("Aborting. Failed to fork: %s" % e.strerror) + sys.exit(1); + + except OSError, e: + logging.error("Aborting. Failed to fork: %s" % e.strerror) + sys.exit(1) + + +def main(): + """ + Program entry point when run interactively. + """ + + # Option handling + parser = OptionParser() + parser.add_option("-c", "--command", dest="command", default="sumo", help="run SUMO as COMMAND [default: %default]", metavar="COMMAND") + parser.add_option("-s", "--shlex", dest="shlex", default=False, action="store_true", help="treat command as shell string to execute, replace {} with command line parameters [default: no]") + parser.add_option("-p", "--port", dest="port", type="int", default=9999, action="store", help="listen for connections on PORT [default: %default]", metavar="PORT") + parser.add_option("-b", "--bind", dest="bind", default="127.0.0.1", help="bind to ADDRESS [default: %default]", metavar="ADDRESS") + parser.add_option("-L", "--logfile", dest="logfile", default=os.path.join(tempfile.gettempdir(), "sumo-launchd.log"), help="log messages to LOGFILE [default: %default]", metavar="LOGFILE") + parser.add_option("-v", "--verbose", dest="count_verbose", default=0, action="count", help="increase verbosity [default: don't log infos, debug]") + parser.add_option("-q", "--quiet", dest="count_quiet", default=0, action="count", help="decrease verbosity [default: log warnings, errors]") + parser.add_option("-d", "--daemon", dest="daemonize", default=False, action="store_true", help="detach and run as daemon [default: no]") + parser.add_option("-k", "--kill", dest="kill", default=False, action="store_true", help="send SIGTERM to running daemon first [default: no]") + parser.add_option("-P", "--pidfile", dest="pidfile", default=os.path.join(tempfile.gettempdir(), "sumo-launchd.pid"), help="if running as a daemon, write pid to PIDFILE [default: %default]", metavar="PIDFILE") + parser.add_option("-t", "--keep-temp", dest="keep_temp", default=False, action="store_true", help="keep all temporary files [default: no]") + (options, args) = parser.parse_args() + _LOGLEVELS = (logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG) + loglevel = _LOGLEVELS[max(0, min(1 + options.count_verbose - options.count_quiet, len(_LOGLEVELS)-1))] + + # catch SIGTERM to exit cleanly when we're kill-ed + signal.signal(signal.SIGTERM, lambda signum, stack_frame: sys.exit(1)) + + # configure logging + logging.basicConfig(filename=options.logfile, level=loglevel) + if not options.daemonize: + logging.getLogger().addHandler(logging.StreamHandler()) + logging.debug("Logging to %s" % options.logfile) + + if args: + logging.warning("Superfluous command line arguments: \"%s\"" % " ".join(args)) + + # this is where we'll spend our time + wait_for_connections(options.command, options.shlex, options.port, options.bind, options.daemonize, options.kill, options.pidfile, options.keep_temp) + + +# Start main() when run interactively +if __name__ == '__main__': + main() diff --git a/misc/gdb/README b/misc/gdb/README new file mode 100644 index 000000000..9793dfe66 --- /dev/null +++ b/misc/gdb/README @@ -0,0 +1,44 @@ +Activating pretty printing in GDB for INET classes: + +Windows: + //TODO + +Mac OS X: + Mac OS comes with gdb 6.2 which does not support gdb pretty printers. + +Linux: + This directory must be included in the python system path and the pretty printer + classes must be registered before starting gdb. This can be done by creating + or modify a '.gdbinit' file in the $HOME directory with the following content. + Do not forget to edit the path to point to this directory. + +$HOME/.gdbinit: +--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<-- +set unwindonsignal on + +python + +import sys + + +# +# other pretty printer initializations +# + + +# inet pretty printer BEGIN + +sys.path.insert(0, '/path/to/inet-dir/misc/gdb') + +if 'register_inet_printers' in dir(): + print 'inet pretty printers already initialized.' +else: + from inet.printers import register_inet_printers + register_inet_printers(None) + print 'Pretty printers initialized: inet' + +# inet pretty printer END + + +end +--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<-- diff --git a/misc/gdb/inet/__init__.py b/misc/gdb/inet/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/misc/gdb/inet/printers.py b/misc/gdb/inet/printers.py new file mode 100644 index 000000000..872f31060 --- /dev/null +++ b/misc/gdb/inet/printers.py @@ -0,0 +1,121 @@ +# +# Pretty-printers for INET classes. +# +# Copyright (C) 2012 OpenSim Ltd. +# +# This file is distributed WITHOUT ANY WARRANTY. See the file +# `license' for details on this and other legal matters. +# +# @author: Zoltan Bojthe +# + +import gdb +import pprint + +# Try to use the new-style pretty-printing if available. +_use_gdb_pp = True +try: + import gdb.printing +except ImportError: + _use_gdb_pp = False + + +class IPv4AddressPrinter: + "Print an IPv4Address" + + def __init__(self, val): + self.val = val + + def to_string(self): + addr = self.val['addr'] + if (addr == 0): + return "" + return str((addr >> 24)&0xFF) + "." + str((addr >> 16)&0xFF) + "." + str((addr >> 8)&0xFF) + "." + str(addr&0xFF) + + +######################################################################################### + +# A "regular expression" printer which conforms to the +# "SubPrettyPrinter" protocol from gdb.printing. +class InetSubPrinter(object): + def __init__(self, name, function): + super(InetSubPrinter, self).__init__() + self.name = name + self.function = function + self.enabled = True + + def invoke(self, value): + if not self.enabled: + return None + return self.function(value) + +# A pretty-printer that conforms to the "PrettyPrinter" protocol from +# gdb.printing. It can also be used directly as an old-style printer. +class InetPrinter(object): + def __init__(self, name): + super(InetPrinter, self).__init__() + self.name = name + self.lookup = {} + self.enabled = True + + def add(self, name, function): + printer = InetSubPrinter(name, function) + self.lookup[name] = printer + + @staticmethod + def get_basic_type(type): + # If it points to a reference, get the reference. + if type.code == gdb.TYPE_CODE_REF or type.code == gdb.TYPE_CODE_PTR: + type = type.target() + + # Get the unqualified type, stripped of typedefs. + type = type.unqualified().strip_typedefs() + + return type.tag + + def __call__(self, val): + typename = self.get_basic_type(val.type) + #print "BASIC TYPE OF '%s' type IS '%s'" % (val.type, typename) + if not typename: + return None + + #print "lookup printer for '%s' type" % (typename) + if typename in self.lookup: + if val.type.code == gdb.TYPE_CODE_REF or val.type.code == gdb.TYPE_CODE_PTR: + if (long(val) == 0): + return None + val = val.dereference() + return self.lookup[typename].invoke(val) + + # Cannot find a pretty printer. Return None. + return None + + +inet_printer = None + + +def register_inet_printers(obj): + "Register OMNeT++ pretty-printers with objfile Obj." + + global _use_gdb_pp + global inet_printer + + if _use_gdb_pp: + gdb.printing.register_pretty_printer(obj, inet_printer) + else: + if obj is None: + obj = gdb + obj.pretty_printers.append(inet_printer) + + +def build_inet_dictionary(): + global inet_printer + + inet_printer = InetPrinter("inet") + + inet_printer.add('IPv4Address', IPv4AddressPrinter) + + +build_inet_dictionary() + +# end diff --git a/src/applications/dhcp/ChangeLog b/src/applications/dhcp/ChangeLog new file mode 100644 index 000000000..07b31e19a --- /dev/null +++ b/src/applications/dhcp/ChangeLog @@ -0,0 +1,8 @@ +2012-06-11 Rudolf Hornig + + Added the DHCP protocol implemantation. + + Code takeover from INETMANET-2.0. + The original code is coming from https://github.com/jmaureir/DHCP + written by Juan Carlos Maureira that was merged into + INETMANET 2.0 by Alfonso Ariza Quintana diff --git a/src/applications/dhcp/DHCPClient.cc b/src/applications/dhcp/DHCPClient.cc index cb0b20409..b1f3abd85 100644 --- a/src/applications/dhcp/DHCPClient.cc +++ b/src/applications/dhcp/DHCPClient.cc @@ -17,7 +17,6 @@ // #include "DHCPClient.h" -//#include "IPvXAddressResolver.h" #include "NotifierConsts.h" #include "InterfaceTableAccess.h" #include "RoutingTableAccess.h" @@ -203,9 +202,9 @@ void DHCPClient::handleMessage(cMessage *msg) { EV << "unknown packet, discarding it" << endl; } - // delete the msg - delete msg; } + // delete the msg + delete msg; } void DHCPClient::handleTimer(cMessage* msg) diff --git a/src/applications/dhcp/package.ned b/src/applications/dhcp/package.ned deleted file mode 100644 index 20e527458..000000000 --- a/src/applications/dhcp/package.ned +++ /dev/null @@ -1,2 +0,0 @@ -@license(LGPL); -package inet.applications.dhcp; \ No newline at end of file diff --git a/src/applications/traci/TraCIDemo.cc b/src/applications/traci/TraCIDemo.cc index b2b6094a1..367dcc378 100644 --- a/src/applications/traci/TraCIDemo.cc +++ b/src/applications/traci/TraCIDemo.cc @@ -25,76 +25,61 @@ Define_Module(TraCIDemo); -void TraCIDemo::initialize(int stage) -{ - cSimpleModule::initialize(stage); - if (stage == 0) - { - debug = par("debug"); +void TraCIDemo::initialize(int stage) { + cSimpleModule::initialize(stage); + if (stage == 3) { + debug = par("debug"); - mobilityStateChangedSignal = registerSignal("mobilityStateChanged"); - traci = TraCIMobilityAccess().get(); - traci->subscribe(mobilityStateChangedSignal, this); + mobilityStateChangedSignal = registerSignal("mobilityStateChanged"); + traci = TraCIMobilityAccess().get(); + traci->subscribe(mobilityStateChangedSignal, this); - sentMessage = false; + sentMessage = false; - setupLowerLayer(); - } + setupLowerLayer(); + } } -void TraCIDemo::setupLowerLayer() -{ - socket.setOutputGate(gate("udp$o")); - socket.bind(12345); - socket.setBroadcast(true); +void TraCIDemo::setupLowerLayer() { + socket.setOutputGate(gate("udp$o")); + socket.joinLocalMulticastGroups(); + socket.bind(12345); + socket.setBroadcast(true); } -void TraCIDemo::handleMessage(cMessage* msg) -{ - if (msg->isSelfMessage()) - { - handleSelfMsg(msg); - } - else - { - handleLowerMsg(msg); - } +void TraCIDemo::handleMessage(cMessage* msg) { + if (msg->isSelfMessage()) { + handleSelfMsg(msg); + } else { + handleLowerMsg(msg); + } } -void TraCIDemo::handleSelfMsg(cMessage* msg) -{ +void TraCIDemo::handleSelfMsg(cMessage* msg) { } -void TraCIDemo::handleLowerMsg(cMessage* msg) -{ - if (!sentMessage) - sendMessage(); - delete msg; +void TraCIDemo::handleLowerMsg(cMessage* msg) { + if (!sentMessage) sendMessage(); + delete msg; } -void TraCIDemo::receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj) -{ - Enter_Method_Silent(); - if (signalID == mobilityStateChangedSignal) - { - handlePositionUpdate(); - } +void TraCIDemo::receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj) { + Enter_Method_Silent(); + if (signalID == mobilityStateChangedSignal) { + handlePositionUpdate(); + } } -void TraCIDemo::sendMessage() -{ - sentMessage = true; +void TraCIDemo::sendMessage() { + sentMessage = true; - cPacket* newMessage = new cPacket(); + cPacket* newMessage = new cPacket(); - socket.sendTo(newMessage, IPv4Address::ALL_HOSTS_MCAST, 12345); + socket.sendTo(newMessage, IPv4Address::ALL_HOSTS_MCAST, 12345); } -void TraCIDemo::handlePositionUpdate() -{ - if (traci->getPosition().x < 7350) - { - if (!sentMessage) - sendMessage(); - } +void TraCIDemo::handlePositionUpdate() { + if (traci->getPosition().x < 7350) { + if (!sentMessage) sendMessage(); + } } diff --git a/src/applications/traci/TraCIDemo.h b/src/applications/traci/TraCIDemo.h index 3c76b34dc..103a0b724 100644 --- a/src/applications/traci/TraCIDemo.h +++ b/src/applications/traci/TraCIDemo.h @@ -29,31 +29,29 @@ /** * Small IVC Demo */ -class TraCIDemo : public cSimpleModule, protected cListener -{ - public: - virtual int numInitStages() const - { - return std::max(4, cSimpleModule::numInitStages()); - } - virtual void initialize(int); - virtual void receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj); - virtual void handleMessage(cMessage* msg); - - protected: - bool debug; - TraCIMobility* traci; - bool sentMessage; - UDPSocket socket; - simsignal_t mobilityStateChangedSignal; - - protected: - void setupLowerLayer(); - virtual void handleSelfMsg(cMessage* apMsg); - virtual void handleLowerMsg(cMessage* apMsg); - - virtual void sendMessage(); - virtual void handlePositionUpdate(); +class TraCIDemo : public cSimpleModule, protected cListener { + public: + virtual int numInitStages() const { + return std::max(4, cSimpleModule::numInitStages()); + } + virtual void initialize(int); + virtual void receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj); + virtual void handleMessage(cMessage* msg); + + protected: + bool debug; + TraCIMobility* traci; + bool sentMessage; + UDPSocket socket; + simsignal_t mobilityStateChangedSignal; + + protected: + void setupLowerLayer(); + virtual void handleSelfMsg(cMessage* apMsg); + virtual void handleLowerMsg(cMessage* apMsg); + + virtual void sendMessage(); + virtual void handlePositionUpdate(); }; #endif diff --git a/src/applications/traci/TraCITestApp.cc b/src/applications/traci/TraCITestApp.cc index 5385c22f0..7fe60b1c7 100644 --- a/src/applications/traci/TraCITestApp.cc +++ b/src/applications/traci/TraCITestApp.cc @@ -24,238 +24,190 @@ Define_Module(TraCITestApp); -void TraCITestApp::initialize(int stage) -{ - cSimpleModule::initialize(stage); - if (stage == 0) - { - debug = par("debug"); - testNumber = par("testNumber"); +void TraCITestApp::initialize(int stage) { + cSimpleModule::initialize(stage); + if (stage == 0) { + debug = par("debug"); + testNumber = par("testNumber"); - mobilityStateChangedSignal = registerSignal("mobilityStateChanged"); - traci = TraCIMobilityAccess().get(); - traci->subscribe(mobilityStateChangedSignal, this); + mobilityStateChangedSignal = registerSignal("mobilityStateChanged"); + traci = TraCIMobilityAccess().get(); + traci->subscribe(mobilityStateChangedSignal, this); - visitedEdges.clear(); - hasStopped = false; + visitedEdges.clear(); + hasStopped = false; - if (debug) - std::cout << "TraCITestApp initialized with testNumber=" << testNumber << std::endl; - } + if (debug) std::cout << "TraCITestApp initialized with testNumber=" << testNumber << std::endl; + } } -void TraCITestApp::finish() -{ +void TraCITestApp::finish() { } -void TraCITestApp::handleSelfMsg(cMessage *msg) -{ +void TraCITestApp::handleSelfMsg(cMessage *msg) { } -void TraCITestApp::handleLowerMsg(cMessage* msg) -{ - delete msg; +void TraCITestApp::handleLowerMsg(cMessage* msg) { + delete msg; } -void TraCITestApp::handleMessage(cMessage* msg) -{ - if (msg->isSelfMessage()) - { - handleSelfMsg(msg); - } - else - { - handleLowerMsg(msg); - } +void TraCITestApp::handleMessage(cMessage* msg) { + if (msg->isSelfMessage()) { + handleSelfMsg(msg); + } else { + handleLowerMsg(msg); + } } -void TraCITestApp::receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj) -{ - if (signalID == mobilityStateChangedSignal) - { - handlePositionUpdate(); - } -} -namespace { -void assertTrue(std::string msg, bool b) -{ - std::cout << (b ? "Passed" : "FAILED") << ": " << msg << std::endl; +void TraCITestApp::receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj) { + if (signalID == mobilityStateChangedSignal) { + handlePositionUpdate(); + } } -template void assertClose(std::string msg, T target, T actual) -{ - assertTrue(msg, std::fabs(target - actual) <= 0.0000001); -} -template void assertEqual(std::string msg, T target, T actual) -{ - assertTrue(msg, target == actual); -} -void assertEqual(std::string msg, std::string target, std::string actual) -{ - assertTrue(msg, target == actual); -} +namespace { + void assertTrue(std::string msg, bool b) { + std::cout << (b?"Passed":"FAILED") << ": " << msg << std::endl; + } + + template void assertClose(std::string msg, T target, T actual) { + assertTrue(msg, std::fabs(target - actual) <= 0.0000001); + } + template void assertEqual(std::string msg, T target, T actual) { + assertTrue(msg, target == actual); + } + void assertEqual(std::string msg, std::string target, std::string actual) { + assertTrue(msg, target == actual); + } } -void TraCITestApp::handlePositionUpdate() -{ - const simtime_t t = simTime(); - const std::string roadId = traci->getRoadId(); - visitedEdges.insert(roadId); - - int testCounter = 0; - - if (testNumber == testCounter++) - { - if (t == 9) - { - assertTrue("(commandSetSpeed) vehicle is driving", traci->getSpeed() > 25); - } - if (t == 10) - { - traci->commandSetSpeedMode(0x00); - traci->commandSetSpeed(0); - } - if (t == 11) - { - assertClose("(commandSetSpeed) vehicle has stopped", 0.0, traci->getSpeed()); - } - } - - if (testNumber == testCounter++) - { - if (t == 1) - { - traci->commandChangeRoute("42", 9999); - traci->commandChangeRoute("43", 9999); - } - if (t == 30) - { - assertTrue("(commandChangeRoute, 9999) vehicle avoided 42", visitedEdges.find("42") == visitedEdges.end()); - assertTrue("(commandChangeRoute, 9999) vehicle avoided 43", visitedEdges.find("43") == visitedEdges.end()); - assertTrue("(commandChangeRoute, 9999) vehicle took 44", visitedEdges.find("44") != visitedEdges.end()); - } - } - - if (testNumber == testCounter++) - { - if (t == 1) - { - traci->commandChangeRoute("42", 9999); - traci->commandChangeRoute("43", 9999); - } - if (t == 3) - { - traci->commandChangeRoute("42", -1); - traci->commandChangeRoute("44", 9999); - } - if (t == 30) - { - assertTrue("(commandChangeRoute, -1) vehicle took 42", visitedEdges.find("42") != visitedEdges.end()); - assertTrue("(commandChangeRoute, -1) vehicle avoided 43", visitedEdges.find("43") == visitedEdges.end()); - assertTrue("(commandChangeRoute, -1) vehicle avoided 44", visitedEdges.find("44") == visitedEdges.end()); - } - } - - if (testNumber == testCounter++) - { - if (t == 1) - { - assertClose("(commandDistanceRequest, air)", 859.4556417, - traci->commandDistanceRequest(Coord(25, 7030), Coord(883, 6980), false)); - assertClose("(commandDistanceRequest, driving)", 845.93, - traci->commandDistanceRequest(Coord(25, 7030), Coord(883, 6980), true)); - } - } - - if (testNumber == testCounter++) - { - if (t == 1) - { - traci->commandStopNode("43", 20, 0, 10, 30); - } - if (t == 30) - { - assertTrue("(commandStopNode) vehicle is at 43", roadId == "43"); - assertClose("(commandStopNode) vehicle is stopped", 0.0, traci->getSpeed()); - } - } - - if (testNumber == testCounter++) - { - if (t == 1) - { - traci->getManager()->commandSetTrafficLightProgram("10", "myProgramRed"); - } - if (t == 30) - { - assertTrue("(commandSetTrafficLightProgram) vehicle is at 31", roadId == "31"); - assertClose("(commandSetTrafficLightProgram) vehicle is stopped", 0.0, traci->getSpeed()); - } - } - - if (testNumber == testCounter++) - { - if (t == 1) - { - traci->getManager()->commandSetTrafficLightPhaseIndex("10", 4); - } - if (t == 30) - { - assertTrue("(commandSetTrafficLightPhaseIndex) vehicle is at 31", roadId == "31"); - assertClose("(commandSetTrafficLightPhaseIndex) vehicle is stopped", 0.0, traci->getSpeed()); - } - } - - if (testNumber == testCounter++) - { - if (t == 1) - { - std::list < std::string > polys = traci->commandGetPolygonIds(); - assertEqual("(commandGetPolygonIds) number is 1", polys.size(), (size_t) 1); - assertEqual("(commandGetPolygonIds) id is correct", *polys.begin(), "poly0"); - std::string typeId = traci->commandGetPolygonTypeId("poly0"); - assertEqual("(commandGetPolygonTypeId) typeId is correct", typeId, "type0"); - std::list shape = traci->commandGetPolygonShape("poly0"); - assertClose("(commandGetPolygonShape) shape x coordinate is correct", 130.0, shape.begin()->x); - assertClose("(commandGetPolygonShape) shape y coordinate is correct", 81.65, shape.begin()->y); - } - } - - if (testNumber == testCounter++) - { - if (t == 1) - { - std::list shape1 = traci->commandGetPolygonShape("poly0"); - assertClose("(commandGetPolygonShape) shape x coordinate is correct", 130.0, shape1.begin()->x); - assertClose("(commandGetPolygonShape) shape y coordinate is correct", 81.65, shape1.begin()->y); - std::list shape2 = shape1; - shape2.begin()->x = 135; - shape2.begin()->y = 85; - traci->commandSetPolygonShape("poly0", shape2); - std::list shape3 = traci->commandGetPolygonShape("poly0"); - assertClose("(commandSetPolygonShape) shape x coordinate was changed", 135.0, shape3.begin()->x); - assertClose("(commandSetPolygonShape) shape y coordinate was changed", 85.0, shape3.begin()->y); - } - } - - if (testNumber == testCounter++) - { - if (t == 30) - { - bool r = traci->getManager()->commandAddVehicle("testVehicle0", "vtype0", "route0", "25_0", 0, 70); - assertTrue("(commandAddVehicle) command reports success", r); - } - if (t == 31) - { - std::map::const_iterator i = traci->getManager()->getManagedHosts().find( - "testVehicle0"); - bool r = (i != traci->getManager()->getManagedHosts().end()); - assertTrue("(commandAddVehicle) vehicle now driving", r); - cModule* mod = i->second; - TraCIMobility* traci2 = check_and_cast(findModuleWhereverInNode("mobility", mod)); - assertTrue("(commandAddVehicle) vehicle driving at speed", traci2->getSpeed() > 25); - } - } +void TraCITestApp::handlePositionUpdate() { + const simtime_t t = simTime(); + const std::string roadId = traci->getRoadId(); + visitedEdges.insert(roadId); + + int testCounter = 0; + + if (testNumber == testCounter++) { + if (t == 9) { + assertTrue("(commandSetSpeed) vehicle is driving", traci->getSpeed() > 25); + } + if (t == 10) { + traci->commandSetSpeedMode(0x00); + traci->commandSetSpeed(0); + } + if (t == 11) { + assertClose("(commandSetSpeed) vehicle has stopped", 0.0, traci->getSpeed()); + } + } + + if (testNumber == testCounter++) { + if (t == 1) { + traci->commandChangeRoute("42", 9999); + traci->commandChangeRoute("43", 9999); + } + if (t == 30) { + assertTrue("(commandChangeRoute, 9999) vehicle avoided 42", visitedEdges.find("42") == visitedEdges.end()); + assertTrue("(commandChangeRoute, 9999) vehicle avoided 43", visitedEdges.find("43") == visitedEdges.end()); + assertTrue("(commandChangeRoute, 9999) vehicle took 44", visitedEdges.find("44") != visitedEdges.end()); + } + } + + if (testNumber == testCounter++) { + if (t == 1) { + traci->commandChangeRoute("42", 9999); + traci->commandChangeRoute("43", 9999); + } + if (t == 3) { + traci->commandChangeRoute("42", -1); + traci->commandChangeRoute("44", 9999); + } + if (t == 30) { + assertTrue("(commandChangeRoute, -1) vehicle took 42", visitedEdges.find("42") != visitedEdges.end()); + assertTrue("(commandChangeRoute, -1) vehicle avoided 43", visitedEdges.find("43") == visitedEdges.end()); + assertTrue("(commandChangeRoute, -1) vehicle avoided 44", visitedEdges.find("44") == visitedEdges.end()); + } + } + + if (testNumber == testCounter++) { + if (t == 1) { + assertClose("(commandDistanceRequest, air)", 859.4556417, traci->commandDistanceRequest(Coord(25,7030), Coord(883,6980), false)); + assertClose("(commandDistanceRequest, driving)", 845.93, traci->commandDistanceRequest(Coord(25,7030), Coord(883,6980), true)); + } + } + + if (testNumber == testCounter++) { + if (t == 1) { + traci->commandStopNode("43", 20, 0, 10, 30); + } + if (t == 30) { + assertTrue("(commandStopNode) vehicle is at 43", roadId == "43"); + assertClose("(commandStopNode) vehicle is stopped", 0.0, traci->getSpeed()); + } + } + + if (testNumber == testCounter++) { + if (t == 1) { + traci->getManager()->commandSetTrafficLightProgram("10", "myProgramRed"); + } + if (t == 30) { + assertTrue("(commandSetTrafficLightProgram) vehicle is at 31", roadId == "31"); + assertClose("(commandSetTrafficLightProgram) vehicle is stopped", 0.0, traci->getSpeed()); + } + } + + if (testNumber == testCounter++) { + if (t == 1) { + traci->getManager()->commandSetTrafficLightPhaseIndex("10", 4); + } + if (t == 30) { + assertTrue("(commandSetTrafficLightPhaseIndex) vehicle is at 31", roadId == "31"); + assertClose("(commandSetTrafficLightPhaseIndex) vehicle is stopped", 0.0, traci->getSpeed()); + } + } + + if (testNumber == testCounter++) { + if (t == 1) { + std::list polys = traci->commandGetPolygonIds(); + assertEqual("(commandGetPolygonIds) number is 1", polys.size(), (size_t)1); + assertEqual("(commandGetPolygonIds) id is correct", *polys.begin(), "poly0"); + std::string typeId = traci->commandGetPolygonTypeId("poly0"); + assertEqual("(commandGetPolygonTypeId) typeId is correct", typeId, "type0"); + std::list shape = traci->commandGetPolygonShape("poly0"); + assertClose("(commandGetPolygonShape) shape x coordinate is correct", 130.0, shape.begin()->x); + assertClose("(commandGetPolygonShape) shape y coordinate is correct", 81.65, shape.begin()->y); + } + } + + if (testNumber == testCounter++) { + if (t == 1) { + std::list shape1 = traci->commandGetPolygonShape("poly0"); + assertClose("(commandGetPolygonShape) shape x coordinate is correct", 130.0, shape1.begin()->x); + assertClose("(commandGetPolygonShape) shape y coordinate is correct", 81.65, shape1.begin()->y); + std::list shape2 = shape1; + shape2.begin()->x = 135; + shape2.begin()->y = 85; + traci->commandSetPolygonShape("poly0", shape2); + std::list shape3 = traci->commandGetPolygonShape("poly0"); + assertClose("(commandSetPolygonShape) shape x coordinate was changed", 135.0, shape3.begin()->x); + assertClose("(commandSetPolygonShape) shape y coordinate was changed", 85.0, shape3.begin()->y); + } + } + + if (testNumber == testCounter++) { + if (t == 30) { + bool r = traci->getManager()->commandAddVehicle("testVehicle0", "vtype0", "route0", "25_0", 0, 70); + assertTrue("(commandAddVehicle) command reports success", r); + } + if (t == 31) { + std::map::const_iterator i = traci->getManager()->getManagedHosts().find("testVehicle0"); + bool r = (i != traci->getManager()->getManagedHosts().end()); + assertTrue("(commandAddVehicle) vehicle now driving", r); + cModule* mod = i->second; + TraCIMobility* traci2 = check_and_cast(findModuleWhereverInNode("mobility", mod)); + assertTrue("(commandAddVehicle) vehicle driving at speed", traci2->getSpeed() > 25); + } + } } diff --git a/src/applications/traci/TraCITestApp.h b/src/applications/traci/TraCITestApp.h index 308a88cdb..7500a2ac7 100644 --- a/src/applications/traci/TraCITestApp.h +++ b/src/applications/traci/TraCITestApp.h @@ -31,33 +31,29 @@ /** * FIXME */ -class TraCITestApp : public cSimpleModule, protected cListener -{ - public: - int numInitStages() const - { - return std::max(cSimpleModule::numInitStages(), 1); - } - void initialize(int stage); - void finish(); - - protected: - // module parameters - bool debug; - int testNumber; - - TraCIMobility* traci; - std::set visitedEdges; /**< set of edges this vehicle visited */ - bool hasStopped; /**< true if at some point in time this vehicle travelled at negligible speed */ - simsignal_t mobilityStateChangedSignal; - - protected: - void handleSelfMsg(cMessage* msg); - void handleLowerMsg(cMessage* msg); - void handleMessage(cMessage* msg); - void receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj); - - void handlePositionUpdate(); +class TraCITestApp : public cSimpleModule, protected cListener { + public: + int numInitStages() const {return std::max(cSimpleModule::numInitStages(), 1);} + void initialize(int stage); + void finish(); + + protected: + // module parameters + bool debug; + int testNumber; + + TraCIMobility* traci; + std::set visitedEdges; /**< set of edges this vehicle visited */ + bool hasStopped; /**< true if at some point in time this vehicle travelled at negligible speed */ + simsignal_t mobilityStateChangedSignal; + + protected: + void handleSelfMsg(cMessage* msg); + void handleLowerMsg(cMessage* msg); + void handleMessage(cMessage* msg); + void receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj); + + void handlePositionUpdate(); }; #endif diff --git a/src/linklayer/IWirelessNicMulti.ned b/src/linklayer/IWirelessNicMulti.ned new file mode 100644 index 000000000..950484853 --- /dev/null +++ b/src/linklayer/IWirelessNicMulti.ned @@ -0,0 +1,28 @@ +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +package inet.linklayer; + +moduleinterface IWirelessNicMulti +{ + parameters: + @display("i=block/ifcard"); + // string mgmtType; // name of the management module type (implements IIeee80211Mgmt) + gates: + input upperLayerIn; // to upper layers + output upperLayerOut; // from upper layers + input radioIn[] @labels(AirFrame); // to receive AirFrames +} + diff --git a/src/linklayer/ieee80211/ChangeLog b/src/linklayer/ieee80211/ChangeLog index 69d5bb66d..4b620bc6d 100644 --- a/src/linklayer/ieee80211/ChangeLog +++ b/src/linklayer/ieee80211/ChangeLog @@ -1,3 +1,9 @@ +2012-06-08 Rudolf Hornig + + Takover from INETMANET-2.0 @ 7fb431b (minor bugfixes) + All files are synced. The following features were omitted: + MULTIQUEUES, HWMP and MESH networking related code. + 2012-03-20 ------ inet-1.99.4 released ------ 2012-02-24 ------ inet-1.99.3 released ------ diff --git a/src/linklayer/ieee80211/Ieee80211NewNic.ned b/src/linklayer/ieee80211/Ieee80211NewNic.ned deleted file mode 100644 index 63b923e75..000000000 --- a/src/linklayer/ieee80211/Ieee80211NewNic.ned +++ /dev/null @@ -1,100 +0,0 @@ -// -// Copyright (C) 2006 Andras Varga -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program; if not, see . -// - - -package inet.linklayer.ieee80211; - -import inet.linklayer.ieee80211.radio.Ieee80211NewRadio; -import inet.linklayer.ieee80211.mgmt.Ieee80211AgentSTA; -import inet.linklayer.ieee80211.mgmt.IIeee80211Mgmt; -import inet.linklayer.ieee80211.mac.Ieee80211NewMac; -import inet.linklayer.IWirelessNic; -import inet.base.IHook; - - -// -// This NIC implements an 802.11 network interface card. -// It can be configured via the mgmtType parameter to act -// as an AP or a STA, or for ad-hoc mode. By default it is -// configured for a simplified station mode (no channel scanning -// association, authentication etc.) -// -// Potential mgmType values: Ieee80211MgmtSTASimplified, Ieee80211MgmtSTA -// Ieee80211MgmtAP, Ieee80211MgmtAPSimplified, Ieee80211MgmtAdhoc -// -module Ieee80211NewNic like IWirelessNic -{ - parameters: - string mgmtType = default("Ieee80211MgmtSTA"); // name of the management module type (implements IIeee80211Mgmt) - string opMode @enum("b","g","a","p") = default("g"); - int numOutputHooks = default(0); - int numInputHooks = default(0); - bool _agentNeeded = (mgmtType == "Ieee80211MgmtSTA"); // internal par. do not use, shows if optional agent module is needed - @display("i=block/ifcard;bgb=259,357"); - gates: - input upperLayerIn; // to upper layers - output upperLayerOut; // from upper layers - input radioIn @labels(AirFrame); // to receive AirFrames - submodules: - outputHook[numOutputHooks]: like IHook if numOutputHooks>0; - inputHook[numInputHooks]: like IHook if numInputHooks>0; - // optional agent module (can be either 0 or 1 sized vector) - agent: Ieee80211AgentSTA if _agentNeeded { - parameters: - @display("p=202,136"); - } - mgmt: like IIeee80211Mgmt { - parameters: - @display("p=96,136;q=wlanDataQueue"); - } - mac: Ieee80211NewMac { - parameters: - opMode = opMode; - queueModule = "mgmt"; - @display("p=96,222"); - } - radio: Ieee80211NewRadio { - parameters: - phyOpMode = opMode; - @display("p=96,307"); - } - connections: - radioIn --> radio.radioIn; - radio.upperLayerIn <-- mac.lowerLayerOut; - radio.upperLayerOut --> mac.lowerLayerIn; - - mac.upperLayerOut --> mgmt.macIn; - mac.upperLayerIn <-- mgmt.macOut; - - mgmt.agentOut --> agent.mgmtIn if _agentNeeded; - mgmt.agentIn <-- agent.mgmtOut if _agentNeeded; - - mgmt.upperLayerOut --> upperLayerOut if numInputHooks == 0; - mgmt.upperLayerIn <-- upperLayerIn if numOutputHooks == 0; - - mgmt.upperLayerOut --> inputHook[0].in if numInputHooks > 0; - for i=0..numInputHooks-2 { - inputHook[i].out --> inputHook[i+1].in; - } - inputHook[numInputHooks-1].out --> upperLayerOut if numInputHooks > 0; - outputHook[0].in <-- upperLayerIn if numOutputHooks > 0; - for i=0..numOutputHooks-2 { - outputHook[i].out --> outputHook[i+1].in; - } - mgmt.upperLayerIn <-- outputHook[numOutputHooks-1].out if numOutputHooks > 0; -} - diff --git a/src/linklayer/ieee80211/Ieee80211Nic.ned b/src/linklayer/ieee80211/Ieee80211Nic.ned index a0be9884c..71efbbb16 100644 --- a/src/linklayer/ieee80211/Ieee80211Nic.ned +++ b/src/linklayer/ieee80211/Ieee80211Nic.ned @@ -19,11 +19,12 @@ package inet.linklayer.ieee80211; import inet.base.IHook; -import inet.linklayer.ieee80211.radio.Ieee80211Radio; -import inet.linklayer.ieee80211.mgmt.Ieee80211AgentSTA; -import inet.linklayer.ieee80211.mgmt.IIeee80211Mgmt; -import inet.linklayer.ieee80211.mac.Ieee80211Mac; import inet.linklayer.IWirelessNic; +import inet.linklayer.ieee80211.mac.Ieee80211Mac; +import inet.linklayer.ieee80211.mgmt.IIeee80211Mgmt; +import inet.linklayer.ieee80211.mgmt.Ieee80211AgentSTA; +import inet.linklayer.ieee80211.radio.Ieee80211Radio; + // // This NIC implements an 802.11 network interface card. @@ -39,6 +40,7 @@ module Ieee80211Nic like IWirelessNic { parameters: string mgmtType = default("Ieee80211MgmtSTA"); // name of the management module type (implements IIeee80211Mgmt) + string opMode @enum("b","g","a","p") = default("g"); int numOutputHooks = default(0); int numInputHooks = default(0); bool _agentNeeded = (mgmtType == "Ieee80211MgmtSTA"); // internal par. do not use, shows if optional agent module is needed @@ -50,7 +52,6 @@ module Ieee80211Nic like IWirelessNic submodules: outputHook[numOutputHooks]: like IHook if numOutputHooks>0; inputHook[numInputHooks]: like IHook if numInputHooks>0; - // optional agent module (can be either 0 or 1 sized vector) agent: Ieee80211AgentSTA if _agentNeeded { parameters: @@ -62,11 +63,13 @@ module Ieee80211Nic like IWirelessNic } mac: Ieee80211Mac { parameters: + opMode = opMode; queueModule = "mgmt"; @display("p=96,222"); } radio: Ieee80211Radio { parameters: + phyOpMode = opMode; @display("p=96,307"); } connections: diff --git a/src/linklayer/ieee80211/mac/Ieee80211Mac.cc b/src/linklayer/ieee80211/mac/Ieee80211Mac.cc index a5a3f8e04..064374cde 100644 --- a/src/linklayer/ieee80211/mac/Ieee80211Mac.cc +++ b/src/linklayer/ieee80211/mac/Ieee80211Mac.cc @@ -1,5 +1,7 @@ // -// Copyright (C) 2006 Andras Varga and Levente M�sz�ros +// Copyright (C) 2006 Andras Varga and Levente Meszaros +// Copyright (C) 2009 Lukáš Hlůže lukas@hluze.cz (802.11e) +// Copyright (C) 2011 Alfonso Ariza (clean code, fix some errors, new radio model) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License @@ -15,72 +17,84 @@ // along with this program; if not, see . // -#include - #include "Ieee80211Mac.h" - -#include "opp_utils.h" #include "RadioState.h" #include "IInterfaceTable.h" #include "InterfaceTableAccess.h" #include "PhyControlInfo_m.h" +#include "AirFrame_m.h" +#include "Radio80211aControlInfo_m.h" +#include "Ieee80211eClassifier.h" +#include "Ieee80211DataRate.h" + +// TODO: 9.3.2.1, If there are buffered multicast or broadcast frames, the PC shall transmit these prior to any unicast frames. +// TODO: control frames must send before Define_Module(Ieee80211Mac); // don't forget to keep synchronized the C++ enum and the runtime enum definition Register_Enum(Ieee80211Mac, - (Ieee80211Mac::IDLE, - Ieee80211Mac::DEFER, - Ieee80211Mac::WAITDIFS, - Ieee80211Mac::BACKOFF, - Ieee80211Mac::WAITACK, - Ieee80211Mac::WAITMULTICAST, - Ieee80211Mac::WAITCTS, - Ieee80211Mac::WAITSIFS, - Ieee80211Mac::RECEIVE)); + (Ieee80211Mac::IDLE, + Ieee80211Mac::DEFER, + Ieee80211Mac::WAITAIFS, + Ieee80211Mac::BACKOFF, + Ieee80211Mac::WAITACK, + Ieee80211Mac::WAITMULTICAST, + Ieee80211Mac::WAITCTS, + Ieee80211Mac::WAITSIFS, + Ieee80211Mac::RECEIVE)); // don't forget to keep synchronized the C++ enum and the runtime enum definition Register_Enum(RadioState, - (RadioState::IDLE, - RadioState::RECV, - RadioState::TRANSMIT, - RadioState::SLEEP)); - -simsignal_t Ieee80211Mac::stateSignal = SIMSIGNAL_NULL; -simsignal_t Ieee80211Mac::radioStateSignal = SIMSIGNAL_NULL; + (RadioState::IDLE, + RadioState::RECV, + RadioState::TRANSMIT, + RadioState::SLEEP)); /**************************************************************** * Construction functions. */ + Ieee80211Mac::Ieee80211Mac() { endSIFS = NULL; endDIFS = NULL; - endBackoff = NULL; endTimeout = NULL; endReserve = NULL; mediumStateChange = NULL; pendingRadioConfigMsg = NULL; + classifier = NULL; } Ieee80211Mac::~Ieee80211Mac() { cancelAndDelete(endSIFS); cancelAndDelete(endDIFS); - cancelAndDelete(endBackoff); cancelAndDelete(endTimeout); cancelAndDelete(endReserve); cancelAndDelete(mediumStateChange); - - if (pendingRadioConfigMsg) - delete pendingRadioConfigMsg; - - while (!transmissionQueue.empty()) + cancelAndDelete(endTXOP); + for (unsigned int i = 0; i < edcCAF.size(); i++) + { + cancelAndDelete(endAIFS(i)); + cancelAndDelete(endBackoff(i)); + while (!transmissionQueue(i)->empty()) + { + Ieee80211Frame *temp = dynamic_cast (transmissionQueue(i)->front()); + transmissionQueue(i)->pop_front(); + delete temp; + } + } + edcCAF.clear(); + for (unsigned int i=0; i(createOne(classifierClass)); + numQueues = classifier->getNumQueues(); + } + for (int i=0; icreateClassifier("Ieee80211MacQueueClassifier"); + if (numCategories()==1) + transmissionQueue(i)->setMaxSize(maxQueueSize); + else + transmissionQueue(i)->setMaxSize(maxCategorieQueueSize); + transmissionQueue(i)->setNumStrictPrioritiesQueue(3); // multicast and control + } + else + { + transmissionQueue(i)->createClassifier("Ieee80211MacQueueClassifier2"); + if (numCategories()==1) + transmissionQueue(i)->setMaxSize(maxQueueSize); + else + transmissionQueue(i)->setMaxSize(maxCategorieQueueSize); + transmissionQueue(i)->setNumStrictPrioritiesQueue(2); // multicast and control + + } + } +#endif // the variable is renamed due to a confusion in the standard // the name retry limit would be misleading, see the header file comment transmissionLimit = par("retryLimit"); if (transmissionLimit == -1) transmissionLimit = 7; - ASSERT(transmissionLimit > 0); + ASSERT(transmissionLimit >= 0); + + EV<<" retryLimit="<= 0); + ASSERT(cwMinData >= 0 && cwMinData <= 32767); + + cwMaxData = par("cwMaxData"); + if (cwMaxData == -1) cwMaxData = CW_MAX; + ASSERT(cwMaxData >= 0 && cwMaxData <= 32767); cwMinMulticast = par("cwMinMulticast"); if (cwMinMulticast == -1) cwMinMulticast = 31; ASSERT(cwMinMulticast >= 0); + EV<<" cwMinMulticast="<(classifier)) + dynamic_cast(classifier)->setDefaultClass(defaultAC); + + for (int i=0; i= 0 && AIFSN(i) < 16); + if (i == 0 || i == 1) + { + cwMin(i) = cwMinData; + cwMax(i) = cwMaxData; + } + if (i == 2) + { + cwMin(i) = (cwMinData + 1) / 2 - 1; + cwMax(i) = cwMinData; + } + if (i == 3) + { + cwMin(i) = (cwMinData + 1) / 4 - 1; + cwMax(i) = (cwMinData + 1) / 2 - 1; + } + } + + ST = par("slotTime"); //added by sorin + if (ST==-1) + ST = 20e-6; //20us + EV<<" slotTime="<subscribe(this, NF_RADIOSTATE_CHANGED); - // initalize self messages + // initialize self messages endSIFS = new cMessage("SIFS"); endDIFS = new cMessage("DIFS"); - endBackoff = new cMessage("Backoff"); + for (int i=0; i0) + throughputTimer = new cMessage("throughput-timer"); + if (throughputTimer) + scheduleAt(simTime()+throughputTimePeriod, throughputTimer); + // end initialize variables throughput over a period of time // initialize watches - WATCH(fsm); - WATCH(radioState); - WATCH(retryCounter); - WATCH(backoff); - WATCH(nav); + validRecMode = false; + initWatches(); + radioModule = gate("lowerLayerOut")->getNextGate()->getOwnerModule()->getId(); + } +} + +void Ieee80211Mac::initWatches() +{ +// initialize watches + WATCH(fsm); + WATCH(radioState); + for (int i=0; isetName(OPP_Global::stripnonalnum(getParentModule()->getFullName()).c_str()); + // interface name: NetworkInterface module's name without special characters ([]) + char *interfaceName = new char[strlen(getParentModule()->getFullName()) + 1]; + char *d = interfaceName; + for (const char *s = getParentModule()->getFullName(); *s; s++) + if (isalnum(*s)) + *d++ = *s; + *d = '\0'; + + e->setName(interfaceName); + delete [] interfaceName; // address e->setMACAddress(address); @@ -231,21 +677,77 @@ void Ieee80211Mac::initializeQueueModule() */ void Ieee80211Mac::handleSelfMsg(cMessage *msg) { - EV << "received self message: " << msg << endl; + if (msg==throughputTimer) + { + throughputLastPeriod = recBytesOverPeriod/SIMTIME_DBL(throughputTimePeriod); + recBytesOverPeriod = 0; + scheduleAt(simTime()+throughputTimePeriod, throughputTimer); + return; + } + + EV << "received self message: " << msg << "(kind: " << msg->getKind() << ")" << endl; if (msg == endReserve) nav = false; + if (msg == endTXOP) + txop = false; + + if ( !strcmp(msg->getName(), "AIFS") || !strcmp(msg->getName(), "Backoff") ) + { + EV << "Changing currentAC to " << msg->getKind() << endl; + currentAC = msg->getKind(); + } + //check internal colision + if ((strcmp(msg->getName(), "Backoff") == 0) || (strcmp(msg->getName(), "AIFS")==0)) + { + int kind; + kind = msg->getKind(); + if (kind<0) + kind = 0; + EV <<" kind is " << kind << ",name is " << msg->getName() < kind; i--) //mozna prochaze jen 3..kind XXX + { + if (((endBackoff(i)->isScheduled() && endBackoff(i)->getArrivalTime() == simTime()) + || (endAIFS(i)->isScheduled() && !backoff(i) && endAIFS(i)->getArrivalTime() == simTime())) + && !transmissionQueue(i)->empty()) + { + EV << "Internal collision AC" << kind << " with AC" << i << endl; + numInternalCollision++; + EV << "Cancel backoff event and schedule new one for AC" << kind << endl; + cancelEvent(endBackoff(kind)); + if (retryCounter() == transmissionLimit - 1) + { + EV << "give up transmission for AC" << currentAC << endl; + giveUpCurrentTransmission(); + } + else + { + EV << "retry transmission for AC" << currentAC << endl; + retryCurrentTransmission(); + } + return; + } + } + currentAC = kind; + } handleWithFSM(msg); } + void Ieee80211Mac::handleUpperMsg(cPacket *msg) { - // check for queue overflow - if (maxQueueSize && (int)transmissionQueue.size() == maxQueueSize) + if (queueModule && numCategories()>1 && (int)transmissionQueueSize() < maxQueueSize) { - EV << "message " << msg << " received from higher layer but MAC queue is full, dropping message\n"; - delete msg; + // the module are continuously asking for packets, except if the queue is full + EV << "requesting another frame from queue module\n"; + queueModule->requestPacket(); + } + + // check if it's a command from the mgmt layer + if (msg->getBitLength()==0 && msg->getKind()!=0) + { + handleCommand(msg); return; } @@ -256,6 +758,7 @@ void Ieee80211Mac::handleUpperMsg(cPacket *msg) msg->getClassName(), msg->getName(), (int)(msg->getByteLength())); EV << "frame " << frame << " received from higher layer, receiver = " << frame->getReceiverAddress() << endl; + // if you get error from this assert check if is client associated to AP ASSERT(!frame->getReceiverAddress().isUnspecified()); // fill in missing fields (receiver address, seq number), and insert into the queue @@ -263,11 +766,113 @@ void Ieee80211Mac::handleUpperMsg(cPacket *msg) frame->setSequenceNumber(sequenceNumber); sequenceNumber = (sequenceNumber+1) % 4096; //XXX seqNum must be checked upon reception of frames! - transmissionQueue.push_back(frame); - + if (mappingAccessCategory(frame) == 200) + { + // if function mappingAccessCategory() returns 200, it means transsmissionQueue is full + return; + } + frame->setMACArrive(simTime()); handleWithFSM(frame); } +#ifdef USEMULTIQUEUE +int Ieee80211Mac::mappingAccessCategory(Ieee80211DataOrMgmtFrame *frame) +{ + bool isDataFrame = (dynamic_cast(frame) != NULL); + + currentAC = classifier ? classifier->classifyPacket(frame) : 0; + // check for queue overflow + if (isDataFrame && maxCategorieQueueSize && (int)transmissionQueue()->size() >= maxCategorieQueueSize) + { + EV << "message " << frame << " received from higher layer but AC queue is full, dropping message\n"; + numDropped()++; + delete frame; + return 200; + } + + if (isDataFrame && maxQueueSize && (int)transmissionQueueSize() >= maxQueueSize) + { + EV << "message " << frame << " received from higher layer but AC queue is full, dropping message\n"; + numDropped()++; + delete frame; + return 200; + } + transmissionQueue()->push_back(frame); + EV << "frame classified as access category "<< currentAC <<" (0 background, 1 best effort, 2 video, 3 voice)\n"; + return true; +} + +#else + +int Ieee80211Mac::mappingAccessCategory(Ieee80211DataOrMgmtFrame *frame) +{ + bool isDataFrame = (dynamic_cast(frame) != NULL); + + currentAC = classifier ? classifier->classifyPacket(frame) : 0; + // check for queue overflow + if (isDataFrame && maxCategorieQueueSize && (int)transmissionQueue()->size() >= maxCategorieQueueSize) + { + EV << "message " << frame << " received from higher layer but AC queue is full, dropping message\n"; + numDropped()++; + delete frame; + return 200; + } + + if (isDataFrame && maxQueueSize && (int)transmissionQueueSize() >= maxQueueSize) + { + EV << "message " << frame << " received from higher layer but AC queue is full, dropping message\n"; + numDropped()++; + delete frame; + return 200; + } + if (isDataFrame) + { + if (!prioritizeMulticast || !frame->getReceiverAddress().isMulticast() || transmissionQueue()->size() < 2) + transmissionQueue()->push_back(frame); + else + { + // if the last frame is management insert here + Ieee80211DataFrame * frameAux = dynamic_cast(transmissionQueue()->back()); + if ((frameAux == NULL) || (frameAux && frameAux->getReceiverAddress().isMulticast())) + transmissionQueue()->push_back(frame); + else + { + // in other case search the possition + std::list::iterator p = transmissionQueue()->end(); + while ((*p)->getReceiverAddress().isMulticast() && (p != transmissionQueue()->begin())) // search the first broadcast frame + { + if (dynamic_cast(*p) == NULL) + break; + p--; + } + p++; + transmissionQueue()->insert(p, frame); + } + } + } + else + { + if (transmissionQueue()->empty() || transmissionQueue()->size() == 1) + { + transmissionQueue()->push_back(frame); + } + else + { + std::list::iterator p; + //we don't know if first frame in the queue is in middle of transmission + //so for sure we placed it on second place + p = transmissionQueue()->begin(); + p++; + while ((dynamic_cast (*p) == NULL) && (p != transmissionQueue()->end())) // search the first not management frame + p++; + transmissionQueue()->insert(p, frame); + } + } + EV << "frame classified as access category "<< currentAC <<" (0 background, 1 best effort, 2 video, 3 voice)\n"; + return true; +} +#endif + void Ieee80211Mac::handleCommand(cMessage *msg) { if (msg->getKind()==PHY_C_CONFIGURERADIO) @@ -289,6 +894,13 @@ void Ieee80211Mac::handleCommand(cMessage *msg) if (fsm.getState() == IDLE || fsm.getState() == DEFER || fsm.getState() == BACKOFF) { EV << "Sending it down immediately\n"; +/* +// Dynamic power + PhyControlInfo *phyControlInfo = dynamic_cast(msg->getControlInfo()); + if (phyControlInfo) + phyControlInfo->setAdaptiveSensitivity(true); +// end dynamic power +*/ sendDown(msg); } else @@ -299,32 +911,104 @@ void Ieee80211Mac::handleCommand(cMessage *msg) } else { - error("Unrecognized command from mgmt layer: (%s)%s msgkind=%d", - msg->getClassName(), msg->getName(), msg->getKind()); + error("Unrecognized command from mgmt layer: (%s)%s msgkind=%d", msg->getClassName(), msg->getName(), msg->getKind()); } } void Ieee80211Mac::handleLowerMsg(cPacket *msg) { + EV<<"->Enter handleLowerMsg...\n"; EV << "received message from lower layer: " << msg << endl; + Radio80211aControlInfo * cinfo = dynamic_cast(msg->getControlInfo()); + if (cinfo && cinfo->getAirtimeMetric()) + { + double rtsTime = 0; + if (rtsThreshold*8getTestFrameSize()) + rtsTime= computeFrameDuration(LENGTH_CTS, basicBitrate) +computeFrameDuration(LENGTH_RTS, basicBitrate); + double frameDuration = cinfo->getTestFrameDuration() + computeFrameDuration(LENGTH_ACK, basicBitrate)+rtsTime; + cinfo->setTestFrameDuration(frameDuration); + } + nb->fireChangeNotification(NF_LINK_FULL_PROMISCUOUS, msg); + validRecMode = false; + if (msg->getControlInfo() && dynamic_cast(msg->getControlInfo())) + { + Radio80211aControlInfo *cinfo = dynamic_cast(msg->getControlInfo()); + recFrameModulationType = cinfo->getModulationType(); + if (recFrameModulationType.getDataRate()>0) + validRecMode = true; + } + + if (rateControlMode == RATE_CR) + { + if (msg->getControlInfo()) + delete msg->removeControlInfo(); + } Ieee80211Frame *frame = dynamic_cast(msg); + + if (msg->getControlInfo() && dynamic_cast(msg->getControlInfo())) + { + Radio80211aControlInfo *cinfo = (Radio80211aControlInfo*) msg->removeControlInfo(); + if (contJ%10==0) + { + snr = _snr; + contJ = 0; + _snr = 0; + } + contJ++; + _snr += cinfo->getSnr()/10; + lossRate = cinfo->getLossRate(); + delete cinfo; + } + + if (contI%samplingCoeff==0) + { + contI = 0; + recvdThroughput = 0; + } + contI++; + + frame = dynamic_cast(msg); + if (timeStampLastMessageReceived == 0) + timeStampLastMessageReceived = simTime(); + else + { + if (frame) + recvdThroughput += ((frame->getBitLength()/(simTime()-timeStampLastMessageReceived))/1000000)/samplingCoeff; + timeStampLastMessageReceived = simTime(); + } + if (frame && throughputTimer) + recBytesOverPeriod += frame->getByteLength(); + + if (!frame) - error("message from physical layer (%s)%s is not a subclass of Ieee80211Frame", - msg->getClassName(), msg->getName()); + { + EV << "message from physical layer (%s)%s is not a subclass of Ieee80211Frame" << msg->getClassName() << " " << msg->getName() << endl; + delete msg; + return; + // error("message from physical layer (%s)%s is not a subclass of Ieee80211Frame",msg->getClassName(), msg->getName()); + } EV << "Self address: " << address - << ", receiver address: " << frame->getReceiverAddress() - << ", received frame is for us: " << isForUs(frame) << endl; + << ", receiver address: " << frame->getReceiverAddress() + << ", received frame is for us: " << isForUs(frame) + << ", received frame was sent by us: " << isSentByUs(frame)<(msg); ASSERT(!twoAddressFrame || twoAddressFrame->getTransmitterAddress() != address); +#ifdef LWMPLS + int msgKind = msg->getKind(); + if (msgKind != COLLISION && msgKind != BITERROR && twoAddressFrame!=NULL) + nb->fireChangeNotification(NF_LINK_REFRESH, twoAddressFrame); +#endif + handleWithFSM(msg); // if we are the owner then we did not send this message up if (msg->getOwner() == this) delete msg; + EV<<"Leave handleLowerMsg...\n"; } void Ieee80211Mac::receiveChangeNotification(int category, const cObject *details) @@ -334,9 +1018,17 @@ void Ieee80211Mac::receiveChangeNotification(int category, const cObject *detail if (category == NF_RADIOSTATE_CHANGED) { - RadioState::State newRadioState = check_and_cast(details)->getState(); + RadioState * rstate = check_and_cast(details); + if (rstate->getRadioId()!=getRadioModuleId()) + return; + + RadioState::State newRadioState = rstate->getState(); + - emit(radioStateSignal, newRadioState); + + // FIXME: double recording, because there's no sample hold in the gui + radioStateVector.record(radioState); + radioStateVector.record(newRadioState); radioState = newRadioState; @@ -349,9 +1041,28 @@ void Ieee80211Mac::receiveChangeNotification(int category, const cObject *detail */ void Ieee80211Mac::handleWithFSM(cMessage *msg) { + removeOldTuplesFromDuplicateMap(); // skip those cases where there's nothing to do, so the switch looks simpler if (isUpperMsg(msg) && fsm.getState() != IDLE) { + if (fsm.getState() == WAITAIFS && endDIFS->isScheduled()) + { + // a difs was schedule because all queues ware empty + // change difs for aifs + simtime_t remaint = getAIFS(currentAC)-getDIFS(); + scheduleAt(endDIFS->getArrivalTime()+remaint, endAIFS(currentAC)); + cancelEvent(endDIFS); + } + else if (fsm.getState() == BACKOFF && endBackoff(numCategories()-1)->isScheduled() && transmissionQueue(numCategories()-1)->empty()) + { + // a backoff was schedule with all the queues empty + // reschedule the backoff with the appropriate AC + backoffPeriod(currentAC) = backoffPeriod(numCategories()-1); + backoff(currentAC) = backoff(numCategories()-1); + backoff(numCategories()-1) = false; + scheduleAt(endBackoff(numCategories()-1)->getArrivalTime(), endBackoff(currentAC)); + cancelEvent(endBackoff(numCategories()-1)); + } EV << "deferring upper message transmission in " << fsm.getStateName() << " state\n"; return; } @@ -360,7 +1071,7 @@ void Ieee80211Mac::handleWithFSM(cMessage *msg) int frameType = frame ? frame->getType() : -1; int msgKind = msg->getKind(); logState(); - emit(stateSignal, fsm.getState()); + stateVector.record(fsm.getState()); if (frame && isLowerMsg(frame)) { @@ -374,144 +1085,362 @@ void Ieee80211Mac::handleWithFSM(cMessage *msg) FSMA_State(IDLE) { FSMA_Enter(sendDownPendingRadioConfigMsg()); + /* + if (fixFSM) + { FSMA_Event_Transition(Data-Ready, - isUpperMsg(msg), + // isUpperMsg(msg), + isUpperMsg(msg) && backoffPeriod[currentAC] > 0, DEFER, - ASSERT(isInvalidBackoffPeriod() || backoffPeriod == 0); - invalidateBackoffPeriod(); + //ASSERT(isInvalidBackoffPeriod() || backoffPeriod == 0); + //invalidateBackoffPeriod(); + ASSERT(false); + ); FSMA_No_Event_Transition(Immediate-Data-Ready, - !transmissionQueue.empty(), + //!transmissionQueue.empty(), + !transmissionQueueEmpty(), DEFER, - invalidateBackoffPeriod(); + // invalidateBackoffPeriod(); + ASSERT(backoff[currentAC]); + ); + } + */ + FSMA_Event_Transition(Data-Ready, + isUpperMsg(msg), + DEFER, + ASSERT(isInvalidBackoffPeriod() || backoffPeriod() == 0); + invalidateBackoffPeriod(); + ); + FSMA_No_Event_Transition(Immediate-Data-Ready, + !transmissionQueueEmpty(), + DEFER, + if (retryCounter() == 0) // jesjones patch. TODO: check this particular case, I haven't been sure about this particular case + invalidateBackoffPeriod(); + ); FSMA_Event_Transition(Receive, isLowerMsg(msg), RECEIVE, - ); + ); } FSMA_State(DEFER) { FSMA_Enter(sendDownPendingRadioConfigMsg()); - FSMA_Event_Transition(Wait-DIFS, + FSMA_Event_Transition(Wait-AIFS, isMediumStateChange(msg) && isMediumFree(), - WAITDIFS, - ;); - FSMA_No_Event_Transition(Immediate-Wait-DIFS, - isMediumFree() || !backoff, - WAITDIFS, - ;); + WAITAIFS, + ;); + FSMA_No_Event_Transition(Immediate-Wait-AIFS, + isMediumFree() || (!isBackoffPending()), + WAITAIFS, + ;); FSMA_Event_Transition(Receive, isLowerMsg(msg), RECEIVE, - ;); + ;); } - FSMA_State(WAITDIFS) + FSMA_State(WAITAIFS) { - FSMA_Enter(scheduleDIFSPeriod()); + FSMA_Enter(scheduleAIFSPeriod()); + + FSMA_Event_Transition(EDCAF-Do-Nothing, + isMsgAIFS(msg) && transmissionQueue()->empty(), + WAITAIFS, + ASSERT(0==1); + ;); FSMA_Event_Transition(Immediate-Transmit-RTS, - msg == endDIFS && !isMulticast(getCurrentTransmission()) - && getCurrentTransmission()->getByteLength() >= rtsThreshold && !backoff, + isMsgAIFS(msg) && !transmissionQueue()->empty() && !isMulticast(getCurrentTransmission()) + && getCurrentTransmission()->getByteLength() >= rtsThreshold && !backoff(), WAITCTS, - sendRTSFrame(getCurrentTransmission()); - cancelDIFSPeriod(); - ); + sendRTSFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + cancelAIFSPeriod(); + ); FSMA_Event_Transition(Immediate-Transmit-Multicast, - msg == endDIFS && isMulticast(getCurrentTransmission()) && !backoff, + isMsgAIFS(msg) && isMulticast(getCurrentTransmission()) && !backoff(), WAITMULTICAST, - sendMulticastFrame(getCurrentTransmission()); - cancelDIFSPeriod(); - ); + sendMulticastFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + cancelAIFSPeriod(); + ); FSMA_Event_Transition(Immediate-Transmit-Data, - msg == endDIFS && !isMulticast(getCurrentTransmission()) && !backoff, + isMsgAIFS(msg) && !isMulticast(getCurrentTransmission()) && !backoff(), WAITACK, - sendDataFrame(getCurrentTransmission()); - cancelDIFSPeriod(); - ); - FSMA_Event_Transition(DIFS-Over, - msg == endDIFS, + sendDataFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + cancelAIFSPeriod(); + ); + /*FSMA_Event_Transition(AIFS-Over, + isMsgAIFS(msg) && backoff[currentAC], BACKOFF, - ASSERT(backoff); if (isInvalidBackoffPeriod()) generateBackoffPeriod(); - ); + );*/ + FSMA_Event_Transition(AIFS-Over, + isMsgAIFS(msg), + BACKOFF, + if (isInvalidBackoffPeriod()) + generateBackoffPeriod(); + ); + // end the difs and no other packet has been received + FSMA_Event_Transition(DIFS-Over, + msg == endDIFS && transmissionQueueEmpty(), + BACKOFF, + currentAC = numCategories()-1; + if (isInvalidBackoffPeriod()) + generateBackoffPeriod(); + ); + FSMA_Event_Transition(DIFS-Over, + msg == endDIFS, + BACKOFF, + for (int i=numCategories()-1; i>=0; i--) + { + if (!transmissionQueue(i)->empty()) + { + currentAC = i; + } + } + if (isInvalidBackoffPeriod()) + generateBackoffPeriod(); + ); FSMA_Event_Transition(Busy, isMediumStateChange(msg) && !isMediumFree(), DEFER, - backoff = true; - cancelDIFSPeriod(); - ); + for (int i=0; iisScheduled()) + backoff(i) = true; + } + if (endDIFS->isScheduled()) backoff(numCategories()-1) = true; + cancelAIFSPeriod(); + ); FSMA_No_Event_Transition(Immediate-Busy, !isMediumFree(), DEFER, - backoff = true; - cancelDIFSPeriod(); - ); + for (int i=0; iisScheduled()) + backoff(i) = true; + } + if (endDIFS->isScheduled()) backoff(numCategories()-1) = true; + cancelAIFSPeriod(); + + ); // radio state changes before we actually get the message, so this must be here FSMA_Event_Transition(Receive, isLowerMsg(msg), RECEIVE, - cancelDIFSPeriod(); - ;); + cancelAIFSPeriod(); + ;); } FSMA_State(BACKOFF) { FSMA_Enter(scheduleBackoffPeriod()); - FSMA_Event_Transition(Transmit-RTS, - msg == endBackoff && !isMulticast(getCurrentTransmission()) - && getCurrentTransmission()->getByteLength() >= rtsThreshold, + if (getCurrentTransmission()) + { + FSMA_Event_Transition(Transmit-RTS, + msg == endBackoff() && !isMulticast(getCurrentTransmission()) + && getCurrentTransmission()->getByteLength() >= rtsThreshold, + WAITCTS, + sendRTSFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + cancelAIFSPeriod(); + decreaseBackoffPeriod(); + cancelBackoffPeriod(); + ); + FSMA_Event_Transition(Transmit-Multicast, + msg == endBackoff() && isMulticast(getCurrentTransmission()), + WAITMULTICAST, + sendMulticastFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + cancelAIFSPeriod(); + decreaseBackoffPeriod(); + cancelBackoffPeriod(); + ); + FSMA_Event_Transition(Transmit-Data, + msg == endBackoff() && !isMulticast(getCurrentTransmission()), + WAITACK, + sendDataFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + cancelAIFSPeriod(); + decreaseBackoffPeriod(); + cancelBackoffPeriod(); + ); + } + FSMA_Event_Transition(AIFS-Over-backoff, + isMsgAIFS(msg) && backoff(), + BACKOFF, + if (isInvalidBackoffPeriod()) + generateBackoffPeriod(); + ); + FSMA_Event_Transition(AIFS-Immediate-Transmit-RTS, + isMsgAIFS(msg) && !transmissionQueue()->empty() && !isMulticast(getCurrentTransmission()) + && getCurrentTransmission()->getByteLength() >= rtsThreshold && !backoff(), WAITCTS, - sendRTSFrame(getCurrentTransmission()); - ); - FSMA_Event_Transition(Transmit-Multicast, - msg == endBackoff && isMulticast(getCurrentTransmission()), + sendRTSFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + cancelAIFSPeriod(); + decreaseBackoffPeriod(); + cancelBackoffPeriod(); + ); + FSMA_Event_Transition(AIFS-Immediate-Transmit-Multicast, + isMsgAIFS(msg) && isMulticast(getCurrentTransmission()) && !backoff(), WAITMULTICAST, - sendMulticastFrame(getCurrentTransmission()); - ); - FSMA_Event_Transition(Transmit-Data, - msg == endBackoff && !isMulticast(getCurrentTransmission()), + sendMulticastFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + cancelAIFSPeriod(); + decreaseBackoffPeriod(); + cancelBackoffPeriod(); + ); + FSMA_Event_Transition(AIFS-Immediate-Transmit-Data, + isMsgAIFS(msg) && !isMulticast(getCurrentTransmission()) && !backoff(), WAITACK, - sendDataFrame(getCurrentTransmission()); - ); + sendDataFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + cancelAIFSPeriod(); + decreaseBackoffPeriod(); + cancelBackoffPeriod(); + ); + FSMA_Event_Transition(Backoff-Idle, + isBakoffMsg(msg) && transmissionQueueEmpty(), + IDLE, + resetStateVariables(); + ); FSMA_Event_Transition(Backoff-Busy, isMediumStateChange(msg) && !isMediumFree(), DEFER, - cancelBackoffPeriod(); - decreaseBackoffPeriod(); - ); + cancelAIFSPeriod(); + decreaseBackoffPeriod(); + cancelBackoffPeriod(); + ); + } FSMA_State(WAITACK) { FSMA_Enter(scheduleDataTimeoutPeriod(getCurrentTransmission())); + FSMA_Event_Transition(Receive-ACK-TXOP, + isLowerMsg(msg) && isForUs(frame) && frameType == ST_ACK && txop, + WAITSIFS, + currentAC = oldcurrentAC; + if (retryCounter() == 0) numSentWithoutRetry()++; + numSent()++; + fr = getCurrentTransmission(); + numBites += fr->getBitLength(); + bites() += fr->getBitLength(); + + + macDelay()->record(simTime() - fr->getMACArrive()); + if (maxjitter() == 0 || maxjitter() < (simTime() - fr->getMACArrive())) + maxjitter() = simTime() - fr->getMACArrive(); + if (minjitter() == 0 || minjitter() > (simTime() - fr->getMACArrive())) + minjitter() = simTime() - fr->getMACArrive(); + EV << "record macDelay AC" << currentAC << " value " << simTime() - fr->getMACArrive() <getBitLength(); + bites[currentAC] += fr->getBitLength(); + + macDelay[currentAC].record(simTime() - fr->getMACArrive()); + if (maxjitter[currentAC] == 0 || maxjitter[currentAC] < (simTime() - fr->getMACArrive())) maxjitter[currentAC]=simTime() - fr->getMACArrive(); + if (minjitter[currentAC] == 0 || minjitter[currentAC] > (simTime() - fr->getMACArrive())) minjitter[currentAC]=simTime() - fr->getMACArrive(); + EV << "record macDelay AC" << currentAC << " value " << simTime() - fr->getMACArrive() <getBitLength(); + bites() += fr->getBitLength(); + + macDelay()->record(simTime() - fr->getMACArrive()); + if (maxjitter() == 0 || maxjitter() < (simTime() - fr->getMACArrive())) + maxjitter() = simTime() - fr->getMACArrive(); + if (minjitter() == 0 || minjitter() > (simTime() - fr->getMACArrive())) + minjitter() = simTime() - fr->getMACArrive(); + EV << "record macDelay AC" << currentAC << " value " << simTime() - fr->getMACArrive() <isScheduled()) cancelEvent(endTXOP); + ); FSMA_Event_Transition(Receive-ACK-Timeout, msg == endTimeout, DEFER, - retryCurrentTransmission(); - ); + currentAC = oldcurrentAC; + retryCurrentTransmission(); + txop = false; + if (endTXOP->isScheduled()) cancelEvent(endTXOP); + ); + FSMA_Event_Transition(Interrupted-ACK-Failure, + isLowerMsg(msg) && retryCounter(oldcurrentAC) == transmissionLimit - 1, + RECEIVE, + currentAC=oldcurrentAC; + giveUpCurrentTransmission(); + txop = false; + if (endTXOP->isScheduled()) cancelEvent(endTXOP); + ); + FSMA_Event_Transition(Retry-Interrupted-ACK, + isLowerMsg(msg), + RECEIVE, + currentAC=oldcurrentAC; + retryCurrentTransmission(); + txop = false; + if (endTXOP->isScheduled()) cancelEvent(endTXOP); + ); } // wait until multicast is sent FSMA_State(WAITMULTICAST) { FSMA_Enter(scheduleMulticastTimeoutPeriod(getCurrentTransmission())); + /* + FSMA_Event_Transition(Transmit-Multicast, + msg == endTimeout, + IDLE, + currentAC=oldcurrentAC; + finishCurrentTransmission(); + numSentMulticast++; + ); + */ + ///changed FSMA_Event_Transition(Transmit-Multicast, msg == endTimeout, - IDLE, - finishCurrentTransmission(); - numSentMulticast++; - ); + DEFER, + currentAC = oldcurrentAC; + fr = getCurrentTransmission(); + numBites += fr->getBitLength(); + bites() += fr->getBitLength(); + finishCurrentTransmission(); + numSentMulticast++; + resetCurrentBackOff(); + ); } // accoriding to 9.2.5.7 CTS procedure FSMA_State(WAITCTS) @@ -520,39 +1449,54 @@ void Ieee80211Mac::handleWithFSM(cMessage *msg) FSMA_Event_Transition(Receive-CTS, isLowerMsg(msg) && isForUs(frame) && frameType == ST_CTS, WAITSIFS, - cancelTimeoutPeriod(); - ); + cancelTimeoutPeriod(); + ); FSMA_Event_Transition(Transmit-RTS-Failed, - msg == endTimeout && retryCounter == transmissionLimit - 1, + msg == endTimeout && retryCounter(oldcurrentAC) == transmissionLimit - 1, IDLE, - giveUpCurrentTransmission(); - ); + currentAC = oldcurrentAC; + giveUpCurrentTransmission(); + ); FSMA_Event_Transition(Receive-CTS-Timeout, msg == endTimeout, DEFER, - retryCurrentTransmission(); - ); + currentAC = oldcurrentAC; + retryCurrentTransmission(); + ); } FSMA_State(WAITSIFS) { FSMA_Enter(scheduleSIFSPeriod(frame)); + FSMA_Event_Transition(Transmit-Data-TXOP, + msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_ACK, + WAITACK, + sendDataFrame(getCurrentTransmission()); + oldcurrentAC = currentAC; + ); FSMA_Event_Transition(Transmit-CTS, msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_RTS, IDLE, - sendCTSFrameOnEndSIFS(); - resetStateVariables(); - ); + sendCTSFrameOnEndSIFS(); + if (fixFSM) + finishReception(); + else + resetStateVariables(); + ); FSMA_Event_Transition(Transmit-DATA, msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_CTS, WAITACK, - sendDataFrameOnEndSIFS(getCurrentTransmission()); - ); + sendDataFrameOnEndSIFS(getCurrentTransmission()); + oldcurrentAC = currentAC; + ); FSMA_Event_Transition(Transmit-ACK, msg == endSIFS && isDataOrMgmtFrame(getFrameReceivedBeforeSIFS()), IDLE, - sendACKFrameOnEndSIFS(); - resetStateVariables(); - ); + sendACKFrameOnEndSIFS(); + if (fixFSM) + finishReception(); + else + resetStateVariables(); + ); } // this is not a real state FSMA_State(RECEIVE) @@ -560,68 +1504,202 @@ void Ieee80211Mac::handleWithFSM(cMessage *msg) FSMA_No_Event_Transition(Immediate-Receive-Error, isLowerMsg(msg) && (msgKind == COLLISION || msgKind == BITERROR), IDLE, - EV << "received frame contains bit errors or collision, next wait period is EIFS\n"; - numCollision++; - resetStateVariables(); - ); + EV << "received frame contains bit errors or collision, next wait period is EIFS\n"; + numCollision++; + if (fixFSM) + finishReception(); + else + resetStateVariables(); + ); FSMA_No_Event_Transition(Immediate-Receive-Multicast, - isLowerMsg(msg) && isMulticast(frame) && isDataOrMgmtFrame(frame), + isLowerMsg(msg) && isMulticast(frame) && !isSentByUs(frame) && isDataOrMgmtFrame(frame), IDLE, - sendUp(frame); - numReceivedMulticast++; - resetStateVariables(); - ); + sendUp(frame); + numReceivedMulticast++; + if (fixFSM) + finishReception(); + else + resetStateVariables(); + ); FSMA_No_Event_Transition(Immediate-Receive-Data, isLowerMsg(msg) && isForUs(frame) && isDataOrMgmtFrame(frame), WAITSIFS, - sendUp(frame); - numReceived++; - ); + sendUp(frame); + numReceived++; + ); FSMA_No_Event_Transition(Immediate-Receive-RTS, isLowerMsg(msg) && isForUs(frame) && frameType == ST_RTS, WAITSIFS, - ); + ); + FSMA_No_Event_Transition(Immediate-Receive-Other-backtobackoff, + isLowerMsg(msg) && isBackoffPending(), //(backoff[0] || backoff[1] || backoff[2] || backoff[3]), + DEFER, + ); + + FSMA_No_Event_Transition(Immediate-Promiscuous-Data, + isLowerMsg(msg) && !isForUs(frame) && isDataOrMgmtFrame(frame), + IDLE, + nb->fireChangeNotification(NF_LINK_PROMISCUOUS, frame); + if (fixFSM) + finishReception(); + else + resetStateVariables(); + numReceivedOther++; + ); FSMA_No_Event_Transition(Immediate-Receive-Other, isLowerMsg(msg), IDLE, - resetStateVariables(); - ); + if (fixFSM) + finishReception(); + else + resetStateVariables(); + numReceivedOther++; + ); } } - + EV<<"leaving handleWithFSM\n\t"; logState(); - emit(stateSignal, fsm.getState()); + stateVector.record(fsm.getState()); + if (simTime() - last > 0.1) + { + for (int i = 0; irecord(bites(i)/(simTime()-last)); + bites(i) = 0; + if (maxjitter(i) > 0 && minjitter(i) > 0) + { + jitter(i)->record(maxjitter(i)-minjitter(i)); + maxjitter(i) = 0; + minjitter(i) = 0; + } + } + last = simTime(); + } +} + +void Ieee80211Mac::finishReception() +{ + if (getCurrentTransmission()) + { + backoff() = true; + } + else + { + resetStateVariables(); + } } + /**************************************************************** * Timing functions. */ -simtime_t Ieee80211Mac::getSIFS() const +simtime_t Ieee80211Mac::getSIFS() { // TODO: return aRxRFDelay() + aRxPLCPDelay() + aMACProcessingDelay() + aRxTxTurnaroundTime(); + if (useModulationParameters) + { + ModulationType modType; + if ((opMode=='b') || (opMode=='g')) + modType = WifiModulationType::getMode80211g(bitrate); + else if (opMode=='a') + modType = WifiModulationType::getMode80211a(bitrate); + else if (opMode=='p') + modType = WifiModulationType::getMode80211p(bitrate); + else + opp_error("mode not supported"); + return WifiModulationType::getSifsTime(modType,wifiPreambleType); + } + return SIFS; } -simtime_t Ieee80211Mac::getSlotTime() const +simtime_t Ieee80211Mac::getSlotTime() { // TODO: return aCCATime() + aRxTxTurnaroundTime + aAirPropagationTime() + aMACProcessingDelay(); + if (useModulationParameters) + { + ModulationType modType; + if ((opMode=='b') || (opMode=='g')) + modType = WifiModulationType::getMode80211g(bitrate); + else if (opMode=='a') + modType = WifiModulationType::getMode80211a(bitrate); + else if (opMode=='p') + modType = WifiModulationType::getMode80211p(bitrate); + else + opp_error("mode not supported"); + return WifiModulationType::getSlotDuration(modType,wifiPreambleType); + } return ST; } -simtime_t Ieee80211Mac::getPIFS() const +simtime_t Ieee80211Mac::getPIFS() { return getSIFS() + getSlotTime(); } -simtime_t Ieee80211Mac::getDIFS() const +simtime_t Ieee80211Mac::getDIFS(int category) { - return getSIFS() + 2 * getSlotTime(); -} - -simtime_t Ieee80211Mac::getEIFS() const -{ -// FIXME: return getSIFS() + getDIFS() + (8 * ACKSize + aPreambleLength + aPLCPHeaderLength) / lowestDatarate; - return getSIFS() + getDIFS() + (8 * LENGTH_ACK + PHY_HEADER_LENGTH) / BITRATE_HEADER; + if (category<0 || category>(numCategories()-1)) + { + int index = numCategories()-1; + if (index<0) + index = 0; + return getSIFS() + ((double)AIFSN(index) * getSlotTime()); + } + else + { + return getSIFS() + ((double)AIFSN(category)) * getSlotTime(); + } + +} + +simtime_t Ieee80211Mac::getHeaderTime(double bitrate) +{ + ModulationType modType; + if ((opMode=='b') || (opMode=='g')) + modType = WifiModulationType::getMode80211g(bitrate); + else if (opMode=='a') + modType = WifiModulationType::getMode80211a(bitrate); + else if (opMode=='p') + modType = WifiModulationType::getMode80211p(bitrate); + else + opp_error("mode not supported"); + return WifiModulationType::getPreambleAndHeader(modType, wifiPreambleType); +} + +simtime_t Ieee80211Mac::getAIFS(int AccessCategory) +{ + return AIFSN(AccessCategory) * getSlotTime() + getSIFS(); +} + +simtime_t Ieee80211Mac::getEIFS() +{ +// FIXME: return getSIFS() + getDIFS() + (8 * ACKSize + aPreambleLength + aPLCPHeaderLength) / lowestDatarate; + if (PHY_HEADER_LENGTH<0) + { + if ((opMode=='b') || (opMode=='g')) + return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 1E+6 + getHeaderTime(1E+6); + else if (opMode=='a') + return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 6E+6 + getHeaderTime(6E+6); + else if (opMode=='p') + return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 6E+6 + getHeaderTime(3E+6); + } + else + { + // FIXME: check how PHY_HEADER_LENGTH is handled. Is that given in bytes or secs ??? + // what is the rela unit? The use seems to be incosistent betwen b and g modes. + if (opMode=='b') + return getSIFS() + getDIFS() + (8 * LENGTH_ACK + PHY_HEADER_LENGTH) / 1E+6; + else if (opMode=='g') + return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 1E+6 + PHY_HEADER_LENGTH; + else if (opMode=='a') + return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 6E+6 + PHY_HEADER_LENGTH; + else if (opMode=='p') + return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 3E+6 + PHY_HEADER_LENGTH; + } + // if arrive here there is an error + opp_error("mode not supported"); + return 0; } simtime_t Ieee80211Mac::computeBackoffPeriod(Ieee80211Frame *msg, int r) @@ -629,22 +1707,21 @@ simtime_t Ieee80211Mac::computeBackoffPeriod(Ieee80211Frame *msg, int r) int cw; EV << "generating backoff slot number for retry: " << r << endl; - - if (isMulticast(msg)) + if (msg && isMulticast(msg)) cw = cwMinMulticast; else { ASSERT(0 <= r && r < transmissionLimit); - cw = (cwMinData + 1) * (1 << r) - 1; + cw = (cwMin() + 1) * (1 << r) - 1; - if (cw > CW_MAX) - cw = CW_MAX; + if (cw > cwMax()) + cw = cwMax(); } int c = intrand(cw + 1); - EV << "generated backoff slot number: " << c << " , cw: " << cw << endl; + EV << "generated backoff slot number: " << c << " , cw: " << cw << " ,cwMin:cwMax = " << cwMin() << ":" << cwMax() << endl; return ((double)c) * getSlotTime(); } @@ -663,7 +1740,7 @@ void Ieee80211Mac::scheduleDIFSPeriod() { if (lastReceiveFailed) { - EV << "receiption of last frame failed, scheduling EIFS period\n"; + EV << "reception of last frame failed, scheduling EIFS period\n"; scheduleAt(simTime() + getEIFS(), endDIFS); } else @@ -675,33 +1752,116 @@ void Ieee80211Mac::scheduleDIFSPeriod() void Ieee80211Mac::cancelDIFSPeriod() { - EV << "cancelling DIFS period\n"; + EV << "canceling DIFS period\n"; cancelEvent(endDIFS); } +void Ieee80211Mac::scheduleAIFSPeriod() +{ + bool schedule = false; + for (int i = 0; iisScheduled() && !transmissionQueue(i)->empty()) + { + + if (lastReceiveFailed) + { + EV << "reception of last frame failed, scheduling EIFS-DIFS+AIFS period (" << i << ")\n"; + scheduleAt(simTime() + getEIFS() - getDIFS() + getAIFS(i), endAIFS(i)); + } + else + { + EV << "scheduling AIFS period (" << i << ")\n"; + scheduleAt(simTime() + getAIFS(i), endAIFS(i)); + } + + } + if (endAIFS(i)->isScheduled()) + schedule = true; + } + if (!schedule && !endDIFS->isScheduled()) + { + // schedule default DIFS + currentAC = numCategories()-1; + scheduleDIFSPeriod(); + } +} + +void Ieee80211Mac::rescheduleAIFSPeriod(int AccessCategory) +{ + ASSERT(1); + EV << "rescheduling AIFS[" << AccessCategory << "]\n"; + cancelEvent(endAIFS(AccessCategory)); + scheduleAt(simTime() + getAIFS(AccessCategory), endAIFS(AccessCategory)); +} + +void Ieee80211Mac::cancelAIFSPeriod() +{ + EV << "canceling AIFS period\n"; + for (int i = 0; iisScheduled()) + { + EV << "scheduling data timeout period\n"; + if (useModulationParameters) + { + ModulationType modType; + if ((opMode=='b') || (opMode=='g')) + modType = WifiModulationType::getMode80211g(bitrate); + else if (opMode=='a') + modType = WifiModulationType::getMode80211a(bitrate); + else if (opMode=='p') + modType = WifiModulationType::getMode80211p(bitrate); + else + opp_error("mode not supported"); + WifiModulationType::getSlotDuration(modType,wifiPreambleType); + tim = computeFrameDuration(frameToSend) +SIMTIME_DBL( + WifiModulationType::getSlotDuration(modType,wifiPreambleType) + + WifiModulationType::getSifsTime(modType,wifiPreambleType) + + WifiModulationType::get_aPHY_RX_START_Delay (modType,wifiPreambleType)); + } + else + tim = computeFrameDuration(frameToSend) +SIMTIME_DBL( getSIFS()) + computeFrameDuration(LENGTH_ACK, basicBitrate) + MAX_PROPAGATION_DELAY * 2; + EV<<" time out="<isScheduled()) + { + EV << "scheduling multicast timeout period\n"; + scheduleAt(simTime() + computeFrameDuration(frameToSend), endTimeout); + } } void Ieee80211Mac::cancelTimeoutPeriod() { - EV << "cancelling timeout period\n"; + EV << "canceling timeout period\n"; cancelEvent(endTimeout); } void Ieee80211Mac::scheduleCTSTimeoutPeriod() { - scheduleAt(simTime() + computeFrameDuration(LENGTH_RTS, basicBitrate) + getSIFS() + - computeFrameDuration(LENGTH_CTS, basicBitrate) + MAX_PROPAGATION_DELAY * 2, endTimeout); + if (!endTimeout->isScheduled()) + { + EV << "scheduling CTS timeout period\n"; + scheduleAt(simTime() + computeFrameDuration(LENGTH_RTS, basicBitrate) + getSIFS() + + computeFrameDuration(LENGTH_CTS, basicBitrate) + MAX_PROPAGATION_DELAY * 2, endTimeout); + } } void Ieee80211Mac::scheduleReservePeriod(Ieee80211Frame *frame) @@ -711,7 +1871,8 @@ void Ieee80211Mac::scheduleReservePeriod(Ieee80211Frame *frame) // see spec. 7.1.3.2 if (!isForUs(frame) && reserve != 0 && reserve < 32768) { - if (endReserve->isScheduled()) { + if (endReserve->isScheduled()) + { simtime_t oldReserve = endReserve->getArrivalTime() - simTime(); if (oldReserve > reserve) @@ -737,40 +1898,52 @@ void Ieee80211Mac::scheduleReservePeriod(Ieee80211Frame *frame) void Ieee80211Mac::invalidateBackoffPeriod() { - backoffPeriod = -1; + backoffPeriod() = -1; } bool Ieee80211Mac::isInvalidBackoffPeriod() { - return backoffPeriod == -1; + return backoffPeriod() == -1; } void Ieee80211Mac::generateBackoffPeriod() { - backoffPeriod = computeBackoffPeriod(getCurrentTransmission(), retryCounter); - ASSERT(backoffPeriod >= 0); - EV << "backoff period set to " << backoffPeriod << endl; + backoffPeriod() = computeBackoffPeriod(getCurrentTransmission(), retryCounter()); + ASSERT(backoffPeriod() >= 0); + EV << "backoff period set to " << backoffPeriod()<< endl; } void Ieee80211Mac::decreaseBackoffPeriod() { - // see spec 9.2.5.2 - simtime_t elapsedBackoffTime = simTime() - endBackoff->getSendingTime(); - backoffPeriod -= ((int)(elapsedBackoffTime / getSlotTime())) * getSlotTime(); - ASSERT(backoffPeriod >= 0); - EV << "backoff period decreased to " << backoffPeriod << endl; + // see spec 9.9.1.5 + // decrase for every EDCAF + // cancel event endBackoff after decrease or we don't know which endBackoff is scheduled + for (int i = 0; iisScheduled()) + { + EV<< "old backoff[" << i << "] is " << backoffPeriod(i) << ", sim time is " << simTime() + << ", endbackoff sending period is " << endBackoff(i)->getSendingTime() << endl; + simtime_t elapsedBackoffTime = simTime() - endBackoff(i)->getSendingTime(); + backoffPeriod(i) -= ((int)(elapsedBackoffTime / getSlotTime())) * getSlotTime(); + EV << "actual backoff[" << i << "] is " <= 0); + EV << "backoff[" << i << "] period decreased to " << backoffPeriod(i) << endl; + } + } } void Ieee80211Mac::scheduleBackoffPeriod() { EV << "scheduling backoff period\n"; - scheduleAt(simTime() + backoffPeriod, endBackoff); + scheduleAt(simTime() + backoffPeriod(), endBackoff()); } void Ieee80211Mac::cancelBackoffPeriod() { - EV << "cancelling Backoff period\n"; - cancelEvent(endBackoff); + EV << "cancelling Backoff period - only if some is scheduled\n"; + for (int i = 0; i (transmissionQueue()->initIterator()); + ASSERT(frame==frameToSend); + if (!txop && TXOP() > 0 && transmissionQueue()->size() >= 2 ) + { + //we start packet burst within TXOP time period + txop = true; + + for (frame=dynamic_cast(transmissionQueue()->initIterator()); frame!=NULL; frame=dynamic_cast(transmissionQueue()->next())) + { + count++; + t = computeFrameDuration(frame) + 2 * getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate); + EV << "t is " << t << endl; + if (TXOP()>time+t) + { + time += t; + EV << "adding t \n"; + } + else + { + break; + } + } + //to be sure we get endTXOP earlier then receive ACK and we have to minus SIFS time from first packet + time -= getSIFS()/2 + getSIFS(); + EV << "scheduling TXOP for AC" << currentAC << ", duration is " << time << ",count is " << count << endl; + scheduleAt(simTime() + time, endTXOP); + } EV << "sending Data frame\n"; - sendDown(buildDataFrame(frameToSend)); + sendDown(setBitrateFrame(buildDataFrame(frameToSend))); } - -void Ieee80211Mac::sendMulticastFrame(Ieee80211DataOrMgmtFrame *frameToSend) +#else +void Ieee80211Mac::sendDataFrame(Ieee80211DataOrMgmtFrame *frameToSend) { - EV << "sending Multicast frame\n"; - sendDown(buildMulticastFrame(frameToSend)); + simtime_t t = 0, time = 0; + int count = 0; + std::list::iterator frame; + + frame = transmissionQueue()->begin(); + ASSERT(*frame==frameToSend); + if (!txop && TXOP() > 0 && transmissionQueue()->size() >= 2 ) + { + //we start packet burst within TXOP time period + txop = true; + + for (frame=transmissionQueue()->begin(); frame != transmissionQueue()->end(); ++frame) + { + count++; + t = computeFrameDuration(*frame) + 2 * getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate); + EV << "t is " << t << endl; + if (TXOP()>time+t) + { + time += t; + EV << "adding t \n"; + } + else + { + break; + } + } + //to be sure we get endTXOP earlier then receive ACK and we have to minus SIFS time from first packet + time -= getSIFS()/2 + getSIFS(); + EV << "scheduling TXOP for AC" << currentAC << ", duration is " << time << ",count is " << count << endl; + scheduleAt(simTime() + time, endTXOP); + } + EV << "sending Data frame\n"; + sendDown(setBitrateFrame(buildDataFrame(frameToSend))); } +#endif void Ieee80211Mac::sendRTSFrame(Ieee80211DataOrMgmtFrame *frameToSend) { @@ -816,6 +2054,12 @@ void Ieee80211Mac::sendRTSFrame(Ieee80211DataOrMgmtFrame *frameToSend) sendDown(setBasicBitrate(buildRTSFrame(frameToSend))); } +void Ieee80211Mac::sendMulticastFrame(Ieee80211DataOrMgmtFrame *frameToSend) +{ + EV << "sending Multicast frame\n"; + sendDown(setBasicBitrate(buildDataFrame(frameToSend))); +} + void Ieee80211Mac::sendCTSFrameOnEndSIFS() { Ieee80211Frame *rtsFrame = (Ieee80211Frame *)endSIFS->getContextPointer(); @@ -840,11 +2084,31 @@ Ieee80211DataOrMgmtFrame *Ieee80211Mac::buildDataFrame(Ieee80211DataOrMgmtFrame if (isMulticast(frameToSend)) frame->setDuration(0); else if (!frameToSend->getMoreFragments()) - frame->setDuration(getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate)); + { + if (txop) + + { +#ifdef USEMULTIQUEUE + Ieee80211DataOrMgmtFrame* nextframeToSend = dynamic_cast (transmissionQueue()->initIterator()); + nextframeToSend = dynamic_cast (transmissionQueue()->next()); + frame->setDuration(3 * getSIFS() + 2 * computeFrameDuration(LENGTH_ACK, basicBitrate) + + computeFrameDuration(nextframeToSend)); +#else + // ++ operation is safe because txop is true + std::list::iterator nextframeToSend; + nextframeToSend = transmissionQueue()->begin(); + ASSERT(transmissionQueue()->end() != nextframeToSend); + nextframeToSend++; + frame->setDuration(3 * getSIFS() + 2 * computeFrameDuration(LENGTH_ACK, basicBitrate) + + computeFrameDuration(*nextframeToSend)); +#endif + } + else + frame->setDuration(getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate)); + } else // FIXME: shouldn't we use the next frame to be sent? - frame->setDuration(3 * getSIFS() + 2 * computeFrameDuration(LENGTH_ACK, basicBitrate) - + computeFrameDuration(frameToSend)); + frame->setDuration(3 * getSIFS() + 2 * computeFrameDuration(LENGTH_ACK, basicBitrate) + computeFrameDuration(frameToSend)); return frame; } @@ -857,8 +2121,7 @@ Ieee80211ACKFrame *Ieee80211Mac::buildACKFrame(Ieee80211DataOrMgmtFrame *frameTo if (!frameToACK->getMoreFragments()) frame->setDuration(0); else - frame->setDuration(frameToACK->getDuration() - getSIFS() - - computeFrameDuration(LENGTH_ACK, basicBitrate)); + frame->setDuration(frameToACK->getDuration() - getSIFS() - computeFrameDuration(LENGTH_ACK, basicBitrate)); return frame; } @@ -879,8 +2142,7 @@ Ieee80211CTSFrame *Ieee80211Mac::buildCTSFrame(Ieee80211RTSFrame *rtsFrame) { Ieee80211CTSFrame *frame = new Ieee80211CTSFrame("wlan-cts"); frame->setReceiverAddress(rtsFrame->getTransmitterAddress()); - frame->setDuration(rtsFrame->getDuration() - getSIFS() - - computeFrameDuration(LENGTH_CTS, basicBitrate)); + frame->setDuration(rtsFrame->getDuration() - getSIFS() - computeFrameDuration(LENGTH_CTS, basicBitrate)); return frame; } @@ -888,6 +2150,17 @@ Ieee80211CTSFrame *Ieee80211Mac::buildCTSFrame(Ieee80211RTSFrame *rtsFrame) Ieee80211DataOrMgmtFrame *Ieee80211Mac::buildMulticastFrame(Ieee80211DataOrMgmtFrame *frameToSend) { Ieee80211DataOrMgmtFrame *frame = (Ieee80211DataOrMgmtFrame *)frameToSend->dup(); + + PhyControlInfo *phyControlInfo_old = dynamic_cast( frameToSend->getControlInfo() ); + if (phyControlInfo_old) + { + ev<<"Per frame1 params"<getBitrate()/1e6<<"Mbps txpower "<txpower()<<"mW"<setControlInfo( phyControlInfo_new ); + } + frame->setDuration(0); return frame; } @@ -901,6 +2174,24 @@ Ieee80211Frame *Ieee80211Mac::setBasicBitrate(Ieee80211Frame *frame) return frame; } +Ieee80211Frame *Ieee80211Mac::setBitrateFrame(Ieee80211Frame *frame) +{ + if (rateControlMode == RATE_CR && forceBitRate==false) + return frame; + PhyControlInfo *ctrl = NULL; + if (frame->getControlInfo()==NULL) + { + ctrl = new PhyControlInfo(); + frame->setControlInfo(ctrl); + } + else + ctrl = dynamic_cast(frame->getControlInfo()); + if (ctrl) + ctrl->setBitrate(getBitrate()); + return frame; +} + + /**************************************************************** * Helper functions. */ @@ -912,24 +2203,29 @@ void Ieee80211Mac::finishCurrentTransmission() void Ieee80211Mac::giveUpCurrentTransmission() { + Ieee80211DataOrMgmtFrame *temp = (Ieee80211DataOrMgmtFrame*) transmissionQueue()->front(); + nb->fireChangeNotification(NF_LINK_BREAK, temp); popTransmissionQueue(); resetStateVariables(); - numGivenUp++; + numGivenUp()++; } void Ieee80211Mac::retryCurrentTransmission() { - ASSERT(retryCounter < transmissionLimit - 1); + ASSERT(retryCounter() < transmissionLimit - 1); getCurrentTransmission()->setRetry(true); - retryCounter++; - numRetry++; - backoff = true; + if (rateControlMode == RATE_AARF || rateControlMode == RATE_ARF) + reportDataFailed(); + else + retryCounter() ++; + numRetry()++; + backoff() = true; generateBackoffPeriod(); } Ieee80211DataOrMgmtFrame *Ieee80211Mac::getCurrentTransmission() { - return (Ieee80211DataOrMgmtFrame *)transmissionQueue.front(); + return transmissionQueue()->empty() ? NULL : (Ieee80211DataOrMgmtFrame *)transmissionQueue()->front(); } void Ieee80211Mac::sendDownPendingRadioConfigMsg() @@ -951,44 +2247,74 @@ void Ieee80211Mac::setMode(Mode mode) void Ieee80211Mac::resetStateVariables() { - backoffPeriod = 0; - retryCounter = 0; + backoffPeriod() = 0; + if (rateControlMode == RATE_AARF || rateControlMode == RATE_ARF) + reportDataOk(); + else + retryCounter() = 0; - if (!transmissionQueue.empty()) { - backoff = true; + if (!transmissionQueue()->empty()) + { + backoff() = true; getCurrentTransmission()->setRetry(false); } - else { - backoff = false; + else + { + backoff() = false; } } -bool Ieee80211Mac::isMediumStateChange(cMessage *msg) const +bool Ieee80211Mac::isMediumStateChange(cMessage *msg) { return msg == mediumStateChange || (msg == endReserve && radioState == RadioState::IDLE); } -bool Ieee80211Mac::isMediumFree() const +bool Ieee80211Mac::isMediumFree() { return radioState == RadioState::IDLE && !endReserve->isScheduled(); } -bool Ieee80211Mac::isMulticast(Ieee80211Frame *frame) const +bool Ieee80211Mac::isMulticast(Ieee80211Frame *frame) { return frame && frame->getReceiverAddress().isMulticast(); } -bool Ieee80211Mac::isForUs(Ieee80211Frame *frame) const +bool Ieee80211Mac::isForUs(Ieee80211Frame *frame) { return frame && frame->getReceiverAddress() == address; } -bool Ieee80211Mac::isDataOrMgmtFrame(Ieee80211Frame *frame) const +bool Ieee80211Mac::isSentByUs(Ieee80211Frame *frame) +{ + + if (dynamic_cast(frame)) + { + //EV<<"ad3 "<<((Ieee80211DataOrMgmtFrame *)frame)->getAddress3(); + //EV<<"myad "<getAddress3() == address)//received frame sent by us + return 1; + } + else + EV<<"Cast failed"<(frame); } -Ieee80211Frame *Ieee80211Mac::getFrameReceivedBeforeSIFS() const +bool Ieee80211Mac::isMsgAIFS(cMessage *msg) +{ + for (int i = 0; igetContextPointer(); } @@ -996,34 +2322,124 @@ Ieee80211Frame *Ieee80211Mac::getFrameReceivedBeforeSIFS() const void Ieee80211Mac::popTransmissionQueue() { EV << "dropping frame from transmission queue\n"; - Ieee80211Frame *temp = transmissionQueue.front(); - transmissionQueue.pop_front(); - delete temp; - + Ieee80211Frame *temp = dynamic_cast(transmissionQueue()->front()); + ASSERT(!transmissionQueue()->empty()); + transmissionQueue()->pop_front(); if (queueModule) { - // tell queue module that we've become idle - EV << "requesting another frame from queue module\n"; - queueModule->requestPacket(); + if (numCategories()==1) + { + // the module are continuously asking for packets + EV << "requesting another frame from queue module\n"; + queueModule->requestPacket(); + } + else if (numCategories()>1 && (int)transmissionQueueSize()==maxQueueSize-1) + { + // Now exist a empty frame space + // the module are continuously asking for packets + EV << "requesting another frame from queue module\n"; + queueModule->requestPacket(); + } } + delete temp; } double Ieee80211Mac::computeFrameDuration(Ieee80211Frame *msg) { - return computeFrameDuration(msg->getBitLength(), bitrate); + + PhyControlInfo *ctrl; + double duration; + ev<<*msg; + ctrl = dynamic_cast ( msg->removeControlInfo() ); + if ( ctrl ) + { + ev<<"Per frame2 params bitrate "<getBitrate()/1e6<getBitLength(), ctrl->getBitrate()); + delete ctrl; + return duration; + } + else + + return computeFrameDuration(msg->getBitLength(), bitrate); } double Ieee80211Mac::computeFrameDuration(int bits, double bitrate) { - return bits / bitrate + PHY_HEADER_LENGTH / BITRATE_HEADER; + double duration; + if (PHY_HEADER_LENGTH<0) + { + ModulationType modType; + if (opMode=='g' || (opMode=='b')) + modType = WifiModulationType::getMode80211g(bitrate); + else if (opMode=='a') + modType = WifiModulationType::getMode80211a(bitrate); + else if (opMode=='p') + modType = WifiModulationType::getMode80211p(bitrate); + else + opp_error("Opmode not supported"); + duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(bits, modType, wifiPreambleType)); + } + else + { + if ((opMode=='g') || (opMode=='a') || (opMode=='p')) + duration = 4*ceil((16+bits+6)/(bitrate/1e6*4))*1e-6 + PHY_HEADER_LENGTH; + else if (opMode=='b') + duration = bits / bitrate + PHY_HEADER_LENGTH / BITRATE_HEADER; + else + opp_error("Opmode not supported"); + } + + EV<<" duration="<isScheduled()) + b[i] = "scheduled"; + if (endAIFS(i)->isScheduled()) + a[i] = "scheduled"; + } + + EV << "# state information: mode = " << modeName(mode) << ", state = " << fsm.getStateName(); + EV << ", backoff 0.."<getId(); + else + EV << "\n# current transmission: none"; + EV << endl; } const char *Ieee80211Mac::modeName(int mode) @@ -1038,3 +2454,583 @@ const char *Ieee80211Mac::modeName(int mode) return s; #undef CASE } + +bool Ieee80211Mac::transmissionQueueEmpty() +{ + for (int i=0; iempty()) return false; + return true; +} + +unsigned int Ieee80211Mac::transmissionQueueSize() +{ + unsigned int totalSize=0; + for (int i=0; isize(); + return totalSize; +} + +void Ieee80211Mac::reportDataOk() +{ + retryCounter() = 0; + if (rateControlMode==RATE_CR) + return; + successCounter ++; + failedCounter = 0; + recovery = false; + if ((successCounter == getSuccessThreshold() || timer == getTimerTimeout()) + && (rateIndex < (getMaxBitrate()))) + { + if (rateControlMode != RATE_CR) + { + rateIndex++; + if (opMode=='b') setBitrate(BITRATES_80211b[rateIndex]); + else if (opMode=='g') setBitrate(BITRATES_80211g[rateIndex]); + else if (opMode=='a') setBitrate(BITRATES_80211a[rateIndex]); + else if (opMode=='p') setBitrate(BITRATES_80211p[rateIndex]); + else opp_error("mode not supported"); + } + timer = 0; + successCounter = 0; + recovery = true; + } +} + +void Ieee80211Mac::reportDataFailed(void) +{ + retryCounter()++; + if (rateControlMode==RATE_CR) + return; + timer++; + failedCounter++; + successCounter = 0; + if (recovery) + { + if (retryCounter() == 1) + { + reportRecoveryFailure(); + if (rateIndex != getMinBitrate() && rateControlMode != RATE_CR) + { + rateIndex--; + if (opMode=='b') setBitrate(BITRATES_80211b[rateIndex]); + else if (opMode=='g') setBitrate(BITRATES_80211g[rateIndex]); + else if (opMode=='a') setBitrate(BITRATES_80211a[rateIndex]); + else if (opMode=='p') setBitrate(BITRATES_80211p[rateIndex]); + else opp_error("mode not supported"); + } + } + timer = 0; + } + else + { + if (needNormalFallback()) + { + reportFailure(); + if (rateIndex != getMinBitrate() && rateControlMode != RATE_CR) + { + rateIndex--; + if (opMode=='b') setBitrate(BITRATES_80211b[rateIndex]); + else if (opMode=='g') setBitrate(BITRATES_80211g[rateIndex]); + else if (opMode=='a') setBitrate(BITRATES_80211a[rateIndex]); + else if (opMode=='p') setBitrate(BITRATES_80211p[rateIndex]); + else opp_error("mode not supported"); + } + } + if (retryCounter() >= 2) + { + timer = 0; + } + } +} + +int Ieee80211Mac::getMinTimerTimeout(void) +{ + return minTimerTimeout; +} + +int Ieee80211Mac::getMinSuccessThreshold(void) +{ + return minSuccessThreshold; +} + +int Ieee80211Mac::getTimerTimeout(void) +{ + return timerTimeout; +} + +int Ieee80211Mac::getSuccessThreshold(void) +{ + return successThreshold; +} + +void Ieee80211Mac::setTimerTimeout(int timer_timeout) +{ + if (timer_timeout >= minTimerTimeout) + timerTimeout = timer_timeout; + else + error("timer_timeout is less than minTimerTimeout"); +} +void Ieee80211Mac::setSuccessThreshold(int success_threshold) +{ + if (success_threshold >= minSuccessThreshold) + successThreshold = success_threshold; + else + error("success_threshold is less than minSuccessThreshold"); +} + +void Ieee80211Mac::reportRecoveryFailure(void) +{ + if (rateControlMode == RATE_AARF) + { + setSuccessThreshold((int)(std::min((double)getSuccessThreshold() * successCoeff, (double) maxSuccessThreshold))); + setTimerTimeout((int)(std::max((double)getMinTimerTimeout(), (double)(getSuccessThreshold() * timerCoeff)))); + } +} + +void Ieee80211Mac::reportFailure(void) +{ + if (rateControlMode == RATE_AARF) + { + setTimerTimeout(getMinTimerTimeout()); + setSuccessThreshold(getMinSuccessThreshold()); + } +} + +bool Ieee80211Mac::needRecoveryFallback(void) +{ + if (retryCounter() == 1) + { + return true; + } + else + { + return false; + } +} + +bool Ieee80211Mac::needNormalFallback(void) +{ + int retryMod = (retryCounter() - 1) % 2; + if (retryMod == 1) + { + return true; + } + else + { + return false; + } +} + +double Ieee80211Mac::getBitrate() +{ + return bitrate; +} + +void Ieee80211Mac::setBitrate(double rate) +{ + bitrate = rate; +} + + +int Ieee80211Mac::getMaxBitrate(void) +{ + if (opMode=='b') + return (NUM_BITERATES_80211b-1); + else if (opMode=='g') + return (NUM_BITERATES_80211g-1); + else if (opMode=='a') + return (NUM_BITERATES_80211a-1); + else if (opMode=='p') + return (NUM_BITERATES_80211p-1); +// +// If arrives here there is an error + opp_error("Mode not supported"); + return 0; +} + +int Ieee80211Mac::getMinBitrate(void) +{ + return 0; +} + + +// method for access to the EDCA data + + +// methods for access to specific AC data +bool & Ieee80211Mac::backoff(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].backoff; +} + +simtime_t & Ieee80211Mac::TXOP(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].TXOP; +} + +simtime_t & Ieee80211Mac::backoffPeriod(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].backoffPeriod; +} + +int & Ieee80211Mac::retryCounter(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].retryCounter; +} + +int & Ieee80211Mac::AIFSN(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].AIFSN; +} + +int & Ieee80211Mac::cwMax(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].cwMax; +} + +int & Ieee80211Mac::cwMin(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].cwMin; +} + +cMessage * Ieee80211Mac::endAIFS(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].endAIFS; +} + +cMessage * Ieee80211Mac::endBackoff(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].endBackoff; +} + +const bool Ieee80211Mac::isBakoffMsg(cMessage *msg) +{ + for (unsigned int i=0; i=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].numRetry; +} + +long & Ieee80211Mac::numSentWithoutRetry(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)numCategories()) + opp_error("AC doesn't exist"); + return edcCAF[i].numSentWithoutRetry; +} + +long & Ieee80211Mac::numGivenUp(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].numGivenUp; +} + +long & Ieee80211Mac::numSent(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].numSent; +} + +long & Ieee80211Mac::numDropped(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].numDropped; +} + +long & Ieee80211Mac::bites(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].bites; +} + +simtime_t & Ieee80211Mac::minjitter(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].minjitter; +} + +simtime_t & Ieee80211Mac::maxjitter(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAF[i].maxjitter; +} + +// out vectors + + +cOutVector * Ieee80211Mac::jitter(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAFOutVector[i].jitter; +} + +cOutVector * Ieee80211Mac::macDelay(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAFOutVector[i].macDelay; +} + +cOutVector * Ieee80211Mac::throughput(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return edcCAFOutVector[i].throughput; +} + +Ieee80211Mac::Ieee80211DataOrMgmtFrameList * Ieee80211Mac::transmissionQueue(int i) +{ + if (i==-1) + i = currentAC; + if (i>=(int)edcCAF.size()) + opp_error("AC doesn't exist"); + return &(edcCAF[i].transmissionQueue); +} + + +ModulationType +Ieee80211Mac::getControlAnswerMode(ModulationType reqMode) +{ + /** + * The standard has relatively unambiguous rules for selecting a + * control response rate (the below is quoted from IEEE 802.11-2007, + * Section 9.6): + * + * To allow the transmitting STA to calculate the contents of the + * Duration/ID field, a STA responding to a received frame shall + * transmit its Control Response frame (either CTS or ACK), other + * than the BlockAck control frame, at the highest rate in the + * BSSBasicRateSet parameter that is less than or equal to the + * rate of the immediately previous frame in the frame exchange + * sequence (as defined in 9.12) and that is of the same + * modulation class (see 9.6.1) as the received frame... + */ + + /** + * If no suitable basic rate was found, we search the mandatory + * rates. The standard (IEEE 802.11-2007, Section 9.6) says: + * + * ...If no rate contained in the BSSBasicRateSet parameter meets + * these conditions, then the control frame sent in response to a + * received frame shall be transmitted at the highest mandatory + * rate of the PHY that is less than or equal to the rate of the + * received frame, and that is of the same modulation class as the + * received frame. In addition, the Control Response frame shall + * be sent using the same PHY options as the received frame, + * unless they conflict with the requirement to use the + * BSSBasicRateSet parameter. + * + * TODO: Note that we're ignoring the last sentence for now, because + * there is not yet any manipulation here of PHY options. + */ + bool found = false; + ModulationType mode; + for (uint32_t idx = 0; idx < (uint32_t)getMaxBitrate(); idx++) + { + ModulationType thismode; + if (opMode=='b') + thismode = WifiModulationType::getMode80211b(BITRATES_80211b[idx]); + else if (opMode=='g') + thismode = WifiModulationType::getMode80211g(BITRATES_80211g[idx]); + else if (opMode=='a') + thismode = WifiModulationType::getMode80211a(BITRATES_80211a[idx]); + else if (opMode=='a') + thismode = WifiModulationType::getMode80211p(BITRATES_80211p[idx]); + + /* If the rate: + * + * - is a mandatory rate for the PHY, and + * - is equal to or faster than our current best choice, and + * - is less than or equal to the rate of the received frame, and + * - is of the same modulation class as the received frame + * + * ...then it's our best choice so far. + */ + if (thismode.getIsMandatory() + && (!found || thismode.getPhyRate() > mode.getPhyRate()) + && thismode.getPhyRate() <= reqMode.getPhyRate() + && thismode.getModulationClass() == reqMode.getModulationClass()) + { + mode = thismode; + // As above; we've found a potentially-suitable transmit + // rate, but we need to continue and consider all the + // mandatory rates before we can be sure we've got the right + // one. + found = true; + } + } + + /** + * If we still haven't found a suitable rate for the response then + * someone has messed up the simulation config. This probably means + * that the WifiPhyStandard is not set correctly, or that a rate that + * is not supported by the PHY has been explicitly requested in a + * WifiRemoteStationManager (or descendant) configuration. + * + * Either way, it is serious - we can either disobey the standard or + * fail, and I have chosen to do the latter... + */ + if (!found) + { + opp_error("Can't find response rate for reqMode. Check standard and selected rates match."); + } + + return mode; +} + +// This methods implemet the duplicate filter +void Ieee80211Mac::sendUp(cMessage *msg) +{ + EV << "sending up " << msg << "\n"; + + if (duplicateDetect) // duplicate detection filter + { + Ieee80211DataOrMgmtFrame *frame =dynamic_cast(msg); + if (frame) + { + Ieee80211ASFTupleList::iterator it = asfTuplesList.find(frame->getTransmitterAddress()); + if (it==asfTuplesList.end()) + { + Ieee80211ASFTuple tuple; + tuple.receivedTime=simTime(); + tuple.sequenceNumber= frame->getSequenceNumber(); + tuple.fragmentNumber=frame->getFragmentNumber(); + asfTuplesList.insert(std::pair(frame->getTransmitterAddress(),tuple)); + } + else + { + // check if duplicate + if (it->second.sequenceNumber==frame->getSequenceNumber() && it->second.fragmentNumber==frame->getFragmentNumber()) + { + return; + } + else + { + // actualize + it->second.sequenceNumber=frame->getSequenceNumber(); + it->second.fragmentNumber=frame->getFragmentNumber(); + it->second.receivedTime=simTime(); + } + } + } + } + + if (msg->isPacket()) + emit(packetSentToUpperSignal, msg); + + send(msg, upperLayerOut); +} + +void Ieee80211Mac::removeOldTuplesFromDuplicateMap() +{ + if (duplicateDetect && lastTimeDelete+duplicateTimeOut>=simTime()) + { + lastTimeDelete=simTime(); + for (Ieee80211ASFTupleList::iterator it = asfTuplesList.begin();it!=asfTuplesList.begin();) + { + if (it->second.receivedTime+duplicateTimeOutgetFullName()) + 1]; + char *d = interfaceName; + for (const char *s = getParentModule()->getFullName(); *s; s++) + if (isalnum(*s)) + *d++ = *s; + *d = '\0'; + InterfaceEntry * e = ift->getInterfaceByName(interfaceName); + delete [] interfaceName; + if (e) + return e->getMacAddress(); + return MACAddress::UNSPECIFIED_ADDRESS; +} diff --git a/src/linklayer/ieee80211/mac/Ieee80211Mac.h b/src/linklayer/ieee80211/mac/Ieee80211Mac.h index 47539c122..465aa4d10 100644 --- a/src/linklayer/ieee80211/mac/Ieee80211Mac.h +++ b/src/linklayer/ieee80211/mac/Ieee80211Mac.h @@ -1,27 +1,32 @@ // -// Copyright (C) 2006 Andras Varga and Levente M�sz�ros +// Copyright (C) 2006 Andras Varga and Levente Meszaros (original code) +// Copyright (C) 2007 Sorin (802.11g) +// Copyright (C) 2009 Lukáš Hlůže (Lukás Hluze) lukas@hluze.cz (802.11e) +// Copyright (C) 2011 Alfonso Ariza (clean code, fix some errors, new radio model) // // This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License +// modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. +// GNU General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public License -// along with this program; if not, see . +// 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. // #ifndef IEEE_80211_MAC_H #define IEEE_80211_MAC_H -// uncomment this if you do not want to log state machine transitions -#define FSM_DEBUG +// un-comment this if you do not want to log state machine transitions +//#define FSM_DEBUG +//#define USEMULTIQUEUE -#include +#include "WifiMode.h" #include "WirelessMacBase.h" #include "IPassiveQueue.h" #include "Ieee80211Frame_m.h" @@ -29,13 +34,18 @@ #include "NotificationBoard.h" #include "RadioState.h" #include "FSMA.h" +#include "IQoSClassifier.h" +#ifdef USEMULTIQUEUE +#include "MultiQueue.h" +#endif /** - * IEEE 802.11b Media Access Control Layer. + * IEEE 802.11g with e Media Access Control Layer. * * Various comments in the code refer to the Wireless LAN Medium Access * Control (MAC) and Physical Layer(PHY) Specifications * ANSI/IEEE Std 802.11, 1999 Edition (R2003) + * ANSI/IEEE Std 802.11, 2007 Edition * * For more info, see the NED file. * @@ -44,7 +54,7 @@ * TODO: CF period * TODO: pass radio power to upper layer * TODO: transmission complete notification to upper layer - * TODO: STA TCF timer syncronization, see Chapter 11 pp 123 + * TODO: STA TCF timer synchronization, see Chapter 11 pp 123 * * Parts of the implementation have been taken over from the * Mobility Framework's Mac80211 module. @@ -53,20 +63,43 @@ */ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable { - typedef std::list Ieee80211DataOrMgmtFrameList; +#ifdef USEMULTIQUEUE + typedef MultiQueue Ieee80211DataOrMgmtFrameList; +#else + typedef std::list Ieee80211DataOrMgmtFrameList; +#endif + /** + * This is used to populate fragments and identify duplicated messages. See spec 9.2.9. + */ + struct Ieee80211ASFTuple + { + int sequenceNumber; + int fragmentNumber; + simtime_t receivedTime; + Ieee80211ASFTuple& operator=(const Ieee80211ASFTuple& other) + { + if (this==&other) return *this; + this->sequenceNumber = other.sequenceNumber; + this->fragmentNumber = other.fragmentNumber; + this->receivedTime = other.receivedTime; + return *this; + } + }; - /** - * This is used to populate fragments and identify duplicated messages. See spec 9.2.9. - */ - struct Ieee80211ASFTuple - { - MACAddress address; - int sequenceNumber; - int fragmentNumber; - }; + typedef std::map Ieee80211ASFTupleList; - typedef std::list Ieee80211ASFTupleList; + enum + { + RATE_ARF, // Auto Rate Fallback + RATE_AARF, // Adaptatice ARF + RATE_CR, // Constant Rate + } rateControlMode; + WifiPreamble wifiPreambleType; + ModulationType recFrameModulationType; + bool validRecMode; + bool useModulationParameters; + bool prioritizeMulticast; protected: /** * @name Configuration parameters @@ -75,15 +108,46 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable //@{ /** MAC address */ MACAddress address; - - /** The bitrate is used to send data and mgmt frames; be sure to use a valid 802.11 bitrate */ + char opMode; + /** The bitrate is used to send unicast data and mgmt frames; be sure to use a valid 802.11 bitrate */ double bitrate; - /** The basic bitrate (1 or 2 Mbps) is used to transmit control frames */ + /** The basic bitrate (1 or 2 Mbps) is used to transmit control frames and multicast/broadcast frames */ double basicBitrate; + // Variables used by the auto bit rate + bool forceBitRate; //if true the + unsigned int intrateIndex; + int contI; + int contJ; + int samplingCoeff; + double recvdThroughput; + int autoBitrate; + int rateIndex; + int successCounter; + int failedCounter; + bool recovery; + int timer; + int successThreshold; + int maxSuccessThreshold; + int timerTimeout; + int minSuccessThreshold; + int minTimerTimeout; + double successCoeff; + double timerCoeff; + double _snr; + double snr; + double lossRate; + simtime_t timeStampLastMessageReceived; + // used to measure the throughput over a period + uint64_t recBytesOverPeriod; + simtime_t throughputTimePeriod; + cMessage * throughputTimer; + double throughputLastPeriod; + /** Maximum number of frames in the queue; should be set in the omnetpp.ini */ int maxQueueSize; + int maxCategorieQueueSize; /** * The minimum length of MPDU to use RTS/CTS mechanism. 0 means always, extremely @@ -104,8 +168,21 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable */ int transmissionLimit; + + /** Default access catagory */ + int defaultAC; + + /** Slot time 9us(fast slot time 802.11g only) 20us(802.11b / 802.11g backward compatible)*/ + simtime_t ST; + + double PHY_HEADER_LENGTH; /** Minimum contention window. */ int cwMinData; + //int cwMin[4]; + + /** Maximum contention window. */ + int cwMaxData; + // int cwMax[4]; /** Contention window size for multicast messages. */ int cwMinMulticast; @@ -122,10 +199,11 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable //@{ // don't forget to keep synchronized the C++ enum and the runtime enum definition /** the 80211 MAC state machine */ - enum State { + enum State + { IDLE, DEFER, - WAITDIFS, + WAITAIFS, BACKOFF, WAITACK, WAITMULTICAST, @@ -135,52 +213,154 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable }; protected: cFSM fsm; + bool fixFSM; + + struct Edca { + simtime_t TXOP; + bool backoff; + simtime_t backoffPeriod; + int retryCounter; + int AIFSN; // Arbitration interframe space number. The duration edcCAF[AC].AIFSis a duration derived from the value AIFSN[AC] by the relation + int cwMax; + int cwMin; + // queue + Ieee80211DataOrMgmtFrameList transmissionQueue; + // per class timers + cMessage *endAIFS; + cMessage *endBackoff; + /** @name Statistics per Access Class*/ + //@{ + long numRetry; + long numSentWithoutRetry; + long numGivenUp; + long numSent; + long numDropped; + long bites; + simtime_t minjitter; + simtime_t maxjitter; + }; + + struct EdcaOutVector { + cOutVector *jitter; + cOutVector *macDelay; + cOutVector *throughput; + }; + + std::vector edcCAF; + std::vector edcCAFOutVector; + // + // methods for access to the current AC data + // + // methods for access to specific AC data + virtual bool & backoff(int i = -1); + virtual simtime_t & TXOP(int i = -1); + virtual simtime_t & backoffPeriod(int i = -1); + virtual int & retryCounter(int i = -1); + virtual int & AIFSN(int i = -1); + virtual int & cwMax(int i = -1); + virtual int & cwMin(int i = -1); + virtual cMessage * endAIFS(int i = -1); + virtual cMessage * endBackoff(int i = -1); + virtual Ieee80211DataOrMgmtFrameList * transmissionQueue(int i = -1); + virtual void setEndAIFS(int i, cMessage *msg){edcCAF[i].endAIFS = msg;} + virtual void setEndBackoff(int i, cMessage *msg){edcCAF[i].endBackoff = msg;} + + // Statistics + virtual long & numRetry(int i = -1); + virtual long & numSentWithoutRetry(int i = -1); + virtual long & numGivenUp(int i = -1); + virtual long & numSent(int i = -1); + virtual long & numDropped(int i = -1); + virtual long & bites(int i = -1); + virtual simtime_t & minjitter(int i = -1); + virtual simtime_t & maxjitter(int i = -1); +// out vectors + virtual cOutVector * jitter(int i = -1); + virtual cOutVector * macDelay(int i = -1); + virtual cOutVector * throughput(int i = -1); + inline const int numCategories(){return edcCAF.size();} + virtual const bool isBakoffMsg(cMessage *msg); + + const char *modeName(int mode); + + /** + * Arbitration interframe space number. + * The duration AIFS[AC] is a duration derived from the value AIFSN[AC] by the relation + * AIFS[AC] = AIFSN[AC] × aSlotTime + aSIFSTime. + * See spec 7.3.2.29 + * + */ + //int AIFSN[4]; + + /** Remaining backoff period in seconds */ + //simtime_t backoffPeriod[4]; + /** True if backoff is enabled */ + // bool backoff[4]; + /** TXOP parametr */ + //simtime_t TXOP[4]; + + /** + * Number of frame retransmission attempts, this is a simpification of + * SLRC and SSRC, see 9.2.4 in the spec + */ + //int retryCounter[4]; + IQoSClassifier *classifier; public: /** 80211 MAC operation modes */ - enum Mode { + enum Mode + { DCF, ///< Distributed Coordination Function PCF, ///< Point Coordination Function + EDCA, }; protected: Mode mode; /** Sequence number to be assigned to the next frame */ - uint16 sequenceNumber; + int sequenceNumber; /** * Indicates that the last frame received had bit errors in it or there was a * collision during receiving the frame. If this flag is set, then the MAC - * will wait EIFS instead of DIFS period of time in WAITDIFS state. + * will wait EIFS - DIFS + AIFS instead of AIFS period of time in WAITAIFS state. */ bool lastReceiveFailed; - /** True if backoff is enabled */ - bool backoff; + /** True during network allocation period. This flag is present to be able to watch this state. */ bool nav; - /** Remaining backoff period in seconds */ - simtime_t backoffPeriod; + /** True if we are in txop bursting packets. */ + bool txop; - /** - * Number of frame retransmission attempts, this is a simpification of - * SLRC and SSRC, see 9.2.4 in the spec - */ - int retryCounter; + /** Indicates which queue is acite. Depends on access category. */ + int currentAC; + + /** Remember currentAC. We need this to figure out internal colision. */ + int oldcurrentAC; + + /** XXX Remember for which AC we wait for ACK. */ + //int ACKcurrentAC; /** Physical radio (medium) state copied from physical layer */ RadioState::State radioState; + // Use to distinguish the radio module that send the event + int radioModule; + + int getRadioModuleId() {return radioModule;} - /** Messages received from upper layer and to be transmitted later */ - Ieee80211DataOrMgmtFrameList transmissionQueue; + Ieee80211DataOrMgmtFrame *fr; /** - * A list of last sender, sequence and fragment number tuples to identify - * duplicates, see spec 9.2.9. - * TODO: this is not yet used - */ + * A list of last sender, sequence and fragment number tuples to identify + * duplicates, see spec 9.2.9. + */ + bool duplicateDetect; + bool purgeOldTuples; + double duplicateTimeOut; + simtime_t lastTimeDelete; Ieee80211ASFTupleList asfTuplesList; /** Passive queue module to request messages from */ @@ -202,8 +382,14 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable /** End of the Data Inter-Frame Time period */ cMessage *endDIFS; + /** End of the Arbitration Inter-Frame Time period */ +// cMessage *endAIFS[4]; + + /** End of the TXOP time limit period */ + cMessage *endTXOP; + /** End of the backoff period */ - cMessage *endBackoff; + //cMessage *endBackoff[4]; /** Timeout after the transmission of an RTS, a CTS, or a DATA frame */ cMessage *endTimeout; @@ -218,16 +404,29 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable protected: /** @name Statistics */ //@{ - long numRetry; - long numSentWithoutRetry; - long numGivenUp; + // long numRetry[4]; + // long numSentWithoutRetry[4]; + // long numGivenUp[4]; long numCollision; - long numSent; + long numInternalCollision; + // long numSent[4]; + long numBites; + long numSentTXOP; long numReceived; long numSentMulticast; long numReceivedMulticast; - static simsignal_t stateSignal; - static simsignal_t radioStateSignal; + // long numDropped[4]; + long numReceivedOther; + long numAckSend; + cOutVector stateVector; + simtime_t last; + // long bites[4]; + // simtime_t minjitter[4]; + // simtime_t maxjitter[4]; + // cOutVector jitter[4]; + // cOutVector macDelay[4]; + cOutVector radioStateVector; + // cOutVector throughput[4]; //@} public: @@ -249,6 +448,10 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable virtual void initialize(int); virtual void registerInterface(); virtual void initializeQueueModule(); + virtual void finish(); + virtual void configureAutoBitRate(); + virtual void initWatches(); + virtual const MACAddress& isInterfaceRegistered(); //@} protected: @@ -279,15 +482,17 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable protected: /** * @name Timing functions - * @brief Calculate various timings based on transmission rate and physical layer characteristics. + * @brief Calculate various timings based on transmission rate and physical layer charactersitics. */ //@{ - virtual simtime_t getSIFS() const; - virtual simtime_t getSlotTime() const; - virtual simtime_t getDIFS() const; - virtual simtime_t getEIFS() const; - virtual simtime_t getPIFS() const; + virtual simtime_t getSIFS(); + virtual simtime_t getSlotTime(); + virtual simtime_t getDIFS(int category = -1); + virtual simtime_t getAIFS(int AccessCategory); + virtual simtime_t getEIFS(); + virtual simtime_t getPIFS(); virtual simtime_t computeBackoffPeriod(Ieee80211Frame *msg, int r); + virtual simtime_t getHeaderTime(double bitrate); //@} protected: @@ -301,6 +506,11 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable virtual void scheduleDIFSPeriod(); virtual void cancelDIFSPeriod(); + virtual void scheduleAIFSPeriod(); + virtual void rescheduleAIFSPeriod(int AccessCategory); + virtual void cancelAIFSPeriod(); +//XXX virtual void checkInternalColision(); + virtual void scheduleDataTimeoutPeriod(Ieee80211DataOrMgmtFrame *frame); virtual void scheduleMulticastTimeoutPeriod(Ieee80211DataOrMgmtFrame *frame); virtual void cancelTimeoutPeriod(); @@ -317,6 +527,7 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable virtual void decreaseBackoffPeriod(); virtual void scheduleBackoffPeriod(); virtual void cancelBackoffPeriod(); + virtual void finishReception(); //@} protected: @@ -351,7 +562,7 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable * basicBitrate not bitrate (e.g. 2Mbps instead of 11Mbps). Used with ACK, CTS, RTS. */ virtual Ieee80211Frame *setBasicBitrate(Ieee80211Frame *frame); - + virtual Ieee80211Frame *setBitrateFrame(Ieee80211Frame *frame); protected: /** * @name Utility functions @@ -360,8 +571,13 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable virtual void finishCurrentTransmission(); virtual void giveUpCurrentTransmission(); virtual void retryCurrentTransmission(); + virtual bool transmissionQueueEmpty(); + virtual unsigned int transmissionQueueSize(); + + /** @brief Mapping to access categories. */ + virtual int mappingAccessCategory(Ieee80211DataOrMgmtFrame *frame); - /** @brief Send down the change channel message to the physical layer if there is any. */ + /** @brief Send down the change channel message to the physical layer if there is any. */ virtual void sendDownPendingRadioConfigMsg(); /** @brief Change the current MAC operation mode. */ @@ -375,22 +591,28 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable /** @brief Used by the state machine to identify medium state change events. This message is currently optimized away and not sent through the kernel. */ - virtual bool isMediumStateChange(cMessage *msg) const; + virtual bool isMediumStateChange(cMessage *msg); /** @brief Tells if the medium is free according to the physical and virtual carrier sense algorithm. */ - virtual bool isMediumFree() const; + virtual bool isMediumFree(); /** @brief Returns true if message is a multicast message */ - virtual bool isMulticast(Ieee80211Frame *msg) const; + virtual bool isMulticast(Ieee80211Frame *msg); /** @brief Returns true if message destination address is ours */ - virtual bool isForUs(Ieee80211Frame *msg) const; + virtual bool isForUs(Ieee80211Frame *msg); + + /** @brief Returns true if message source address is ours */ + virtual bool isSentByUs(Ieee80211Frame *msg); /** @brief Checks if the frame is a data or management frame */ - virtual bool isDataOrMgmtFrame(Ieee80211Frame *frame) const; + virtual bool isDataOrMgmtFrame(Ieee80211Frame *frame); + + /** @brief Checks if the message is endAIFS and set currentAC */ + virtual bool isMsgAIFS(cMessage *msg); /** @brief Returns the last frame received before the SIFS period. */ - virtual Ieee80211Frame *getFrameReceivedBeforeSIFS() const; + virtual Ieee80211Frame *getFrameReceivedBeforeSIFS(); /** @brief Deletes frame at the front of queue. */ virtual void popTransmissionQueue(); @@ -407,8 +629,53 @@ class INET_API Ieee80211Mac : public WirelessMacBase, public INotifiable virtual void logState(); /** @brief Produce a readable name of the given MAC operation mode */ - const char *modeName(int mode); //@} + int getTimeout(void); + virtual int getMaxBitrate(void); + virtual int getMinBitrate(void); + + virtual void reportDataOk(void); + virtual void reportDataFailed(void); + + virtual int getMinTimerTimeout(void); + virtual int getMinSuccessThreshold(void); + + virtual int getTimerTimeout(void); + virtual int getSuccessThreshold(void); + + virtual void setTimerTimeout(int timer_timeout); + virtual void setSuccessThreshold(int success_threshold); + + virtual void reportRecoveryFailure(void); + virtual void reportFailure(void); + + virtual bool needRecoveryFallback(void); + virtual bool needNormalFallback(void); + + virtual double getBitrate(); + virtual void setBitrate(double b_rate); + + virtual void resetCurrentBackOff() + { + backoff() = true; + backoffPeriod() = -1; + } + + virtual bool isBackoffPending() + { + for (unsigned int i = 0; i. +// 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. // package inet.linklayer.ieee80211.mac; // -// Implementation of the 802.11b MAC protocol. This module is intended -// to be used in combination with the ~Ieee80211Radio module as the physical -// layer. (The ~SnrEval80211 and ~Decider80211 modules should also work if +// Implementation of the 802.11 MAC protocol. This module is intended +// to be used in combination with the Ieee80211Radio module as the physical +// layer. (The SnrEval80211 and Decider80211 modules should also work if // per-packet bitrate setting gets implemented.) // // Encapsulation/decapsulation must be done in the upper layers. (It is -// typically in the 802.11 management module, see in ~Ieee80211Nic). -// The base class for 802.11 frame messages is ~Ieee80211Frame, but this -// module expects ~Ieee80211DataOrMgmtFrame (a subclass) from upper layers +// typically in the 802.11 management module, see in Ieee80211Nic). +// The base class for 802.11 frame messages is Ieee80211Frame, but this +// module expects Ieee80211DataOrMgmtFrame (a subclass) from upper layers // (the management module). This module will assign the transmitter address // (address 2) and the frame sequence number/fragment number fields in the // frames; all other fields must already be filled when this module gets @@ -57,18 +59,62 @@ simple Ieee80211Mac string address = default("auto"); // MAC address as hex string (12 hex digits), or // "auto". "auto" values will be replaced by // a generated MAC address in init stage 0. - string queueModule = default(""); // name of optional external queue module - int maxQueueSize = default(14); // max queue length in frames; only used if queueModule=="" + string queueModule = default(""); // name of optional external queue module + int maxQueueSize = default(50); // max queue length in frames; only used if queueModule=="" + + bool EDCA = default(false); // enable Enhanced Distributed Channel Access (802.11e) + // parameters for EDCA = true + string classifier = default("Ieee80211eClassifier"); + int maxCategorieQueueSize = default(50); // Max queue length in frames per categorie; only used if queueModule=="" + int defaultAC = default(0); // the default AC category for frames that cannot be classified + int AIFSN0 = default(7); // AIFSN for background + int AIFSN1 = default(3); // AIFSN for best effort + int AIFSN2 = default(2); // AIFSN for video + int AIFSN3 = default(2); // AIFSN for voice + double TXOP0 @unit(s) = default(0s); + double TXOP1 @unit(s) = default(0s); + double TXOP2 @unit(s) = default(3.008ms); + double TXOP3 @unit(s) = default(1.504ms); + // parameters for EDCA = false + int AIFSN = default(2); // if there is only one AC (EDCA = false) + + bool useModulationParameters = default(false); // if true, slot time, DIFS, and ACK timeout (aPHY-RX-START-Delay) are function of modulation time (2007 standard) + bool prioritizeMulticast = default(false); // if true, prioritize multicast frames (9.3.2.1 Fundamental access) + double bitrate @unit("bps"); - double basicBitrate @unit("bps") = default(2000000bps); + string opMode @enum("b","g","a","p") = default("g"); + string wifiPreambleMode @enum("LONG","SHORT") = default("LONG"); // preamble mode; see IEEE 2007, 19.3.2 + + double basicBitrate @unit("bps") = default(2e6bps); + int mtu @unit("B") = default(1500B); + double slotTime @unit("s") = default(9us); int rtsThresholdBytes @unit("B") = default(2346B); // longer messages will be sent using RTS/CTS int retryLimit = default(-1); // maximum number of retries per message, -1 means default int cwMinData = default(-1); // contention window for normal data frames, -1 means default - int cwMinMulticast = default(-1); // contention window for multicast messages, -1 means default - int mtu @unit("B") = default(1500B); + int cwMaxData = default(-1); // contention window for normal data frames, -1 means default + int cwMinMulticast = default(-1); // contention window for broadcast messages, -1 means default + bool fixFSM = default(true); + + double phyHeaderLength = default(-1); // if -1, the MAC will compute it in function of the modulation type + bool forceBitRate = default(false); // if true, the MAC will force the bitrate to the physical layer + int autoBitrate @enum(0,1,2) = default(0); // 0 = constant bit rate (autobitrate algorithm disabled), 1 = ARF Rate, 2 = AARF Rate + // parameters used by the autobitrate + int minTimerTimeout = default(15); + int timerTimeout = default(minTimerTimeout); + int minSuccessThreshold = default(10); + int successThreshold = default(minSuccessThreshold); + int maxSuccessThreshold = default(60); + double successCoeff = default(2.0); + double timerCoeff = default(2.0); + // duplicate detection + bool duplicateDetectionFilter = default(true); // whether to detect and filter out duplicate frames + bool purgeOldTuples = default(true); // delete old tuples in the duplicate list + double duplicateTimeOut @unit("s") = default(20s); // timeout for the duplicate detection + // statistics + double throughputTimePeriod @unit("s") = default(0); // period of time used by throughput measurement statistic + bool multiMac = default(false); // allows multiples mac interfaces in the same link layer @display("i=block/layer"); - @statistic[state](title="state"; record=vector; interpolationmode=sample-hold); // ENUM!! - @statistic[radioState](title="radio state"; record=vector; interpolationmode=sample-hold); // ENUM!! + gates: input upperLayerIn @labels(Ieee80211Frame); output upperLayerOut @labels(Ieee80211Frame); diff --git a/src/linklayer/ieee80211/mac/Ieee80211NewMac.cc b/src/linklayer/ieee80211/mac/Ieee80211NewMac.cc deleted file mode 100644 index e98e583a3..000000000 --- a/src/linklayer/ieee80211/mac/Ieee80211NewMac.cc +++ /dev/null @@ -1,3036 +0,0 @@ -// -// Copyright (C) 2006 Andras Varga and Levente Meszaros -// Copyright (C) 2009 Lukáš Hlůže lukas@hluze.cz (802.11e) -// Copyright (C) 2011 Alfonso Ariza (clean code, fix some errors, new radio model) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program; if not, see . -// - -#include "Ieee80211NewMac.h" -#include "RadioState.h" -#include "IInterfaceTable.h" -#include "InterfaceTableAccess.h" -#include "PhyControlInfo_m.h" -#include "AirFrame_m.h" -#include "Radio80211aControlInfo_m.h" -#include "Ieee80211eClassifier.h" -#include "Ieee80211DataRate.h" - -// TODO: 9.3.2.1, If there are buffered multicast or broadcast frames, the PC shall transmit these prior to any unicast frames. -// TODO: control frames must send before - -Define_Module(Ieee80211NewMac); - -// don't forget to keep synchronized the C++ enum and the runtime enum definition -Register_Enum(Ieee80211NewMac, - (Ieee80211NewMac::IDLE, - Ieee80211NewMac::DEFER, - Ieee80211NewMac::WAITAIFS, - Ieee80211NewMac::BACKOFF, - Ieee80211NewMac::WAITACK, - Ieee80211NewMac::WAITMULTICAST, - Ieee80211NewMac::WAITCTS, - Ieee80211NewMac::WAITSIFS, - Ieee80211NewMac::RECEIVE)); - -// don't forget to keep synchronized the C++ enum and the runtime enum definition -Register_Enum(RadioState, - (RadioState::IDLE, - RadioState::RECV, - RadioState::TRANSMIT, - RadioState::SLEEP)); - -/**************************************************************** - * Construction functions. - */ - -Ieee80211NewMac::Ieee80211NewMac() -{ - endSIFS = NULL; - endDIFS = NULL; - endTimeout = NULL; - endReserve = NULL; - mediumStateChange = NULL; - pendingRadioConfigMsg = NULL; - classifier = NULL; -} - -Ieee80211NewMac::~Ieee80211NewMac() -{ - cancelAndDelete(endSIFS); - cancelAndDelete(endDIFS); - cancelAndDelete(endTimeout); - cancelAndDelete(endReserve); - cancelAndDelete(mediumStateChange); - cancelAndDelete(endTXOP); - for (unsigned int i = 0; i < edcCAF.size(); i++) - { - cancelAndDelete(endAIFS(i)); - cancelAndDelete(endBackoff(i)); - while (!transmissionQueue(i)->empty()) - { - Ieee80211Frame *temp = dynamic_cast (transmissionQueue(i)->front()); - transmissionQueue(i)->pop_front(); - delete temp; - } - } - edcCAF.clear(); - for (unsigned int i=0; i(createOne(classifierClass)); - numQueues = classifier->getNumQueues(); - } - - for (int i=0; icreateClassifier("Ieee80211MacQueueClassifier"); - if (numCategories()==1) - transmissionQueue(i)->setMaxSize(maxQueueSize); - else - transmissionQueue(i)->setMaxSize(maxCategorieQueueSize); - transmissionQueue(i)->setNumStrictPrioritiesQueue(3); // multicast and control - } - else - { - transmissionQueue(i)->createClassifier("Ieee80211MacQueueClassifier2"); - if (numCategories()==1) - transmissionQueue(i)->setMaxSize(maxQueueSize); - else - transmissionQueue(i)->setMaxSize(maxCategorieQueueSize); - transmissionQueue(i)->setNumStrictPrioritiesQueue(2); // multicast and control - - } - } -#endif - // the variable is renamed due to a confusion in the standard - // the name retry limit would be misleading, see the header file comment - transmissionLimit = par("retryLimit"); - if (transmissionLimit == -1) transmissionLimit = 7; - ASSERT(transmissionLimit >= 0); - - EV<<" retryLimit="<= 0 && cwMinData <= 32767); - - cwMaxData = par("cwMaxData"); - if (cwMaxData == -1) cwMaxData = CW_MAX; - ASSERT(cwMaxData >= 0 && cwMaxData <= 32767); - - cwMinMulticast = par("cwMinMulticast"); - if (cwMinMulticast == -1) cwMinMulticast = 31; - ASSERT(cwMinMulticast >= 0); - EV<<" cwMinMulticast="<(classifier)) - dynamic_cast(classifier)->setDefaultClass(defaultAC); - - for (int i=0; i= 0 && AIFSN(i) < 16); - if (i == 0 || i == 1) - { - cwMin(i) = cwMinData; - cwMax(i) = cwMaxData; - } - if (i == 2) - { - cwMin(i) = (cwMinData + 1) / 2 - 1; - cwMax(i) = cwMinData; - } - if (i == 3) - { - cwMin(i) = (cwMinData + 1) / 4 - 1; - cwMax(i) = (cwMinData + 1) / 2 - 1; - } - } - - ST = par("slotTime"); //added by sorin - if (ST==-1) - ST = 20e-6; //20us - EV<<" slotTime="<subscribe(this, NF_RADIOSTATE_CHANGED); - - // initialize self messages - endSIFS = new cMessage("SIFS"); - endDIFS = new cMessage("DIFS"); - for (int i=0; i0) - throughputTimer = new cMessage("throughput-timer"); - if (throughputTimer) - scheduleAt(simTime()+throughputTimePeriod, throughputTimer); - // end initialize variables throughput over a period of time - // initialize watches - validRecMode = false; - initWatches(); - radioModule = gate("lowerLayerOut")->getNextGate()->getOwnerModule()->getId(); - } -} - -void Ieee80211NewMac::initWatches() -{ -// initialize watches - WATCH(fsm); - WATCH(radioState); - for (int i=0; igetFullName()) + 1]; - char *d = interfaceName; - for (const char *s = getParentModule()->getFullName(); *s; s++) - if (isalnum(*s)) - *d++ = *s; - *d = '\0'; - - e->setName(interfaceName); - delete [] interfaceName; - - // address - e->setMACAddress(address); - e->setInterfaceToken(address.formInterfaceIdentifier()); - - // FIXME: MTU on 802.11 = ? - e->setMtu(par("mtu").longValue()); - - // capabilities - e->setBroadcast(true); - e->setMulticast(true); - e->setPointToPoint(false); - - // add - ift->addInterface(e); -} - -void Ieee80211NewMac::initializeQueueModule() -{ - // use of external queue module is optional -- find it if there's one specified - if (par("queueModule").stringValue()[0]) - { - cModule *module = getParentModule()->getSubmodule(par("queueModule").stringValue()); - queueModule = check_and_cast(module); - - EV << "Requesting first two frames from queue module\n"; - queueModule->requestPacket(); - // needed for backoff: mandatory if next message is already present - queueModule->requestPacket(); - } -} - -/**************************************************************** - * Message handling functions. - */ -void Ieee80211NewMac::handleSelfMsg(cMessage *msg) -{ - if (msg==throughputTimer) - { - throughputLastPeriod = recBytesOverPeriod/SIMTIME_DBL(throughputTimePeriod); - recBytesOverPeriod = 0; - scheduleAt(simTime()+throughputTimePeriod, throughputTimer); - return; - } - - EV << "received self message: " << msg << "(kind: " << msg->getKind() << ")" << endl; - - if (msg == endReserve) - nav = false; - - if (msg == endTXOP) - txop = false; - - if ( !strcmp(msg->getName(), "AIFS") || !strcmp(msg->getName(), "Backoff") ) - { - EV << "Changing currentAC to " << msg->getKind() << endl; - currentAC = msg->getKind(); - } - //check internal colision - if ((strcmp(msg->getName(), "Backoff") == 0) || (strcmp(msg->getName(), "AIFS")==0)) - { - int kind; - kind = msg->getKind(); - if (kind<0) - kind = 0; - EV <<" kind is " << kind << ",name is " << msg->getName() < kind; i--) //mozna prochaze jen 3..kind XXX - { - if (((endBackoff(i)->isScheduled() && endBackoff(i)->getArrivalTime() == simTime()) - || (endAIFS(i)->isScheduled() && !backoff(i) && endAIFS(i)->getArrivalTime() == simTime())) - && !transmissionQueue(i)->empty()) - { - EV << "Internal collision AC" << kind << " with AC" << i << endl; - numInternalCollision++; - EV << "Cancel backoff event and schedule new one for AC" << kind << endl; - cancelEvent(endBackoff(kind)); - if (retryCounter() == transmissionLimit - 1) - { - EV << "give up transmission for AC" << currentAC << endl; - giveUpCurrentTransmission(); - } - else - { - EV << "retry transmission for AC" << currentAC << endl; - retryCurrentTransmission(); - } - return; - } - } - currentAC = kind; - } - handleWithFSM(msg); -} - - -void Ieee80211NewMac::handleUpperMsg(cPacket *msg) -{ - if (queueModule && numCategories()>1 && (int)transmissionQueueSize() < maxQueueSize) - { - // the module are continuously asking for packets, except if the queue is full - EV << "requesting another frame from queue module\n"; - queueModule->requestPacket(); - } - - // check if it's a command from the mgmt layer - if (msg->getBitLength()==0 && msg->getKind()!=0) - { - handleCommand(msg); - return; - } - - // must be a Ieee80211DataOrMgmtFrame, within the max size because we don't support fragmentation - Ieee80211DataOrMgmtFrame *frame = check_and_cast(msg); - if (frame->getByteLength() > fragmentationThreshold) - error("message from higher layer (%s)%s is too long for 802.11b, %d bytes (fragmentation is not supported yet)", - msg->getClassName(), msg->getName(), (int)(msg->getByteLength())); - EV << "frame " << frame << " received from higher layer, receiver = " << frame->getReceiverAddress() << endl; - - // if you get error from this assert check if is client associated to AP - ASSERT(!frame->getReceiverAddress().isUnspecified()); - - // fill in missing fields (receiver address, seq number), and insert into the queue - frame->setTransmitterAddress(address); - frame->setSequenceNumber(sequenceNumber); - sequenceNumber = (sequenceNumber+1) % 4096; //XXX seqNum must be checked upon reception of frames! - - if (mappingAccessCategory(frame) == 200) - { - // if function mappingAccessCategory() returns 200, it means transsmissionQueue is full - return; - } - frame->setMACArrive(simTime()); - handleWithFSM(frame); -} - -#ifdef USEMULTIQUEUE -int Ieee80211NewMac::mappingAccessCategory(Ieee80211DataOrMgmtFrame *frame) -{ - bool isDataFrame = (dynamic_cast(frame) != NULL); - - currentAC = classifier ? classifier->classifyPacket(frame) : 0; - // check for queue overflow - if (isDataFrame && maxCategorieQueueSize && (int)transmissionQueue()->size() >= maxCategorieQueueSize) - { - EV << "message " << frame << " received from higher layer but AC queue is full, dropping message\n"; - numDropped()++; - delete frame; - return 200; - } - - if (isDataFrame && maxQueueSize && (int)transmissionQueueSize() >= maxQueueSize) - { - EV << "message " << frame << " received from higher layer but AC queue is full, dropping message\n"; - numDropped()++; - delete frame; - return 200; - } - transmissionQueue()->push_back(frame); - EV << "frame classified as access category "<< currentAC <<" (0 background, 1 best effort, 2 video, 3 voice)\n"; - return true; -} - -#else - -int Ieee80211NewMac::mappingAccessCategory(Ieee80211DataOrMgmtFrame *frame) -{ - bool isDataFrame = (dynamic_cast(frame) != NULL); - - currentAC = classifier ? classifier->classifyPacket(frame) : 0; - // check for queue overflow - if (isDataFrame && maxCategorieQueueSize && (int)transmissionQueue()->size() >= maxCategorieQueueSize) - { - EV << "message " << frame << " received from higher layer but AC queue is full, dropping message\n"; - numDropped()++; - delete frame; - return 200; - } - - if (isDataFrame && maxQueueSize && (int)transmissionQueueSize() >= maxQueueSize) - { - EV << "message " << frame << " received from higher layer but AC queue is full, dropping message\n"; - numDropped()++; - delete frame; - return 200; - } - if (isDataFrame) - { - if (!prioritizeMulticast || !frame->getReceiverAddress().isMulticast() || transmissionQueue()->size() < 2) - transmissionQueue()->push_back(frame); - else - { - // if the last frame is management insert here - Ieee80211DataFrame * frameAux = dynamic_cast(transmissionQueue()->back()); - if ((frameAux == NULL) || (frameAux && frameAux->getReceiverAddress().isMulticast())) - transmissionQueue()->push_back(frame); - else - { - // in other case search the possition - std::list::iterator p = transmissionQueue()->end(); - while ((*p)->getReceiverAddress().isMulticast() && (p != transmissionQueue()->begin())) // search the first broadcast frame - { - if (dynamic_cast(*p) == NULL) - break; - p--; - } - p++; - transmissionQueue()->insert(p, frame); - } - } - } - else - { - if (transmissionQueue()->empty() || transmissionQueue()->size() == 1) - { - transmissionQueue()->push_back(frame); - } - else - { - std::list::iterator p; - //we don't know if first frame in the queue is in middle of transmission - //so for sure we placed it on second place - p = transmissionQueue()->begin(); - p++; - while ((dynamic_cast (*p) == NULL) && (p != transmissionQueue()->end())) // search the first not management frame - p++; - transmissionQueue()->insert(p, frame); - } - } - EV << "frame classified as access category "<< currentAC <<" (0 background, 1 best effort, 2 video, 3 voice)\n"; - return true; -} -#endif - -void Ieee80211NewMac::handleCommand(cMessage *msg) -{ - if (msg->getKind()==PHY_C_CONFIGURERADIO) - { - EV << "Passing on command " << msg->getName() << " to physical layer\n"; - if (pendingRadioConfigMsg != NULL) - { - // merge contents of the old command into the new one, then delete it - PhyControlInfo *pOld = check_and_cast(pendingRadioConfigMsg->getControlInfo()); - PhyControlInfo *pNew = check_and_cast(msg->getControlInfo()); - if (pNew->getChannelNumber()==-1 && pOld->getChannelNumber()!=-1) - pNew->setChannelNumber(pOld->getChannelNumber()); - if (pNew->getBitrate()==-1 && pOld->getBitrate()!=-1) - pNew->setBitrate(pOld->getBitrate()); - delete pendingRadioConfigMsg; - pendingRadioConfigMsg = NULL; - } - - if (fsm.getState() == IDLE || fsm.getState() == DEFER || fsm.getState() == BACKOFF) - { - EV << "Sending it down immediately\n"; -/* -// Dynamic power - PhyControlInfo *phyControlInfo = dynamic_cast(msg->getControlInfo()); - if (phyControlInfo) - phyControlInfo->setAdaptiveSensitivity(true); -// end dynamic power -*/ - sendDown(msg); - } - else - { - EV << "Delaying " << msg->getName() << " until next IDLE or DEFER state\n"; - pendingRadioConfigMsg = msg; - } - } - else - { - error("Unrecognized command from mgmt layer: (%s)%s msgkind=%d", msg->getClassName(), msg->getName(), msg->getKind()); - } -} - -void Ieee80211NewMac::handleLowerMsg(cPacket *msg) -{ - EV<<"->Enter handleLowerMsg...\n"; - EV << "received message from lower layer: " << msg << endl; - Radio80211aControlInfo * cinfo = dynamic_cast(msg->getControlInfo()); - if (cinfo && cinfo->getAirtimeMetric()) - { - double rtsTime = 0; - if (rtsThreshold*8getTestFrameSize()) - rtsTime= computeFrameDuration(LENGTH_CTS, basicBitrate) +computeFrameDuration(LENGTH_RTS, basicBitrate); - double frameDuration = cinfo->getTestFrameDuration() + computeFrameDuration(LENGTH_ACK, basicBitrate)+rtsTime; - cinfo->setTestFrameDuration(frameDuration); - } - nb->fireChangeNotification(NF_LINK_FULL_PROMISCUOUS, msg); - validRecMode = false; - if (msg->getControlInfo() && dynamic_cast(msg->getControlInfo())) - { - Radio80211aControlInfo *cinfo = dynamic_cast(msg->getControlInfo()); - recFrameModulationType = cinfo->getModulationType(); - if (recFrameModulationType.getDataRate()>0) - validRecMode = true; - } - - if (rateControlMode == RATE_CR) - { - if (msg->getControlInfo()) - delete msg->removeControlInfo(); - } - - Ieee80211Frame *frame = dynamic_cast(msg); - - if (msg->getControlInfo() && dynamic_cast(msg->getControlInfo())) - { - Radio80211aControlInfo *cinfo = (Radio80211aControlInfo*) msg->removeControlInfo(); - if (contJ%10==0) - { - snr = _snr; - contJ = 0; - _snr = 0; - } - contJ++; - _snr += cinfo->getSnr()/10; - lossRate = cinfo->getLossRate(); - delete cinfo; - } - - if (contI%samplingCoeff==0) - { - contI = 0; - recvdThroughput = 0; - } - contI++; - - frame = dynamic_cast(msg); - if (timeStampLastMessageReceived == 0) - timeStampLastMessageReceived = simTime(); - else - { - if (frame) - recvdThroughput += ((frame->getBitLength()/(simTime()-timeStampLastMessageReceived))/1000000)/samplingCoeff; - timeStampLastMessageReceived = simTime(); - } - if (frame && throughputTimer) - recBytesOverPeriod += frame->getByteLength(); - - - if (!frame) - { - EV << "message from physical layer (%s)%s is not a subclass of Ieee80211Frame" << msg->getClassName() << " " << msg->getName() << endl; - delete msg; - return; - // error("message from physical layer (%s)%s is not a subclass of Ieee80211Frame",msg->getClassName(), msg->getName()); - } - - EV << "Self address: " << address - << ", receiver address: " << frame->getReceiverAddress() - << ", received frame is for us: " << isForUs(frame) - << ", received frame was sent by us: " << isSentByUs(frame)<(msg); - ASSERT(!twoAddressFrame || twoAddressFrame->getTransmitterAddress() != address); - -#ifdef LWMPLS - int msgKind = msg->getKind(); - if (msgKind != COLLISION && msgKind != BITERROR && twoAddressFrame!=NULL) - nb->fireChangeNotification(NF_LINK_REFRESH, twoAddressFrame); -#endif - - handleWithFSM(msg); - - // if we are the owner then we did not send this message up - if (msg->getOwner() == this) - delete msg; - EV<<"Leave handleLowerMsg...\n"; -} - -void Ieee80211NewMac::receiveChangeNotification(int category, const cObject *details) -{ - Enter_Method_Silent(); - printNotificationBanner(category, details); - - if (category == NF_RADIOSTATE_CHANGED) - { - RadioState * rstate = check_and_cast(details); - if (rstate->getRadioId()!=getRadioModuleId()) - return; - - RadioState::State newRadioState = rstate->getState(); - - - - // FIXME: double recording, because there's no sample hold in the gui - radioStateVector.record(radioState); - radioStateVector.record(newRadioState); - - radioState = newRadioState; - - handleWithFSM(mediumStateChange); - } -} - -/** - * Msg can be upper, lower, self or NULL (when radio state changes) - */ -void Ieee80211NewMac::handleWithFSM(cMessage *msg) -{ - removeOldTuplesFromDuplicateMap(); - // skip those cases where there's nothing to do, so the switch looks simpler - if (isUpperMsg(msg) && fsm.getState() != IDLE) - { - if (fsm.getState() == WAITAIFS && endDIFS->isScheduled()) - { - // a difs was schedule because all queues ware empty - // change difs for aifs - simtime_t remaint = getAIFS(currentAC)-getDIFS(); - scheduleAt(endDIFS->getArrivalTime()+remaint, endAIFS(currentAC)); - cancelEvent(endDIFS); - } - else if (fsm.getState() == BACKOFF && endBackoff(numCategories()-1)->isScheduled() && transmissionQueue(numCategories()-1)->empty()) - { - // a backoff was schedule with all the queues empty - // reschedule the backoff with the appropriate AC - backoffPeriod(currentAC) = backoffPeriod(numCategories()-1); - backoff(currentAC) = backoff(numCategories()-1); - backoff(numCategories()-1) = false; - scheduleAt(endBackoff(numCategories()-1)->getArrivalTime(), endBackoff(currentAC)); - cancelEvent(endBackoff(numCategories()-1)); - } - EV << "deferring upper message transmission in " << fsm.getStateName() << " state\n"; - return; - } - - Ieee80211Frame *frame = dynamic_cast(msg); - int frameType = frame ? frame->getType() : -1; - int msgKind = msg->getKind(); - logState(); - stateVector.record(fsm.getState()); - - if (frame && isLowerMsg(frame)) - { - lastReceiveFailed = (msgKind == COLLISION || msgKind == BITERROR); - scheduleReservePeriod(frame); - } - - // TODO: fix bug according to the message: [omnetpp] A possible bug in the Ieee80211's FSM. - FSMA_Switch(fsm) - { - FSMA_State(IDLE) - { - FSMA_Enter(sendDownPendingRadioConfigMsg()); - /* - if (fixFSM) - { - FSMA_Event_Transition(Data-Ready, - // isUpperMsg(msg), - isUpperMsg(msg) && backoffPeriod[currentAC] > 0, - DEFER, - //ASSERT(isInvalidBackoffPeriod() || backoffPeriod == 0); - //invalidateBackoffPeriod(); - ASSERT(false); - - ); - FSMA_No_Event_Transition(Immediate-Data-Ready, - //!transmissionQueue.empty(), - !transmissionQueueEmpty(), - DEFER, - // invalidateBackoffPeriod(); - ASSERT(backoff[currentAC]); - - ); - } - */ - FSMA_Event_Transition(Data-Ready, - isUpperMsg(msg), - DEFER, - ASSERT(isInvalidBackoffPeriod() || backoffPeriod() == 0); - invalidateBackoffPeriod(); - ); - FSMA_No_Event_Transition(Immediate-Data-Ready, - !transmissionQueueEmpty(), - DEFER, - if (retryCounter() == 0) // jesjones patch. TODO: check this particular case, I haven't been sure about this particular case - invalidateBackoffPeriod(); - ); - FSMA_Event_Transition(Receive, - isLowerMsg(msg), - RECEIVE, - ); - } - FSMA_State(DEFER) - { - FSMA_Enter(sendDownPendingRadioConfigMsg()); - FSMA_Event_Transition(Wait-AIFS, - isMediumStateChange(msg) && isMediumFree(), - WAITAIFS, - ;); - FSMA_No_Event_Transition(Immediate-Wait-AIFS, - isMediumFree() || (!isBackoffPending()), - WAITAIFS, - ;); - FSMA_Event_Transition(Receive, - isLowerMsg(msg), - RECEIVE, - ;); - } - FSMA_State(WAITAIFS) - { - FSMA_Enter(scheduleAIFSPeriod()); - - FSMA_Event_Transition(EDCAF-Do-Nothing, - isMsgAIFS(msg) && transmissionQueue()->empty(), - WAITAIFS, - ASSERT(0==1); - ;); - FSMA_Event_Transition(Immediate-Transmit-RTS, - isMsgAIFS(msg) && !transmissionQueue()->empty() && !isMulticast(getCurrentTransmission()) - && getCurrentTransmission()->getByteLength() >= rtsThreshold && !backoff(), - WAITCTS, - sendRTSFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - cancelAIFSPeriod(); - ); - FSMA_Event_Transition(Immediate-Transmit-Multicast, - isMsgAIFS(msg) && isMulticast(getCurrentTransmission()) && !backoff(), - WAITMULTICAST, - sendMulticastFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - cancelAIFSPeriod(); - ); - FSMA_Event_Transition(Immediate-Transmit-Data, - isMsgAIFS(msg) && !isMulticast(getCurrentTransmission()) && !backoff(), - WAITACK, - sendDataFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - cancelAIFSPeriod(); - ); - /*FSMA_Event_Transition(AIFS-Over, - isMsgAIFS(msg) && backoff[currentAC], - BACKOFF, - if (isInvalidBackoffPeriod()) - generateBackoffPeriod(); - );*/ - FSMA_Event_Transition(AIFS-Over, - isMsgAIFS(msg), - BACKOFF, - if (isInvalidBackoffPeriod()) - generateBackoffPeriod(); - ); - // end the difs and no other packet has been received - FSMA_Event_Transition(DIFS-Over, - msg == endDIFS && transmissionQueueEmpty(), - BACKOFF, - currentAC = numCategories()-1; - if (isInvalidBackoffPeriod()) - generateBackoffPeriod(); - ); - FSMA_Event_Transition(DIFS-Over, - msg == endDIFS, - BACKOFF, - for (int i=numCategories()-1; i>=0; i--) - { - if (!transmissionQueue(i)->empty()) - { - currentAC = i; - } - } - if (isInvalidBackoffPeriod()) - generateBackoffPeriod(); - ); - FSMA_Event_Transition(Busy, - isMediumStateChange(msg) && !isMediumFree(), - DEFER, - for (int i=0; iisScheduled()) - backoff(i) = true; - } - if (endDIFS->isScheduled()) backoff(numCategories()-1) = true; - cancelAIFSPeriod(); - ); - FSMA_No_Event_Transition(Immediate-Busy, - !isMediumFree(), - DEFER, - for (int i=0; iisScheduled()) - backoff(i) = true; - } - if (endDIFS->isScheduled()) backoff(numCategories()-1) = true; - cancelAIFSPeriod(); - - ); - // radio state changes before we actually get the message, so this must be here - FSMA_Event_Transition(Receive, - isLowerMsg(msg), - RECEIVE, - cancelAIFSPeriod(); - ;); - } - FSMA_State(BACKOFF) - { - FSMA_Enter(scheduleBackoffPeriod()); - if (getCurrentTransmission()) - { - FSMA_Event_Transition(Transmit-RTS, - msg == endBackoff() && !isMulticast(getCurrentTransmission()) - && getCurrentTransmission()->getByteLength() >= rtsThreshold, - WAITCTS, - sendRTSFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - cancelAIFSPeriod(); - decreaseBackoffPeriod(); - cancelBackoffPeriod(); - ); - FSMA_Event_Transition(Transmit-Multicast, - msg == endBackoff() && isMulticast(getCurrentTransmission()), - WAITMULTICAST, - sendMulticastFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - cancelAIFSPeriod(); - decreaseBackoffPeriod(); - cancelBackoffPeriod(); - ); - FSMA_Event_Transition(Transmit-Data, - msg == endBackoff() && !isMulticast(getCurrentTransmission()), - WAITACK, - sendDataFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - cancelAIFSPeriod(); - decreaseBackoffPeriod(); - cancelBackoffPeriod(); - ); - } - FSMA_Event_Transition(AIFS-Over-backoff, - isMsgAIFS(msg) && backoff(), - BACKOFF, - if (isInvalidBackoffPeriod()) - generateBackoffPeriod(); - ); - FSMA_Event_Transition(AIFS-Immediate-Transmit-RTS, - isMsgAIFS(msg) && !transmissionQueue()->empty() && !isMulticast(getCurrentTransmission()) - && getCurrentTransmission()->getByteLength() >= rtsThreshold && !backoff(), - WAITCTS, - sendRTSFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - cancelAIFSPeriod(); - decreaseBackoffPeriod(); - cancelBackoffPeriod(); - ); - FSMA_Event_Transition(AIFS-Immediate-Transmit-Multicast, - isMsgAIFS(msg) && isMulticast(getCurrentTransmission()) && !backoff(), - WAITMULTICAST, - sendMulticastFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - cancelAIFSPeriod(); - decreaseBackoffPeriod(); - cancelBackoffPeriod(); - ); - FSMA_Event_Transition(AIFS-Immediate-Transmit-Data, - isMsgAIFS(msg) && !isMulticast(getCurrentTransmission()) && !backoff(), - WAITACK, - sendDataFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - cancelAIFSPeriod(); - decreaseBackoffPeriod(); - cancelBackoffPeriod(); - ); - FSMA_Event_Transition(Backoff-Idle, - isBakoffMsg(msg) && transmissionQueueEmpty(), - IDLE, - resetStateVariables(); - ); - FSMA_Event_Transition(Backoff-Busy, - isMediumStateChange(msg) && !isMediumFree(), - DEFER, - cancelAIFSPeriod(); - decreaseBackoffPeriod(); - cancelBackoffPeriod(); - ); - - } - FSMA_State(WAITACK) - { - FSMA_Enter(scheduleDataTimeoutPeriod(getCurrentTransmission())); - FSMA_Event_Transition(Receive-ACK-TXOP, - isLowerMsg(msg) && isForUs(frame) && frameType == ST_ACK && txop, - WAITSIFS, - currentAC = oldcurrentAC; - if (retryCounter() == 0) numSentWithoutRetry()++; - numSent()++; - fr = getCurrentTransmission(); - numBites += fr->getBitLength(); - bites() += fr->getBitLength(); - - - macDelay()->record(simTime() - fr->getMACArrive()); - if (maxjitter() == 0 || maxjitter() < (simTime() - fr->getMACArrive())) - maxjitter() = simTime() - fr->getMACArrive(); - if (minjitter() == 0 || minjitter() > (simTime() - fr->getMACArrive())) - minjitter() = simTime() - fr->getMACArrive(); - EV << "record macDelay AC" << currentAC << " value " << simTime() - fr->getMACArrive() <getBitLength(); - bites[currentAC] += fr->getBitLength(); - - macDelay[currentAC].record(simTime() - fr->getMACArrive()); - if (maxjitter[currentAC] == 0 || maxjitter[currentAC] < (simTime() - fr->getMACArrive())) maxjitter[currentAC]=simTime() - fr->getMACArrive(); - if (minjitter[currentAC] == 0 || minjitter[currentAC] > (simTime() - fr->getMACArrive())) minjitter[currentAC]=simTime() - fr->getMACArrive(); - EV << "record macDelay AC" << currentAC << " value " << simTime() - fr->getMACArrive() <getBitLength(); - bites() += fr->getBitLength(); - - macDelay()->record(simTime() - fr->getMACArrive()); - if (maxjitter() == 0 || maxjitter() < (simTime() - fr->getMACArrive())) - maxjitter() = simTime() - fr->getMACArrive(); - if (minjitter() == 0 || minjitter() > (simTime() - fr->getMACArrive())) - minjitter() = simTime() - fr->getMACArrive(); - EV << "record macDelay AC" << currentAC << " value " << simTime() - fr->getMACArrive() <isScheduled()) cancelEvent(endTXOP); - ); - FSMA_Event_Transition(Receive-ACK-Timeout, - msg == endTimeout, - DEFER, - currentAC = oldcurrentAC; - retryCurrentTransmission(); - txop = false; - if (endTXOP->isScheduled()) cancelEvent(endTXOP); - ); - FSMA_Event_Transition(Interrupted-ACK-Failure, - isLowerMsg(msg) && retryCounter(oldcurrentAC) == transmissionLimit - 1, - RECEIVE, - currentAC=oldcurrentAC; - giveUpCurrentTransmission(); - txop = false; - if (endTXOP->isScheduled()) cancelEvent(endTXOP); - ); - FSMA_Event_Transition(Retry-Interrupted-ACK, - isLowerMsg(msg), - RECEIVE, - currentAC=oldcurrentAC; - retryCurrentTransmission(); - txop = false; - if (endTXOP->isScheduled()) cancelEvent(endTXOP); - ); - } - // wait until multicast is sent - FSMA_State(WAITMULTICAST) - { - FSMA_Enter(scheduleMulticastTimeoutPeriod(getCurrentTransmission())); - /* - FSMA_Event_Transition(Transmit-Multicast, - msg == endTimeout, - IDLE, - currentAC=oldcurrentAC; - finishCurrentTransmission(); - numSentMulticast++; - ); - */ - ///changed - FSMA_Event_Transition(Transmit-Multicast, - msg == endTimeout, - DEFER, - currentAC = oldcurrentAC; - fr = getCurrentTransmission(); - numBites += fr->getBitLength(); - bites() += fr->getBitLength(); - finishCurrentTransmission(); - numSentMulticast++; - resetCurrentBackOff(); - ); - } - // accoriding to 9.2.5.7 CTS procedure - FSMA_State(WAITCTS) - { - FSMA_Enter(scheduleCTSTimeoutPeriod()); - FSMA_Event_Transition(Receive-CTS, - isLowerMsg(msg) && isForUs(frame) && frameType == ST_CTS, - WAITSIFS, - cancelTimeoutPeriod(); - ); - FSMA_Event_Transition(Transmit-RTS-Failed, - msg == endTimeout && retryCounter(oldcurrentAC) == transmissionLimit - 1, - IDLE, - currentAC = oldcurrentAC; - giveUpCurrentTransmission(); - ); - FSMA_Event_Transition(Receive-CTS-Timeout, - msg == endTimeout, - DEFER, - currentAC = oldcurrentAC; - retryCurrentTransmission(); - ); - } - FSMA_State(WAITSIFS) - { - FSMA_Enter(scheduleSIFSPeriod(frame)); - FSMA_Event_Transition(Transmit-Data-TXOP, - msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_ACK, - WAITACK, - sendDataFrame(getCurrentTransmission()); - oldcurrentAC = currentAC; - ); - FSMA_Event_Transition(Transmit-CTS, - msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_RTS, - IDLE, - sendCTSFrameOnEndSIFS(); - if (fixFSM) - finishReception(); - else - resetStateVariables(); - ); - FSMA_Event_Transition(Transmit-DATA, - msg == endSIFS && getFrameReceivedBeforeSIFS()->getType() == ST_CTS, - WAITACK, - sendDataFrameOnEndSIFS(getCurrentTransmission()); - oldcurrentAC = currentAC; - ); - FSMA_Event_Transition(Transmit-ACK, - msg == endSIFS && isDataOrMgmtFrame(getFrameReceivedBeforeSIFS()), - IDLE, - sendACKFrameOnEndSIFS(); - if (fixFSM) - finishReception(); - else - resetStateVariables(); - ); - } - // this is not a real state - FSMA_State(RECEIVE) - { - FSMA_No_Event_Transition(Immediate-Receive-Error, - isLowerMsg(msg) && (msgKind == COLLISION || msgKind == BITERROR), - IDLE, - EV << "received frame contains bit errors or collision, next wait period is EIFS\n"; - numCollision++; - if (fixFSM) - finishReception(); - else - resetStateVariables(); - ); - FSMA_No_Event_Transition(Immediate-Receive-Multicast, - isLowerMsg(msg) && isMulticast(frame) && !isSentByUs(frame) && isDataOrMgmtFrame(frame), - IDLE, - sendUp(frame); - numReceivedMulticast++; - if (fixFSM) - finishReception(); - else - resetStateVariables(); - ); - FSMA_No_Event_Transition(Immediate-Receive-Data, - isLowerMsg(msg) && isForUs(frame) && isDataOrMgmtFrame(frame), - WAITSIFS, - sendUp(frame); - numReceived++; - ); - FSMA_No_Event_Transition(Immediate-Receive-RTS, - isLowerMsg(msg) && isForUs(frame) && frameType == ST_RTS, - WAITSIFS, - ); - FSMA_No_Event_Transition(Immediate-Receive-Other-backtobackoff, - isLowerMsg(msg) && isBackoffPending(), //(backoff[0] || backoff[1] || backoff[2] || backoff[3]), - DEFER, - ); - - FSMA_No_Event_Transition(Immediate-Promiscuous-Data, - isLowerMsg(msg) && !isForUs(frame) && isDataOrMgmtFrame(frame), - IDLE, - nb->fireChangeNotification(NF_LINK_PROMISCUOUS, frame); - if (fixFSM) - finishReception(); - else - resetStateVariables(); - numReceivedOther++; - ); - FSMA_No_Event_Transition(Immediate-Receive-Other, - isLowerMsg(msg), - IDLE, - if (fixFSM) - finishReception(); - else - resetStateVariables(); - numReceivedOther++; - ); - } - } - EV<<"leaving handleWithFSM\n\t"; - logState(); - stateVector.record(fsm.getState()); - if (simTime() - last > 0.1) - { - for (int i = 0; irecord(bites(i)/(simTime()-last)); - bites(i) = 0; - if (maxjitter(i) > 0 && minjitter(i) > 0) - { - jitter(i)->record(maxjitter(i)-minjitter(i)); - maxjitter(i) = 0; - minjitter(i) = 0; - } - } - last = simTime(); - } -} - -void Ieee80211NewMac::finishReception() -{ - if (getCurrentTransmission()) - { - backoff() = true; - } - else - { - resetStateVariables(); - } -} - - -/**************************************************************** - * Timing functions. - */ -simtime_t Ieee80211NewMac::getSIFS() -{ -// TODO: return aRxRFDelay() + aRxPLCPDelay() + aMACProcessingDelay() + aRxTxTurnaroundTime(); - if (useModulationParameters) - { - ModulationType modType; - if ((opMode=='b') || (opMode=='g')) - modType = WifiModulationType::getMode80211g(bitrate); - else if (opMode=='a') - modType = WifiModulationType::getMode80211a(bitrate); - else if (opMode=='p') - modType = WifiModulationType::getMode80211p(bitrate); - else - opp_error("mode not supported"); - return WifiModulationType::getSifsTime(modType,wifiPreambleType); - } - - return SIFS; -} - -simtime_t Ieee80211NewMac::getSlotTime() -{ -// TODO: return aCCATime() + aRxTxTurnaroundTime + aAirPropagationTime() + aMACProcessingDelay(); - if (useModulationParameters) - { - ModulationType modType; - if ((opMode=='b') || (opMode=='g')) - modType = WifiModulationType::getMode80211g(bitrate); - else if (opMode=='a') - modType = WifiModulationType::getMode80211a(bitrate); - else if (opMode=='p') - modType = WifiModulationType::getMode80211p(bitrate); - else - opp_error("mode not supported"); - return WifiModulationType::getSlotDuration(modType,wifiPreambleType); - } - return ST; -} - -simtime_t Ieee80211NewMac::getPIFS() -{ - return getSIFS() + getSlotTime(); -} - -simtime_t Ieee80211NewMac::getDIFS(int category) -{ - if (category<0 || category>(numCategories()-1)) - { - int index = numCategories()-1; - if (index<0) - index = 0; - return getSIFS() + ((double)AIFSN(index) * getSlotTime()); - } - else - { - return getSIFS() + ((double)AIFSN(category)) * getSlotTime(); - } - -} - -simtime_t Ieee80211NewMac::getHeaderTime(double bitrate) -{ - ModulationType modType; - if ((opMode=='b') || (opMode=='g')) - modType = WifiModulationType::getMode80211g(bitrate); - else if (opMode=='a') - modType = WifiModulationType::getMode80211a(bitrate); - else if (opMode=='p') - modType = WifiModulationType::getMode80211p(bitrate); - else - opp_error("mode not supported"); - return WifiModulationType::getPreambleAndHeader(modType, wifiPreambleType); -} - -simtime_t Ieee80211NewMac::getAIFS(int AccessCategory) -{ - return AIFSN(AccessCategory) * getSlotTime() + getSIFS(); -} - -simtime_t Ieee80211NewMac::getEIFS() -{ -// FIXME: return getSIFS() + getDIFS() + (8 * ACKSize + aPreambleLength + aPLCPHeaderLength) / lowestDatarate; - if (PHY_HEADER_LENGTH<0) - { - if ((opMode=='b') || (opMode=='g')) - return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 1E+6 + getHeaderTime(1E+6); - else if (opMode=='a') - return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 6E+6 + getHeaderTime(6E+6); - else if (opMode=='p') - return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 6E+6 + getHeaderTime(3E+6); - } - else - { - // FIXME: check how PHY_HEADER_LENGTH is handled. Is that given in bytes or secs ??? - // what is the rela unit? The use seems to be incosistent betwen b and g modes. - if (opMode=='b') - return getSIFS() + getDIFS() + (8 * LENGTH_ACK + PHY_HEADER_LENGTH) / 1E+6; - else if (opMode=='g') - return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 1E+6 + PHY_HEADER_LENGTH; - else if (opMode=='a') - return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 6E+6 + PHY_HEADER_LENGTH; - else if (opMode=='p') - return getSIFS() + getDIFS() + (8 * LENGTH_ACK) / 3E+6 + PHY_HEADER_LENGTH; - } - // if arrive here there is an error - opp_error("mode not supported"); - return 0; -} - -simtime_t Ieee80211NewMac::computeBackoffPeriod(Ieee80211Frame *msg, int r) -{ - int cw; - - EV << "generating backoff slot number for retry: " << r << endl; - if (msg && isMulticast(msg)) - cw = cwMinMulticast; - else - { - ASSERT(0 <= r && r < transmissionLimit); - - cw = (cwMin() + 1) * (1 << r) - 1; - - if (cw > cwMax()) - cw = cwMax(); - } - - int c = intrand(cw + 1); - - EV << "generated backoff slot number: " << c << " , cw: " << cw << " ,cwMin:cwMax = " << cwMin() << ":" << cwMax() << endl; - - return ((double)c) * getSlotTime(); -} - -/**************************************************************** - * Timer functions. - */ -void Ieee80211NewMac::scheduleSIFSPeriod(Ieee80211Frame *frame) -{ - EV << "scheduling SIFS period\n"; - endSIFS->setContextPointer(frame->dup()); - scheduleAt(simTime() + getSIFS(), endSIFS); -} - -void Ieee80211NewMac::scheduleDIFSPeriod() -{ - if (lastReceiveFailed) - { - EV << "reception of last frame failed, scheduling EIFS period\n"; - scheduleAt(simTime() + getEIFS(), endDIFS); - } - else - { - EV << "scheduling DIFS period\n"; - scheduleAt(simTime() + getDIFS(), endDIFS); - } -} - -void Ieee80211NewMac::cancelDIFSPeriod() -{ - EV << "canceling DIFS period\n"; - cancelEvent(endDIFS); -} - -void Ieee80211NewMac::scheduleAIFSPeriod() -{ - bool schedule = false; - for (int i = 0; iisScheduled() && !transmissionQueue(i)->empty()) - { - - if (lastReceiveFailed) - { - EV << "reception of last frame failed, scheduling EIFS-DIFS+AIFS period (" << i << ")\n"; - scheduleAt(simTime() + getEIFS() - getDIFS() + getAIFS(i), endAIFS(i)); - } - else - { - EV << "scheduling AIFS period (" << i << ")\n"; - scheduleAt(simTime() + getAIFS(i), endAIFS(i)); - } - - } - if (endAIFS(i)->isScheduled()) - schedule = true; - } - if (!schedule && !endDIFS->isScheduled()) - { - // schedule default DIFS - currentAC = numCategories()-1; - scheduleDIFSPeriod(); - } -} - -void Ieee80211NewMac::rescheduleAIFSPeriod(int AccessCategory) -{ - ASSERT(1); - EV << "rescheduling AIFS[" << AccessCategory << "]\n"; - cancelEvent(endAIFS(AccessCategory)); - scheduleAt(simTime() + getAIFS(AccessCategory), endAIFS(AccessCategory)); -} - -void Ieee80211NewMac::cancelAIFSPeriod() -{ - EV << "canceling AIFS period\n"; - for (int i = 0; iisScheduled()) - { - EV << "scheduling data timeout period\n"; - if (useModulationParameters) - { - ModulationType modType; - if ((opMode=='b') || (opMode=='g')) - modType = WifiModulationType::getMode80211g(bitrate); - else if (opMode=='a') - modType = WifiModulationType::getMode80211a(bitrate); - else if (opMode=='p') - modType = WifiModulationType::getMode80211p(bitrate); - else - opp_error("mode not supported"); - WifiModulationType::getSlotDuration(modType,wifiPreambleType); - tim = computeFrameDuration(frameToSend) +SIMTIME_DBL( - WifiModulationType::getSlotDuration(modType,wifiPreambleType) + - WifiModulationType::getSifsTime(modType,wifiPreambleType) + - WifiModulationType::get_aPHY_RX_START_Delay (modType,wifiPreambleType)); - } - else - tim = computeFrameDuration(frameToSend) +SIMTIME_DBL( getSIFS()) + computeFrameDuration(LENGTH_ACK, basicBitrate) + MAX_PROPAGATION_DELAY * 2; - EV<<" time out="<isScheduled()) - { - EV << "scheduling multicast timeout period\n"; - scheduleAt(simTime() + computeFrameDuration(frameToSend), endTimeout); - } -} - -void Ieee80211NewMac::cancelTimeoutPeriod() -{ - EV << "canceling timeout period\n"; - cancelEvent(endTimeout); -} - -void Ieee80211NewMac::scheduleCTSTimeoutPeriod() -{ - if (!endTimeout->isScheduled()) - { - EV << "scheduling CTS timeout period\n"; - scheduleAt(simTime() + computeFrameDuration(LENGTH_RTS, basicBitrate) + getSIFS() - + computeFrameDuration(LENGTH_CTS, basicBitrate) + MAX_PROPAGATION_DELAY * 2, endTimeout); - } -} - -void Ieee80211NewMac::scheduleReservePeriod(Ieee80211Frame *frame) -{ - simtime_t reserve = frame->getDuration(); - - // see spec. 7.1.3.2 - if (!isForUs(frame) && reserve != 0 && reserve < 32768) - { - if (endReserve->isScheduled()) - { - simtime_t oldReserve = endReserve->getArrivalTime() - simTime(); - - if (oldReserve > reserve) - return; - - reserve = std::max(reserve, oldReserve); - cancelEvent(endReserve); - } - else if (radioState == RadioState::IDLE) - { - // NAV: the channel just became virtually busy according to the spec - scheduleAt(simTime(), mediumStateChange); - } - - EV << "scheduling reserve period for: " << reserve << endl; - - ASSERT(reserve > 0); - - nav = true; - scheduleAt(simTime() + reserve, endReserve); - } -} - -void Ieee80211NewMac::invalidateBackoffPeriod() -{ - backoffPeriod() = -1; -} - -bool Ieee80211NewMac::isInvalidBackoffPeriod() -{ - return backoffPeriod() == -1; -} - -void Ieee80211NewMac::generateBackoffPeriod() -{ - backoffPeriod() = computeBackoffPeriod(getCurrentTransmission(), retryCounter()); - ASSERT(backoffPeriod() >= 0); - EV << "backoff period set to " << backoffPeriod()<< endl; -} - -void Ieee80211NewMac::decreaseBackoffPeriod() -{ - // see spec 9.9.1.5 - // decrase for every EDCAF - // cancel event endBackoff after decrease or we don't know which endBackoff is scheduled - for (int i = 0; iisScheduled()) - { - EV<< "old backoff[" << i << "] is " << backoffPeriod(i) << ", sim time is " << simTime() - << ", endbackoff sending period is " << endBackoff(i)->getSendingTime() << endl; - simtime_t elapsedBackoffTime = simTime() - endBackoff(i)->getSendingTime(); - backoffPeriod(i) -= ((int)(elapsedBackoffTime / getSlotTime())) * getSlotTime(); - EV << "actual backoff[" << i << "] is " <= 0); - EV << "backoff[" << i << "] period decreased to " << backoffPeriod(i) << endl; - } - } -} - -void Ieee80211NewMac::scheduleBackoffPeriod() -{ - EV << "scheduling backoff period\n"; - scheduleAt(simTime() + backoffPeriod(), endBackoff()); -} - -void Ieee80211NewMac::cancelBackoffPeriod() -{ - EV << "cancelling Backoff period - only if some is scheduled\n"; - for (int i = 0; igetContextPointer(); - endSIFS->setContextPointer(NULL); - sendACKFrame(check_and_cast(frameToACK)); - delete frameToACK; -} - -void Ieee80211NewMac::sendACKFrame(Ieee80211DataOrMgmtFrame *frameToACK) -{ - EV << "sending ACK frame\n"; - numAckSend++; - sendDown(setBasicBitrate(buildACKFrame(frameToACK))); -} - -void Ieee80211NewMac::sendDataFrameOnEndSIFS(Ieee80211DataOrMgmtFrame *frameToSend) -{ - Ieee80211Frame *ctsFrame = (Ieee80211Frame *)endSIFS->getContextPointer(); - endSIFS->setContextPointer(NULL); - sendDataFrame(frameToSend); - delete ctsFrame; -} - -#ifdef USEMULTIQUEUE -void Ieee80211NewMac::sendDataFrame(Ieee80211DataOrMgmtFrame *frameToSend) -{ - simtime_t t = 0, time = 0; - int count = 0; - Ieee80211DataOrMgmtFrame* frame; - - frame = dynamic_cast (transmissionQueue()->initIterator()); - ASSERT(frame==frameToSend); - if (!txop && TXOP() > 0 && transmissionQueue()->size() >= 2 ) - { - //we start packet burst within TXOP time period - txop = true; - - for (frame=dynamic_cast(transmissionQueue()->initIterator()); frame!=NULL; frame=dynamic_cast(transmissionQueue()->next())) - { - count++; - t = computeFrameDuration(frame) + 2 * getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate); - EV << "t is " << t << endl; - if (TXOP()>time+t) - { - time += t; - EV << "adding t \n"; - } - else - { - break; - } - } - //to be sure we get endTXOP earlier then receive ACK and we have to minus SIFS time from first packet - time -= getSIFS()/2 + getSIFS(); - EV << "scheduling TXOP for AC" << currentAC << ", duration is " << time << ",count is " << count << endl; - scheduleAt(simTime() + time, endTXOP); - } - EV << "sending Data frame\n"; - sendDown(setBitrateFrame(buildDataFrame(frameToSend))); -} -#else -void Ieee80211NewMac::sendDataFrame(Ieee80211DataOrMgmtFrame *frameToSend) -{ - simtime_t t = 0, time = 0; - int count = 0; - std::list::iterator frame; - - frame = transmissionQueue()->begin(); - ASSERT(*frame==frameToSend); - if (!txop && TXOP() > 0 && transmissionQueue()->size() >= 2 ) - { - //we start packet burst within TXOP time period - txop = true; - - for (frame=transmissionQueue()->begin(); frame != transmissionQueue()->end(); ++frame) - { - count++; - t = computeFrameDuration(*frame) + 2 * getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate); - EV << "t is " << t << endl; - if (TXOP()>time+t) - { - time += t; - EV << "adding t \n"; - } - else - { - break; - } - } - //to be sure we get endTXOP earlier then receive ACK and we have to minus SIFS time from first packet - time -= getSIFS()/2 + getSIFS(); - EV << "scheduling TXOP for AC" << currentAC << ", duration is " << time << ",count is " << count << endl; - scheduleAt(simTime() + time, endTXOP); - } - EV << "sending Data frame\n"; - sendDown(setBitrateFrame(buildDataFrame(frameToSend))); -} -#endif - -void Ieee80211NewMac::sendRTSFrame(Ieee80211DataOrMgmtFrame *frameToSend) -{ - EV << "sending RTS frame\n"; - sendDown(setBasicBitrate(buildRTSFrame(frameToSend))); -} - -void Ieee80211NewMac::sendMulticastFrame(Ieee80211DataOrMgmtFrame *frameToSend) -{ - EV << "sending Multicast frame\n"; - sendDown(setBasicBitrate(buildDataFrame(frameToSend))); -} - -void Ieee80211NewMac::sendCTSFrameOnEndSIFS() -{ - Ieee80211Frame *rtsFrame = (Ieee80211Frame *)endSIFS->getContextPointer(); - endSIFS->setContextPointer(NULL); - sendCTSFrame(check_and_cast(rtsFrame)); - delete rtsFrame; -} - -void Ieee80211NewMac::sendCTSFrame(Ieee80211RTSFrame *rtsFrame) -{ - EV << "sending CTS frame\n"; - sendDown(setBasicBitrate(buildCTSFrame(rtsFrame))); -} - -/**************************************************************** - * Frame builder functions. - */ -Ieee80211DataOrMgmtFrame *Ieee80211NewMac::buildDataFrame(Ieee80211DataOrMgmtFrame *frameToSend) -{ - Ieee80211DataOrMgmtFrame *frame = (Ieee80211DataOrMgmtFrame *)frameToSend->dup(); - - if (isMulticast(frameToSend)) - frame->setDuration(0); - else if (!frameToSend->getMoreFragments()) - { - if (txop) - - { -#ifdef USEMULTIQUEUE - Ieee80211DataOrMgmtFrame* nextframeToSend = dynamic_cast (transmissionQueue()->initIterator()); - nextframeToSend = dynamic_cast (transmissionQueue()->next()); - frame->setDuration(3 * getSIFS() + 2 * computeFrameDuration(LENGTH_ACK, basicBitrate) - + computeFrameDuration(nextframeToSend)); -#else - // ++ operation is safe because txop is true - std::list::iterator nextframeToSend; - nextframeToSend = transmissionQueue()->begin(); - ASSERT(transmissionQueue()->end() != nextframeToSend); - nextframeToSend++; - frame->setDuration(3 * getSIFS() + 2 * computeFrameDuration(LENGTH_ACK, basicBitrate) - + computeFrameDuration(*nextframeToSend)); -#endif - } - else - frame->setDuration(getSIFS() + computeFrameDuration(LENGTH_ACK, basicBitrate)); - } - else - // FIXME: shouldn't we use the next frame to be sent? - frame->setDuration(3 * getSIFS() + 2 * computeFrameDuration(LENGTH_ACK, basicBitrate) + computeFrameDuration(frameToSend)); - - return frame; -} - -Ieee80211ACKFrame *Ieee80211NewMac::buildACKFrame(Ieee80211DataOrMgmtFrame *frameToACK) -{ - Ieee80211ACKFrame *frame = new Ieee80211ACKFrame("wlan-ack"); - frame->setReceiverAddress(frameToACK->getTransmitterAddress()); - - if (!frameToACK->getMoreFragments()) - frame->setDuration(0); - else - frame->setDuration(frameToACK->getDuration() - getSIFS() - computeFrameDuration(LENGTH_ACK, basicBitrate)); - - return frame; -} - -Ieee80211RTSFrame *Ieee80211NewMac::buildRTSFrame(Ieee80211DataOrMgmtFrame *frameToSend) -{ - Ieee80211RTSFrame *frame = new Ieee80211RTSFrame("wlan-rts"); - frame->setTransmitterAddress(address); - frame->setReceiverAddress(frameToSend->getReceiverAddress()); - frame->setDuration(3 * getSIFS() + computeFrameDuration(LENGTH_CTS, basicBitrate) + - computeFrameDuration(frameToSend) + - computeFrameDuration(LENGTH_ACK, basicBitrate)); - - return frame; -} - -Ieee80211CTSFrame *Ieee80211NewMac::buildCTSFrame(Ieee80211RTSFrame *rtsFrame) -{ - Ieee80211CTSFrame *frame = new Ieee80211CTSFrame("wlan-cts"); - frame->setReceiverAddress(rtsFrame->getTransmitterAddress()); - frame->setDuration(rtsFrame->getDuration() - getSIFS() - computeFrameDuration(LENGTH_CTS, basicBitrate)); - - return frame; -} - -Ieee80211DataOrMgmtFrame *Ieee80211NewMac::buildMulticastFrame(Ieee80211DataOrMgmtFrame *frameToSend) -{ - Ieee80211DataOrMgmtFrame *frame = (Ieee80211DataOrMgmtFrame *)frameToSend->dup(); - - PhyControlInfo *phyControlInfo_old = dynamic_cast( frameToSend->getControlInfo() ); - if (phyControlInfo_old) - { - ev<<"Per frame1 params"<getBitrate()/1e6<<"Mbps txpower "<txpower()<<"mW"<setControlInfo( phyControlInfo_new ); - } - - frame->setDuration(0); - return frame; -} - -Ieee80211Frame *Ieee80211NewMac::setBasicBitrate(Ieee80211Frame *frame) -{ - ASSERT(frame->getControlInfo()==NULL); - PhyControlInfo *ctrl = new PhyControlInfo(); - ctrl->setBitrate(basicBitrate); - frame->setControlInfo(ctrl); - return frame; -} - -Ieee80211Frame *Ieee80211NewMac::setBitrateFrame(Ieee80211Frame *frame) -{ - if (rateControlMode == RATE_CR && forceBitRate==false) - return frame; - PhyControlInfo *ctrl = NULL; - if (frame->getControlInfo()==NULL) - { - ctrl = new PhyControlInfo(); - frame->setControlInfo(ctrl); - } - else - ctrl = dynamic_cast(frame->getControlInfo()); - if (ctrl) - ctrl->setBitrate(getBitrate()); - return frame; -} - - -/**************************************************************** - * Helper functions. - */ -void Ieee80211NewMac::finishCurrentTransmission() -{ - popTransmissionQueue(); - resetStateVariables(); -} - -void Ieee80211NewMac::giveUpCurrentTransmission() -{ - Ieee80211DataOrMgmtFrame *temp = (Ieee80211DataOrMgmtFrame*) transmissionQueue()->front(); - nb->fireChangeNotification(NF_LINK_BREAK, temp); - popTransmissionQueue(); - resetStateVariables(); - numGivenUp()++; -} - -void Ieee80211NewMac::retryCurrentTransmission() -{ - ASSERT(retryCounter() < transmissionLimit - 1); - getCurrentTransmission()->setRetry(true); - if (rateControlMode == RATE_AARF || rateControlMode == RATE_ARF) - reportDataFailed(); - else - retryCounter() ++; - numRetry()++; - backoff() = true; - generateBackoffPeriod(); -} - -Ieee80211DataOrMgmtFrame *Ieee80211NewMac::getCurrentTransmission() -{ - return transmissionQueue()->empty() ? NULL : (Ieee80211DataOrMgmtFrame *)transmissionQueue()->front(); -} - -void Ieee80211NewMac::sendDownPendingRadioConfigMsg() -{ - if (pendingRadioConfigMsg != NULL) - { - sendDown(pendingRadioConfigMsg); - pendingRadioConfigMsg = NULL; - } -} - -void Ieee80211NewMac::setMode(Mode mode) -{ - if (mode == PCF) - error("PCF mode not yet supported"); - - this->mode = mode; -} - -void Ieee80211NewMac::resetStateVariables() -{ - backoffPeriod() = 0; - if (rateControlMode == RATE_AARF || rateControlMode == RATE_ARF) - reportDataOk(); - else - retryCounter() = 0; - - if (!transmissionQueue()->empty()) - { - backoff() = true; - getCurrentTransmission()->setRetry(false); - } - else - { - backoff() = false; - } -} - -bool Ieee80211NewMac::isMediumStateChange(cMessage *msg) -{ - return msg == mediumStateChange || (msg == endReserve && radioState == RadioState::IDLE); -} - -bool Ieee80211NewMac::isMediumFree() -{ - return radioState == RadioState::IDLE && !endReserve->isScheduled(); -} - -bool Ieee80211NewMac::isMulticast(Ieee80211Frame *frame) -{ - return frame && frame->getReceiverAddress().isMulticast(); -} - -bool Ieee80211NewMac::isForUs(Ieee80211Frame *frame) -{ - return frame && frame->getReceiverAddress() == address; -} - -bool Ieee80211NewMac::isSentByUs(Ieee80211Frame *frame) -{ - - if (dynamic_cast(frame)) - { - //EV<<"ad3 "<<((Ieee80211DataOrMgmtFrame *)frame)->getAddress3(); - //EV<<"myad "<getAddress3() == address)//received frame sent by us - return 1; - } - else - EV<<"Cast failed"<(frame); -} - -bool Ieee80211NewMac::isMsgAIFS(cMessage *msg) -{ - for (int i = 0; igetContextPointer(); -} - -void Ieee80211NewMac::popTransmissionQueue() -{ - EV << "dropping frame from transmission queue\n"; - Ieee80211Frame *temp = dynamic_cast(transmissionQueue()->front()); - ASSERT(!transmissionQueue()->empty()); - transmissionQueue()->pop_front(); - if (queueModule) - { - if (numCategories()==1) - { - // the module are continuously asking for packets - EV << "requesting another frame from queue module\n"; - queueModule->requestPacket(); - } - else if (numCategories()>1 && (int)transmissionQueueSize()==maxQueueSize-1) - { - // Now exist a empty frame space - // the module are continuously asking for packets - EV << "requesting another frame from queue module\n"; - queueModule->requestPacket(); - } - } - delete temp; -} - -double Ieee80211NewMac::computeFrameDuration(Ieee80211Frame *msg) -{ - - PhyControlInfo *ctrl; - double duration; - ev<<*msg; - ctrl = dynamic_cast ( msg->removeControlInfo() ); - if ( ctrl ) - { - ev<<"Per frame2 params bitrate "<getBitrate()/1e6<getBitLength(), ctrl->getBitrate()); - delete ctrl; - return duration; - } - else - - return computeFrameDuration(msg->getBitLength(), bitrate); -} - -double Ieee80211NewMac::computeFrameDuration(int bits, double bitrate) -{ - double duration; - if (PHY_HEADER_LENGTH<0) - { - ModulationType modType; - if (opMode=='g' || (opMode=='b')) - modType = WifiModulationType::getMode80211g(bitrate); - else if (opMode=='a') - modType = WifiModulationType::getMode80211a(bitrate); - else if (opMode=='p') - modType = WifiModulationType::getMode80211p(bitrate); - else - opp_error("Opmode not supported"); - duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(bits, modType, wifiPreambleType)); - } - else - { - if ((opMode=='g') || (opMode=='a') || (opMode=='p')) - duration = 4*ceil((16+bits+6)/(bitrate/1e6*4))*1e-6 + PHY_HEADER_LENGTH; - else if (opMode=='b') - duration = bits / bitrate + PHY_HEADER_LENGTH / BITRATE_HEADER; - else - opp_error("Opmode not supported"); - } - - EV<<" duration="<isScheduled()) - b[i] = "scheduled"; - if (endAIFS(i)->isScheduled()) - a[i] = "scheduled"; - } - - EV << "# state information: mode = " << modeName(mode) << ", state = " << fsm.getStateName(); - EV << ", backoff 0.."<getId(); - else - EV << "\n# current transmission: none"; - EV << endl; -} - -const char *Ieee80211NewMac::modeName(int mode) -{ -#define CASE(x) case x: s=#x; break - const char *s = "???"; - switch (mode) - { - CASE(DCF); - CASE(PCF); - } - return s; -#undef CASE -} - -bool Ieee80211NewMac::transmissionQueueEmpty() -{ - for (int i=0; iempty()) return false; - return true; -} - -unsigned int Ieee80211NewMac::transmissionQueueSize() -{ - unsigned int totalSize=0; - for (int i=0; isize(); - return totalSize; -} - -void Ieee80211NewMac::reportDataOk() -{ - retryCounter() = 0; - if (rateControlMode==RATE_CR) - return; - successCounter ++; - failedCounter = 0; - recovery = false; - if ((successCounter == getSuccessThreshold() || timer == getTimerTimeout()) - && (rateIndex < (getMaxBitrate()))) - { - if (rateControlMode != RATE_CR) - { - rateIndex++; - if (opMode=='b') setBitrate(BITRATES_80211b[rateIndex]); - else if (opMode=='g') setBitrate(BITRATES_80211g[rateIndex]); - else if (opMode=='a') setBitrate(BITRATES_80211a[rateIndex]); - else if (opMode=='p') setBitrate(BITRATES_80211p[rateIndex]); - else opp_error("mode not supported"); - } - timer = 0; - successCounter = 0; - recovery = true; - } -} - -void Ieee80211NewMac::reportDataFailed(void) -{ - retryCounter()++; - if (rateControlMode==RATE_CR) - return; - timer++; - failedCounter++; - successCounter = 0; - if (recovery) - { - if (retryCounter() == 1) - { - reportRecoveryFailure(); - if (rateIndex != getMinBitrate() && rateControlMode != RATE_CR) - { - rateIndex--; - if (opMode=='b') setBitrate(BITRATES_80211b[rateIndex]); - else if (opMode=='g') setBitrate(BITRATES_80211g[rateIndex]); - else if (opMode=='a') setBitrate(BITRATES_80211a[rateIndex]); - else if (opMode=='p') setBitrate(BITRATES_80211p[rateIndex]); - else opp_error("mode not supported"); - } - } - timer = 0; - } - else - { - if (needNormalFallback()) - { - reportFailure(); - if (rateIndex != getMinBitrate() && rateControlMode != RATE_CR) - { - rateIndex--; - if (opMode=='b') setBitrate(BITRATES_80211b[rateIndex]); - else if (opMode=='g') setBitrate(BITRATES_80211g[rateIndex]); - else if (opMode=='a') setBitrate(BITRATES_80211a[rateIndex]); - else if (opMode=='p') setBitrate(BITRATES_80211p[rateIndex]); - else opp_error("mode not supported"); - } - } - if (retryCounter() >= 2) - { - timer = 0; - } - } -} - -int Ieee80211NewMac::getMinTimerTimeout(void) -{ - return minTimerTimeout; -} - -int Ieee80211NewMac::getMinSuccessThreshold(void) -{ - return minSuccessThreshold; -} - -int Ieee80211NewMac::getTimerTimeout(void) -{ - return timerTimeout; -} - -int Ieee80211NewMac::getSuccessThreshold(void) -{ - return successThreshold; -} - -void Ieee80211NewMac::setTimerTimeout(int timer_timeout) -{ - if (timer_timeout >= minTimerTimeout) - timerTimeout = timer_timeout; - else - error("timer_timeout is less than minTimerTimeout"); -} -void Ieee80211NewMac::setSuccessThreshold(int success_threshold) -{ - if (success_threshold >= minSuccessThreshold) - successThreshold = success_threshold; - else - error("success_threshold is less than minSuccessThreshold"); -} - -void Ieee80211NewMac::reportRecoveryFailure(void) -{ - if (rateControlMode == RATE_AARF) - { - setSuccessThreshold((int)(std::min((double)getSuccessThreshold() * successCoeff, (double) maxSuccessThreshold))); - setTimerTimeout((int)(std::max((double)getMinTimerTimeout(), (double)(getSuccessThreshold() * timerCoeff)))); - } -} - -void Ieee80211NewMac::reportFailure(void) -{ - if (rateControlMode == RATE_AARF) - { - setTimerTimeout(getMinTimerTimeout()); - setSuccessThreshold(getMinSuccessThreshold()); - } -} - -bool Ieee80211NewMac::needRecoveryFallback(void) -{ - if (retryCounter() == 1) - { - return true; - } - else - { - return false; - } -} - -bool Ieee80211NewMac::needNormalFallback(void) -{ - int retryMod = (retryCounter() - 1) % 2; - if (retryMod == 1) - { - return true; - } - else - { - return false; - } -} - -double Ieee80211NewMac::getBitrate() -{ - return bitrate; -} - -void Ieee80211NewMac::setBitrate(double rate) -{ - bitrate = rate; -} - - -int Ieee80211NewMac::getMaxBitrate(void) -{ - if (opMode=='b') - return (NUM_BITERATES_80211b-1); - else if (opMode=='g') - return (NUM_BITERATES_80211g-1); - else if (opMode=='a') - return (NUM_BITERATES_80211a-1); - else if (opMode=='p') - return (NUM_BITERATES_80211p-1); -// -// If arrives here there is an error - opp_error("Mode not supported"); - return 0; -} - -int Ieee80211NewMac::getMinBitrate(void) -{ - return 0; -} - - -// method for access to the EDCA data - - -// methods for access to specific AC data -bool & Ieee80211NewMac::backoff(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].backoff; -} - -simtime_t & Ieee80211NewMac::TXOP(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].TXOP; -} - -simtime_t & Ieee80211NewMac::backoffPeriod(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].backoffPeriod; -} - -int & Ieee80211NewMac::retryCounter(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].retryCounter; -} - -int & Ieee80211NewMac::AIFSN(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].AIFSN; -} - -int & Ieee80211NewMac::cwMax(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].cwMax; -} - -int & Ieee80211NewMac::cwMin(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].cwMin; -} - -cMessage * Ieee80211NewMac::endAIFS(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].endAIFS; -} - -cMessage * Ieee80211NewMac::endBackoff(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].endBackoff; -} - -const bool Ieee80211NewMac::isBakoffMsg(cMessage *msg) -{ - for (unsigned int i=0; i=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].numRetry; -} - -long & Ieee80211NewMac::numSentWithoutRetry(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)numCategories()) - opp_error("AC doesn't exist"); - return edcCAF[i].numSentWithoutRetry; -} - -long & Ieee80211NewMac::numGivenUp(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].numGivenUp; -} - -long & Ieee80211NewMac::numSent(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].numSent; -} - -long & Ieee80211NewMac::numDropped(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].numDropped; -} - -long & Ieee80211NewMac::bites(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].bites; -} - -simtime_t & Ieee80211NewMac::minjitter(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].minjitter; -} - -simtime_t & Ieee80211NewMac::maxjitter(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAF[i].maxjitter; -} - -// out vectors - - -cOutVector * Ieee80211NewMac::jitter(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAFOutVector[i].jitter; -} - -cOutVector * Ieee80211NewMac::macDelay(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAFOutVector[i].macDelay; -} - -cOutVector * Ieee80211NewMac::throughput(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return edcCAFOutVector[i].throughput; -} - -Ieee80211NewMac::Ieee80211DataOrMgmtFrameList * Ieee80211NewMac::transmissionQueue(int i) -{ - if (i==-1) - i = currentAC; - if (i>=(int)edcCAF.size()) - opp_error("AC doesn't exist"); - return &(edcCAF[i].transmissionQueue); -} - - -ModulationType -Ieee80211NewMac::getControlAnswerMode(ModulationType reqMode) -{ - /** - * The standard has relatively unambiguous rules for selecting a - * control response rate (the below is quoted from IEEE 802.11-2007, - * Section 9.6): - * - * To allow the transmitting STA to calculate the contents of the - * Duration/ID field, a STA responding to a received frame shall - * transmit its Control Response frame (either CTS or ACK), other - * than the BlockAck control frame, at the highest rate in the - * BSSBasicRateSet parameter that is less than or equal to the - * rate of the immediately previous frame in the frame exchange - * sequence (as defined in 9.12) and that is of the same - * modulation class (see 9.6.1) as the received frame... - */ - - /** - * If no suitable basic rate was found, we search the mandatory - * rates. The standard (IEEE 802.11-2007, Section 9.6) says: - * - * ...If no rate contained in the BSSBasicRateSet parameter meets - * these conditions, then the control frame sent in response to a - * received frame shall be transmitted at the highest mandatory - * rate of the PHY that is less than or equal to the rate of the - * received frame, and that is of the same modulation class as the - * received frame. In addition, the Control Response frame shall - * be sent using the same PHY options as the received frame, - * unless they conflict with the requirement to use the - * BSSBasicRateSet parameter. - * - * TODO: Note that we're ignoring the last sentence for now, because - * there is not yet any manipulation here of PHY options. - */ - bool found = false; - ModulationType mode; - for (uint32_t idx = 0; idx < (uint32_t)getMaxBitrate(); idx++) - { - ModulationType thismode; - if (opMode=='b') - thismode = WifiModulationType::getMode80211b(BITRATES_80211b[idx]); - else if (opMode=='g') - thismode = WifiModulationType::getMode80211g(BITRATES_80211g[idx]); - else if (opMode=='a') - thismode = WifiModulationType::getMode80211a(BITRATES_80211a[idx]); - else if (opMode=='a') - thismode = WifiModulationType::getMode80211p(BITRATES_80211p[idx]); - - /* If the rate: - * - * - is a mandatory rate for the PHY, and - * - is equal to or faster than our current best choice, and - * - is less than or equal to the rate of the received frame, and - * - is of the same modulation class as the received frame - * - * ...then it's our best choice so far. - */ - if (thismode.getIsMandatory() - && (!found || thismode.getPhyRate() > mode.getPhyRate()) - && thismode.getPhyRate() <= reqMode.getPhyRate() - && thismode.getModulationClass() == reqMode.getModulationClass()) - { - mode = thismode; - // As above; we've found a potentially-suitable transmit - // rate, but we need to continue and consider all the - // mandatory rates before we can be sure we've got the right - // one. - found = true; - } - } - - /** - * If we still haven't found a suitable rate for the response then - * someone has messed up the simulation config. This probably means - * that the WifiPhyStandard is not set correctly, or that a rate that - * is not supported by the PHY has been explicitly requested in a - * WifiRemoteStationManager (or descendant) configuration. - * - * Either way, it is serious - we can either disobey the standard or - * fail, and I have chosen to do the latter... - */ - if (!found) - { - opp_error("Can't find response rate for reqMode. Check standard and selected rates match."); - } - - return mode; -} - -// This methods implemet the duplicate filter -void Ieee80211NewMac::sendUp(cMessage *msg) -{ - EV << "sending up " << msg << "\n"; - - if (duplicateDetect) // duplicate detection filter - { - Ieee80211DataOrMgmtFrame *frame =dynamic_cast(msg); - if (frame) - { - Ieee80211ASFTupleList::iterator it = asfTuplesList.find(frame->getTransmitterAddress()); - if (it==asfTuplesList.end()) - { - Ieee80211ASFTuple tuple; - tuple.receivedTime=simTime(); - tuple.sequenceNumber= frame->getSequenceNumber(); - tuple.fragmentNumber=frame->getFragmentNumber(); - asfTuplesList.insert(std::pair(frame->getTransmitterAddress(),tuple)); - } - else - { - // check if duplicate - if (it->second.sequenceNumber==frame->getSequenceNumber() && it->second.fragmentNumber==frame->getFragmentNumber()) - { - return; - } - else - { - // actualize - it->second.sequenceNumber=frame->getSequenceNumber(); - it->second.fragmentNumber=frame->getFragmentNumber(); - it->second.receivedTime=simTime(); - } - } - } - } - - if (msg->isPacket()) - emit(packetSentToUpperSignal, msg); - - send(msg, upperLayerOut); -} - -void Ieee80211NewMac::removeOldTuplesFromDuplicateMap() -{ - if (duplicateDetect && lastTimeDelete+duplicateTimeOut>=simTime()) - { - lastTimeDelete=simTime(); - for (Ieee80211ASFTupleList::iterator it = asfTuplesList.begin();it!=asfTuplesList.begin();) - { - if (it->second.receivedTime+duplicateTimeOutgetFullName()) + 1]; - char *d = interfaceName; - for (const char *s = getParentModule()->getFullName(); *s; s++) - if (isalnum(*s)) - *d++ = *s; - *d = '\0'; - InterfaceEntry * e = ift->getInterfaceByName(interfaceName); - delete [] interfaceName; - if (e) - return e->getMacAddress(); - return MACAddress::UNSPECIFIED_ADDRESS; -} diff --git a/src/linklayer/ieee80211/mac/Ieee80211NewMac.h b/src/linklayer/ieee80211/mac/Ieee80211NewMac.h deleted file mode 100644 index 944ef44b8..000000000 --- a/src/linklayer/ieee80211/mac/Ieee80211NewMac.h +++ /dev/null @@ -1,682 +0,0 @@ -// -// Copyright (C) 2006 Andras Varga and Levente Meszaros (original code) -// Copyright (C) 2007 Sorin (802.11g) -// Copyright (C) 2009 Lukáš Hlůže (Lukás Hluze) lukas@hluze.cz (802.11e) -// Copyright (C) 2011 Alfonso Ariza (clean code, fix some errors, new radio model) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU 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. -// - -#ifndef IEEE_80211New_MAC_H -#define IEEE_80211New_MAC_H - -// un-comment this if you do not want to log state machine transitions -//#define FSM_DEBUG -//#define USEMULTIQUEUE - -#include "WifiMode.h" -#include "WirelessMacBase.h" -#include "IPassiveQueue.h" -#include "Ieee80211Frame_m.h" -#include "Ieee80211Consts.h" -#include "NotificationBoard.h" -#include "RadioState.h" -#include "FSMA.h" -#include "IQoSClassifier.h" -#ifdef USEMULTIQUEUE -#include "MultiQueue.h" -#endif - -/** - * IEEE 802.11g with e Media Access Control Layer. - * - * Various comments in the code refer to the Wireless LAN Medium Access - * Control (MAC) and Physical Layer(PHY) Specifications - * ANSI/IEEE Std 802.11, 1999 Edition (R2003) - * ANSI/IEEE Std 802.11, 2007 Edition - * - * For more info, see the NED file. - * - * TODO: support fragmentation - * TODO: PCF mode - * TODO: CF period - * TODO: pass radio power to upper layer - * TODO: transmission complete notification to upper layer - * TODO: STA TCF timer synchronization, see Chapter 11 pp 123 - * - * Parts of the implementation have been taken over from the - * Mobility Framework's Mac80211 module. - * - * @ingroup macLayer - */ -class INET_API Ieee80211NewMac : public WirelessMacBase, public INotifiable -{ -#ifdef USEMULTIQUEUE - typedef MultiQueue Ieee80211DataOrMgmtFrameList; -#else - typedef std::list Ieee80211DataOrMgmtFrameList; -#endif - /** - * This is used to populate fragments and identify duplicated messages. See spec 9.2.9. - */ - struct Ieee80211ASFTuple - { - int sequenceNumber; - int fragmentNumber; - simtime_t receivedTime; - Ieee80211ASFTuple& operator=(const Ieee80211ASFTuple& other) - { - if (this==&other) return *this; - this->sequenceNumber = other.sequenceNumber; - this->fragmentNumber = other.fragmentNumber; - this->receivedTime = other.receivedTime; - return *this; - } - }; - - typedef std::map Ieee80211ASFTupleList; - - enum - { - RATE_ARF, // Auto Rate Fallback - RATE_AARF, // Adaptatice ARF - RATE_CR, // Constant Rate - } rateControlMode; - - WifiPreamble wifiPreambleType; - ModulationType recFrameModulationType; - bool validRecMode; - bool useModulationParameters; - bool prioritizeMulticast; - protected: - /** - * @name Configuration parameters - * These are filled in during the initialization phase and not supposed to change afterwards. - */ - //@{ - /** MAC address */ - MACAddress address; - char opMode; - /** The bitrate is used to send unicast data and mgmt frames; be sure to use a valid 802.11 bitrate */ - double bitrate; - - /** The basic bitrate (1 or 2 Mbps) is used to transmit control frames and multicast/broadcast frames */ - double basicBitrate; - // Variables used by the auto bit rate - bool forceBitRate; //if true the - unsigned int intrateIndex; - int contI; - int contJ; - int samplingCoeff; - double recvdThroughput; - int autoBitrate; - int rateIndex; - int successCounter; - int failedCounter; - bool recovery; - int timer; - int successThreshold; - int maxSuccessThreshold; - int timerTimeout; - int minSuccessThreshold; - int minTimerTimeout; - double successCoeff; - double timerCoeff; - double _snr; - double snr; - double lossRate; - simtime_t timeStampLastMessageReceived; - // used to measure the throughput over a period - uint64_t recBytesOverPeriod; - simtime_t throughputTimePeriod; - cMessage * throughputTimer; - double throughputLastPeriod; - - - /** Maximum number of frames in the queue; should be set in the omnetpp.ini */ - int maxQueueSize; - int maxCategorieQueueSize; - - /** - * The minimum length of MPDU to use RTS/CTS mechanism. 0 means always, extremely - * large value means never. See spec 9.2.6 and 361. - */ - int rtsThreshold; - - /** - * Maximum number of transmissions for a message. - * This includes the initial transmission and all subsequent retransmissions. - * Thus a value 0 is invalid and a value 1 means no retransmissions. - * See: dot11ShortRetryLimit on page 484. - * 'This attribute shall indicate the maximum number of - * transmission attempts of a frame, the length of which is less - * than or equal to dot11RTSThreshold, that shall be made before a - * failure condition is indicated. The default value of this - * attribute shall be 7' - */ - int transmissionLimit; - - - /** Default access catagory */ - int defaultAC; - - /** Slot time 9us(fast slot time 802.11g only) 20us(802.11b / 802.11g backward compatible)*/ - simtime_t ST; - - double PHY_HEADER_LENGTH; - /** Minimum contention window. */ - int cwMinData; - //int cwMin[4]; - - /** Maximum contention window. */ - int cwMaxData; - // int cwMax[4]; - - /** Contention window size for multicast messages. */ - int cwMinMulticast; - - /** Messages longer than this threshold will be sent in multiple fragments. see spec 361 */ - static const int fragmentationThreshold = 2346; - //@} - - public: - /** - * @name Ieee80211Mac state variables - * Various state information checked and modified according to the state machine. - */ - //@{ - // don't forget to keep synchronized the C++ enum and the runtime enum definition - /** the 80211 MAC state machine */ - enum State - { - IDLE, - DEFER, - WAITAIFS, - BACKOFF, - WAITACK, - WAITMULTICAST, - WAITCTS, - WAITSIFS, - RECEIVE, - }; - protected: - cFSM fsm; - bool fixFSM; - - struct Edca { - simtime_t TXOP; - bool backoff; - simtime_t backoffPeriod; - int retryCounter; - int AIFSN; // Arbitration interframe space number. The duration edcCAF[AC].AIFSis a duration derived from the value AIFSN[AC] by the relation - int cwMax; - int cwMin; - // queue - Ieee80211DataOrMgmtFrameList transmissionQueue; - // per class timers - cMessage *endAIFS; - cMessage *endBackoff; - /** @name Statistics per Access Class*/ - //@{ - long numRetry; - long numSentWithoutRetry; - long numGivenUp; - long numSent; - long numDropped; - long bites; - simtime_t minjitter; - simtime_t maxjitter; - }; - - struct EdcaOutVector { - cOutVector *jitter; - cOutVector *macDelay; - cOutVector *throughput; - }; - - std::vector edcCAF; - std::vector edcCAFOutVector; - // - // methods for access to the current AC data - // - // methods for access to specific AC data - virtual bool & backoff(int i = -1); - virtual simtime_t & TXOP(int i = -1); - virtual simtime_t & backoffPeriod(int i = -1); - virtual int & retryCounter(int i = -1); - virtual int & AIFSN(int i = -1); - virtual int & cwMax(int i = -1); - virtual int & cwMin(int i = -1); - virtual cMessage * endAIFS(int i = -1); - virtual cMessage * endBackoff(int i = -1); - virtual Ieee80211DataOrMgmtFrameList * transmissionQueue(int i = -1); - virtual void setEndAIFS(int i, cMessage *msg){edcCAF[i].endAIFS = msg;} - virtual void setEndBackoff(int i, cMessage *msg){edcCAF[i].endBackoff = msg;} - - // Statistics - virtual long & numRetry(int i = -1); - virtual long & numSentWithoutRetry(int i = -1); - virtual long & numGivenUp(int i = -1); - virtual long & numSent(int i = -1); - virtual long & numDropped(int i = -1); - virtual long & bites(int i = -1); - virtual simtime_t & minjitter(int i = -1); - virtual simtime_t & maxjitter(int i = -1); -// out vectors - virtual cOutVector * jitter(int i = -1); - virtual cOutVector * macDelay(int i = -1); - virtual cOutVector * throughput(int i = -1); - inline const int numCategories(){return edcCAF.size();} - virtual const bool isBakoffMsg(cMessage *msg); - - const char *modeName(int mode); - - /** - * Arbitration interframe space number. - * The duration AIFS[AC] is a duration derived from the value AIFSN[AC] by the relation - * AIFS[AC] = AIFSN[AC] × aSlotTime + aSIFSTime. - * See spec 7.3.2.29 - * - */ - //int AIFSN[4]; - - /** Remaining backoff period in seconds */ - //simtime_t backoffPeriod[4]; - /** True if backoff is enabled */ - // bool backoff[4]; - /** TXOP parametr */ - //simtime_t TXOP[4]; - - /** - * Number of frame retransmission attempts, this is a simpification of - * SLRC and SSRC, see 9.2.4 in the spec - */ - //int retryCounter[4]; - - IQoSClassifier *classifier; - public: - /** 80211 MAC operation modes */ - enum Mode - { - DCF, ///< Distributed Coordination Function - PCF, ///< Point Coordination Function - EDCA, - }; - protected: - Mode mode; - - /** Sequence number to be assigned to the next frame */ - int sequenceNumber; - - /** - * Indicates that the last frame received had bit errors in it or there was a - * collision during receiving the frame. If this flag is set, then the MAC - * will wait EIFS - DIFS + AIFS instead of AIFS period of time in WAITAIFS state. - */ - bool lastReceiveFailed; - - - - /** True during network allocation period. This flag is present to be able to watch this state. */ - bool nav; - - /** True if we are in txop bursting packets. */ - bool txop; - - /** Indicates which queue is acite. Depends on access category. */ - int currentAC; - - /** Remember currentAC. We need this to figure out internal colision. */ - int oldcurrentAC; - - /** XXX Remember for which AC we wait for ACK. */ - //int ACKcurrentAC; - - /** Physical radio (medium) state copied from physical layer */ - RadioState::State radioState; - // Use to distinguish the radio module that send the event - int radioModule; - - int getRadioModuleId() {return radioModule;} - - Ieee80211DataOrMgmtFrame *fr; - - /** - * A list of last sender, sequence and fragment number tuples to identify - * duplicates, see spec 9.2.9. - */ - bool duplicateDetect; - bool purgeOldTuples; - double duplicateTimeOut; - simtime_t lastTimeDelete; - Ieee80211ASFTupleList asfTuplesList; - - /** Passive queue module to request messages from */ - IPassiveQueue *queueModule; - - /** - * The last change channel message received and not yet sent to the physical layer, or NULL. - * The message will be sent down when the state goes to IDLE or DEFER next time. - */ - cMessage *pendingRadioConfigMsg; - //@} - - protected: - /** @name Timer messages */ - //@{ - /** End of the Short Inter-Frame Time period */ - cMessage *endSIFS; - - /** End of the Data Inter-Frame Time period */ - cMessage *endDIFS; - - /** End of the Arbitration Inter-Frame Time period */ -// cMessage *endAIFS[4]; - - /** End of the TXOP time limit period */ - cMessage *endTXOP; - - /** End of the backoff period */ - //cMessage *endBackoff[4]; - - /** Timeout after the transmission of an RTS, a CTS, or a DATA frame */ - cMessage *endTimeout; - - /** End of medium reserve period (NAV) when two other nodes were communicating on the channel */ - cMessage *endReserve; - - /** Radio state change self message. Currently this is optimized away and sent directly */ - cMessage *mediumStateChange; - //@} - - protected: - /** @name Statistics */ - //@{ - // long numRetry[4]; - // long numSentWithoutRetry[4]; - // long numGivenUp[4]; - long numCollision; - long numInternalCollision; - // long numSent[4]; - long numBites; - long numSentTXOP; - long numReceived; - long numSentMulticast; - long numReceivedMulticast; - // long numDropped[4]; - long numReceivedOther; - long numAckSend; - cOutVector stateVector; - simtime_t last; - // long bites[4]; - // simtime_t minjitter[4]; - // simtime_t maxjitter[4]; - // cOutVector jitter[4]; - // cOutVector macDelay[4]; - cOutVector radioStateVector; - // cOutVector throughput[4]; - //@} - - public: - /** - * @name Construction functions - */ - //@{ - Ieee80211NewMac(); - virtual ~Ieee80211NewMac(); - //@} - - protected: - /** - * @name Initialization functions - */ - //@{ - /** @brief Initialization of the module and its variables */ - virtual int numInitStages() const {return 2;} - virtual void initialize(int); - virtual void registerInterface(); - virtual void initializeQueueModule(); - virtual void finish(); - virtual void configureAutoBitRate(); - virtual void initWatches(); - virtual const MACAddress& isInterfaceRegistered(); - //@} - - protected: - /** - * @name Message handing functions - * @brief Functions called from other classes to notify about state changes and to handle messages. - */ - //@{ - /** @brief Called by the NotificationBoard whenever a change occurs we're interested in */ - virtual void receiveChangeNotification(int category, const cObject * details); - - /** @brief Handle commands (msg kind+control info) coming from upper layers */ - virtual void handleCommand(cMessage *msg); - - /** @brief Handle timer self messages */ - virtual void handleSelfMsg(cMessage *msg); - - /** @brief Handle messages from upper layer */ - virtual void handleUpperMsg(cPacket *msg); - - /** @brief Handle messages from lower (physical) layer */ - virtual void handleLowerMsg(cPacket *msg); - - /** @brief Handle all kinds of messages and notifications with the state machine */ - virtual void handleWithFSM(cMessage *msg); - //@} - - protected: - /** - * @name Timing functions - * @brief Calculate various timings based on transmission rate and physical layer charactersitics. - */ - //@{ - virtual simtime_t getSIFS(); - virtual simtime_t getSlotTime(); - virtual simtime_t getDIFS(int category = -1); - virtual simtime_t getAIFS(int AccessCategory); - virtual simtime_t getEIFS(); - virtual simtime_t getPIFS(); - virtual simtime_t computeBackoffPeriod(Ieee80211Frame *msg, int r); - virtual simtime_t getHeaderTime(double bitrate); - //@} - - protected: - /** - * @name Timer functions - * @brief These functions have the side effect of starting the corresponding timers. - */ - //@{ - virtual void scheduleSIFSPeriod(Ieee80211Frame *frame); - - virtual void scheduleDIFSPeriod(); - virtual void cancelDIFSPeriod(); - - virtual void scheduleAIFSPeriod(); - virtual void rescheduleAIFSPeriod(int AccessCategory); - virtual void cancelAIFSPeriod(); -//XXX virtual void checkInternalColision(); - - virtual void scheduleDataTimeoutPeriod(Ieee80211DataOrMgmtFrame *frame); - virtual void scheduleMulticastTimeoutPeriod(Ieee80211DataOrMgmtFrame *frame); - virtual void cancelTimeoutPeriod(); - - virtual void scheduleCTSTimeoutPeriod(); - - /** @brief Schedule network allocation period according to 9.2.5.4. */ - virtual void scheduleReservePeriod(Ieee80211Frame *frame); - - /** @brief Generates a new backoff period based on the contention window. */ - virtual void invalidateBackoffPeriod(); - virtual bool isInvalidBackoffPeriod(); - virtual void generateBackoffPeriod(); - virtual void decreaseBackoffPeriod(); - virtual void scheduleBackoffPeriod(); - virtual void cancelBackoffPeriod(); - virtual void finishReception(); - //@} - - protected: - /** - * @name Frame transmission functions - */ - //@{ - virtual void sendACKFrameOnEndSIFS(); - virtual void sendACKFrame(Ieee80211DataOrMgmtFrame *frame); - virtual void sendRTSFrame(Ieee80211DataOrMgmtFrame *frameToSend); - virtual void sendCTSFrameOnEndSIFS(); - virtual void sendCTSFrame(Ieee80211RTSFrame *rtsFrame); - virtual void sendDataFrameOnEndSIFS(Ieee80211DataOrMgmtFrame *frameToSend); - virtual void sendDataFrame(Ieee80211DataOrMgmtFrame *frameToSend); - virtual void sendMulticastFrame(Ieee80211DataOrMgmtFrame *frameToSend); - //@} - - protected: - /** - * @name Frame builder functions - */ - //@{ - virtual Ieee80211DataOrMgmtFrame *buildDataFrame(Ieee80211DataOrMgmtFrame *frameToSend); - virtual Ieee80211ACKFrame *buildACKFrame(Ieee80211DataOrMgmtFrame *frameToACK); - virtual Ieee80211RTSFrame *buildRTSFrame(Ieee80211DataOrMgmtFrame *frameToSend); - virtual Ieee80211CTSFrame *buildCTSFrame(Ieee80211RTSFrame *rtsFrame); - virtual Ieee80211DataOrMgmtFrame *buildMulticastFrame(Ieee80211DataOrMgmtFrame *frameToSend); - //@} - - /** - * @brief Attaches a PhyControlInfo to the frame which will cause it to be sent at - * basicBitrate not bitrate (e.g. 2Mbps instead of 11Mbps). Used with ACK, CTS, RTS. - */ - virtual Ieee80211Frame *setBasicBitrate(Ieee80211Frame *frame); - virtual Ieee80211Frame *setBitrateFrame(Ieee80211Frame *frame); - protected: - /** - * @name Utility functions - */ - //@{ - virtual void finishCurrentTransmission(); - virtual void giveUpCurrentTransmission(); - virtual void retryCurrentTransmission(); - virtual bool transmissionQueueEmpty(); - virtual unsigned int transmissionQueueSize(); - - /** @brief Mapping to access categories. */ - virtual int mappingAccessCategory(Ieee80211DataOrMgmtFrame *frame); - - /** @brief Send down the change channel message to the physical layer if there is any. */ - virtual void sendDownPendingRadioConfigMsg(); - - /** @brief Change the current MAC operation mode. */ - virtual void setMode(Mode mode); - - /** @brief Returns the current frame being transmitted */ - virtual Ieee80211DataOrMgmtFrame *getCurrentTransmission(); - - /** @brief Reset backoff, backoffPeriod and retryCounter for IDLE state */ - virtual void resetStateVariables(); - - /** @brief Used by the state machine to identify medium state change events. - This message is currently optimized away and not sent through the kernel. */ - virtual bool isMediumStateChange(cMessage *msg); - - /** @brief Tells if the medium is free according to the physical and virtual carrier sense algorithm. */ - virtual bool isMediumFree(); - - /** @brief Returns true if message is a multicast message */ - virtual bool isMulticast(Ieee80211Frame *msg); - - /** @brief Returns true if message destination address is ours */ - virtual bool isForUs(Ieee80211Frame *msg); - - /** @brief Returns true if message source address is ours */ - virtual bool isSentByUs(Ieee80211Frame *msg); - - /** @brief Checks if the frame is a data or management frame */ - virtual bool isDataOrMgmtFrame(Ieee80211Frame *frame); - - /** @brief Checks if the message is endAIFS and set currentAC */ - virtual bool isMsgAIFS(cMessage *msg); - - /** @brief Returns the last frame received before the SIFS period. */ - virtual Ieee80211Frame *getFrameReceivedBeforeSIFS(); - - /** @brief Deletes frame at the front of queue. */ - virtual void popTransmissionQueue(); - - /** - * @brief Computes the duration (in seconds) of the transmission of a frame - * over the physical channel. 'bits' should be the total length of the MAC frame - * in bits, but excluding the physical layer framing (preamble etc.) - */ - virtual double computeFrameDuration(Ieee80211Frame *msg); - virtual double computeFrameDuration(int bits, double bitrate); - - /** @brief Logs all state information */ - virtual void logState(); - - /** @brief Produce a readable name of the given MAC operation mode */ - //@} - int getTimeout(void); - virtual int getMaxBitrate(void); - virtual int getMinBitrate(void); - - virtual void reportDataOk(void); - virtual void reportDataFailed(void); - - virtual int getMinTimerTimeout(void); - virtual int getMinSuccessThreshold(void); - - virtual int getTimerTimeout(void); - virtual int getSuccessThreshold(void); - - virtual void setTimerTimeout(int timer_timeout); - virtual void setSuccessThreshold(int success_threshold); - - virtual void reportRecoveryFailure(void); - virtual void reportFailure(void); - - virtual bool needRecoveryFallback(void); - virtual bool needNormalFallback(void); - - virtual double getBitrate(); - virtual void setBitrate(double b_rate); - - virtual void resetCurrentBackOff() - { - backoff() = true; - backoffPeriod() = -1; - } - - virtual bool isBackoffPending() - { - for (unsigned int i = 0; iLimitations -// -// The following features not supported: 1) fragmentation, 2) power management, -// 3) polling (PCF). Physical layer algorithms such as frequency hopping and -// direct sequence spread spectrum are not modelled directly. -// -// Fields related to the above unsupported features are omitted from -// management frame formats as well (for example, FH/DS/CF parameter sets, -// beacon/probe timestamp which is related to physical layer synchronization, -// listen interval which is related to power management, capability information -// which is related to PCF and other non-modelled features). -// -simple Ieee80211NewMac -{ - parameters: - string address = default("auto"); // MAC address as hex string (12 hex digits), or - // "auto". "auto" values will be replaced by - // a generated MAC address in init stage 0. - string queueModule = default(""); // name of optional external queue module - int maxQueueSize = default(50); // max queue length in frames; only used if queueModule=="" - - bool EDCA = default(false); // enable Enhanced Distributed Channel Access (802.11e) - // parameters for EDCA = true - string classifier = default("Ieee80211eClassifier"); - int maxCategorieQueueSize = default(50); // Max queue length in frames per categorie; only used if queueModule=="" - int defaultAC = default(0); // the default AC category for frames that cannot be classified - int AIFSN0 = default(7); // AIFSN for background - int AIFSN1 = default(3); // AIFSN for best effort - int AIFSN2 = default(2); // AIFSN for video - int AIFSN3 = default(2); // AIFSN for voice - double TXOP0 @unit(s)= default(0s); - double TXOP1 @unit(s)= default(0s); - double TXOP2 @unit(s)= default(3.008ms); - double TXOP3 @unit(s)= default(1.504ms); - // parameters for EDCA = false - int AIFSN = default(2); // if there is only one AC (EDCA = false) - - bool useModulationParameters = default(false); // if true, slot time, DIFS, and ACK timeout (aPHY-RX-START-Delay) are function of modulation time (2007 standard) - bool prioritizeMulticast = default(false); // if true, prioritize multicast frames (9.3.2.1 Fundamental access) - - double bitrate @unit("bps"); - string opMode @enum("b","g","a","p") = default("g"); - string wifiPreambleMode @enum("LONG","SHORT") = default("LONG"); // preamble mode; see IEEE 2007, 19.3.2 - - double basicBitrate @unit("bps") = default(2e6bps); - int mtu @unit("B") = default(1500B); - double slotTime @unit("s") = default(9us); - int rtsThresholdBytes @unit("B") = default(2346B); // longer messages will be sent using RTS/CTS - int retryLimit = default(-1); // maximum number of retries per message, -1 means default - int cwMinData = default(-1); // contention window for normal data frames, -1 means default - int cwMaxData = default(-1); // contention window for normal data frames, -1 means default - int cwMinMulticast = default(-1); // contention window for broadcast messages, -1 means default - bool fixFSM = default(true); - - double phyHeaderLength = default(-1); // if -1, the MAC will compute it in function of the modulation type - bool forceBitRate = default(false); // if true, the MAC will force the bitrate to the physical layer - int autoBitrate @enum(0,1,2) = default(0); // 0 = constant bit rate (autobitrate algorithm disabled), 1 = ARF Rate, 2 = AARF Rate - // parameters used by the autobitrate - int minTimerTimeout = default(15); - int timerTimeout = default(minTimerTimeout); - int minSuccessThreshold = default(10); - int successThreshold = default(minSuccessThreshold); - int maxSuccessThreshold = default(60); - double successCoeff = default(2.0); - double timerCoeff = default(2.0); - // duplicate detection - bool duplicateDetectionFilter = default(true); // whether to detect and filter out duplicate frames - bool purgeOldTuples = default(true); // delete old tuples in the duplicate list - double duplicateTimeOut @unit("s") = default(20s); // timeout for the duplicate detection - // statistics - double throughputTimePeriod @unit("s") = default(0); // period of time used by throughput measurement statistic - bool multiMac = default(false); // allows multiples mac interfaces in the same link layer - @display("i=block/layer"); - - gates: - input upperLayerIn @labels(Ieee80211Frame); - output upperLayerOut @labels(Ieee80211Frame); - input lowerLayerIn @labels(Ieee80211Frame); - output lowerLayerOut @labels(Ieee80211Frame); -} diff --git a/src/linklayer/ieee80211/mgmt/Ieee80211MgmtAP.cc b/src/linklayer/ieee80211/mgmt/Ieee80211MgmtAP.cc index efd00b634..86ee1ab25 100644 --- a/src/linklayer/ieee80211/mgmt/Ieee80211MgmtAP.cc +++ b/src/linklayer/ieee80211/mgmt/Ieee80211MgmtAP.cc @@ -228,7 +228,6 @@ void Ieee80211MgmtAP::sendBeacon() sendOrEnqueue(frame); } -#ifdef WITH_DHCP void Ieee80211MgmtAP::handleDataFrame(Ieee80211DataFrame *frame) { // check toDS bit @@ -290,56 +289,6 @@ void Ieee80211MgmtAP::handleDataFrame(Ieee80211DataFrame *frame) } } -#else -void Ieee80211MgmtAP::handleDataFrame(Ieee80211DataFrame *frame) -{ - // check toDS bit - if (!frame->getToDS()) - { - // looks like this is not for us - discard - EV << "Frame is not for us (toDS=false) -- discarding\n"; - delete frame; - return; - } - - // handle broadcast/multicast frames - if (frame->getAddress3().isMulticast()) - { - EV << "Handling multicast frame\n"; - - if (hasRelayUnit) - sendToUpperLayer(frame->dup()); - - distributeReceivedDataFrame(frame); - return; - } - - // look up destination address in our STA list - STAList::iterator it = staList.find(frame->getAddress3()); - if (it==staList.end()) - { - // not our STA -- pass up frame to relayUnit for LAN bridging if we have one - if (hasRelayUnit) - sendToUpperLayer(frame); - else - { - EV << "Frame's destination address is not in our STA list -- dropping frame\n"; - delete frame; - } - } - else - { - // dest address is our STA, but is it already associated? - if (it->second.status == ASSOCIATED) - distributeReceivedDataFrame(frame); // send it out to the destination STA - else { - EV << "Frame's destination STA is not in associated state -- dropping frame\n"; - delete frame; - } - } -} -#endif - void Ieee80211MgmtAP::handleAuthenticationFrame(Ieee80211AuthenticationFrame *frame) { int frameAuthSeq = frame->getBody().getSequenceNumber(); diff --git a/src/linklayer/ieee80211/radio/Ieee80211NewRadio.ned b/src/linklayer/ieee80211/radio/Ieee80211NewRadio.ned deleted file mode 100644 index 2d17f4db1..000000000 --- a/src/linklayer/ieee80211/radio/Ieee80211NewRadio.ned +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright (C) Andras Varga, Levente Meszaros -// Based on the Mobility Framework's SnrEval by Marc Loebbers -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program; if not, see . -// - - -package inet.linklayer.ieee80211.radio; -import inet.linklayer.radio.Radio; -// -// Physical layer for the IEEE 802.11 models. Its external interface -// (including gates and how it communicates with other modules) -// is the same as the Radio module's. -// -// @see Radio -// @author Alfonso Ariza Quintana -// -simple Ieee80211NewRadio extends Radio -{ - parameters: - @display("i=block/wrxtx"); - radioModel = "Ieee80211NewRadioModel"; // specify the radio model responsible for modulation, error correction and frame length calculation - double snirThreshold @unit("dB") = default(4dB); // if signal-noise ratio is below this threshold, frame is considered noise (in dB) - string berTableFile = default(""); - string phyOpMode @enum("b","g","a","p") = default("g"); - string wifiPreambleMode @enum("LONG","SHORT") = default("LONG"); // Wifi preambre mode Ieee 2007, 19.3.2 - string errorModel @enum("YansModel","NistModel") = default("NistModel"); - int btSize @unit("b") = default(8192b);// test size frame for Airtime Link Metric - bool airtimeLinkComputation = default(false); - - bool AutoHeaderSize = default(false); // in the receiver the radio model compute the header size in function of timers and bitrate -} - diff --git a/src/linklayer/ieee80211/radio/Ieee80211NewRadioModel.cc b/src/linklayer/ieee80211/radio/Ieee80211NewRadioModel.cc deleted file mode 100644 index ca7c19528..000000000 --- a/src/linklayer/ieee80211/radio/Ieee80211NewRadioModel.cc +++ /dev/null @@ -1,356 +0,0 @@ -// -// Copyright (C) 2006 Andras Varga, Levente Meszaros -// Based on the Mobility Framework's SnrEval by Marc Loebbers -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU 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. -// -// 2010 Alfoso Ariza (universidad de Málaga), new radio model, inspired in the yans and ns3 models - -#include "Ieee80211NewRadioModel.h" -#include "Ieee80211Consts.h" -#include "FWMath.h" -#include "yans-error-rate-model.h" -#include "nist-error-rate-model.h" -#define NS3CALMODE - - -Register_Class(Ieee80211NewRadioModel); - -Ieee80211NewRadioModel::~Ieee80211NewRadioModel() -{ - if (parseTable) - delete parseTable; - delete errorModel; -} - - -void Ieee80211NewRadioModel::initializeFrom(cModule *radioModule) -{ - snirThreshold = dB2fraction(radioModule->par("snirThreshold").doubleValue()); - - - if (strcmp("SHORT", radioModule->par("wifiPreambleMode").stringValue())==0) - wifiPreamble = WIFI_PREAMBLE_SHORT; - else if (strcmp("LONG", radioModule->par("wifiPreambleMode").stringValue())==0) - wifiPreamble = WIFI_PREAMBLE_LONG; - else - wifiPreamble = WIFI_PREAMBLE_LONG; - - if (strcmp("b", radioModule->par("phyOpMode").stringValue())==0) - phyOpMode = 'b'; - else if (strcmp("g", radioModule->par("phyOpMode").stringValue())==0) - phyOpMode = 'g'; - else if (strcmp("a", radioModule->par("phyOpMode").stringValue())==0) - phyOpMode = 'a'; - else if (strcmp("p", radioModule->par("phyOpMode").stringValue())==0) - phyOpMode = 'p'; - else - phyOpMode = 'g'; - - if (strcmp("YansModel", radioModule->par("errorModel").stringValue())==0) - errorModel = new YansErrorRateModel(); - else if (strcmp("NistModel", radioModule->par("errorModel").stringValue())==0) - errorModel = new NistErrorRateModel(); - else - opp_error("Error %s model is not valid",radioModule->par("errorModel").stringValue()); - - - btSize = radioModule->par("btSize").longValue(); - autoHeaderSize = radioModule->par("AutoHeaderSize"); - - useTestFrame = radioModule->par("airtimeLinkComputation").boolValue(); - - parseTable = NULL; - PHY_HEADER_LENGTH = 26e-6; - - snirVector.setName("snirVector"); - i = 0; - const char *fname = radioModule->par("berTableFile"); - std::string name(fname); - if (!name.empty()) - { - parseTable = new BerParseFile(phyOpMode); - parseTable->parseFile(fname); - fileBer = true; - } - else - fileBer = false; -} - -double Ieee80211NewRadioModel::calculateDurationTestFrame(AirFrame *airframe) -{ - double duration; -#ifndef NS3CALMODE - if (phyOpMode=='g') - duration=4*ceil((16+btSize+6)/(airframe->getBitrate()/1e6*4))*1e-6 + PHY_HEADER_LENGTH; - else - // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate - duration=btSize/airframe->getBitrate() + 192/BITRATE_HEADER; -#else - ModulationType modeBody; - if (phyOpMode == 'g') - { - modeBody = WifiModulationType::getMode80211g(airframe->getBitrate()); - duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(btSize, modeBody, wifiPreamble)); - } - else if (phyOpMode == 'b') - { - // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate - modeBody = WifiModulationType::getMode80211b(airframe->getBitrate()); - duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(btSize, modeBody, wifiPreamble)); - } - else if (phyOpMode == 'a') - { - // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate - modeBody = WifiModulationType::getMode80211a(airframe->getBitrate()); - duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(btSize, modeBody, wifiPreamble)); - } - else if (phyOpMode == 'p') - { - // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate - modeBody = WifiModulationType::getMode80211p(airframe->getBitrate()); - duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(btSize, modeBody, wifiPreamble)); - } - else - opp_error("Radio model not supported yet, must be a,b,g or p"); -#endif - EV << "Radio:Test frameDuration=" << duration * 1e6 << "us(" << btSize << "bits)" << endl; - return duration; -} - -double Ieee80211NewRadioModel::calculateDuration(AirFrame *airframe) -{ - double duration; -#ifndef NS3CALMODE - if (phyOpMode=='g') - duration = 4*ceil((16+airframe->getBitLength()+6)/(airframe->getBitrate()/1e6*4))*1e-6 + PHY_HEADER_LENGTH; - else - // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate - duration = airframe->getBitLength()/airframe->getBitrate() + 192/BITRATE_HEADER; -#else - ModulationType modeBody; - if (phyOpMode=='g') - { - modeBody = WifiModulationType::getMode80211g(airframe->getBitrate()); - duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(airframe->getBitLength(), modeBody, wifiPreamble)); - } - else if (phyOpMode=='b') - { - // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate - modeBody = WifiModulationType::getMode80211b(airframe->getBitrate()); - duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(airframe->getBitLength(), modeBody, wifiPreamble)); - } - else if (phyOpMode=='a') - { - // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate - modeBody = WifiModulationType::getMode80211a(airframe->getBitrate()); - duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(airframe->getBitLength(), modeBody, wifiPreamble)); - } - else if (phyOpMode=='p') - { - // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate - modeBody = WifiModulationType::getMode80211p(airframe->getBitrate()); - duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(airframe->getBitLength(), modeBody, wifiPreamble)); - } - else - opp_error("Radio model not supported yet, must be a,b,g or p"); - - airframe->setModulationType(modeBody); -#endif - EV<<"Radio:frameDuration="<getBitLength()<<"bits)"<snr; - for (SnrList::const_iterator iter = receivedList.begin(); iter != receivedList.end(); iter++) - if (iter->snr < snirMin) - snirMin = iter->snr; - - cPacket *frame = airframe->getEncapsulatedPacket(); - EV << "packet (" << frame->getClassName() << ")" << frame->getName() << " (" << frame->info() << ") snrMin=" << snirMin << endl; - - if (i%1000==0) - { - snirVector.record(10*log10(snirMin)); - i = 0; - } - i++; - - if (snirMin <= snirThreshold) - { - // if snir is too low for the packet to be recognized - EV << "COLLISION! Packet got lost. Noise only\n"; - return false; - } - else if (isPacketOK(snirMin, frame->getBitLength(), airframe->getBitrate())) - { - EV << "packet was received correctly, it is now handed to upper layer...\n"; - return true; - } - else - { - EV << "Packet has BIT ERRORS! It is lost!\n"; - return false; - } -} - -double Ieee80211NewRadioModel::getTestFrameError(double snirMin, double bitrate) -{ - ModulationType modeBody; - ModulationType modeHeader; - - WifiPreamble preambleUsed = wifiPreamble; - double headerNoError; - uint32_t headerSize; - if (phyOpMode == 'b') - headerSize = HEADER_WITHOUT_PREAMBLE; - else - headerSize = 24; - - if (phyOpMode == 'g') - { - modeBody = WifiModulationType::getMode80211g(bitrate); - modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); - if (autoHeaderSize) - { - ModulationType modeBodyA = WifiModulationType::getMode80211a(bitrate); - headerSize = ceil( - SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration (modeBodyA, preambleUsed)) - * modeHeader.getDataRate()); - } - } - else if (phyOpMode == 'b') - { - modeBody = WifiModulationType::getMode80211b(bitrate); - modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); - if (autoHeaderSize) - headerSize = ceil( - SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration (modeBody, preambleUsed)) - * modeHeader.getDataRate()); - } - else if (phyOpMode == 'a') - { - modeBody = WifiModulationType::getMode80211a(bitrate); - modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); - if (autoHeaderSize) - headerSize = ceil( - SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration (modeBody, preambleUsed)) - * modeHeader.getDataRate()); - } - else if (phyOpMode == 'p') - { - modeBody = WifiModulationType::getMode80211p(bitrate); - modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); - if (autoHeaderSize) - headerSize = ceil( - SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration (modeBody, preambleUsed)) - * modeHeader.getDataRate()); - } - else - { - opp_error("Radio model not supported yet, must be a,b,g or p"); - } - - headerNoError = errorModel->GetChunkSuccessRate(modeHeader, snirMin, headerSize); - // probability of no bit error in the MPDU - double MpduNoError; - if (fileBer) - MpduNoError = 1 - parseTable->getPer(bitrate, snirMin, btSize / 8); - else - MpduNoError = errorModel->GetChunkSuccessRate(modeHeader, snirMin, btSize); - return (1 - (headerNoError * MpduNoError)); -} - - -bool Ieee80211NewRadioModel::isPacketOK(double snirMin, int lengthMPDU, double bitrate) -{ - double berHeader, berMPDU; - ModulationType modeBody; - ModulationType modeHeader; - - WifiPreamble preambleUsed = wifiPreamble; - double headerNoError; - uint32_t headerSize; - if (phyOpMode=='b') - headerSize = HEADER_WITHOUT_PREAMBLE; - else - headerSize = 24; - - if (phyOpMode=='g') - { - modeBody = WifiModulationType::getMode80211g(bitrate); - modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); - if (autoHeaderSize) - { - ModulationType modeBodyA = WifiModulationType::getMode80211a(bitrate); - headerSize = ceil(SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration(modeBodyA, preambleUsed))*modeHeader.getDataRate()); - } - } - else if (phyOpMode=='b') - { - modeBody = WifiModulationType::getMode80211b(bitrate); - modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); - if (autoHeaderSize) - headerSize = ceil(SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration(modeBody, preambleUsed))*modeHeader.getDataRate()); - } - else if (phyOpMode=='a') - { - modeBody = WifiModulationType::getMode80211a(bitrate); - modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); - if (autoHeaderSize) - headerSize = ceil(SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration(modeBody, preambleUsed))*modeHeader.getDataRate()); - } - else if (phyOpMode=='p') - { - modeBody = WifiModulationType::getMode80211p(bitrate); - modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); - if (autoHeaderSize) - headerSize = ceil(SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration(modeBody, preambleUsed))*modeHeader.getDataRate()); - } - else - { - opp_error("Radio model not supported yet, must be a,b,g or p"); - } - - headerNoError = errorModel->GetChunkSuccessRate(modeHeader, snirMin, headerSize); - // probability of no bit error in the MPDU - double MpduNoError; - if (fileBer) - MpduNoError = 1-parseTable->getPer(bitrate, snirMin, lengthMPDU/8); - else - MpduNoError = errorModel->GetChunkSuccessRate(modeBody, snirMin, lengthMPDU); - - EV << "berHeader: " << berHeader << " berMPDU: " <=1 && headerNoError>=1) - return true; - double rand = dblrand(); - - if (rand > headerNoError) - return false; // error in header - else if (dblrand() > MpduNoError) - return false; // error in MPDU - else - return true; // no error -} - -double Ieee80211NewRadioModel::dB2fraction(double dB) -{ - return pow(10.0, (dB / 10)); -} - diff --git a/src/linklayer/ieee80211/radio/Ieee80211NewRadioModel.h b/src/linklayer/ieee80211/radio/Ieee80211NewRadioModel.h deleted file mode 100644 index a6d79f57c..000000000 --- a/src/linklayer/ieee80211/radio/Ieee80211NewRadioModel.h +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright (C) 2006 Andras Varga, Levente Meszaros -// Based on the Mobility Framework's SnrEval by Marc Loebbers -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU 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. -// - -#ifndef IEEE80211GRADIOMODEL_H -#define IEEE80211GRADIOMODEL_H - -#include "IRadioModel.h" -#include "BerParseFile.h" -#include "IErrorModel.h" -#include "WifiPreambleType.h" - -/** - * Radio model for IEEE 802.11. The implementation is largely based on the - * Mobility Framework's SnrEval80211 and Decider80211 modules. - * See the NED file for more info. - */ - - - - -class INET_API Ieee80211NewRadioModel : public IRadioModel -{ - protected: - double snirThreshold; - cOutVector snirVector; - int i; - BerParseFile *parseTable; - bool fileBer; - - char phyOpMode; - - double PHY_HEADER_LENGTH; - IErrorModel * errorModel; - WifiPreamble wifiPreamble; - bool autoHeaderSize; - - unsigned int btSize; // - bool useTestFrame; - - public: - virtual void initializeFrom(cModule *radioModule); - - virtual double calculateDuration(AirFrame *airframe); - - virtual bool isReceivedCorrectly(AirFrame *airframe, const SnrList& receivedList); - ~Ieee80211NewRadioModel(); - - // used by the Airtime Link Metric computation - virtual bool haveTestFrame() {return useTestFrame;} - virtual double calculateDurationTestFrame(AirFrame *airframe); - virtual double getTestFrameError(double snirMin, double bitrate); - virtual int getTestFrameSize() - { - if (useTestFrame) return btSize; - else return -1; - } - protected: - // utility - virtual bool isPacketOK(double snirMin, int lengthMPDU, double bitrate); - // utility - virtual double dB2fraction(double dB); - -}; - -#endif - diff --git a/src/linklayer/ieee80211/radio/Ieee80211Radio.ned b/src/linklayer/ieee80211/radio/Ieee80211Radio.ned index dd50a85b1..f6dcb5166 100644 --- a/src/linklayer/ieee80211/radio/Ieee80211Radio.ned +++ b/src/linklayer/ieee80211/radio/Ieee80211Radio.ned @@ -1,6 +1,6 @@ // // Copyright (C) Andras Varga, Levente Meszaros -// Based on the Mobility Framework's ~SnrEval by Marc Loebbers +// Based on the Mobility Framework's SnrEval by Marc Loebbers // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License @@ -18,20 +18,14 @@ package inet.linklayer.ieee80211.radio; - import inet.linklayer.radio.Radio; - - // // Physical layer for the IEEE 802.11 models. Its external interface // (including gates and how it communicates with other modules) -// is the same as the ~IRadio module's. +// is the same as the Radio module's. // -// The implementation is largely based on the Mobility Framework's -// SnrEval80211 and Decider80211 modules. -// -// @see ~IRadio -// @author Andras Varga +// @see Radio +// @author Alfonso Ariza Quintana // simple Ieee80211Radio extends Radio { @@ -39,4 +33,13 @@ simple Ieee80211Radio extends Radio @display("i=block/wrxtx"); radioModel = "Ieee80211RadioModel"; // specify the radio model responsible for modulation, error correction and frame length calculation double snirThreshold @unit("dB") = default(4dB); // if signal-noise ratio is below this threshold, frame is considered noise (in dB) + string berTableFile = default(""); + string phyOpMode @enum("b","g","a","p") = default("g"); + string wifiPreambleMode @enum("LONG","SHORT") = default("LONG"); // Wifi preambre mode Ieee 2007, 19.3.2 + string errorModel @enum("YansModel","NistModel") = default("NistModel"); + int btSize @unit("b") = default(8192b);// test size frame for Airtime Link Metric + bool airtimeLinkComputation = default(false); + + bool AutoHeaderSize = default(false); // in the receiver the radio model compute the header size in function of timers and bitrate } + diff --git a/src/linklayer/ieee80211/radio/Ieee80211RadioModel.cc b/src/linklayer/ieee80211/radio/Ieee80211RadioModel.cc index ab72ed97e..8ddaddf1b 100644 --- a/src/linklayer/ieee80211/radio/Ieee80211RadioModel.cc +++ b/src/linklayer/ieee80211/radio/Ieee80211RadioModel.cc @@ -3,37 +3,174 @@ // Based on the Mobility Framework's SnrEval by Marc Loebbers // // This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License +// modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. +// GNU General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public License -// along with this program; if not, see . +// 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. // - +// 2010 Alfoso Ariza (universidad de Málaga), new radio model, inspired in the yans and ns3 models #include "Ieee80211RadioModel.h" #include "Ieee80211Consts.h" #include "FWMath.h" +#include "yans-error-rate-model.h" +#include "nist-error-rate-model.h" +#define NS3CALMODE Register_Class(Ieee80211RadioModel); +Ieee80211RadioModel::~Ieee80211RadioModel() +{ + if (parseTable) + delete parseTable; + delete errorModel; +} + void Ieee80211RadioModel::initializeFrom(cModule *radioModule) { snirThreshold = dB2fraction(radioModule->par("snirThreshold").doubleValue()); + + + if (strcmp("SHORT", radioModule->par("wifiPreambleMode").stringValue())==0) + wifiPreamble = WIFI_PREAMBLE_SHORT; + else if (strcmp("LONG", radioModule->par("wifiPreambleMode").stringValue())==0) + wifiPreamble = WIFI_PREAMBLE_LONG; + else + wifiPreamble = WIFI_PREAMBLE_LONG; + + if (strcmp("b", radioModule->par("phyOpMode").stringValue())==0) + phyOpMode = 'b'; + else if (strcmp("g", radioModule->par("phyOpMode").stringValue())==0) + phyOpMode = 'g'; + else if (strcmp("a", radioModule->par("phyOpMode").stringValue())==0) + phyOpMode = 'a'; + else if (strcmp("p", radioModule->par("phyOpMode").stringValue())==0) + phyOpMode = 'p'; + else + phyOpMode = 'g'; + + if (strcmp("YansModel", radioModule->par("errorModel").stringValue())==0) + errorModel = new YansErrorRateModel(); + else if (strcmp("NistModel", radioModule->par("errorModel").stringValue())==0) + errorModel = new NistErrorRateModel(); + else + opp_error("Error %s model is not valid",radioModule->par("errorModel").stringValue()); + + + btSize = radioModule->par("btSize").longValue(); + autoHeaderSize = radioModule->par("AutoHeaderSize"); + + useTestFrame = radioModule->par("airtimeLinkComputation").boolValue(); + + parseTable = NULL; + PHY_HEADER_LENGTH = 26e-6; + + snirVector.setName("snirVector"); + i = 0; + const char *fname = radioModule->par("berTableFile"); + std::string name(fname); + if (!name.empty()) + { + parseTable = new BerParseFile(phyOpMode); + parseTable->parseFile(fname); + fileBer = true; + } + else + fileBer = false; +} + +double Ieee80211RadioModel::calculateDurationTestFrame(AirFrame *airframe) +{ + double duration; +#ifndef NS3CALMODE + if (phyOpMode=='g') + duration=4*ceil((16+btSize+6)/(airframe->getBitrate()/1e6*4))*1e-6 + PHY_HEADER_LENGTH; + else + // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate + duration=btSize/airframe->getBitrate() + 192/BITRATE_HEADER; +#else + ModulationType modeBody; + if (phyOpMode == 'g') + { + modeBody = WifiModulationType::getMode80211g(airframe->getBitrate()); + duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(btSize, modeBody, wifiPreamble)); + } + else if (phyOpMode == 'b') + { + // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate + modeBody = WifiModulationType::getMode80211b(airframe->getBitrate()); + duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(btSize, modeBody, wifiPreamble)); + } + else if (phyOpMode == 'a') + { + // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate + modeBody = WifiModulationType::getMode80211a(airframe->getBitrate()); + duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(btSize, modeBody, wifiPreamble)); + } + else if (phyOpMode == 'p') + { + // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate + modeBody = WifiModulationType::getMode80211p(airframe->getBitrate()); + duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(btSize, modeBody, wifiPreamble)); + } + else + opp_error("Radio model not supported yet, must be a,b,g or p"); +#endif + EV << "Radio:Test frameDuration=" << duration * 1e6 << "us(" << btSize << "bits)" << endl; + return duration; } double Ieee80211RadioModel::calculateDuration(AirFrame *airframe) { - // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate - return airframe->getBitLength()/airframe->getBitrate() + PHY_HEADER_LENGTH/BITRATE_HEADER; + double duration; +#ifndef NS3CALMODE + if (phyOpMode=='g') + duration = 4*ceil((16+airframe->getBitLength()+6)/(airframe->getBitrate()/1e6*4))*1e-6 + PHY_HEADER_LENGTH; + else + // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate + duration = airframe->getBitLength()/airframe->getBitrate() + 192/BITRATE_HEADER; +#else + ModulationType modeBody; + if (phyOpMode=='g') + { + modeBody = WifiModulationType::getMode80211g(airframe->getBitrate()); + duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(airframe->getBitLength(), modeBody, wifiPreamble)); + } + else if (phyOpMode=='b') + { + // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate + modeBody = WifiModulationType::getMode80211b(airframe->getBitrate()); + duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(airframe->getBitLength(), modeBody, wifiPreamble)); + } + else if (phyOpMode=='a') + { + // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate + modeBody = WifiModulationType::getMode80211a(airframe->getBitrate()); + duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(airframe->getBitLength(), modeBody, wifiPreamble)); + } + else if (phyOpMode=='p') + { + // The physical layer header is sent with 1Mbit/s and the rest with the frame's bitrate + modeBody = WifiModulationType::getMode80211p(airframe->getBitrate()); + duration = SIMTIME_DBL(WifiModulationType::calculateTxDuration(airframe->getBitLength(), modeBody, wifiPreamble)); + } + else + opp_error("Radio model not supported yet, must be a,b,g or p"); + + airframe->setModulationType(modeBody); +#endif + EV<<"Radio:frameDuration="<getBitLength()<<"bits)"<getEncapsulatedPacket(); EV << "packet (" << frame->getClassName() << ")" << frame->getName() << " (" << frame->info() << ") snrMin=" << snirMin << endl; + if (i%1000==0) + { + snirVector.record(10*log10(snirMin)); + i = 0; + } + i++; + if (snirMin <= snirThreshold) { // if snir is too low for the packet to be recognized - EV << "COLLISION! Packet got lost\n"; + EV << "COLLISION! Packet got lost. Noise only\n"; return false; } - else if (isPacketOK(snirMin, airframe->getEncapsulatedPacket()->getBitLength(), airframe->getBitrate())) + else if (isPacketOK(snirMin, frame->getBitLength(), airframe->getBitrate())) { EV << "packet was received correctly, it is now handed to upper layer...\n"; return true; @@ -66,28 +210,135 @@ bool Ieee80211RadioModel::isReceivedCorrectly(AirFrame *airframe, const SnrList& } } +double Ieee80211RadioModel::getTestFrameError(double snirMin, double bitrate) +{ + ModulationType modeBody; + ModulationType modeHeader; + + WifiPreamble preambleUsed = wifiPreamble; + double headerNoError; + uint32_t headerSize; + if (phyOpMode == 'b') + headerSize = HEADER_WITHOUT_PREAMBLE; + else + headerSize = 24; + + if (phyOpMode == 'g') + { + modeBody = WifiModulationType::getMode80211g(bitrate); + modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); + if (autoHeaderSize) + { + ModulationType modeBodyA = WifiModulationType::getMode80211a(bitrate); + headerSize = ceil( + SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration (modeBodyA, preambleUsed)) + * modeHeader.getDataRate()); + } + } + else if (phyOpMode == 'b') + { + modeBody = WifiModulationType::getMode80211b(bitrate); + modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); + if (autoHeaderSize) + headerSize = ceil( + SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration (modeBody, preambleUsed)) + * modeHeader.getDataRate()); + } + else if (phyOpMode == 'a') + { + modeBody = WifiModulationType::getMode80211a(bitrate); + modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); + if (autoHeaderSize) + headerSize = ceil( + SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration (modeBody, preambleUsed)) + * modeHeader.getDataRate()); + } + else if (phyOpMode == 'p') + { + modeBody = WifiModulationType::getMode80211p(bitrate); + modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); + if (autoHeaderSize) + headerSize = ceil( + SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration (modeBody, preambleUsed)) + * modeHeader.getDataRate()); + } + else + { + opp_error("Radio model not supported yet, must be a,b,g or p"); + } + + headerNoError = errorModel->GetChunkSuccessRate(modeHeader, snirMin, headerSize); + // probability of no bit error in the MPDU + double MpduNoError; + if (fileBer) + MpduNoError = 1 - parseTable->getPer(bitrate, snirMin, btSize / 8); + else + MpduNoError = errorModel->GetChunkSuccessRate(modeHeader, snirMin, btSize); + return (1 - (headerNoError * MpduNoError)); +} + bool Ieee80211RadioModel::isPacketOK(double snirMin, int lengthMPDU, double bitrate) { double berHeader, berMPDU; + ModulationType modeBody; + ModulationType modeHeader; - berHeader = 0.5 * exp(-snirMin * BANDWIDTH / BITRATE_HEADER); - - // if PSK modulation - if (bitrate == 1E+6 || bitrate == 2E+6) - berMPDU = 0.5 * exp(-snirMin * BANDWIDTH / bitrate); - // if CCK modulation (modeled with 16-QAM) - else if (bitrate == 5.5E+6) - berMPDU = 0.5 * (1 - 1 / sqrt(pow(2.0, 4))) * erfc(snirMin * BANDWIDTH / bitrate); - else // CCK, modelled with 256-QAM - berMPDU = 0.25 * (1 - 1 / sqrt(pow(2.0, 8))) * erfc(snirMin * BANDWIDTH / bitrate); + WifiPreamble preambleUsed = wifiPreamble; + double headerNoError; + uint32_t headerSize; + if (phyOpMode=='b') + headerSize = HEADER_WITHOUT_PREAMBLE; + else + headerSize = 24; - // probability of no bit error in the PLCP header - double headerNoError = pow(1.0 - berHeader, HEADER_WITHOUT_PREAMBLE); + if (phyOpMode=='g') + { + modeBody = WifiModulationType::getMode80211g(bitrate); + modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); + if (autoHeaderSize) + { + ModulationType modeBodyA = WifiModulationType::getMode80211a(bitrate); + headerSize = ceil(SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration(modeBodyA, preambleUsed))*modeHeader.getDataRate()); + } + } + else if (phyOpMode=='b') + { + modeBody = WifiModulationType::getMode80211b(bitrate); + modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); + if (autoHeaderSize) + headerSize = ceil(SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration(modeBody, preambleUsed))*modeHeader.getDataRate()); + } + else if (phyOpMode=='a') + { + modeBody = WifiModulationType::getMode80211a(bitrate); + modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); + if (autoHeaderSize) + headerSize = ceil(SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration(modeBody, preambleUsed))*modeHeader.getDataRate()); + } + else if (phyOpMode=='p') + { + modeBody = WifiModulationType::getMode80211p(bitrate); + modeHeader = WifiModulationType::getPlcpHeaderMode(modeBody, preambleUsed); + if (autoHeaderSize) + headerSize = ceil(SIMTIME_DBL(WifiModulationType::getPlcpHeaderDuration(modeBody, preambleUsed))*modeHeader.getDataRate()); + } + else + { + opp_error("Radio model not supported yet, must be a,b,g or p"); + } + headerNoError = errorModel->GetChunkSuccessRate(modeHeader, snirMin, headerSize); // probability of no bit error in the MPDU - double MpduNoError = pow(1.0 - berMPDU, lengthMPDU); - EV << "berHeader: " << berHeader << " berMPDU: " << berMPDU << endl; + double MpduNoError; + if (fileBer) + MpduNoError = 1-parseTable->getPer(bitrate, snirMin, lengthMPDU/8); + else + MpduNoError = errorModel->GetChunkSuccessRate(modeBody, snirMin, lengthMPDU); + + EV << "berHeader: " << berHeader << " berMPDU: " <=1 && headerNoError>=1) + return true; double rand = dblrand(); if (rand > headerNoError) @@ -103,4 +354,3 @@ double Ieee80211RadioModel::dB2fraction(double dB) return pow(10.0, (dB / 10)); } - diff --git a/src/linklayer/ieee80211/radio/Ieee80211RadioModel.h b/src/linklayer/ieee80211/radio/Ieee80211RadioModel.h index ed4751e22..6689e8480 100644 --- a/src/linklayer/ieee80211/radio/Ieee80211RadioModel.h +++ b/src/linklayer/ieee80211/radio/Ieee80211RadioModel.h @@ -3,33 +3,55 @@ // Based on the Mobility Framework's SnrEval by Marc Loebbers // // This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License +// modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. +// GNU General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public License -// along with this program; if not, see . +// 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. // #ifndef IEEE80211RADIOMODEL_H #define IEEE80211RADIOMODEL_H #include "IRadioModel.h" +#include "BerParseFile.h" +#include "IErrorModel.h" +#include "WifiPreambleType.h" /** * Radio model for IEEE 802.11. The implementation is largely based on the * Mobility Framework's SnrEval80211 and Decider80211 modules. * See the NED file for more info. */ + + + + class INET_API Ieee80211RadioModel : public IRadioModel { protected: double snirThreshold; + cOutVector snirVector; + int i; + BerParseFile *parseTable; + bool fileBer; + + char phyOpMode; + + double PHY_HEADER_LENGTH; + IErrorModel * errorModel; + WifiPreamble wifiPreamble; + bool autoHeaderSize; + + unsigned int btSize; // + bool useTestFrame; public: virtual void initializeFrom(cModule *radioModule); @@ -37,16 +59,23 @@ class INET_API Ieee80211RadioModel : public IRadioModel virtual double calculateDuration(AirFrame *airframe); virtual bool isReceivedCorrectly(AirFrame *airframe, const SnrList& receivedList); + ~Ieee80211RadioModel(); + // used by the Airtime Link Metric computation - virtual bool haveTestFrame() {return false;} - virtual double calculateDurationTestFrame(AirFrame *airframe) {return 0;} - virtual double getTestFrameError(double snirMin, double bitrate) {return 0;} - virtual int getTestFrameSize() {return 0;} + virtual bool haveTestFrame() {return useTestFrame;} + virtual double calculateDurationTestFrame(AirFrame *airframe); + virtual double getTestFrameError(double snirMin, double bitrate); + virtual int getTestFrameSize() + { + if (useTestFrame) return btSize; + else return -1; + } protected: // utility virtual bool isPacketOK(double snirMin, int lengthMPDU, double bitrate); // utility virtual double dB2fraction(double dB); + }; #endif diff --git a/src/linklayer/ieee80211mesh/Ieee80211NewNicMesh.ned b/src/linklayer/ieee80211mesh/Ieee80211NewNicMesh.ned deleted file mode 100644 index 88d903dbd..000000000 --- a/src/linklayer/ieee80211mesh/Ieee80211NewNicMesh.ned +++ /dev/null @@ -1,114 +0,0 @@ -// -// Copyright (C) 2008 Alfonso Ariza -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU 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. -// -// - -package inet.linklayer.ieee80211mesh; - -import inet.linklayer.ieee80211.radio.Ieee80211NewRadio; -import inet.linklayer.ieee80211.mgmt.Ieee80211AgentSTA; -import inet.linklayer.ieee80211.mgmt.IIeee80211Mgmt; -import inet.linklayer.ieee80211.mac.Ieee80211NewMac; -import inet.linklayer.ieee80211mesh.mgmt.Ieee80211Mesh; -import inet.linklayer.IWirelessNic; -import inet.base.IHook; -import inet.linklayer.ieee80211mesh.locator.ILocator; - - -// -// This NIC implements an 802.11g network interface card in ad-hoc mode. -// -module Ieee80211NewNicMesh like IWirelessNic -{ - parameters: - string mgmtType = default("Ieee80211Mesh"); // name of the management module type (implements IIeee80211Mgmt) - string opMode @enum("b","g","a","p") = default("g"); - int numOutputHooks = default(0); - int numInputHooks = default(0); - bool _agentNeeded = false; // internal par. do not use, shows if optional agent module is needed - bool hasLocator = default(false); - @display("i=block/ifcard;bgb=259,357"); - gates: - input upperLayerIn; // to upper layers - output upperLayerOut; // from upper layers - input fromEthernet @labels(Ieee80211Frame); // to Ethernet MAC - output toEthernet @labels(Ieee80211Frame); // to Ethernet MAC - input radioIn @labels(AirFrame); // to receive AirFrames - submodules: - outputHook[numOutputHooks]: like IHook if numOutputHooks>0; - inputHook[numInputHooks]: like IHook if numInputHooks>0; - locator: like ILocator if hasLocator { - @display("i=abstract/people;p=164,182"); - } - // optional agent module (can be either 0 or 1 sized vector) - agent: Ieee80211AgentSTA if _agentNeeded { - parameters: - @display("p=202,136"); - } - mgmt: Ieee80211Mesh { - parameters: - locatorActive = hasLocator; - @display("p=96,136;q=wlanDataQueue;i=block/switch"); - gates: - macIn[1]; - macOut[1]; - } - mac: Ieee80211NewMac { - parameters: - opMode = opMode; - queueModule = "mgmt"; - @display("p=96,222"); - } - radio: Ieee80211NewRadio { - parameters: - phyOpMode = opMode; - @display("p=96,307"); - } - connections allowunconnected: - radioIn --> radio.radioIn; - radio.upperLayerIn <-- mac.lowerLayerOut; - radio.upperLayerOut --> mac.lowerLayerIn; - - mac.upperLayerOut --> mgmt.macIn[0]; - mac.upperLayerIn <-- mgmt.macOut[0]; - - mgmt.agentOut --> agent.mgmtIn if _agentNeeded; - mgmt.agentIn <-- agent.mgmtOut if _agentNeeded; - - mgmt.toEthernet --> toEthernet; - mgmt.fromEthernet <-- fromEthernet; - - mgmt.upperLayerOut --> upperLayerOut if numInputHooks == 0; - mgmt.upperLayerIn <-- upperLayerIn if numOutputHooks == 0; - - mgmt.upperLayerOut --> inputHook[0].in if numInputHooks > 0; - for i=0..numInputHooks-2 { - inputHook[i].out --> inputHook[i+1].in; - } - inputHook[numInputHooks-1].out --> upperLayerOut if numInputHooks > 0; - outputHook[0].in <-- upperLayerIn if numOutputHooks > 0; - for i=0..numOutputHooks-2 { - outputHook[i].out --> outputHook[i+1].in; - } - mgmt.upperLayerIn <-- outputHook[numOutputHooks-1].out if numOutputHooks > 0; - mgmt.locatorIn <-- locator.outGate if hasLocator; - mgmt.locatorOut --> locator.inGate if hasLocator; -} - - - - diff --git a/src/linklayer/ieee80211mesh/Ieee80211NicMesh.ned b/src/linklayer/ieee80211mesh/Ieee80211NicMesh.ned index 5602ad698..8b2855529 100644 --- a/src/linklayer/ieee80211mesh/Ieee80211NicMesh.ned +++ b/src/linklayer/ieee80211mesh/Ieee80211NicMesh.ned @@ -19,54 +19,96 @@ package inet.linklayer.ieee80211mesh; -import inet.linklayer.ieee80211mesh.mgmt.Ieee80211Mesh; import inet.linklayer.ieee80211.radio.Ieee80211Radio; +import inet.linklayer.ieee80211.mgmt.Ieee80211AgentSTA; +import inet.linklayer.ieee80211.mgmt.IIeee80211Mgmt; import inet.linklayer.ieee80211.mac.Ieee80211Mac; +import inet.linklayer.ieee80211mesh.mgmt.Ieee80211Mesh; import inet.linklayer.IWirelessNic; +import inet.base.IHook; +import inet.linklayer.ieee80211mesh.locator.ILocator; // -// This NIC implements an 802.11 network interface card in ad-hoc mode. +// This NIC implements an 802.11g network interface card in ad-hoc mode. // module Ieee80211NicMesh like IWirelessNic { parameters: - @display("i=block/ifcard"); - string mgmtType = "Ieee80211Mesh"; + string mgmtType = default("Ieee80211Mesh"); // name of the management module type (implements IIeee80211Mgmt) + string opMode @enum("b","g","a","p") = default("g"); + int numOutputHooks = default(0); + int numInputHooks = default(0); + bool _agentNeeded = false; // internal par. do not use, shows if optional agent module is needed + bool hasLocator = default(false); + @display("i=block/ifcard;bgb=259,357"); gates: input upperLayerIn; // to upper layers output upperLayerOut; // from upper layers - input radioIn; // to receive AirFrames input fromEthernet @labels(Ieee80211Frame); // to Ethernet MAC output toEthernet @labels(Ieee80211Frame); // to Ethernet MAC - + input radioIn @labels(AirFrame); // to receive AirFrames submodules: + outputHook[numOutputHooks]: like IHook if numOutputHooks>0; + inputHook[numInputHooks]: like IHook if numInputHooks>0; + locator: like ILocator if hasLocator { + @display("i=abstract/people;p=164,182"); + } + // optional agent module (can be either 0 or 1 sized vector) + agent: Ieee80211AgentSTA if _agentNeeded { + parameters: + @display("p=202,136"); + } mgmt: Ieee80211Mesh { parameters: - - @display("p=96,69;q=wlanDataQueue"); + locatorActive = hasLocator; + @display("p=96,136;q=wlanDataQueue;i=block/switch"); + gates: + macIn[1]; + macOut[1]; } mac: Ieee80211Mac { parameters: + opMode = opMode; queueModule = "mgmt"; - @display("p=96,155"); + @display("p=96,222"); } radio: Ieee80211Radio { parameters: - @display("p=96,240"); + phyOpMode = opMode; + @display("p=96,307"); } connections allowunconnected: radioIn --> radio.radioIn; radio.upperLayerIn <-- mac.lowerLayerOut; radio.upperLayerOut --> mac.lowerLayerIn; - mac.upperLayerOut --> mgmt.macIn++; - mac.upperLayerIn <-- mgmt.macOut++; - + mac.upperLayerOut --> mgmt.macIn[0]; + mac.upperLayerIn <-- mgmt.macOut[0]; - mgmt.upperLayerOut --> upperLayerOut; - mgmt.upperLayerIn <-- upperLayerIn; + mgmt.agentOut --> agent.mgmtIn if _agentNeeded; + mgmt.agentIn <-- agent.mgmtOut if _agentNeeded; + mgmt.toEthernet --> toEthernet; mgmt.fromEthernet <-- fromEthernet; + + mgmt.upperLayerOut --> upperLayerOut if numInputHooks == 0; + mgmt.upperLayerIn <-- upperLayerIn if numOutputHooks == 0; + + mgmt.upperLayerOut --> inputHook[0].in if numInputHooks > 0; + for i=0..numInputHooks-2 { + inputHook[i].out --> inputHook[i+1].in; + } + inputHook[numInputHooks-1].out --> upperLayerOut if numInputHooks > 0; + outputHook[0].in <-- upperLayerIn if numOutputHooks > 0; + for i=0..numOutputHooks-2 { + outputHook[i].out --> outputHook[i+1].in; + } + mgmt.upperLayerIn <-- outputHook[numOutputHooks-1].out if numOutputHooks > 0; + mgmt.locatorIn <-- locator.outGate if hasLocator; + mgmt.locatorOut --> locator.inGate if hasLocator; } + + + diff --git a/src/linklayer/ieee80211mesh/Ieee80211NewNicMeshMulti.ned b/src/linklayer/ieee80211mesh/Ieee80211NicMeshMulti.ned similarity index 94% rename from src/linklayer/ieee80211mesh/Ieee80211NewNicMeshMulti.ned rename to src/linklayer/ieee80211mesh/Ieee80211NicMeshMulti.ned index 047779742..c9786a387 100644 --- a/src/linklayer/ieee80211mesh/Ieee80211NewNicMeshMulti.ned +++ b/src/linklayer/ieee80211mesh/Ieee80211NicMeshMulti.ned @@ -19,10 +19,10 @@ package inet.linklayer.ieee80211mesh; -import inet.linklayer.ieee80211.radio.Ieee80211NewRadio; +import inet.linklayer.ieee80211.radio.Ieee80211Radio; import inet.linklayer.ieee80211.mgmt.Ieee80211AgentSTA; import inet.linklayer.ieee80211.mgmt.IIeee80211Mgmt; -import inet.linklayer.ieee80211.mac.Ieee80211NewMac; +import inet.linklayer.ieee80211.mac.Ieee80211Mac; import inet.linklayer.ieee80211mesh.mgmt.Ieee80211Mesh; import inet.base.IHook; import inet.linklayer.ieee80211mesh.locator.ILocator; @@ -31,7 +31,7 @@ import inet.linklayer.ieee80211mesh.locator.ILocator; // // This NIC implements an 802.11g network interface card in ad-hoc mode. // -module Ieee80211NewNicMeshMulti +module Ieee80211NicMeshMulti { parameters: string mgmtType = default("Ieee80211Mesh"); // name of the management module type (implements IIeee80211Mgmt) @@ -67,12 +67,12 @@ module Ieee80211NewNicMeshMulti macIn[numChannels]; macOut[numChannels]; } - mac[numChannels]: Ieee80211NewMac { + mac[numChannels]: Ieee80211Mac { parameters: queueModule = "mgmt"; @display("p=96,222"); } - radio[numChannels]: Ieee80211NewRadio { + radio[numChannels]: Ieee80211Radio { parameters: @display("p=96,307"); } diff --git a/src/linklayer/ieee80211mesh/nodes/ApMeshNode.ned b/src/linklayer/ieee80211mesh/nodes/ApMeshNode.ned index 2f6e91105..0135d0a1b 100644 --- a/src/linklayer/ieee80211mesh/nodes/ApMeshNode.ned +++ b/src/linklayer/ieee80211mesh/nodes/ApMeshNode.ned @@ -30,8 +30,8 @@ import inet.linklayer.IWiredNic; import inet.linklayer.IExternalNic; import inet.base.NotificationBoard; import inet.nodes.inet.NetworkLayer; -import inet.linklayer.ieee80211mesh.Ieee80211NewNicMesh; -import inet.linklayer.ieee80211mesh.Ieee80211NewNicMeshMulti; +import inet.linklayer.ieee80211mesh.Ieee80211NicMesh; +import inet.linklayer.ieee80211mesh.Ieee80211NicMeshMulti; import inet.networklayer.autorouting.ipv4.HostAutoConfigurator2; // @@ -99,7 +99,7 @@ module ApMeshNode @display("p=204,138"); } - wlanMesh: Ieee80211NewNicMeshMulti { + wlanMesh: Ieee80211NicMeshMulti { parameters: numChannels = meshChannels; @display("p=159,386;q=queue"); diff --git a/src/linklayer/ieee80211mesh/nodes/ApMeshRelay.ned b/src/linklayer/ieee80211mesh/nodes/ApMeshRelay.ned index 6e62d9b24..32d638866 100644 --- a/src/linklayer/ieee80211mesh/nodes/ApMeshRelay.ned +++ b/src/linklayer/ieee80211mesh/nodes/ApMeshRelay.ned @@ -29,8 +29,8 @@ import inet.linklayer.IWiredNic; import inet.linklayer.IExternalNic; import inet.base.NotificationBoard; import inet.nodes.inet.NetworkLayer; -import inet.linklayer.ieee80211mesh.Ieee80211NewNicMesh; -import inet.linklayer.ieee80211mesh.Ieee80211NewNicMeshMulti; +import inet.linklayer.ieee80211mesh.Ieee80211NicMesh; +import inet.linklayer.ieee80211mesh.Ieee80211NicMeshMulti; import inet.networklayer.autorouting.ipv4.HostAutoConfigurator2; // @@ -106,7 +106,7 @@ module ApMeshRelay ifOut[numRadios+1]; } - wlanMesh: Ieee80211NewNicMeshMulti { + wlanMesh: Ieee80211NicMeshMulti { parameters: mgmt.forceRelayUnit = true; @display("p=159,386;q=queue"); diff --git a/src/linklayer/ieee80211mesh/nodes/BasicMobileManetMesh.ned b/src/linklayer/ieee80211mesh/nodes/BasicMobileManetMesh.ned index 5fabf1550..1615356f9 100644 --- a/src/linklayer/ieee80211mesh/nodes/BasicMobileManetMesh.ned +++ b/src/linklayer/ieee80211mesh/nodes/BasicMobileManetMesh.ned @@ -21,8 +21,8 @@ package inet.linklayer.ieee80211mesh.nodes; import inet.base.MMapBoard; import inet.base.NotificationBoard; -import inet.linklayer.ieee80211mesh.Ieee80211NewNicMesh; -import inet.linklayer.ieee80211mesh.Ieee80211NewNicMeshMulti; +import inet.linklayer.ieee80211mesh.Ieee80211NicMesh; +import inet.linklayer.ieee80211mesh.Ieee80211NicMeshMulti; import inet.networklayer.common.InterfaceTable; import inet.base.Sink; @@ -87,7 +87,7 @@ module BasicMobileManetMesh @display("p=159,294;i=block/sink"); } // the name of radio interface must have "wlan", valid examples wlan, wlan802, localwlan .... - wlan: Ieee80211NewNicMeshMulti { + wlan: Ieee80211NicMeshMulti { parameters: numChannels = meshChannels; @display("p=159,386;q=queue"); diff --git a/src/linklayer/ieee80211mesh/nodes/gateWayMesh.ned b/src/linklayer/ieee80211mesh/nodes/gateWayMesh.ned index c8b1af682..20e61aa7a 100644 --- a/src/linklayer/ieee80211mesh/nodes/gateWayMesh.ned +++ b/src/linklayer/ieee80211mesh/nodes/gateWayMesh.ned @@ -30,8 +30,8 @@ import inet.linklayer.IWiredNic; import inet.linklayer.IExternalNic; import inet.base.NotificationBoard; import inet.nodes.inet.NetworkLayer; -import inet.linklayer.ieee80211mesh.Ieee80211NewNicMesh; -import inet.linklayer.ieee80211mesh.Ieee80211NewNicMeshMulti; +import inet.linklayer.ieee80211mesh.Ieee80211NicMesh; +import inet.linklayer.ieee80211mesh.Ieee80211NicMeshMulti; import inet.networklayer.autorouting.ipv4.HostAutoConfigurator2; import inet.transport.IUDP; @@ -142,7 +142,7 @@ module gateWayMesh @display("p=183,233"); } - wlanMesh: Ieee80211NewNicMeshMulti { + wlanMesh: Ieee80211NicMeshMulti { parameters: numChannels = meshChannels; @display("p=159,386;q=queue"); diff --git a/src/mobility/ChangeLog b/src/mobility/ChangeLog index 9466630ba..3a51653e1 100644 --- a/src/mobility/ChangeLog +++ b/src/mobility/ChangeLog @@ -1,3 +1,8 @@ +2012-06-08 Rudolf Hornig + + Added LinearNodeDistributionMobility and TRACIMobility from the + INETMANET project. + 2012-05-18 Rudolf Hornig Mobility models now correctly refer to the constraint area. @@ -5,7 +10,6 @@ 2012-04-27 Levente Meszaros Mobility: added default icon - 2012-03-20 ------ inet-1.99.4 released ------ 2012-02-24 ------ inet-1.99.3 released ------ diff --git a/src/mobility/models/LinealNodeDistributionMobility.cc b/src/mobility/models/LinearNodeDistributionMobility.cc similarity index 85% rename from src/mobility/models/LinealNodeDistributionMobility.cc rename to src/mobility/models/LinearNodeDistributionMobility.cc index 93636b622..c2b645fa0 100644 --- a/src/mobility/models/LinealNodeDistributionMobility.cc +++ b/src/mobility/models/LinearNodeDistributionMobility.cc @@ -17,13 +17,13 @@ */ -#include "LinealNodeDistributionMobility.h" +#include "LinearNodeDistributionMobility.h" -Define_Module(LinealNodeDistributionMobility); +Define_Module(LinearNodeDistributionMobility); -LinealNodeDistributionMobility::LinealNodeDistributionMobility() +LinearNodeDistributionMobility::LinearNodeDistributionMobility() { initialX = 0; initialY = 0; @@ -31,7 +31,7 @@ LinealNodeDistributionMobility::LinealNodeDistributionMobility() orientation = 0; } -void LinealNodeDistributionMobility::initialize(int stage) +void LinearNodeDistributionMobility::initialize(int stage) { MobilityBase::initialize(stage); EV << "initializing StaticGridMobility stage " << stage << endl; @@ -44,7 +44,7 @@ void LinealNodeDistributionMobility::initialize(int stage) } } -void LinealNodeDistributionMobility::initializePosition() +void LinearNodeDistributionMobility::initializePosition() { int index = visualRepresentation->getIndex(); double rad = PI * orientation / 180.0; @@ -61,7 +61,7 @@ void LinealNodeDistributionMobility::initializePosition() lastPosition.z = 0; } -void LinealNodeDistributionMobility::finish() +void LinearNodeDistributionMobility::finish() { MobilityBase::finish(); recordScalar("x", lastPosition.x); diff --git a/src/mobility/models/LinealNodeDistributionMobility.h b/src/mobility/models/LinearNodeDistributionMobility.h similarity index 93% rename from src/mobility/models/LinealNodeDistributionMobility.h rename to src/mobility/models/LinearNodeDistributionMobility.h index b151c607c..4b04cc6eb 100644 --- a/src/mobility/models/LinealNodeDistributionMobility.h +++ b/src/mobility/models/LinearNodeDistributionMobility.h @@ -32,7 +32,7 @@ * @ingroup mobility * @author Alfonso Ariza */ -class INET_API LinealNodeDistributionMobility : public StationaryMobility +class INET_API LinearNodeDistributionMobility : public StationaryMobility { protected: @@ -52,7 +52,7 @@ class INET_API LinealNodeDistributionMobility : public StationaryMobility virtual void finish(); public: - LinealNodeDistributionMobility(); + LinearNodeDistributionMobility(); }; #endif diff --git a/src/mobility/models/LinealNodeDistributionMobility.ned b/src/mobility/models/LinearNodeDistributionMobility.ned similarity index 79% rename from src/mobility/models/LinealNodeDistributionMobility.ned rename to src/mobility/models/LinearNodeDistributionMobility.ned index cee078201..676fca46b 100644 --- a/src/mobility/models/LinealNodeDistributionMobility.ned +++ b/src/mobility/models/LinearNodeDistributionMobility.ned @@ -16,20 +16,18 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // - package inet.mobility.models; - // -// Places all nodes in a rectangular grid. +// Mobility model which places all hosts at constant distances +// in a line with an orientation // -// @see ~ChannelControl -// @author Isabel Dietrich +// @author Alfonso Ariza // -simple LinealNodeDistributionMobility extends StationaryMobility +simple LinearNodeDistributionMobility extends StationaryMobility { parameters: double separation @unit(m); double orientation @unit(deg) = default(0deg); - @class(LinealNodeDistributionMobility); + @class(LinearNodeDistributionMobility); } diff --git a/src/mobility/models/TraCIMobility.cc b/src/mobility/models/TraCIMobility.cc index 932de2564..47524243c 100644 --- a/src/mobility/models/TraCIMobility.cc +++ b/src/mobility/models/TraCIMobility.cc @@ -1,5 +1,5 @@ // -// Copyright (C) 2006-2011 Christoph Sommer +// Copyright (C) 2006-2012 Christoph Sommer // // Documentation for these modules is at http://veins.car2x.org/ // @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +#ifdef WITH_TRACI + #include #include #include @@ -30,80 +32,80 @@ namespace { const double MY_INFINITY = (std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : std::numeric_limits::max()); double roadIdAsDouble(std::string road_id) { - std::istringstream iss(road_id); - double d; - if (!(iss >> d)) return MY_INFINITY; - return d; + std::istringstream iss(road_id); + double d; + if (!(iss >> d)) return MY_INFINITY; + return d; } } void TraCIMobility::Statistics::initialize() { - firstRoadNumber = MY_INFINITY; - startTime = simTime(); - totalTime = 0; - stopTime = 0; - minSpeed = MY_INFINITY; - maxSpeed = -MY_INFINITY; - totalDistance = 0; - totalCO2Emission = 0; + firstRoadNumber = MY_INFINITY; + startTime = simTime(); + totalTime = 0; + stopTime = 0; + minSpeed = MY_INFINITY; + maxSpeed = -MY_INFINITY; + totalDistance = 0; + totalCO2Emission = 0; } void TraCIMobility::Statistics::watch(cSimpleModule& ) { - WATCH(totalTime); - WATCH(minSpeed); - WATCH(maxSpeed); - WATCH(totalDistance); + WATCH(totalTime); + WATCH(minSpeed); + WATCH(maxSpeed); + WATCH(totalDistance); } void TraCIMobility::Statistics::recordScalars(cSimpleModule& module) { - if (firstRoadNumber != MY_INFINITY) module.recordScalar("firstRoadNumber", firstRoadNumber); - module.recordScalar("startTime", startTime); - module.recordScalar("totalTime", totalTime); - module.recordScalar("stopTime", stopTime); - if (minSpeed != MY_INFINITY) module.recordScalar("minSpeed", minSpeed); - if (maxSpeed != -MY_INFINITY) module.recordScalar("maxSpeed", maxSpeed); - module.recordScalar("totalDistance", totalDistance); - module.recordScalar("totalCO2Emission", totalCO2Emission); + if (firstRoadNumber != MY_INFINITY) module.recordScalar("firstRoadNumber", firstRoadNumber); + module.recordScalar("startTime", startTime); + module.recordScalar("totalTime", totalTime); + module.recordScalar("stopTime", stopTime); + if (minSpeed != MY_INFINITY) module.recordScalar("minSpeed", minSpeed); + if (maxSpeed != -MY_INFINITY) module.recordScalar("maxSpeed", maxSpeed); + module.recordScalar("totalDistance", totalDistance); + module.recordScalar("totalCO2Emission", totalCO2Emission); } void TraCIMobility::initialize(int stage) { if (stage == 0) { - debug = par("debug"); - accidentCount = par("accidentCount"); + debug = par("debug"); + accidentCount = par("accidentCount"); - currentPosXVec.setName("posx"); - currentPosYVec.setName("posy"); - currentSpeedVec.setName("speed"); - currentAccelerationVec.setName("acceleration"); - currentCO2EmissionVec.setName("co2emission"); + currentPosXVec.setName("posx"); + currentPosYVec.setName("posy"); + currentSpeedVec.setName("speed"); + currentAccelerationVec.setName("acceleration"); + currentCO2EmissionVec.setName("co2emission"); - statistics.initialize(); - statistics.watch(*this); + statistics.initialize(); + statistics.watch(*this); - WATCH(road_id); - WATCH(speed); - WATCH(angle); - WATCH(lastPosition.x); - WATCH(lastPosition.y); + WATCH(road_id); + WATCH(speed); + WATCH(angle); + WATCH(lastPosition.x); + WATCH(lastPosition.y); - startAccidentMsg = 0; - stopAccidentMsg = 0; - manager = 0; - last_speed = -1; + startAccidentMsg = 0; + stopAccidentMsg = 0; + manager = 0; + last_speed = -1; if (accidentCount > 0) { - simtime_t accidentStart = par("accidentStart"); - startAccidentMsg = new cMessage("scheduledAccident"); - stopAccidentMsg = new cMessage("scheduledAccidentResolved"); - scheduleAt(simTime() + accidentStart, startAccidentMsg); - } + simtime_t accidentStart = par("accidentStart"); + startAccidentMsg = new cMessage("scheduledAccident"); + stopAccidentMsg = new cMessage("scheduledAccidentResolved"); + scheduleAt(simTime() + accidentStart, startAccidentMsg); + } if (ev.isGUI()) updateDisplayString(); - } + } MobilityBase::initialize(stage); } @@ -115,189 +117,191 @@ void TraCIMobility::initializePosition() { void TraCIMobility::finish() { - statistics.stopTime = simTime(); + statistics.stopTime = simTime(); - statistics.recordScalars(*this); + statistics.recordScalars(*this); - cancelAndDelete(startAccidentMsg); - cancelAndDelete(stopAccidentMsg); + cancelAndDelete(startAccidentMsg); + cancelAndDelete(stopAccidentMsg); - isPreInitialized = false; + isPreInitialized = false; } void TraCIMobility::handleSelfMessage(cMessage *msg) { if (msg == startAccidentMsg) { - commandSetSpeed(0); - simtime_t accidentDuration = par("accidentDuration"); - scheduleAt(simTime() + accidentDuration, stopAccidentMsg); - accidentCount--; - } + commandSetSpeed(0); + simtime_t accidentDuration = par("accidentDuration"); + scheduleAt(simTime() + accidentDuration, stopAccidentMsg); + accidentCount--; + } else if (msg == stopAccidentMsg) { - commandSetSpeed(-1); + commandSetSpeed(-1); if (accidentCount > 0) { - simtime_t accidentInterval = par("accidentInterval"); - scheduleAt(simTime() + accidentInterval, startAccidentMsg); - } - } + simtime_t accidentInterval = par("accidentInterval"); + scheduleAt(simTime() + accidentInterval, startAccidentMsg); + } + } } void TraCIMobility::preInitialize(std::string external_id, const Coord& position, std::string road_id, double speed, double angle) { - this->external_id = external_id; - this->lastUpdate = 0; - nextPos = position; - lastPosition = position; - this->road_id = road_id; - this->speed = speed; - this->angle = angle; - - isPreInitialized = true; + this->external_id = external_id; + this->lastUpdate = 0; + nextPos = position; + lastPosition = position; + this->road_id = road_id; + this->speed = speed; + this->angle = angle; + + isPreInitialized = true; } -void TraCIMobility::nextPosition(const Coord& position, std::string road_id, double speed, double angle) +void TraCIMobility::nextPosition(const Coord& position, std::string road_id, double speed, double angle, TraCIScenarioManager::VehicleSignal signals) { - if (debug) EV << "nextPosition " << position.x << " " << position.y << " " << road_id << " " << speed << " " << angle << std::endl; - isPreInitialized = false; - nextPos = position; - this->road_id = road_id; - this->speed = speed; - this->angle = angle; + if (debug) EV << "nextPosition " << position.x << " " << position.y << " " << road_id << " " << speed << " " << angle << std::endl; + isPreInitialized = false; + nextPos = position; + this->road_id = road_id; + this->speed = speed; + this->angle = angle; + this->signals = signals; move(); } void TraCIMobility::move() { - // ensure we're not called twice in one time step - ASSERT(lastUpdate != simTime()); + // ensure we're not called twice in one time step + ASSERT(lastUpdate != simTime()); - // keep statistics (for current step) - currentPosXVec.record(lastPosition.x); - currentPosYVec.record(lastPosition.y); + // keep statistics (for current step) + currentPosXVec.record(lastPosition.x); + currentPosYVec.record(lastPosition.y); - // keep statistics (relative to last step) + // keep statistics (relative to last step) if (statistics.startTime != simTime()) { - simtime_t updateInterval = simTime() - this->lastUpdate; - this->lastUpdate = simTime(); + simtime_t updateInterval = simTime() - this->lastUpdate; + this->lastUpdate = simTime(); - double distance = lastPosition.distance(nextPos); - statistics.totalDistance += distance; - statistics.totalTime += updateInterval; + double distance = lastPosition.distance(nextPos); + statistics.totalDistance += distance; + statistics.totalTime += updateInterval; if (speed != -1) { - statistics.minSpeed = std::min(statistics.minSpeed, speed); - statistics.maxSpeed = std::max(statistics.maxSpeed, speed); - currentSpeedVec.record(speed); + statistics.minSpeed = std::min(statistics.minSpeed, speed); + statistics.maxSpeed = std::max(statistics.maxSpeed, speed); + currentSpeedVec.record(speed); if (last_speed != -1) { - double acceleration = (speed - last_speed) / updateInterval; - double co2emission = calculateCO2emission(speed, acceleration); - currentAccelerationVec.record(acceleration); - currentCO2EmissionVec.record(co2emission); + double acceleration = (speed - last_speed) / updateInterval; + double co2emission = calculateCO2emission(speed, acceleration); + currentAccelerationVec.record(acceleration); + currentCO2EmissionVec.record(co2emission); statistics.totalCO2Emission+=co2emission * updateInterval.dbl(); - } - last_speed = speed; + } + last_speed = speed; } else { - last_speed = -1; - speed = -1; - } - } + last_speed = -1; + speed = -1; + } + } - lastPosition = nextPos; + lastPosition = nextPos; if (ev.isGUI()) updateDisplayString(); - fixIfHostGetsOutside(); + fixIfHostGetsOutside(); emitMobilityStateChangedSignal(); - updateVisualRepresentation(); + updateVisualRepresentation(); } void TraCIMobility::updateDisplayString() { - ASSERT(-M_PI <= angle); - ASSERT(angle < M_PI); + ASSERT(-M_PI <= angle); + ASSERT(angle < M_PI); - getParentModule()->getDisplayString().setTagArg("b", 2, "rect"); - getParentModule()->getDisplayString().setTagArg("b", 3, "red"); - getParentModule()->getDisplayString().setTagArg("b", 4, "red"); - getParentModule()->getDisplayString().setTagArg("b", 5, "0"); + getParentModule()->getDisplayString().setTagArg("b", 2, "rect"); + getParentModule()->getDisplayString().setTagArg("b", 3, "red"); + getParentModule()->getDisplayString().setTagArg("b", 4, "red"); + getParentModule()->getDisplayString().setTagArg("b", 5, "0"); if (angle < -M_PI + 0.5 * M_PI_4 * 1) { - getParentModule()->getDisplayString().setTagArg("t", 0, "\u2190"); - getParentModule()->getDisplayString().setTagArg("b", 0, "4"); - getParentModule()->getDisplayString().setTagArg("b", 1, "2"); - } + getParentModule()->getDisplayString().setTagArg("t", 0, "\u2190"); + getParentModule()->getDisplayString().setTagArg("b", 0, "4"); + getParentModule()->getDisplayString().setTagArg("b", 1, "2"); + } else if (angle < -M_PI + 0.5 * M_PI_4 * 3) { - getParentModule()->getDisplayString().setTagArg("t", 0, "\u2199"); - getParentModule()->getDisplayString().setTagArg("b", 0, "3"); - getParentModule()->getDisplayString().setTagArg("b", 1, "3"); - } + getParentModule()->getDisplayString().setTagArg("t", 0, "\u2199"); + getParentModule()->getDisplayString().setTagArg("b", 0, "3"); + getParentModule()->getDisplayString().setTagArg("b", 1, "3"); + } else if (angle < -M_PI + 0.5 * M_PI_4 * 5) { - getParentModule()->getDisplayString().setTagArg("t", 0, "\u2193"); - getParentModule()->getDisplayString().setTagArg("b", 0, "2"); - getParentModule()->getDisplayString().setTagArg("b", 1, "4"); - } + getParentModule()->getDisplayString().setTagArg("t", 0, "\u2193"); + getParentModule()->getDisplayString().setTagArg("b", 0, "2"); + getParentModule()->getDisplayString().setTagArg("b", 1, "4"); + } else if (angle < -M_PI + 0.5 * M_PI_4 * 7) { - getParentModule()->getDisplayString().setTagArg("t", 0, "\u2198"); - getParentModule()->getDisplayString().setTagArg("b", 0, "3"); - getParentModule()->getDisplayString().setTagArg("b", 1, "3"); - } + getParentModule()->getDisplayString().setTagArg("t", 0, "\u2198"); + getParentModule()->getDisplayString().setTagArg("b", 0, "3"); + getParentModule()->getDisplayString().setTagArg("b", 1, "3"); + } else if (angle < -M_PI + 0.5 * M_PI_4 * 9) { - getParentModule()->getDisplayString().setTagArg("t", 0, "\u2192"); - getParentModule()->getDisplayString().setTagArg("b", 0, "4"); - getParentModule()->getDisplayString().setTagArg("b", 1, "2"); - } + getParentModule()->getDisplayString().setTagArg("t", 0, "\u2192"); + getParentModule()->getDisplayString().setTagArg("b", 0, "4"); + getParentModule()->getDisplayString().setTagArg("b", 1, "2"); + } else if (angle < -M_PI + 0.5 * M_PI_4 * 11) { - getParentModule()->getDisplayString().setTagArg("t", 0, "\u2197"); - getParentModule()->getDisplayString().setTagArg("b", 0, "3"); - getParentModule()->getDisplayString().setTagArg("b", 1, "3"); - } + getParentModule()->getDisplayString().setTagArg("t", 0, "\u2197"); + getParentModule()->getDisplayString().setTagArg("b", 0, "3"); + getParentModule()->getDisplayString().setTagArg("b", 1, "3"); + } else if (angle < -M_PI + 0.5 * M_PI_4 * 13) { - getParentModule()->getDisplayString().setTagArg("t", 0, "\u2191"); - getParentModule()->getDisplayString().setTagArg("b", 0, "2"); - getParentModule()->getDisplayString().setTagArg("b", 1, "4"); - } + getParentModule()->getDisplayString().setTagArg("t", 0, "\u2191"); + getParentModule()->getDisplayString().setTagArg("b", 0, "2"); + getParentModule()->getDisplayString().setTagArg("b", 1, "4"); + } else if (angle < -M_PI + 0.5 * M_PI_4 * 15) { - getParentModule()->getDisplayString().setTagArg("t", 0, "\u2196"); - getParentModule()->getDisplayString().setTagArg("b", 0, "3"); - getParentModule()->getDisplayString().setTagArg("b", 1, "3"); - } + getParentModule()->getDisplayString().setTagArg("t", 0, "\u2196"); + getParentModule()->getDisplayString().setTagArg("b", 0, "3"); + getParentModule()->getDisplayString().setTagArg("b", 1, "3"); + } else { - getParentModule()->getDisplayString().setTagArg("t", 0, "\u2190"); - getParentModule()->getDisplayString().setTagArg("b", 0, "4"); - getParentModule()->getDisplayString().setTagArg("b", 1, "2"); - } + getParentModule()->getDisplayString().setTagArg("t", 0, "\u2190"); + getParentModule()->getDisplayString().setTagArg("b", 0, "4"); + getParentModule()->getDisplayString().setTagArg("b", 1, "2"); + } } void TraCIMobility::fixIfHostGetsOutside() { - raiseErrorIfOutside(); + raiseErrorIfOutside(); } double TraCIMobility::calculateCO2emission(double v, double a) const { - // Calculate CO2 emission parameters according to: - // Cappiello, A. and Chabini, I. and Nam, E.K. and Lue, A. and Abou Zeid, M., "A statistical model of vehicle emissions and fuel consumption," IEEE 5th International Conference on Intelligent Transportation Systems (IEEE ITSC), pp. 801-809, 2002 + // Calculate CO2 emission parameters according to: + // Cappiello, A. and Chabini, I. and Nam, E.K. and Lue, A. and Abou Zeid, M., "A statistical model of vehicle emissions and fuel consumption," IEEE 5th International Conference on Intelligent Transportation Systems (IEEE ITSC), pp. 801-809, 2002 - double A = 1000 * 0.1326; // W/m/s - double B = 1000 * 2.7384e-03; // W/(m/s)^2 - double C = 1000 * 1.0843e-03; // W/(m/s)^3 - double M = 1325.0; // kg + double A = 1000 * 0.1326; // W/m/s + double B = 1000 * 2.7384e-03; // W/(m/s)^2 + double C = 1000 * 1.0843e-03; // W/(m/s)^3 + double M = 1325.0; // kg - // power in W + // power in W double P_tract = A*v + B*v*v + C*v*v*v + M*a*v; // for sloped roads: +M*g*sin_theta*v - /* - // "Category 7 vehicle" (e.g. a '92 Suzuki Swift) - double alpha = 1.01; - double beta = 0.0162; - double delta = 1.90e-06; - double zeta = 0.252; - double alpha1 = 0.985; - */ - - // "Category 9 vehicle" (e.g. a '94 Dodge Spirit) - double alpha = 1.11; - double beta = 0.0134; - double delta = 1.98e-06; - double zeta = 0.241; - double alpha1 = 0.973; + /* + // "Category 7 vehicle" (e.g. a '92 Suzuki Swift) + double alpha = 1.01; + double beta = 0.0162; + double delta = 1.90e-06; + double zeta = 0.252; + double alpha1 = 0.985; + */ + + // "Category 9 vehicle" (e.g. a '94 Dodge Spirit) + double alpha = 1.11; + double beta = 0.0134; + double delta = 1.98e-06; + double zeta = 0.241; + double alpha1 = 0.973; if (P_tract <= 0) return alpha1; return alpha + beta*v*3.6 + delta*v*v*v*(3.6*3.6*3.6) + zeta*a*v; } +#endif diff --git a/src/mobility/models/TraCIMobility.h b/src/mobility/models/TraCIMobility.h index c40f6e1e3..3957f0e16 100644 --- a/src/mobility/models/TraCIMobility.h +++ b/src/mobility/models/TraCIMobility.h @@ -1,5 +1,5 @@ // -// Copyright (C) 2006-2011 Christoph Sommer +// Copyright (C) 2006-2012 Christoph Sommer // // Documentation for these modules is at http://veins.car2x.org/ // @@ -20,25 +20,34 @@ #ifndef MOBILITY_TRACI_TRACIMOBILITY_H #define MOBILITY_TRACI_TRACIMOBILITY_H +#ifdef WITH_TRACI #include #include #include #include +#include + #include "MobilityBase.h" #include "ModuleAccess.h" #include "world/traci/TraCIScenarioManager.h" /** * @brief - * TraCIMobility is a mobility module for hosts controlled by TraCIScenarioManager. - * It receives position and state updates from an external module and updates - * the parent module accordingly. - * See NED file for more info. + * Used in modules created by the TraCIScenarioManager. + * + * This module relies on the TraCIScenarioManager for state updates + * and can not be used on its own. + * + * See the Veins website for a tutorial, documentation, and publications . + * + * @author Christoph Sommer, David Eckhoff, Luca Bedogni, Bastian Halmos + * + * @see TraCIScenarioManager + * @see TraCIScenarioManagerLaunchd * * @ingroup mobility - * @author Christoph Sommer */ class INET_API TraCIMobility : public MobilityBase { @@ -73,7 +82,7 @@ class INET_API TraCIMobility : public MobilityBase virtual void handleSelfMessage(cMessage *msg); virtual void preInitialize(std::string external_id, const Coord& position, std::string road_id = "", double speed = -1, double angle = -1); - virtual void nextPosition(const Coord& position, std::string road_id = "", double speed = -1, double angle = -1); + virtual void nextPosition(const Coord& position, std::string road_id = "", double speed = -1, double angle = -1, TraCIScenarioManager::VehicleSignal signals = TraCIScenarioManager::VEH_SIGNAL_UNDEF); virtual void move(); virtual void updateDisplayString(); virtual void setExternalId(std::string external_id) { @@ -94,6 +103,10 @@ class INET_API TraCIMobility : public MobilityBase if (speed == -1) throw cRuntimeError("TraCIMobility::getSpeed called with no speed set yet"); return speed; } + virtual TraCIScenarioManager::VehicleSignal getSignals() const { + if (signals == -1) throw cRuntimeError("TraCIMobility::getSignals called with no signals set yet"); + return signals; + } /** * returns angle in rads, 0 being east, with -M_PI <= angle < M_PI. */ @@ -114,6 +127,14 @@ class INET_API TraCIMobility : public MobilityBase void commandChangeRoute(std::string roadId, double travelTime) { getManager()->commandChangeRoute(getExternalId(), roadId, travelTime); } + + void commandNewRoute(std::string roadId) { + getManager()->commandNewRoute(getExternalId(), roadId); + } + void commandParkVehicle() { + getManager()->commandSetVehicleParking(getExternalId()); + } + double commandDistanceRequest(Coord position1, Coord position2, bool returnDrivingDistance) { return getManager()->commandDistanceRequest(position1, position2, returnDrivingDistance); } @@ -157,6 +178,7 @@ class INET_API TraCIMobility : public MobilityBase std::string road_id; /**< updated by nextPosition() */ double speed; /**< updated by nextPosition() */ double angle; /**< updated by nextPosition() */ + TraCIScenarioManager::VehicleSignal signals; /** #endif +#endif diff --git a/src/mobility/models/TraCIMobility.ned b/src/mobility/models/TraCIMobility.ned index ab325f92c..02908f472 100644 --- a/src/mobility/models/TraCIMobility.ned +++ b/src/mobility/models/TraCIMobility.ned @@ -1,5 +1,5 @@ // -// Copyright (C) 2006-2011 Christoph Sommer +// Copyright (C) 2006-2012 Christoph Sommer // // Documentation for these modules is at http://veins.car2x.org/ // @@ -21,9 +21,17 @@ package inet.mobility.models; // -// TraCIMobility is a mobility module for hosts controlled by TraCIScenarioManager. -// It receives position and state updates from an external module and updates -// the parent module accordingly. +// Used in modules created by the TraCIScenarioManager. +// +// This module relies on the TraCIScenarioManager for state updates +// and can not be used on its own. +// +// See the Veins website for a tutorial, documentation, and publications . +// +// @author Christoph Sommer, David Eckhoff, Luca Bedogni, Bastian Halmos +// +// @see TraCIScenarioManager +// @see TraCIScenarioManagerLaunchd // simple TraCIMobility extends MobilityBase { diff --git a/src/networklayer/autorouting/ipv4/ChangeLog b/src/networklayer/autorouting/ipv4/ChangeLog index e4d89a856..17b22b32d 100644 --- a/src/networklayer/autorouting/ipv4/ChangeLog +++ b/src/networklayer/autorouting/ipv4/ChangeLog @@ -1,3 +1,10 @@ +2012-06-18 Rudolf Hornig + + Added HostAutoConfigurator module (as it is required by the TraCI modules/examples) + This configurator is deprectaed and should be used ONLY if the hosts are + dynamically created/deleted during the simulation. Otherwise please use the + new IPv4NetworkConfigurator. + 2012-06-15 Zoltan Bojthe IPv4NetworkConfigurator: diff --git a/src/networklayer/autorouting/ipv4/HostAutoConfigurator.cc b/src/networklayer/autorouting/ipv4/HostAutoConfigurator.cc index 494124de0..092c6ee67 100644 --- a/src/networklayer/autorouting/ipv4/HostAutoConfigurator.cc +++ b/src/networklayer/autorouting/ipv4/HostAutoConfigurator.cc @@ -1,21 +1,21 @@ /* -* HostAutoConfigurator - automatically assigns IP addresses and sets up routing table -* Copyright (C) 2009 Christoph Sommer -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ + * HostAutoConfigurator - automatically assigns IP addresses and sets up routing table + * Copyright (C) 2009 Christoph Sommer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ #include #include @@ -28,109 +28,80 @@ #include "IInterfaceTable.h" #include "IPv4Address.h" - Define_Module(HostAutoConfigurator); -void HostAutoConfigurator::initialize(int stage) -{ - cSimpleModule::initialize(stage); - - if (stage == 0) - { - debug = par("debug").boolValue(); - } - else if (stage == 2) - { - setupNetworkLayer(); - } -} +void HostAutoConfigurator::initialize(int stage) { + cSimpleModule::initialize(stage); -void HostAutoConfigurator::finish() -{ + if (stage == 0) { + debug = par("debug").boolValue(); + } + else if (stage == 2) { + setupNetworkLayer(); + } } -void HostAutoConfigurator::handleMessage(cMessage* apMsg) -{ +void HostAutoConfigurator::finish() { } -void HostAutoConfigurator::handleSelfMsg(cMessage* apMsg) -{ -} -namespace -{ -void addToMcastGroup(InterfaceEntry* ie, IRoutingTable* routingTable, const IPv4Address& mcastGroup) -{ - IPv4InterfaceData::IPv4AddressVector mcg = ie->ipv4Data()->getJoinedMulticastGroups(); - - if (std::find(mcg.begin(), mcg.end(), mcastGroup) == mcg.end()) - ie->ipv4Data()->joinMulticastGroup(mcastGroup); - - IPv4Route* re = new IPv4Route(); //TODO: add @c delete to destructor - re->setDestination(mcastGroup); - re->setNetmask(IPv4Address::ALLONES_ADDRESS); // TODO: can't set this to none? - re->setGateway(IPv4Address()); // none - re->setInterface(ie); - re->setSource(IPv4Route::MANUAL); - re->setMetric(1); - routingTable->addRoute(re); +void HostAutoConfigurator::handleMessage(cMessage* apMsg) { } + +void HostAutoConfigurator::handleSelfMsg(cMessage* apMsg) { } void HostAutoConfigurator::setupNetworkLayer() { - EV << "host auto configuration started" << std::endl; - - std::string interfaces = par("interfaces").stringValue(); - IPv4Address addressBase = IPv4Address(par("addressBase").stringValue()); - IPv4Address netmask = IPv4Address(par("netmask").stringValue()); - std::string mcastGroups = par("mcastGroups").stringValue(); - IPv4Address myAddress = IPv4Address(addressBase.getInt() + uint32(getParentModule()->getId())); - - // get our host module - cModule* host = getParentModule(); - if (!host) throw std::runtime_error("No parent module found"); - - // get our routing table - IRoutingTable* routingTable = IPvXAddressResolver().routingTableOf(host); - if (!routingTable) throw std::runtime_error("No routing table found"); - - // get our interface table - IInterfaceTable *ift = IPvXAddressResolver().interfaceTableOf(host); - if (!ift) throw std::runtime_error("No interface table found"); - - // look at all interface table entries - cStringTokenizer interfaceTokenizer(interfaces.c_str()); - const char *ifname; - while ((ifname = interfaceTokenizer.nextToken()) != NULL) - { - InterfaceEntry* ie = ift->getInterfaceByName(ifname); - if (!ie) throw std::runtime_error("No such interface"); - - // assign IP Address to all connected interfaces - if (ie->isLoopback()) - { - EV << "interface " << ifname << " skipped (is loopback)" << std::endl; - continue; - } - - EV << "interface " << ifname << " gets " << myAddress.str() << "/" << netmask.str() << std::endl; - - ie->ipv4Data()->setIPAddress(myAddress); - ie->ipv4Data()->setNetmask(netmask); - ie->setBroadcast(true); - - // associate interface with default multicast groups - addToMcastGroup(ie, routingTable, IPv4Address::ALL_HOSTS_MCAST); - addToMcastGroup(ie, routingTable, IPv4Address::ALL_ROUTERS_MCAST); - - // associate interface with specified multicast groups - cStringTokenizer interfaceTokenizer(mcastGroups.c_str()); - const char *mcastGroup_s; - while ((mcastGroup_s = interfaceTokenizer.nextToken()) != NULL) - { - IPv4Address mcastGroup(mcastGroup_s); - addToMcastGroup(ie, routingTable, mcastGroup); - } - } + EV << "host auto configuration started" << std::endl; + + std::string interfaces = par("interfaces").stringValue(); + IPv4Address addressBase = IPv4Address(par("addressBase").stringValue()); + IPv4Address netmask = IPv4Address(par("netmask").stringValue()); + std::string mcastGroups = par("mcastGroups").stringValue(); + IPv4Address myAddress = IPv4Address(addressBase.getInt() + uint32(getParentModule()->getId())); + + // get our host module + cModule* host = getParentModule(); + if (!host) throw std::runtime_error("No parent module found"); + + // get our routing table + IRoutingTable* routingTable = IPvXAddressResolver().routingTableOf(host); + if (!routingTable) throw std::runtime_error("No routing table found"); + + // get our interface table + IInterfaceTable *ift = IPvXAddressResolver().interfaceTableOf(host); + if (!ift) throw std::runtime_error("No interface table found"); + + // look at all interface table entries + cStringTokenizer interfaceTokenizer(interfaces.c_str()); + const char *ifname; + while ((ifname = interfaceTokenizer.nextToken()) != NULL) { + InterfaceEntry* ie = ift->getInterfaceByName(ifname); + if (!ie) throw std::runtime_error("No such interface"); + + // assign IP Address to all connected interfaces + if (ie->isLoopback()) { + EV << "interface " << ifname << " skipped (is loopback)" << std::endl; + continue; + } + + EV << "interface " << ifname << " gets " << myAddress.str() << "/" << netmask.str() << std::endl; + + ie->ipv4Data()->setIPAddress(myAddress); + ie->ipv4Data()->setNetmask(netmask); + ie->setBroadcast(true); + + // associate interface with default multicast groups + ie->ipv4Data()->joinMulticastGroup(IPv4Address::ALL_HOSTS_MCAST); + ie->ipv4Data()->joinMulticastGroup(IPv4Address::ALL_ROUTERS_MCAST); + + // associate interface with specified multicast groups + cStringTokenizer interfaceTokenizer(mcastGroups.c_str()); + const char *mcastGroup_s; + while ((mcastGroup_s = interfaceTokenizer.nextToken()) != NULL) { + IPv4Address mcastGroup(mcastGroup_s); + ie->ipv4Data()->joinMulticastGroup(mcastGroup); + } + } } diff --git a/src/networklayer/autorouting/ipv4/HostAutoConfigurator.h b/src/networklayer/autorouting/ipv4/HostAutoConfigurator.h index b29ab6296..ce99b5143 100644 --- a/src/networklayer/autorouting/ipv4/HostAutoConfigurator.h +++ b/src/networklayer/autorouting/ipv4/HostAutoConfigurator.h @@ -1,21 +1,21 @@ /* -* HostAutoConfigurator - automatically assigns IP addresses and sets up routing table -* Copyright (C) 2009 Christoph Sommer -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ + * HostAutoConfigurator - automatically assigns IP addresses and sets up routing table + * Copyright (C) 2009 Christoph Sommer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ #ifndef NETWORKLAYER_AUTOROUTING_HOSTAUTOCONFIGURATOR_H #define NETWORKLAYER_AUTOROUTING_HOSTAUTOCONFIGURATOR_H @@ -24,24 +24,24 @@ #include "INETDefs.h" /** -* HostAutoConfigurator automatically assigns IP addresses and sets up routing table. -* -* @author Christoph Sommer -*/ + * HostAutoConfigurator automatically assigns IP addresses and sets up routing table. + * + * @author Christoph Sommer + */ class INET_API HostAutoConfigurator : public cSimpleModule { - public: - virtual void initialize(int stage); - virtual void finish(); - virtual int numInitStages() const {return 3;} + public: + virtual void initialize(int stage); + virtual void finish(); + virtual int numInitStages() const {return 3;} - virtual void handleMessage(cMessage *msg); - virtual void handleSelfMsg(cMessage *msg); + virtual void handleMessage(cMessage *msg); + virtual void handleSelfMsg(cMessage *msg); - protected: - void setupNetworkLayer(); + protected: + void setupNetworkLayer(); - bool debug; /**< whether to emit debug messages */ + bool debug; /**< whether to emit debug messages */ }; #endif diff --git a/src/networklayer/autorouting/ipv4/HostAutoConfigurator.ned b/src/networklayer/autorouting/ipv4/HostAutoConfigurator.ned index f9eaebbde..1a7df396c 100644 --- a/src/networklayer/autorouting/ipv4/HostAutoConfigurator.ned +++ b/src/networklayer/autorouting/ipv4/HostAutoConfigurator.ned @@ -6,21 +6,25 @@ // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // - + package inet.networklayer.autorouting.ipv4; - + // // HostAutoConfigurator automatically assigns IP addresses and sets up routing table. +// +// This configurator is deprecated. Please use IPv4NetworkCOnfigurator whenever it is possible. +// This module is kept only because the IPv4networkConfigurator cannot assign IP addresses +// to modules that are dynamically created/destroyed. // simple HostAutoConfigurator { diff --git a/src/networklayer/manetrouting/ChangeLog b/src/networklayer/manetrouting/ChangeLog index b62d67054..7ab78979b 100644 --- a/src/networklayer/manetrouting/ChangeLog +++ b/src/networklayer/manetrouting/ChangeLog @@ -1,3 +1,16 @@ +2012-06-15 Zoltan Bojthe + + IPv4Route: removed RouteType type field and getType(), setType() + functions + + OMNeT++ 4.3 compatibility fixes - for cClassDescriptor changes + cClassDescriptor::getArraySize() renamed to getFieldArraySize() + +2012-06-09 Rudolf Hornig + + Code taken over from the INETMAMNET-2.0 repository. + Some IFDEFs were added to make it compile without the + 80211MESH module which is not present in INET. 2012-03-20 ------ inet-1.99.4 released ------ 2012-02-24 ------ inet-1.99.3 released ------ diff --git a/src/networklayer/manetrouting/base/ManetRoutingBase.cc b/src/networklayer/manetrouting/base/ManetRoutingBase.cc index a57cd5f22..cdbf3ead3 100644 --- a/src/networklayer/manetrouting/base/ManetRoutingBase.cc +++ b/src/networklayer/manetrouting/base/ManetRoutingBase.cc @@ -111,6 +111,9 @@ bool ManetTimer::isScheduled() ManetRoutingBase::ManetRoutingBase() { +#ifdef WITH_80211MESH + locator = NULL; +#endif isRegistered = false; regPosition = false; mac_layer_ = false; @@ -122,7 +125,6 @@ ManetRoutingBase::ManetRoutingBase() staticNode = false; colaborativeProtocol = NULL; arp = NULL; - locator = NULL; isGateway = false; proxyAddress.clear(); addressGroupVector.clear(); @@ -309,6 +311,7 @@ void ManetRoutingBase::registerRoutingModule() nb->subscribe(this,NF_L2_AP_DISASSOCIATED); nb->subscribe(this,NF_L2_AP_ASSOCIATED); +#ifdef WITH_80211MESH locator = LocatorModuleAccess().getIfExists(); if (locator) { @@ -320,6 +323,7 @@ void ManetRoutingBase::registerRoutingModule() nb->subscribe(this,NF_LOCATOR_ASSOC); nb->subscribe(this,NF_LOCATOR_DISASSOC); } +#endif if (par("PublicRoutingTables").boolValue()) { @@ -817,6 +821,7 @@ void ManetRoutingBase::omnet_chg_rte(const Uint128 &dst, const Uint128 >wy, co } } +#ifdef WITH_80211MESH if (locator && locator->isApIp(desAddress) && del_entry) { std::vector list; @@ -836,6 +841,7 @@ void ManetRoutingBase::omnet_chg_rte(const Uint128 &dst, const Uint128 >wy, co } } } +#endif if (del_entry) return; @@ -879,6 +885,7 @@ void ManetRoutingBase::omnet_chg_rte(const Uint128 &dst, const Uint128 >wy, co /// routing protocol name otherwise entry->setSource(routeSource); inet_rt->addRoute(entry); +#ifdef WITH_80211MESH if (locator && locator->isApIp(desAddress)) { std::vector list; @@ -912,6 +919,7 @@ void ManetRoutingBase::omnet_chg_rte(const Uint128 &dst, const Uint128 >wy, co inet_rt->addRoute(entry); } } +#endif } // This methods use the nic index to identify the output nic. @@ -953,6 +961,7 @@ void ManetRoutingBase::omnet_chg_rte(const Uint128 &dst, const Uint128 >wy, co } } +#ifdef WITH_80211MESH if (locator && locator->isApIp(desAddress) && del_entry) { std::vector list; @@ -972,7 +981,7 @@ void ManetRoutingBase::omnet_chg_rte(const Uint128 &dst, const Uint128 >wy, co } } } - +#endif if (del_entry) return; @@ -1020,6 +1029,7 @@ void ManetRoutingBase::omnet_chg_rte(const Uint128 &dst, const Uint128 >wy, co inet_rt->addRoute(entry); +#ifdef WITH_80211MESH if (locator && locator->isApIp(desAddress)) { std::vector list; @@ -1053,6 +1063,7 @@ void ManetRoutingBase::omnet_chg_rte(const Uint128 &dst, const Uint128 >wy, co inet_rt->addRoute(e); } } +#endif } @@ -1173,10 +1184,12 @@ void ManetRoutingBase::receiveChangeNotification(int category, const cObject *de } } } +#ifdef WITH_80211MESH else if(category == NF_LOCATOR_ASSOC) processLocatorAssoc(details); else if(category == NF_LOCATOR_DISASSOC) processLocatorDisAssoc(details); +#endif } void ManetRoutingBase::receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj) @@ -1490,6 +1503,7 @@ bool ManetRoutingBase::setRoute(const Uint128 & destination, const Uint128 &next } } +#ifdef WITH_80211MESH if (locator && locator->isApIp(desAddress) && del_entry) { std::vector list; @@ -1509,7 +1523,7 @@ bool ManetRoutingBase::setRoute(const Uint128 & destination, const Uint128 &next } } } - +#endif if (del_entry) return true; @@ -1551,6 +1565,7 @@ bool ManetRoutingBase::setRoute(const Uint128 & destination, const Uint128 &next inet_rt->addRoute(entry); +#ifdef WITH_80211MESH if (locator && locator->isApIp(desAddress)) { std::vector list; @@ -1584,6 +1599,7 @@ bool ManetRoutingBase::setRoute(const Uint128 & destination, const Uint128 &next inet_rt->addRoute(e); } } +#endif return true; } @@ -1817,6 +1833,7 @@ bool ManetRoutingBase::addressIsForUs(const Uint128 &addr) const bool ManetRoutingBase::getAp(const Uint128 &destination, Uint128& accesPointAddr) const { +#ifdef WITH_80211MESH if (locator == NULL) return false; if (isInMacLayer()) @@ -1834,44 +1851,41 @@ bool ManetRoutingBase::getAp(const Uint128 &destination, Uint128& accesPointAddr accesPointAddr = ipAddr.getInt(); } return true; +#else + return false; +#endif } void ManetRoutingBase::getApList(const MACAddress & dest,std::vector& list) { - list.clear(); - if (locator == NULL) - { - list.push_back(dest); - return; - } - else + list.clear(); +#ifdef WITH_80211MESH + if (locator) { MACAddress ap = locator->getLocatorMacToMac(dest); if (!ap.isUnspecified()) locator->getApList(ap,list); else locator->getApList(dest,list); - list.push_back(dest); } +#endif + list.push_back(dest); } void ManetRoutingBase::getApListIp(const IPv4Address &dest,std::vector& list) { list.clear(); - if (locator == NULL) - { - list.push_back(dest); - return; - } - else +#ifdef WITH_80211MESH + if (locator) { IPv4Address ap = locator->getLocatorIpToIp(dest); if (!ap.isUnspecified()) locator->getApListIp(ap,list); else locator->getApListIp(dest,list); - list.push_back(dest); } +#endif + list.push_back(dest); } void ManetRoutingBase::getListRelatedAp(const Uint128 & add, std::vector& list) @@ -1900,12 +1914,16 @@ void ManetRoutingBase::getListRelatedAp(const Uint128 & add, std::vectorisThisAp(); else - return locator->isThisApIp(); + return locator->isThisApIp(); +#else + return false; +#endif } diff --git a/src/networklayer/manetrouting/base/ManetRoutingBase.h b/src/networklayer/manetrouting/base/ManetRoutingBase.h index b70edaf7c..d7f72a42b 100644 --- a/src/networklayer/manetrouting/base/ManetRoutingBase.h +++ b/src/networklayer/manetrouting/base/ManetRoutingBase.h @@ -33,7 +33,9 @@ #include "uint128.h" #include "NotifierConsts.h" #include "ICMP.h" +#ifdef WITH_80211MESH #include "ILocator.h" +#endif #include "ARP.h" #include #include @@ -131,7 +133,9 @@ class INET_API ManetRoutingBase : public cSimpleModule, public INotifiable, prot bool isGateway; std::vector proxyAddress; +#ifdef WITH_80211MESH ILocator *locator; +#endif protected: ~ManetRoutingBase(); diff --git a/src/networklayer/manetrouting/dsr/dsr-pkt_omnet.cc b/src/networklayer/manetrouting/dsr/dsr-pkt_omnet.cc index a44497ab5..a8942b339 100644 --- a/src/networklayer/manetrouting/dsr/dsr-pkt_omnet.cc +++ b/src/networklayer/manetrouting/dsr/dsr-pkt_omnet.cc @@ -154,7 +154,9 @@ DSRPkt::DSRPkt(struct dsr_pkt *dp, int interface_id) : IPv4Datagram() memcpy((char*)options, (char*)opth, dsr_pkt_opts_len(dp)); setBitLength(getBitLength()+((DSR_OPT_HDR_LEN+options->p_len)*8)); setHeaderLength(getByteLength()); +#ifdef NEWFRAGMENT setTotalPayloadLength(dp->totalPayloadLength); +#endif if (dp->payload) { encapsulate(dp->payload); diff --git a/src/networklayer/manetrouting/dsr/dsr-uu-omnetpp.cc b/src/networklayer/manetrouting/dsr/dsr-uu-omnetpp.cc index 360b6a53c..06920ce5b 100644 --- a/src/networklayer/manetrouting/dsr/dsr-uu-omnetpp.cc +++ b/src/networklayer/manetrouting/dsr/dsr-uu-omnetpp.cc @@ -171,7 +171,9 @@ void DSRUU::omnet_deliver(struct dsr_pkt *dp) dgram->setIdentification(dp->nh.iph->id); // Identification dgram->setMoreFragments(dp->nh.iph->tos & 0x2000); dgram->setDontFragment(dp->nh.iph->frag_off & 0x4000); +#ifdef NEWFRAGMENT dgram->setTotalPayloadLength(dp->totalPayloadLength); +#endif dgram->setTimeToLive(dp->nh.iph->ttl); // TTL dgram->setTransportProtocol(dp->encapsulate_protocol); // Transport protocol @@ -986,7 +988,7 @@ double DSRUU::PathCost(struct dsr_pkt *dp) cost = getCost(dp->costVector[dp->costVectorSize-1].address); else { - cost = getCost(IPv4Address(dp->src.s_addr)); + cost = getCost(IPv4Address(dp->src.s_addr)); } if (cost<0) diff --git a/src/networklayer/manetrouting/dsr/dsr-uu/dsr-pkt.cc b/src/networklayer/manetrouting/dsr/dsr-uu/dsr-pkt.cc index 97b8099a0..ee164a5a6 100644 --- a/src/networklayer/manetrouting/dsr/dsr-uu/dsr-pkt.cc +++ b/src/networklayer/manetrouting/dsr/dsr-uu/dsr-pkt.cc @@ -290,7 +290,9 @@ dsr_pkt * dsr_pkt_alloc(cPacket * p) // dp->nh.iph->check= p->; // Check sum dp->nh.iph->saddr= dgram->getSrcAddress().getInt(); dp->nh.iph->daddr= dgram->getDestAddress().getInt(); +#ifdef NEWFRAGMENT dp->totalPayloadLength = dgram->getTotalPayloadLength(); +#endif //if (dgram->getFragmentOffset()==0 && !dgram->getMoreFragments()) dp->payload = p->decapsulate(); //else diff --git a/src/networklayer/manetrouting/dymo/dymo_um_omnet.cc b/src/networklayer/manetrouting/dymo/dymo_um_omnet.cc index cabb6fa01..d739278a9 100644 --- a/src/networklayer/manetrouting/dymo/dymo_um_omnet.cc +++ b/src/networklayer/manetrouting/dymo/dymo_um_omnet.cc @@ -42,8 +42,9 @@ #include "IPv4Address.h" #include "IPvXAddress.h" #include "ControlManetRouting_m.h" +#ifdef WITH_80211MESH #include "LocatorNotificationInfo_m.h" - +#endif const int UDP_HEADER_BYTES = 8; typedef std::vector IPAddressVector; @@ -1766,6 +1767,7 @@ int DYMOUM::re_info_type(struct re_block *b, rtable_entry_t *e, u_int8_t is_rreq void DYMOUM::processLocatorAssoc(const cObject *details) { +#ifdef WITH_80211MESH LocatorNotificationInfo *infoLoc = check_and_cast(details); Uint128 destAddr = infoLoc->getMacAddr().getInt(); Uint128 apAddr; @@ -1804,10 +1806,12 @@ void DYMOUM::processLocatorAssoc(const cObject *details) } return; } +#endif } void DYMOUM::processLocatorDisAssoc(const cObject *details) { +#ifdef WITH_80211MESH LocatorNotificationInfo *infoLoc = check_and_cast(details); Uint128 destAddr = infoLoc->getMacAddr().getInt(); if (isInMacLayer()) @@ -1826,5 +1830,6 @@ void DYMOUM::processLocatorDisAssoc(const cObject *details) rtable_delete(fwd_rt); return; } +#endif } diff --git a/src/networklayer/ospfv2/router/OSPFRoutingTableEntry.cc b/src/networklayer/ospfv2/router/OSPFRoutingTableEntry.cc index 2c8325caa..80176bc94 100644 --- a/src/networklayer/ospfv2/router/OSPFRoutingTableEntry.cc +++ b/src/networklayer/ospfv2/router/OSPFRoutingTableEntry.cc @@ -148,6 +148,7 @@ std::ostream& operator<<(std::ostream& out, const OSPF::RoutingTableEntry& entry case OSPF::RoutingTableEntry::TYPE2_EXTERNAL: out << "Type2External"; break; default: out << "Unknown"; break; } + out << ", iface: " << entry.getInterfaceName(); out << ", Cost: " << entry.getCost() << ", Type2Cost: " << entry.getType2Cost() << ", Origin: ["; diff --git a/src/transport/contract/ChangeLog b/src/transport/contract/ChangeLog index 34bbd6f24..aeef7a628 100644 --- a/src/transport/contract/ChangeLog +++ b/src/transport/contract/ChangeLog @@ -1,3 +1,9 @@ +2012-06-12 Rudolf Hornig + + Code takover from INETMANET-2.0: + UDPSocket: Added the possibility to specify the output interface when + sending an UDP packet. + 2012-03-20 ------ inet-1.99.4 released ------ 2012-02-24 ------ inet-1.99.3 released ------ diff --git a/src/transport/contract/UDPSocket.h b/src/transport/contract/UDPSocket.h index d62534023..929820d35 100644 --- a/src/transport/contract/UDPSocket.h +++ b/src/transport/contract/UDPSocket.h @@ -178,8 +178,8 @@ class INET_API UDPSocket void sendTo(cPacket *msg, IPvXAddress destAddr, int destPort); /** - * Causes the socket to leave each multicast groups that are registered with - * any of the interfaces. + * Sends a data packet to the given address and port using the provided + * interface. */ void sendTo(cPacket *msg, IPvXAddress destAddr, int destPort, int outInterface); diff --git a/src/transport/udp/ChangeLog b/src/transport/udp/ChangeLog index 7b7b2b087..94648528f 100644 --- a/src/transport/udp/ChangeLog +++ b/src/transport/udp/ChangeLog @@ -3,6 +3,11 @@ Fixed feature-related bugfix: possible memory leak if packet is multicast and IPv4 or IPv6 feature is disabled +2012-06-12 Rudolf Hornig + + Code takover from INETMANET-2.0: + Added the possibility to specify the output interface when + sending an UDP packet. 2012-03-20 ------ inet-1.99.4 released ------ 2012-03-12 Tamas Borbely diff --git a/src/transport/udp/UDP.cc b/src/transport/udp/UDP.cc index 8cebe4d94..3e5707fab 100644 --- a/src/transport/udp/UDP.cc +++ b/src/transport/udp/UDP.cc @@ -236,18 +236,13 @@ void UDP::processPacketFromApp(cPacket *appData) if (destAddr.isUnspecified() || destPort == -1) error("send: missing destination address or port when sending over unconnected port"); - int interfaceId = -1; - if (ctrl->getInterfaceId() == -1) + int interfaceId = ctrl->getInterfaceId(); + if (interfaceId == -1 && destAddr.isMulticast()) { - if (destAddr.isMulticast()) - { - std::map::iterator it = sd->multicastAddrs.find(destAddr); - interfaceId = (it != sd->multicastAddrs.end() && it->second != -1) ? it->second : sd->multicastOutputInterfaceId; - } - sendDown(appData, sd->localAddr, sd->localPort, destAddr, destPort, interfaceId, sd->multicastLoop, sd->ttl, sd->typeOfService); + std::map::iterator it = sd->multicastAddrs.find(destAddr); + interfaceId = (it != sd->multicastAddrs.end() && it->second != -1) ? it->second : sd->multicastOutputInterfaceId; } - else - sendDown(appData, sd->localAddr, sd->localPort, destAddr, destPort, ctrl->getInterfaceId(), sd->multicastLoop, sd->ttl, sd->typeOfService); + sendDown(appData, sd->localAddr, sd->localPort, destAddr, destPort, interfaceId, sd->multicastLoop, sd->ttl, sd->typeOfService); delete ctrl; // cannot be deleted earlier, due to destAddr } @@ -423,34 +418,33 @@ void UDP::processUndeliverablePacket(UDPPacket *udpPacket, cObject *ctrl) // send back ICMP PORT_UNREACHABLE if (dynamic_cast(ctrl) != NULL) { +#ifdef WITH_IPv4 IPv4ControlInfo *ctrl4 = (IPv4ControlInfo *)ctrl; - bool isMulticast = ctrl4->getDestAddr().isMulticast(); - bool isBroadcast = ctrl4->getDestAddr() == IPv4Address::ALLONES_ADDRESS; - if (!isMulticast && !isBroadcast) + + if (!ctrl4->getDestAddr().isMulticast() && !ctrl4->getDestAddr().isLimitedBroadcastAddress()) { -#ifdef WITH_IPv4 if (!icmp) icmp = ICMPAccess().get(); icmp->sendErrorMessage(udpPacket, ctrl4, ICMP_DESTINATION_UNREACHABLE, ICMP_DU_PORT_UNREACHABLE); -#endif } else - delete udpPacket; // drop multicast packet +#endif + delete udpPacket; } else if (dynamic_cast(ctrl) != NULL) { +#ifdef WITH_IPv6 IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl; if (!ctrl6->getDestAddr().isMulticast()) { -#ifdef WITH_IPv6 if (!icmpv6) icmpv6 = ICMPv6Access().get(); icmpv6->sendErrorMessage(udpPacket, ctrl6, ICMPv6_DESTINATION_UNREACHABLE, PORT_UNREACHABLE); -#endif } else - delete udpPacket; // drop multicast packet +#endif + delete udpPacket; } else if (ctrl == NULL) { diff --git a/src/underTest/linklayer/ieee80211/mgmt/Ieee80211NicExtended.ned b/src/underTest/linklayer/ieee80211/mgmt/Ieee80211NicExtended.ned index c6d30f870..334069874 100644 --- a/src/underTest/linklayer/ieee80211/mgmt/Ieee80211NicExtended.ned +++ b/src/underTest/linklayer/ieee80211/mgmt/Ieee80211NicExtended.ned @@ -16,10 +16,10 @@ // @author: Juan-Carlos Maureira // package inet.underTest.linklayer.ieee80211.mgmt; -import inet.linklayer.ieee80211.radio.Ieee80211NewRadio; +import inet.linklayer.ieee80211.radio.Ieee80211Radio; import inet.underTest.linklayer.ieee80211.mgmt.Ieee80211AgentSTAExtended; import inet.linklayer.ieee80211.mgmt.IIeee80211Mgmt; -import inet.linklayer.ieee80211.mac.Ieee80211NewMac; +import inet.linklayer.ieee80211.mac.Ieee80211Mac; import inet.linklayer.IWirelessNic; import inet.base.IHook; import inet.linklayer.ieee80211.mgmt.IIeee80211Mgmt; @@ -60,13 +60,13 @@ module Ieee80211NicExtended like IWirelessNic parameters: @display("p=96,136;q=wlanDataQueue"); } - mac: Ieee80211NewMac { + mac: Ieee80211Mac { parameters: opMode = opMode; queueModule = "mgmt"; @display("p=96,222"); } - radio: Ieee80211NewRadio { + radio: Ieee80211Radio { parameters: @display("p=96,307"); } diff --git a/src/underTest/nodes/wireless/WirelessRouterExtended.ned b/src/underTest/nodes/wireless/WirelessRouterExtended.ned index b6e38e275..718bb99fb 100644 --- a/src/underTest/nodes/wireless/WirelessRouterExtended.ned +++ b/src/underTest/nodes/wireless/WirelessRouterExtended.ned @@ -28,7 +28,7 @@ import inet.nodes.inet.NetworkLayer; import inet.applications.IPingApp; import inet.applications.ITCPApp; import inet.applications.IUDPApp; -import inet.linklayer.ieee80211.Ieee80211NewNic; +import inet.linklayer.ieee80211.Ieee80211Nic; import inet.transport.udp.UDP; import inet.transport.tcp.TCP; import inet.mobility.models.StationaryMobility; diff --git a/src/world/traci/ChangeLog b/src/world/traci/ChangeLog new file mode 100644 index 000000000..103230b32 --- /dev/null +++ b/src/world/traci/ChangeLog @@ -0,0 +1,12 @@ +2012-06-19 + + Removed unnecessary dependency from the radio feature. + +2012-06-18 Rudolf Hornig + + Synchronized with https://github.com/sommer/inet-sommer.git + +2012-06-08 Rudolf Hornig + + Initial commit of TRACI scenario mamanger from the + INETMANET project. diff --git a/src/world/traci/TraCIScenarioManager.cc b/src/world/traci/TraCIScenarioManager.cc index 7cadbe364..84da75165 100644 --- a/src/world/traci/TraCIScenarioManager.cc +++ b/src/world/traci/TraCIScenarioManager.cc @@ -1,5 +1,5 @@ // -// Copyright (C) 2006-2011 Christoph Sommer +// Copyright (C) 2006-2012 Christoph Sommer // // Documentation for these modules is at http://veins.car2x.org/ // @@ -52,11 +52,16 @@ void TraCIScenarioManager::initialize(int stage) { return; } + debug = par("debug"); + connectAt = par("connectAt"); + firstStepAt = par("firstStepAt"); updateInterval = par("updateInterval"); + if (firstStepAt == -1) firstStepAt = connectAt + updateInterval; moduleType = par("moduleType").stdstringValue(); moduleName = par("moduleName").stdstringValue(); moduleDisplayString = par("moduleDisplayString").stdstringValue(); + penetrationRate = par("penetrationRate").doubleValue(); host = par("host").stdstringValue(); port = par("port"); autoShutdown = par("autoShutdown"); @@ -94,16 +99,13 @@ void TraCIScenarioManager::initialize(int stage) { activeVehicleCount = 0; autoShutdownTriggered = false; - executeOneTimestepTrigger = new cMessage("step"); - scheduleAt(0, executeOneTimestepTrigger); - - cc = dynamic_cast(simulation.getModuleByPath("channelControl")); - if (cc == 0) error("Could not find a ChannelControl module named channelControl"); - - MYDEBUG << "TraCIScenarioManager connecting to TraCI server" << endl; socketPtr = 0; - connect(); - init_traci(); + + ASSERT(firstStepAt > connectAt); + connectAndStartTrigger = new cMessage("connect"); + scheduleAt(connectAt, connectAndStartTrigger); + executeOneTimestepTrigger = new cMessage("step"); + scheduleAt(firstStepAt, executeOneTimestepTrigger); MYDEBUG << "initialized TraCIScenarioManager" << endl; } @@ -226,6 +228,8 @@ TraCIScenarioManager::TraCIBuffer TraCIScenarioManager::queryTraCIOptional(uint8 } void TraCIScenarioManager::connect() { + MYDEBUG << "TraCIScenarioManager connecting to TraCI server" << endl; + if (initsocketlibonce() != 0) error("Could not init socketlib"); in_addr addr; @@ -349,6 +353,11 @@ void TraCIScenarioManager::handleMessage(cMessage *msg) { } void TraCIScenarioManager::handleSelfMsg(cMessage *msg) { + if (msg == connectAndStartTrigger) { + connect(); + init_traci(); + return; + } if (msg == executeOneTimestepTrigger) { executeOneTimestep(); return; @@ -595,6 +604,14 @@ bool TraCIScenarioManager::commandAddVehicle(std::string vehicleId, std::string void TraCIScenarioManager::addModule(std::string nodeId, std::string type, std::string name, std::string displayString, const Coord& position, std::string road_id, double speed, double angle) { if (hosts.find(nodeId) != hosts.end()) error("tried adding duplicate module"); + double option1 = hosts.size() / (hosts.size() + unEquippedHosts.size() + 1.0); + double option2 = (hosts.size() + 1) / (hosts.size() + unEquippedHosts.size() + 1.0); + + if (fabs(option1 - penetrationRate) < fabs(option2 - penetrationRate)) { + unEquippedHosts.insert(nodeId); + return; + } + int32_t nodeVectorIndex = nextNodeVectorIndex++; cModule* parentmod = getParentModule(); @@ -627,6 +644,11 @@ cModule* TraCIScenarioManager::getManagedModule(std::string nodeId) { return hosts[nodeId]; } +bool TraCIScenarioManager::isModuleUnequipped(std::string nodeId) { + if (unEquippedHosts.find(nodeId) == unEquippedHosts.end()) return false; + return true; +} + void TraCIScenarioManager::deleteModule(std::string nodeId) { cModule* mod = getManagedModule(nodeId); if (!mod) error("no vehicle with Id \"%s\" found", nodeId.c_str()); @@ -663,7 +685,7 @@ void TraCIScenarioManager::executeOneTimestep() { uint32_t targetTime = getCurrentTimeMs(); - if (targetTime > 0) { + if (targetTime > round(connectAt.dbl() * 1000)) { TraCIBuffer buf = queryTraCI(CMD_SIMSTEP2, TraCIBuffer() << targetTime); uint32_t count; buf >> count; @@ -868,13 +890,14 @@ void TraCIScenarioManager::subscribeToVehicleVariables(std::string vehicleId) { uint32_t beginTime = 0; uint32_t endTime = 0x7FFFFFFF; std::string objectId = vehicleId; - uint8_t variableNumber = 4; + uint8_t variableNumber = 5; uint8_t variable1 = VAR_POSITION; uint8_t variable2 = VAR_ROAD_ID; uint8_t variable3 = VAR_SPEED; uint8_t variable4 = VAR_ANGLE; + uint8_t variable5 = VAR_SIGNALS; - TraCIBuffer buf = queryTraCI(CMD_SUBSCRIBE_VEHICLE_VARIABLE, TraCIBuffer() << beginTime << endTime << objectId << variableNumber << variable1 << variable2 << variable3 << variable4); + TraCIBuffer buf = queryTraCI(CMD_SUBSCRIBE_VEHICLE_VARIABLE, TraCIBuffer() << beginTime << endTime << objectId << variableNumber << variable1 << variable2 << variable3 << variable4 << variable5); processSubcriptionResult(buf); ASSERT(buf.eof()); } @@ -932,6 +955,10 @@ void TraCIScenarioManager::processSimSubscription(std::string objectId, TraCIBuf cModule* mod = getManagedModule(idstring); if (mod) deleteModule(idstring); + if(unEquippedHosts.find(idstring) != unEquippedHosts.end()) { + unEquippedHosts.erase(idstring); + } + } if ((count > 0) && (count >= activeVehicleCount) && autoShutdown) autoShutdownTriggered = true; @@ -958,6 +985,7 @@ void TraCIScenarioManager::processVehicleSubscription(std::string objectId, TraC std::string edge; double speed; double angle_traci; + int signals; int numRead = 0; uint8_t variableNumber_resp; buf >> variableNumber_resp; @@ -1021,6 +1049,11 @@ void TraCIScenarioManager::processVehicleSubscription(std::string objectId, TraC ASSERT(varType == TYPE_DOUBLE); buf >> angle_traci; numRead++; + } else if (variable1_resp == VAR_SIGNALS) { + uint8_t varType; buf >> varType; + ASSERT(varType == TYPE_INTEGER); + buf >> signals; + numRead++; } else { error("Received unhandled vehicle subscription result"); } @@ -1029,8 +1062,8 @@ void TraCIScenarioManager::processVehicleSubscription(std::string objectId, TraC // bail out if we didn't want to receive these subscription results if (!isSubscribed) return; - // make sure we got updates for all 4 attributes - if (numRead != 4) return; + // make sure we got updates for all attributes + if (numRead != 5) return; Coord p = traci2omnet(TraCICoord(px, py)); if ((p.x < 0) || (p.y < 0)) error("received bad node position (%.2f, %.2f), translated to (%.2f, %.2f)", px, py, p.x, p.y); @@ -1046,6 +1079,14 @@ void TraCIScenarioManager::processVehicleSubscription(std::string objectId, TraC deleteModule(objectId); MYDEBUG << "Vehicle #" << objectId << " left region of interest" << endl; } + else if(unEquippedHosts.find(objectId) != unEquippedHosts.end()) { + unEquippedHosts.erase(objectId); + MYDEBUG << "Vehicle (unequipped) # " << objectId<< " left region of interest" << endl; + } + return; + } + + if (isModuleUnequipped(objectId)) { return; } diff --git a/src/world/traci/TraCIScenarioManager.h b/src/world/traci/TraCIScenarioManager.h index 97786f080..133475bbf 100644 --- a/src/world/traci/TraCIScenarioManager.h +++ b/src/world/traci/TraCIScenarioManager.h @@ -1,5 +1,5 @@ // -// Copyright (C) 2006-2011 Christoph Sommer +// Copyright (C) 2006-2012 Christoph Sommer // // Documentation for these modules is at http://veins.car2x.org/ // @@ -30,18 +30,25 @@ #include #include "INETDefs.h" -#include "IChannelControl.h" +#include "Coord.h" #include "ModuleAccess.h" /** - * TraCIScenarioManager connects OMNeT++ to a TraCI server running road traffic simulations. - * It sets up and controls simulation experiments, moving nodes with the help - * of a TraCIMobility module. + * @brief + * Creates and moves nodes controlled by a TraCI server. * - * Last tested with SUMO r5488 (2008-04-30) - * https://sumo.svn.sourceforge.net/svnroot/sumo/trunk/sumo + * If the server is a SUMO road traffic simulation, you can use the + * TraCIScenarioManagerLaunchd module and sumo-launchd.py script instead. + * + * All nodes created thus must have a TraCIMobility submodule. + * + * See the Veins website for a tutorial, documentation, and publications . + * + * @author Christoph Sommer, David Eckhoff, Falko Dressler, Zheng Yao, Tobias Mayer, Alvaro Torres Cortes, Luca Bedogni + * + * @see TraCIMobility + * @see TraCIScenarioManagerLaunchd * - * @author Christoph Sommer */ class INET_API TraCIScenarioManager : public cSimpleModule { @@ -57,6 +64,25 @@ class INET_API TraCIScenarioManager : public cSimpleModule uint8_t alpha; }; + enum VehicleSignal { + VEH_SIGNAL_UNDEF = -1, + VEH_SIGNAL_NONE = 0, + VEH_SIGNAL_BLINKER_RIGHT = 1, + VEH_SIGNAL_BLINKER_LEFT = 2, + VEH_SIGNAL_BLINKER_EMERGENCY = 4, + VEH_SIGNAL_BRAKELIGHT = 8, + VEH_SIGNAL_FRONTLIGHT = 16, + VEH_SIGNAL_FOGLIGHT = 32, + VEH_SIGNAL_HIGHBEAM = 64, + VEH_SIGNAL_BACKDRIVE = 128, + VEH_SIGNAL_WIPER = 256, + VEH_SIGNAL_DOOR_OPEN_LEFT = 512, + VEH_SIGNAL_DOOR_OPEN_RIGHT = 1024, + VEH_SIGNAL_EMERGENCY_BLUE = 2048, + VEH_SIGNAL_EMERGENCY_RED = 4096, + VEH_SIGNAL_EMERGENCY_YELLOW = 8192 + }; + ~TraCIScenarioManager(); virtual int numInitStages() const { return std::max(cSimpleModule::numInitStages(), 2); } virtual void initialize(int stage); @@ -210,7 +236,9 @@ class INET_API TraCIScenarioManager : public cSimpleModule }; bool debug; /**< whether to emit debug messages */ - simtime_t updateInterval; /**< time interval to update the host's position */ + simtime_t connectAt; /**< when to connect to TraCI server (must be the initial timestep of the server) */ + simtime_t firstStepAt; /**< when to start synchronizing with the TraCI server (-1: immediately after connecting) */ + simtime_t updateInterval; /**< time interval of hosts' position updates */ std::string moduleType; /**< module type to be used in the simulation for each managed vehicle */ std::string moduleName; /**< module name to be used in the simulation for each managed vehicle */ std::string moduleDisplayString; /**< module displayString to be used in the simulation for each managed vehicle */ @@ -218,6 +246,7 @@ class INET_API TraCIScenarioManager : public cSimpleModule int port; bool autoShutdown; /**< Shutdown module as soon as no more vehicles are in the simulation */ int margin; + double penetrationRate; std::list roiRoads; /**< which roads (e.g. "hwy1 hwy2") are considered to consitute the region of interest, if not empty */ std::list > roiRects; /**< which rectangles (e.g. "0,0-10,10 20,20-30,30) are considered to consitute the region of interest, if not empty */ @@ -227,13 +256,13 @@ class INET_API TraCIScenarioManager : public cSimpleModule size_t nextNodeVectorIndex; /**< next OMNeT++ module vector index to use */ std::map hosts; /**< vector of all hosts managed by us */ + std::set unEquippedHosts; std::set subscribedVehicles; /**< all vehicles we have already subscribed to */ uint32_t activeVehicleCount; /**< number of vehicles reported as active by TraCI server */ bool autoShutdownTriggered; + cMessage* connectAndStartTrigger; /**< self-message scheduled for when to connect to TraCI server and start running */ cMessage* executeOneTimestepTrigger; /**< self-message scheduled for when to next call executeOneTimestep */ - IChannelControl* cc; - uint32_t getCurrentTimeMs(); /**< get current simulation time (in ms) */ void executeOneTimestep(); /**< read and execute all commands for the next timestep */ @@ -245,6 +274,8 @@ class INET_API TraCIScenarioManager : public cSimpleModule cModule* getManagedModule(std::string nodeId); /**< returns a pointer to the managed module named moduleName, or 0 if no module can be found */ void deleteModule(std::string nodeId); + bool isModuleUnequipped(std::string nodeId); /**< returns true if this vehicle is Unequipped */ + /** * returns whether a given position lies within the simulation's region of interest. * Modules are destroyed and re-created as managed vehicles leave and re-enter the ROI diff --git a/src/world/traci/TraCIScenarioManager.ned b/src/world/traci/TraCIScenarioManager.ned index 7533f27a8..b67ede277 100644 --- a/src/world/traci/TraCIScenarioManager.ned +++ b/src/world/traci/TraCIScenarioManager.ned @@ -1,5 +1,5 @@ // -// Copyright (C) 2006-2011 Christoph Sommer +// Copyright (C) 2006-2012 Christoph Sommer // // Documentation for these modules is at http://veins.car2x.org/ // @@ -21,15 +21,27 @@ package inet.world.traci; // -// TraCIScenarioManager connects OMNeT++ to a TraCI server running road traffic simulations. -// It sets up and controls simulation experiments, moving nodes with the help -// of a TraCIMobility module. +// Creates and moves nodes controlled by a TraCI server. +// +// If the server is a SUMO road traffic simulation, you can use the +// TraCIScenarioManagerLaunchd module and sumo-launchd.py script instead. +// +// All nodes created thus must have a TraCIMobility submodule. +// +// See the Veins website for a tutorial, documentation, and publications . +// +// @author Christoph Sommer, David Eckhoff, Falko Dressler, Zheng Yao, Tobias Mayer, Alvaro Torres Cortes, Luca Bedogni +// +// @see TraCIMobility +// @see TraCIScenarioManagerLaunchd // simple TraCIScenarioManager { parameters: - @display("i=block/cogwheel"); + @display("i=block/network2"); bool debug = default(false); // emit debug messages? + double connectAt @unit("s") = default(0s); // when to connect to TraCI server (must be the initial timestep of the server) + double firstStepAt @unit("s") = default(-1s); // when to start synchronizing with the TraCI server (-1: immediately after connecting) double updateInterval @unit("s") = default(1s); // time interval of hosts' position updates string moduleType = default("inet.nodes.wireless.WirelessHostSimplified"); // module type to be used in the simulation for each managed vehicle string moduleName = default("host"); // module name to be used in the simulation for each managed vehicle @@ -40,5 +52,6 @@ simple TraCIScenarioManager int margin = default(25); // margin to add to all received vehicle positions string roiRoads = default(""); // which roads (e.g. "hwy1 hwy2") are considered to consitute the region of interest, if not empty string roiRects = default(""); // which rectangles (e.g. "0,0-10,10 20,20-30,30) are considered to consitute the region of interest, if not empty + double penetrationRate = default(1); //the probability of a vehicle being equipped with Car2X technology } diff --git a/src/world/traci/TraCIScenarioManagerLaunchd.cc b/src/world/traci/TraCIScenarioManagerLaunchd.cc index 36c4ff095..7d31b4d17 100644 --- a/src/world/traci/TraCIScenarioManagerLaunchd.cc +++ b/src/world/traci/TraCIScenarioManagerLaunchd.cc @@ -1,5 +1,5 @@ // -// Copyright (C) 2006-2011 Christoph Sommer +// Copyright (C) 2006-2012 Christoph Sommer // // Documentation for these modules is at http://veins.car2x.org/ // diff --git a/src/world/traci/TraCIScenarioManagerLaunchd.h b/src/world/traci/TraCIScenarioManagerLaunchd.h index 56fd6b9e9..6e5d05370 100644 --- a/src/world/traci/TraCIScenarioManagerLaunchd.h +++ b/src/world/traci/TraCIScenarioManagerLaunchd.h @@ -1,5 +1,5 @@ // -// Copyright (C) 2006-2011 Christoph Sommer +// Copyright (C) 2006-2012 Christoph Sommer // // Documentation for these modules is at http://veins.car2x.org/ // @@ -27,9 +27,21 @@ #include "world/traci/TraCIScenarioManager.h" /** - * A TraCIScenarioManager that interacts with sumo-launchd + * @brief + * Extends the TraCIScenarioManager for use with sumo-launchd.py and SUMO. + * + * Connects to a running instance of the sumo-launchd.py script + * to automatically launch/kill SUMO when the simulation starts/ends. + * + * All other functionality is provided by the TraCIScenarioManager. + * + * See the Veins website for a tutorial, documentation, and publications . + * + * @author Christoph Sommer, David Eckhoff + * + * @see TraCIMobility + * @see TraCIScenarioManager * - * @author Christoph Sommer */ class INET_API TraCIScenarioManagerLaunchd : public TraCIScenarioManager { diff --git a/src/world/traci/TraCIScenarioManagerLaunchd.ned b/src/world/traci/TraCIScenarioManagerLaunchd.ned index 2dd9649c9..f313d10a7 100644 --- a/src/world/traci/TraCIScenarioManagerLaunchd.ned +++ b/src/world/traci/TraCIScenarioManagerLaunchd.ned @@ -1,5 +1,5 @@ // -// Copyright (C) 2006-2011 Christoph Sommer +// Copyright (C) 2006-2012 Christoph Sommer // // Documentation for these modules is at http://veins.car2x.org/ // @@ -21,26 +21,39 @@ package inet.world.traci; // -// TraCIScenarioManager connects OMNeT++ to a TraCI server running road traffic simulations. -// It sets up and controls simulation experiments, moving nodes with the help -// of a TraCIMobility module. +// Extends the TraCIScenarioManager for use with sumo-launchd.py and SUMO. +// +// Connects to a running instance of the sumo-launchd.py script +// to automatically launch/kill SUMO when the simulation starts/ends. +// +// All other functionality is provided by the TraCIScenarioManager. +// +// See the Veins website for a tutorial, documentation, and publications . +// +// @author Christoph Sommer, David Eckhoff +// +// @see TraCIMobility +// @see TraCIScenarioManager // simple TraCIScenarioManagerLaunchd { parameters: - @display("i=block/cogwheel"); + @display("i=block/network2"); bool debug = default(false); // emit debug messages? + double connectAt @unit("s") = default(0s); // when to connect to TraCI server (must be the initial timestep of the server) + double firstStepAt @unit("s") = default(-1s); // when to start synchronizing with the TraCI server (-1: immediately after connecting) double updateInterval @unit("s") = default(1s); // time interval of hosts' position updates string moduleType = default("inet.nodes.wireless.WirelessHostSimplified"); // module type to be used in the simulation for each managed vehicle string moduleName = default("host"); // module name to be used in the simulation for each managed vehicle string moduleDisplayString = default("i=misc/node2;is=vs;r=0,,#707070,1"); // module displayString to be used in the simulation for each managed vehicle - string host = default("localhost"); // TraCI server hostname - int port = default(9999); // TraCI server port - xml launchConfig; // launch configuration to send to sumo-launchd + string host = default("localhost"); // sumo-launchd.py server hostname + int port = default(9999); // sumo-launchd.py server port + xml launchConfig; // launch configuration to send to sumo-launchd.py int seed = default(-1); // seed value to set in launch configuration, if missing (-1: current run number) bool autoShutdown = default(true); // Shutdown module as soon as no more vehicles are in the simulation int margin = default(25); // margin to add to all received vehicle positions string roiRoads = default(""); // which roads (e.g. "hwy1 hwy2") are considered to consitute the region of interest, if not empty string roiRects = default(""); // which rectangles (e.g. "0,0-10,10 20,20-30,30) are considered to consitute the region of interest, if not empty + double penetrationRate = default(1); //the probability of a vehicle being equipped with Car2X technology } diff --git a/tests/fingerprint/examples-TODO.csv_off b/tests/fingerprint/examples-TODO.csv_off index 5557e48e7..6759aa724 100644 --- a/tests/fingerprint/examples-TODO.csv_off +++ b/tests/fingerprint/examples-TODO.csv_off @@ -2,10 +2,6 @@ ###/examples/adhoc/ieee80211/, -f omnetpp.ini -c Ping2 -r 0, -1s, 0 ,# interactive config, needed a *.numHosts parameter ###/examples/adhoc/mf80211/, -f omnetpp.ini -c Ping2 -r 0, -1s, 0 ,# interactive config, needed a *.numHosts parameter -/examples/bgpv4/BGPCompleteTest/, -f omnetpp.ini -c config1 -r 0, 1000s, 5616-a8ba # example is wrong: broadcast address is assigned to some interfaces, fingerprint is changed by 'IPv4 fix: subnet directed broadcast (e.g. 192.168.1.255) did not work' -/examples/bgpv4/BGPOpen/, -f omnetpp.ini -c config1 -r 0, 1000s, 0 ,# Error in module (MessageChecker) Net.A.snifferIn (id=8) during finalization: Several message(s) have to be checked. -/examples/bgpv4/BGPUpdate/, -f omnetpp.ini -c config1 -r 0, 1000s, 0 ,# Error in module (MessageChecker) BGPTest.A.snifferIn (id=11) during finalization: Several message(s) have to be checked. - /examples/emulation/extclient/, -f omnetpp.ini -c General -r 0, 77.77s, 0 ,# pcap devices not supported /examples/emulation/extserver/, -f omnetpp.ini -c Downlink_Traffic -r 0, 77.77s, 0 ,# pcap devices not supported /examples/emulation/extserver/, -f omnetpp.ini -c Uplink_and_Downlink_Traffic -r 0, 77.77s, 0 ,# pcap devices not supported @@ -31,5 +27,3 @@ ###/examples/wireless/lan80211/, -f omnetpp-ftp.ini -c NHosts -r 0, -1s, 0 ,# interactive config, needed a *.numHosts parameter ###/examples/wireless/lan80211/, -f omnetpp.ini -c Ping2 -r 0, -1s, 0 ,# interactive config, needed a *.numHosts parameter ###/examples/wireless/lan80211/, -f omnetpp-streaming.ini -c Streaming2 -r 0, -1s, 0 ,# interactive config, needed a *.numHosts parameter -/examples/wireless/synchronized/, -f omnetpp.ini -c NonSynchronized -r 0, 0.25s, 2ef3-dcae # you must run $INET/examples/wireless/synchronized/generate-routing-files.pl before run this example -/examples/wireless/synchronized/, -f omnetpp.ini -c Synchronized -r 0, 0.25s, ef61-26be # you must run $INET/examples/wireless/synchronized/generate-routing-files.pl before run this example diff --git a/tests/fingerprint/examples-quick.csv b/tests/fingerprint/examples-quick.csv index 8db6a0a0f..192eebb17 100644 --- a/tests/fingerprint/examples-quick.csv +++ b/tests/fingerprint/examples-quick.csv @@ -1,9 +1,10 @@ # workingdir, args, simtimelimit, fingerprint -/examples/ospfv2/areas/, -f omnetpp.ini -c General -r 0, 1s, 3019-7538 -/examples/ospfv2/backbone/, -f omnetpp.ini -c General -r 0, 1s, 005a-d8e2 -/examples/ospfv2/fulltest/, -f omnetpp.ini -c General -r 0, 1s, d2b2-3f8e -/examples/ospfv2/simpletest/, -f omnetpp.ini -c General -r 0, 1s, 45de-8912 -/examples/wireless/handover/, -f omnetpp.ini -c General -r 0, 1s, d80e-d966 -/examples/wireless/throughput/, -f omnetpp.ini -c Throughput1 -r 0, 1s, 2518-ae6a -/examples/wireless/throughput/, -f omnetpp.ini -c Throughput2 -r 0, 1s, 2656-9ced -/examples/wireless/hosttohost/, -f omnetpp.ini -c Throughput1 -r 0, 1s, 1dca-6cc7 +/examples/ospfv2/areas/, -f omnetpp.ini -c General -r 0, 1s, 54a5-fe26 +/examples/ospfv2/backbone/, -f omnetpp.ini -c General -r 0, 1s, 924c-8743 +/examples/ospfv2/fulltest/, -f omnetpp.ini -c General -r 0, 1s, fca7-2693 +/examples/ospfv2/simpletest/, -f omnetpp.ini -c General -r 0, 1s, 936c-1a63 + +/examples/wireless/handover/, -f omnetpp.ini -c General -r 0, 1s, d738-a222 +/examples/wireless/throughput/, -f omnetpp.ini -c Throughput1 -r 0, 1s, f2f7-f262 +/examples/wireless/throughput/, -f omnetpp.ini -c Throughput2 -r 0, 1s, 915f-0ec2 +/examples/wireless/hosttohost/, -f omnetpp.ini -c Throughput1 -r 0, 1s, 2b11-cb18 diff --git a/tests/fingerprint/examples.csv b/tests/fingerprint/examples.csv index 1a62fe9c3..b0b3ae2e3 100644 --- a/tests/fingerprint/examples.csv +++ b/tests/fingerprint/examples.csv @@ -1,23 +1,20 @@ # workingdir, args, simtimelimit, fingerprint -/examples/adhoc/ieee80211/, -f fingerprints.ini -c Ping1 -r 0, 1000s, 5228-ee97 -/examples/adhoc/ieee80211/, -f omnetpp.ini -c Ping1 -r 0, 100s, feaf-82e0 +/examples/adhoc/ieee80211/, -f fingerprints.ini -c Ping1 -r 0, 1000s, e2cc-3884 +/examples/adhoc/ieee80211/, -f omnetpp.ini -c Ping1 -r 0, 100s, a5fc-5578 # /examples/adhoc/ieee80211/, -f omnetpp.ini -c Ping2 -r 0, 100s, 0 # [Config Ping2] # interactive config, needed a *.numHosts parameter -/examples/adhoc/mf80211/, -f fingerprints.ini -c Ping1 -r 0, 1000s, 5895-685a -/examples/adhoc/mf80211/, -f omnetpp.ini -c Ping1 -r 0, 2000s, a2f8-e537 -# /examples/adhoc/mf80211/, -f omnetpp.ini -c Ping2 -r 0, 100s, 0 # [Config Ping2] # interactive config, needed a *.numHosts parameter - -/examples/bgpv4/BGP2RoutersInAS/, -f omnetpp.ini -c config1 -r 0, 1000s, 9c4b-26f6 -/examples/bgpv4/BGP3Routers/, -f omnetpp.ini -c config1 -r 0, 1000s, 4aec-0906 -# /examples/bgpv4/BGPCompleteTest/, -f omnetpp.ini -c config1 -r 0, 1000s, 5616-a8ba # example is wrong, broadcast address is assigned to some interfaces, fingerprint is changed by 'IPv4 fix: subnet directed broadcast (e.g. 192.168.1.255) did not work' -# /examples/bgpv4/BGPOpen/, -f omnetpp.ini -c config1 -r 0, 1000s, 0 # runtime error -# /examples/bgpv4/BGPUpdate/, -f omnetpp.ini -c config1 -r 0, 1000s, 0 # runtime error -/examples/bgpv4/BGPandOSPF/, -f omnetpp.ini -c config1 -r 0, 1000s, aa17-f7c7 -/examples/bgpv4/BGPandOSPFSimple/, -f omnetpp.ini -c config1 -r 0, 1000s, 2be6-f6a8 - -/examples/diffserv/onedomain, -f omnetpp.ini -c Exp11 -r 0, 10s, 8ef0-801b -/examples/diffserv/onedomain, -f omnetpp.ini -c Exp21 -r 0, 10s, d471-926e -/examples/diffserv/onedomain, -f omnetpp.ini -c Exp31 -r 0, 10s, 3105-d9ee -/examples/diffserv/onedomain, -f omnetpp.ini -c Exp51 -r 0, 10s, cc24-8009 + +/examples/bgpv4/BGP2RoutersInAS/, -f omnetpp.ini -c config1 -r 0, 1000s, edc5-2a9b +/examples/bgpv4/BGP3Routers/, -f omnetpp.ini -c config1 -r 0, 1000s, 3a8e-6883 +/examples/bgpv4/BGPCompleteTest/, -f omnetpp.ini -c config1 -r 0, 1000s, d043-9882 +/examples/bgpv4/BGPOpen/, -f omnetpp.ini -c config1 -r 0, 62s, 897c-ff8c +/examples/bgpv4/BGPUpdate/, -f omnetpp.ini -c config1 -r 0, 30s, 2a8a-624c +/examples/bgpv4/BGPandOSPF/, -f omnetpp.ini -c config1 -r 0, 1000s, b44e-a876 +/examples/bgpv4/BGPandOSPFSimple/, -f omnetpp.ini -c config1 -r 0, 1000s, 449a-d97e + +/examples/diffserv/onedomain, -f omnetpp.ini -c Exp11 -r 0, 10s, 8ef0-801b +/examples/diffserv/onedomain, -f omnetpp.ini -c Exp21 -r 0, 10s, d471-926e +/examples/diffserv/onedomain, -f omnetpp.ini -c Exp31 -r 0, 10s, 3105-d9ee +/examples/diffserv/onedomain, -f omnetpp.ini -c Exp51 -r 0, 10s, cc24-8009 # /examples/emulation/extclient/, -f omnetpp.ini -c General -r 0, 100s, 0 # pcap devices not supported # /examples/emulation/extserver/, -f omnetpp.ini -c Uplink_Traffic -r 0, 100s, 0 # pcap devices not supported @@ -35,7 +32,7 @@ /examples/ethernet/lans/, -f fingerprints.ini -c MixedLAN1 -r 0, 200s, ea41-e50e /examples/ethernet/lans/, -f hub.ini -c Hub1 -r 0, 100s, 4d10-13a7 /examples/ethernet/lans/, -f hub.ini -c Hub2 -r 0, 10s, 1da5-f95b -/examples/ethernet/lans/, -f hub.ini -c Hub3 -r 0, 100s, 1240-d7aa +/examples/ethernet/lans/, -f hub.ini -c Hub3 -r 0, 100s, 4d10-13a7 /examples/ethernet/lans/, -f hub.ini -c Hub4 -r 0, 100s, 4d10-13a7 /examples/ethernet/lans/, -f largeNet.ini -c LargeNet -r 0, 5s, 9a54-83c1 /examples/ethernet/lans/, -f mixed.ini -c MixedLAN -r 0, 100s, 6aaf-80bb @@ -52,7 +49,7 @@ /examples/httptools/socket/tenserverssocket/, -f omnetpp.ini -c uniform -r 0, 50000s, ab8b-8c23 /examples/httptools/socket/tenserverssocket/, -f omnetpp.ini -c histogram -r 0, 50000s, 97c2-3aad -/examples/inet/ber/, -f omnetpp.ini -c General -r 0, 20s, 2e35-3638 +/examples/inet/ber/, -f omnetpp.ini -c General -r 0, 20s, 5fa7-14d7 /examples/inet/broadcast/, -f omnetpp.ini -c General -r 0, 20s, 1c71-a2e8 @@ -78,7 +75,7 @@ /examples/inet/ipv4largenet/, -f omnetpp.ini -c IPv4LargeNet -r 0, 20s, 189b-8711 -/examples/inet/kidsnw1/, -f omnetpp.ini -c General -r 0, 1000s, 0e68-ccde +/examples/inet/kidsnw1/, -f omnetpp.ini -c General -r 0, 1000s, 77aa-05b5 /examples/inet/multicast/, -f omnetpp.ini -c General -r 0, 2000s, d95c-fe95 @@ -124,16 +121,17 @@ /examples/inet/tcpclientserver/, -f omnetpp.ini -c lwip__lwip__stream -r 0, 100s, 8d97-f1e2 /examples/inet/tcpclientserver/, -f omnetpp.ini -c inet__lwip -r 0, 100s, acf7-9b07 -/examples/inet/tcpsack/, -f omnetpp.ini -c One -r 0, 1.5s, 9d3b-fb8e -/examples/inet/tcpsack/, -f omnetpp.ini -c Two -r 0, 1.5s, 25e0-1d59 -/examples/inet/tcpsack/, -f omnetpp.ini -c Three -r 0, 1.5s, 0477-0ae8 -/examples/inet/tcpsack/, -f omnetpp.ini -c Four -r 0, 1.5s, ac85-9ff8 -/examples/inet/tcpsack/, -f omnetpp.ini -c Five -r 0, 1.5s, ef69-f5ca -/examples/inet/tcpsack/, -f omnetpp.ini -c Six -r 0, 1.5s, 7048-47c4 -/examples/inet/tcptimestamps/, -f omnetpp.ini -c One -r 0, 1.5s, 056f-10a5 -/examples/inet/tcptimestamps/, -f omnetpp.ini -c Two -r 0, 1.5s, 2612-a366 -/examples/inet/tcpwindowscale/, -f omnetpp.ini -c WS_disabled -r 0, 1.5s, 4fea-0392 -/examples/inet/tcpwindowscale/, -f omnetpp.ini -c WS_enabled -r 0, 1.5s, 2d8f-5bab +/examples/inet/tcpsack/, -f omnetpp.ini -c One -r 0, 1.5s, 545e-aa1c +/examples/inet/tcpsack/, -f omnetpp.ini -c Two -r 0, 1.5s, df3a-e48f +/examples/inet/tcpsack/, -f omnetpp.ini -c Three -r 0, 1.5s, b3eb-761c +/examples/inet/tcpsack/, -f omnetpp.ini -c Four -r 0, 1.5s, 4526-33ea +/examples/inet/tcpsack/, -f omnetpp.ini -c Five -r 0, 1.5s, b29f-e0bb +/examples/inet/tcpsack/, -f omnetpp.ini -c Six -r 0, 1.5s, 80c6-1c4b + +/examples/inet/tcptimestamps/, -f omnetpp.ini -c One -r 0, 1.5s, fc59-3920 +/examples/inet/tcptimestamps/, -f omnetpp.ini -c Two -r 0, 1.5s, 3e5e-a3a1 +/examples/inet/tcpwindowscale/, -f omnetpp.ini -c WS_disabled -r 0, 1.5s, d4db-b9cc +/examples/inet/tcpwindowscale/, -f omnetpp.ini -c WS_enabled -r 0, 1.5s, b6be-e1f5 /examples/inet/udpburst/, -f omnetpp.ini -c General -r 0, 1000s, bc26-623c # /examples/ipv6/demonetworketh/, -f omnetpp.ini -c General -r 0, 100s, 34b1-536e # unstable fingerprint @@ -197,17 +195,22 @@ /examples/mpls/testte_routing/, -f omnetpp.ini -c General -r 0, 10s, cfa2-62ca /examples/mpls/testte_tunnel/, -f omnetpp.ini -c General -r 0, 50s, 6d61-9a55 -/examples/ospfv2/areas/, -f omnetpp.ini -c General -r 0, 1000s, 4b2d-096b +/examples/ospfv2/areas/, -f omnetpp.ini -c General -r 0, 500s, 6aee-7a00 +/examples/ospfv2/areatests/, -f omnetpp.ini -c backbone -r 0, 100s, acd0-064a +/examples/ospfv2/areatests/, -f omnetpp.ini -c backboneandonestub -r 0, 100s, 133f-6c8a +/examples/ospfv2/areatests/, -f omnetpp.ini -c backboneandtwostubs -r 0, 100s, 10e6-f3b7 # /examples/ospfv2/backbone/, -f omnetpp.ini -c General -r 0, 100s, 0 # Error in module (OSPFRouting) Backbone.R6.ospf (id=132) at event #23916, t=45.089338342798: check_and_cast(): cannot cast (OSPF::NetworkLSA *) to type 'OSPF::RouterLSA *'. -/examples/ospfv2/fulltest/, -f omnetpp.ini -c General -r 0, 100s, 94e9-0c4a -/examples/ospfv2/simpletest/, -f omnetpp.ini -c General -r 0, 500s, c745-6efe +/examples/ospfv2/dynamictest/, -f omnetpp.ini -c stable -r 0, 1000s, f030-0270 +/examples/ospfv2/dynamictest/, -f omnetpp.ini -c dynamic1 -r 0, 1000s, a307-65a8 +/examples/ospfv2/fulltest/, -f omnetpp.ini -c General -r 0, 100s, e843-8517 +/examples/ospfv2/simpletest/, -f omnetpp.ini -c General -r 0, 500s, 334e-74f4 # /examples/rtp/multicast1/, -f omnetpp.ini -c General -r 0, 100s, a422-b4ed # unstable fingerprint -# /examples/rtp/multicast11/, -f omnetpp.ini -c General -r 0, 100s, cfaf-783c # unstable fingerprint # /examples/rtp/unicast/, -f omnetpp.ini -c General -r 0, 100s, 1ef9-fff6 # unstable fingerprint +# /examples/rtp/unicast1/, -f omnetpp.ini -c General -r 0, 100s, cfaf-783c # unstable fingerprint # /examples/rtp/unicast2/, -f omnetpp.ini -c General -r 0, 100s, f9be-62bb # unstable fingerprint -/examples/sctp/multihomed/, -f omnetpp.ini -c General -r 0, 500s, 7185-cd44 +/examples/sctp/multihomed/, -f omnetpp.ini -c General -r 0, 500s, f252-459d /examples/sctp/nclients/, -f omnetpp.ini -c General -r 0, 500s, d999-82c6 /examples/voiptool/VoIPToolLargeNet/, -f omnetpp.ini -c General -r 0, 5s, d535-b1ff @@ -217,18 +220,18 @@ /examples/voiptool/VoIPToolTest/, -f omnetpp.ini -c pcm_s16le -r 0, 5s, 1a6d-102c /examples/voiptool/VoIPToolTrafficTest/, -f omnetpp.ini -c General -r 0, 2s, 9617-db37 -/examples/wireless/handover/, -f omnetpp.ini -c General -r 0, 1500s, 461b-e121 -/examples/wireless/hosttohost/, -f omnetpp.ini -c Throughput1 -r 0, 5s, 7879-1960 -/examples/wireless/lan80211/, -f omnetpp-ftp.ini -c TwoHosts -r 0, 100s, d308-cd4f +/examples/wireless/handover/, -f omnetpp.ini -c General -r 0, 1500s, d726-6818 +/examples/wireless/hosttohost/, -f omnetpp.ini -c Throughput1 -r 0, 5s, 9fee-c831 +/examples/wireless/lan80211/, -f omnetpp-ftp.ini -c TwoHosts -r 0, 100s, 6c1b-1738 # /examples/wireless/lan80211/, -f omnetpp-ftp.ini -c NHosts -r 0, 100s, 0 # interactive config, needed a *.numHosts parameter -/examples/wireless/lan80211/, -f omnetpp-streaming.ini -c Streaming1 -r 0, 50s, d0f0-c3ff +/examples/wireless/lan80211/, -f omnetpp-streaming.ini -c Streaming1 -r 0, 50s, 8e7c-9b87 # /examples/wireless/lan80211/, -f omnetpp-streaming.ini -c Streaming2 -r 0, 100s, 0 # interactive config, needed a *.numHosts parameter -/examples/wireless/lan80211/, -f omnetpp.ini -c Ping1 -r 0, 50s, 5069-6864 +/examples/wireless/lan80211/, -f omnetpp.ini -c Ping1 -r 0, 25s, 6686-2f0d # /examples/wireless/lan80211/, -f omnetpp.ini -c Ping2 -r 0, 100s, 0 # interactive config, needed a *.numHosts parameter -/examples/wireless/multiradio/, -f omnetpp.ini -c IndependentWlans -r 0, 1000s, 3d64-78f9 -/examples/wireless/multiradio/, -f omnetpp.ini -c SwitchedWlans -r 0, 1000s, 5cee-e02f -/examples/wireless/multiradio/, -f omnetpp.ini -c RoutedWlans -r 0, 1000s, 44b9-299e -# /examples/wireless/synchronized/, -f omnetpp.ini -c Synchronized -r 0, 100s, 0 # you must run $INET/examples/wireless/synchronized/generate-routing-files.pl before run this example -# /examples/wireless/synchronized/, -f omnetpp.ini -c NonSynchronized -r 0, 100s, 0 # you must run $INET/examples/wireless/synchronized/generate-routing-files.pl before run this example -/examples/wireless/throughput/, -f omnetpp.ini -c Throughput1 -r 0, 20s, 36f7-cb04 -/examples/wireless/throughput/, -f omnetpp.ini -c Throughput2 -r 0, 10s, 39ea-2016 +/examples/wireless/multiradio/, -f omnetpp.ini -c IndependentWlans -r 0, 100s, 5d25-3c8f +/examples/wireless/multiradio/, -f omnetpp.ini -c SwitchedWlans -r 0, 100s, 5cb1-9226 +/examples/wireless/multiradio/, -f omnetpp.ini -c RoutedWlans -r 0, 100s, 6e3a-aae1 +/examples/wireless/synchronized/, -f omnetpp.ini -c Synchronized -r 0, 2s, 1d1a-6e75 +/examples/wireless/synchronized/, -f omnetpp.ini -c NonSynchronized -r 0, 2s, 897d-1556 +/examples/wireless/throughput/, -f omnetpp.ini -c Throughput1 -r 0, 20s, d3e1-ed60 +/examples/wireless/throughput/, -f omnetpp.ini -c Throughput2 -r 0, 10s, d849-f755 diff --git a/tests/fingerprint/examples.csv.unstable b/tests/fingerprint/examples.csv.unstable index 282c8cb97..f9009c484 100644 --- a/tests/fingerprint/examples.csv.unstable +++ b/tests/fingerprint/examples.csv.unstable @@ -12,6 +12,6 @@ /examples/ipv6/nclients/, -f omnetpp.ini -c ETH -r 0, 1000s, b2e0-2ac0 /examples/mobileipv6/, -f omnetpp.ini -c One -r 0, 25s, 05c2-e365 /examples/rtp/multicast1/, -f omnetpp.ini -c General -r 0, 500s, 54b5-a6b3 -/examples/rtp/multicast11/, -f omnetpp.ini -c General -r 0, 1000s, cfaf-783c /examples/rtp/unicast/, -f omnetpp.ini -c General -r 0, 500s, a8ae-e2ce +/examples/rtp/unicast1/, -f omnetpp.ini -c General -r 0, 1000s, cfaf-783c /examples/rtp/unicast2/, -f omnetpp.ini -c General -r 0, 500s, 4493-d000 diff --git a/tests/fingerprint/gen_runallexamples.pl b/tests/fingerprint/gen_runallexamples.pl old mode 100644 new mode 100755 diff --git a/tests/fingerprint/manet.csv b/tests/fingerprint/manet.csv index c3138f7f1..cf54166b4 100644 --- a/tests/fingerprint/manet.csv +++ b/tests/fingerprint/manet.csv @@ -1,45 +1,45 @@ # workingdir, args, simtimelimit, fingerprint -/examples/manetrouting/fg80211/ini/, -f Mob_DSR_omnetpp.ini -c General -r 0, 100s, 6415-38a7 +/examples/manetrouting/fg80211/ini/, -f Mob_DSR_omnetpp.ini -c General -r 0, 100s, add6-a333 -/examples/manetrouting/fg80211/, -f omnetpp.ini -c General -r 0, 100s, af47-aca8 -/examples/manetrouting/fg80211/, -f omnetpp.ini -c DYMOUM -r 0, 100s, 091b-a1c4 -/examples/manetrouting/fg80211/, -f omnetpp.ini -c DYMO -r 0, 100s, 0404-10f9 +/examples/manetrouting/fg80211/, -f omnetpp.ini -c General -r 0, 100s, 1677-918e +/examples/manetrouting/fg80211/, -f omnetpp.ini -c DYMOUM -r 0, 100s, f41c-3a6b +/examples/manetrouting/fg80211/, -f omnetpp.ini -c DYMO -r 0, 100s, 1436-46b4 # /examples/manetrouting/fg80211/, -f omnetpp.ini -c AODVUU -r 0, 100s, b0d4-813f # unstable fingerprint -/examples/manetrouting/fg80211/, -f omnetpp.ini -c DSRUU -r 0, 100s, e30f-d59e -/examples/manetrouting/fg80211/, -f omnetpp.ini -c OLSR -r 0, 20s, 1d50-bda3 +/examples/manetrouting/fg80211/, -f omnetpp.ini -c DSRUU -r 0, 100s, 10c7-2261 +/examples/manetrouting/fg80211/, -f omnetpp.ini -c OLSR -r 0, 20s, 2465-1fef # /examples/manetrouting/fg80211/, -f omnetpp.ini -c OLSR_ETX -r 0, 10s, 8f2c-447e # unstable fingerprint -/examples/manetrouting/fg80211/, -f omnetpp.ini -c DSDV_2 -r 0, 20s, fb54-b6d2 -/examples/manetrouting/fg80211/, -f omnetpp.ini -c Batman -r 0, 20s, 3b51-e629 +/examples/manetrouting/fg80211/, -f omnetpp.ini -c DSDV_2 -r 0, 10s, 8780-9d03 +/examples/manetrouting/fg80211/, -f omnetpp.ini -c Batman -r 0, 20s, 682d-be52 -/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c General -r 0, 10s, 23b1-7964 -/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c DYMO -r 0, 10s, a1fc-b1a4 -/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c DYMOUM -r 0, 10s, f94a-93a7 +/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c General -r 0, 10s, 9327-eb70 +/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c DYMO -r 0, 10s, 8cd3-888c +/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c DYMOUM -r 0, 10s, 2b26-aa8c # /examples/manetrouting/grid_aodv/, -f omnetpp.ini -c AODVUU -r 0, 10s, d517-50b0 # unstable fingerprint -/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c DSRUU -r 0, 10s, d07a-9b87 -/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c OLSR -r 0, 10s, a02b-95fe +/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c DSRUU -r 0, 10s, afe3-fae1 +/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c OLSR -r 0, 10s, 13ca-250d # /examples/manetrouting/grid_aodv/, -f omnetpp.ini -c OLSR_ETX -r 0, 10s, 2dc8-6dbe # unstable fingerprint -/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c DSDV_2 -r 0, 10s, 2dd5-8bba -/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c Batman -r 0, 10s, bdaf-bc29 +/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c DSDV_2 -r 0, 5s, 5eaf-579d +/examples/manetrouting/grid_aodv/, -f omnetpp.ini -c Batman -r 0, 10s, 2bad-cd0e # /examples/manetrouting/multiradio/, -f omnetpp.ini -c MultiRadio -r 0, 20s, fe4d-3bd7 # unstable fingerprint # /examples/manetrouting/multiradio/, -f omnetpp.ini -c SingleRadio -r 0, 20s, 6de8-cf4d # unstable fingerprint -/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c General -r 0, 40s, afe9-2047 -/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c DYMOUM -r 0, 100s, d24c-16f4 -/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c DYMO -r 0, 100s, 0008-b39f -/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c AODVUU -r 0, 100s, 5433-e6ba -/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c DSRUU -r 0, 100s, 2414-a4a8 -/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c OLSR -r 0, 5s, ed09-932b +/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c General -r 0, 40s, 2812-9bc2 +/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c DYMOUM -r 0, 100s, b616-275e +/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c DYMO -r 0, 100s, 87d9-edb9 +/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c AODVUU -r 0, 100s, dbce-36aa +/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c DSRUU -r 0, 100s, dbce-36aa +/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c OLSR -r 0, 5s, 12b8-442b # /examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c OLSR_ETX -r 0, 5s, 3520-fea0 # unstable fingerprint -/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c DSDV_2 -r 0, 10s, f439-7a1b -/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c Batman -r 0, 2s, 0900-418e +/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c DSDV_2 -r 0, 5s, 18e8-002b +/examples/manetrouting/net80211_aodv/, -f omnetpp.ini -c Batman -r 0, 2s, 4a99-c91b -/examples/manetrouting/net80211_control/, -f omnetpp.ini -c General -r 0, 10s, 82e9-7b6f +/examples/manetrouting/net80211_control/, -f omnetpp.ini -c General -r 0, 10s, 3858-1ce0 /examples/manetrouting/net80211_control/, -f omnetpp.ini -c DYMOUM -r 0, 10s, cc58-905d -/examples/manetrouting/net80211_control/, -f omnetpp.ini -c AODVUU -r 0, 10s, 82e9-7b6f +/examples/manetrouting/net80211_control/, -f omnetpp.ini -c AODVUU -r 0, 10s, 3858-1ce0 /examples/manetrouting/net80211_control/, -f omnetpp.ini -c DSRUU -r 0, 10s, cc58-905d -/examples/manetrouting/net80211_control/, -f omnetpp.ini -c OLSR -r 0, 10s, 82e9-7b6f +/examples/manetrouting/net80211_control/, -f omnetpp.ini -c OLSR -r 0, 10s, 3858-1ce0 # /examples/manetrouting/net80211_control/, -f omnetpp.ini -c OLSR_ETX -r 0, 10s, bf02-6ed6 # unstable fingerprint -/examples/manetrouting/net80211_control/, -f omnetpp.ini -c DSDV_2 -r 0, 3s, 9e57-d19b +/examples/manetrouting/net80211_control/, -f omnetpp.ini -c DSDV_2 -r 0, 3s, 50a1-7dd8 /examples/manetrouting/net80211_control/, -f omnetpp.ini -c DYMO -r 0, 10s, cc58-905d -/examples/manetrouting/net80211_control/, -f omnetpp.ini -c Batman -r 0, 10s, 31da-b6e2 +/examples/manetrouting/net80211_control/, -f omnetpp.ini -c Batman -r 0, 10s, 5061-4efa diff --git a/tests/module/ospf_1_area.test b/tests/module/ospf_1_area.test new file mode 100644 index 000000000..908993e99 --- /dev/null +++ b/tests/module/ospf_1_area.test @@ -0,0 +1,239 @@ +%description: +Testing OSPF routing + Backbone only with n routers + UDP communications through entire backbone +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; + + +network Test1 +{ + parameters: + int numIRouters = default(0); + @display("p=10,10;b=712,152"); + types: + channel C extends ThruputMeteringChannel + { + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; + } + submodules: + H1: StandardHost { + parameters: + @display("p=56,92;i=device/laptop"); + gates: + ethg[1]; + } + N1: EtherHub { + parameters: + @display("p=184,182"); + gates: + ethg[2]; + } + R1: OSPFRouter { + parameters: + @display("p=296,92"); + gates: + ethg[2]; + } + RI[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R2: OSPFRouter { + parameters: + @display("p=416,92"); + gates: + ethg[2]; + } + N2: EtherHub { + parameters: + @display("p=532,182"); + gates: + ethg[2]; + } + H2: StandardHost { + parameters: + @display("p=660,92;i=device/laptop"); + gates: + ethg[1]; + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+ + ""+ + ""+ + ""+ + ""+ + ""); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=75,43"); + } + connections: + H1.ethg[0] <--> C <--> N1.ethg[0]; + N1.ethg[1] <--> C <--> R1.ethg[0]; + + R1.ethg[1] <--> C <--> R2.ethg[0] if numIRouters == 0; + R1.ethg[1] <--> C <--> RI[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RI[i-1].ethg[1] <--> C <--> RI[i].ethg[0]; + } + RI[numIRouters-1].ethg[1] <--> C <--> R2.ethg[0] if numIRouters > 0; + + R2.ethg[1] <--> C <--> N2.ethg[0]; + N2.ethg[1] <--> C <--> H2.ethg[0]; +} + + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Simple test" +network = Test1 +ned-path = .;../../../../src;../../lib +tkenv-plugin-path = ../../../etc/plugins +sim-time-limit = 200s + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + +**.numUdpApps = 2 +**.udpApp[0].typename = "UDPBasicApp" +**.udpApp[0].destPort = 1234 +**.udpApp[0].messageLength = 32 bytes +**.udpApp[0].sendInterval = 1s +**.udpApp[0].startTime = 4s +**.udpApp[0].stopTime = this.startTime + 100s +**.H2.udpApp[0].destAddresses = "H1" +**.H1.udpApp[0].destAddresses = "H2" +**.udpApp[1].typename = "UDPEchoApp" +**.udpApp[1].localPort = 1234 + +**.arp.cacheTimeout = 1s + +**.numIRouters = ${0,1,2,3,5,10,25} + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/module/ospf_1_area_HostInterface.test b/tests/module/ospf_1_area_HostInterface.test new file mode 100644 index 000000000..904095c4c --- /dev/null +++ b/tests/module/ospf_1_area_HostInterface.test @@ -0,0 +1,239 @@ +%description: +Testing OSPF routing + Backbone only with n routers + UDP communications through entire backbone +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; + + +network Test1 +{ + parameters: + int numIRouters = default(0); + @display("p=10,10;b=712,152"); + types: + channel C extends ThruputMeteringChannel + { + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; + } + submodules: + H1: StandardHost { + parameters: + @display("p=56,92;i=device/laptop"); + gates: + ethg[1]; + } + N1: EtherHub { + parameters: + @display("p=184,182"); + gates: + ethg[2]; + } + R1: OSPFRouter { + parameters: + @display("p=296,92"); + gates: + ethg[2]; + } + RI[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R2: OSPFRouter { + parameters: + @display("p=416,92"); + gates: + ethg[2]; + } + N2: EtherHub { + parameters: + @display("p=532,182"); + gates: + ethg[2]; + } + H2: StandardHost { + parameters: + @display("p=660,92;i=device/laptop"); + gates: + ethg[1]; + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+ + ""+ + ""+ + ""+ + ""+ + ""); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=75,43"); + } + connections: + H1.ethg[0] <--> C <--> N1.ethg[0]; + N1.ethg[1] <--> C <--> R1.ethg[0]; + + R1.ethg[1] <--> C <--> R2.ethg[0] if numIRouters == 0; + R1.ethg[1] <--> C <--> RI[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RI[i-1].ethg[1] <--> C <--> RI[i].ethg[0]; + } + RI[numIRouters-1].ethg[1] <--> C <--> R2.ethg[0] if numIRouters > 0; + + R2.ethg[1] <--> C <--> N2.ethg[0]; + N2.ethg[1] <--> C <--> H2.ethg[0]; +} + + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Simple test" +network = Test1 +ned-path = .;../../../../src;../../lib +tkenv-plugin-path = ../../../etc/plugins +sim-time-limit = 200s + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + +**.numUdpApps = 2 +**.udpApp[0].typename = "UDPBasicApp" +**.udpApp[0].destPort = 1234 +**.udpApp[0].messageLength = 32 bytes +**.udpApp[0].sendInterval = 1s +**.udpApp[0].startTime = 4s +**.udpApp[0].stopTime = this.startTime + 100s +**.H2.udpApp[0].destAddresses = "H1" +**.H1.udpApp[0].destAddresses = "H2" +**.udpApp[1].typename = "UDPEchoApp" +**.udpApp[1].localPort = 1234 + +**.arp.cacheTimeout = 1s + +**.numIRouters = ${0,1,2,3,5,10,25} + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/module/ospf_backbone_and_2_areas.test b/tests/module/ospf_backbone_and_2_areas.test new file mode 100644 index 000000000..6b1900156 --- /dev/null +++ b/tests/module/ospf_backbone_and_2_areas.test @@ -0,0 +1,294 @@ +%description: +Testing OSPF routing + Backbone and 2 areas + UDP communications through entire network +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; + + +network Test1 +{ + parameters: + int numIRouters = default(0); + @display("p=10,10;b=712,152"); + types: + channel C extends ThruputMeteringChannel + { + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; + } + submodules: + H1: StandardHost { + parameters: + @display("p=56,92;i=device/laptop"); + gates: + ethg[1]; + } + N1: EtherHub { + parameters: + @display("p=184,182"); + gates: + ethg[2]; + } + RA1: OSPFRouter { + gates: + ethg[2]; + } + RA1I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R1: OSPFRouter { + parameters: + @display("p=296,92"); + gates: + ethg[2]; + } + RI[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R2: OSPFRouter { + parameters: + @display("p=416,92"); + gates: + ethg[2]; + } + RA2I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + RA2: OSPFRouter { + gates: + ethg[2]; + } + N2: EtherHub { + parameters: + @display("p=532,182"); + gates: + ethg[2]; + } + H2: StandardHost { + parameters: + @display("p=660,92;i=device/laptop"); + gates: + ethg[1]; + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+ + ""+ + ""+ + ""+ + ""+ + ""); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=75,43"); + } + connections: + H1.ethg[0] <--> C <--> N1.ethg[0]; + N1.ethg[1] <--> C <--> RA1.ethg[0]; + RA1.ethg[1] <--> C <--> R1.ethg[0] if numIRouters == 0; + RA1.ethg[1] <--> C <--> RA1I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA1I[i-1].ethg[1] <--> C <--> RA1I[i].ethg[0]; + } + RA1I[numIRouters-1].ethg[1] <--> C <--> R1.ethg[0] if numIRouters > 0; + + R1.ethg[1] <--> C <--> R2.ethg[0] if numIRouters == 0; + R1.ethg[1] <--> C <--> RI[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RI[i-1].ethg[1] <--> C <--> RI[i].ethg[0]; + } + RI[numIRouters-1].ethg[1] <--> C <--> R2.ethg[0] if numIRouters > 0; + + R2.ethg[1] <--> C <--> RA2.ethg[0] if numIRouters == 0; + R2.ethg[1] <--> C <--> RA2I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA2I[i-1].ethg[1] <--> C <--> RA2I[i].ethg[0]; + } + RA2I[numIRouters-1].ethg[1] <--> C <--> RA2.ethg[0] if numIRouters > 0; + + RA2.ethg[1] <--> C <--> N2.ethg[0]; + N2.ethg[1] <--> C <--> H2.ethg[0]; +} + + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Simple test" +network = Test1 +ned-path = .;../../../../src;../../lib +tkenv-plugin-path = ../../../etc/plugins +sim-time-limit = 200s + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + +**.numUdpApps = 2 +**.udpApp[0].typename = "UDPBasicApp" +**.udpApp[0].destPort = 1234 +**.udpApp[0].messageLength = 32 bytes +**.udpApp[0].sendInterval = 1s +**.udpApp[0].startTime = 51s +**.udpApp[0].stopTime = this.startTime + 100s +**.H2.udpApp[0].destAddresses = "H1" +**.H1.udpApp[0].destAddresses = "H2" +**.udpApp[1].typename = "UDPEchoApp" +**.udpApp[1].localPort = 1234 + +**.arp.cacheTimeout = 1s + +**.numIRouters = ${0,1,2,3,5,7,8} + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/module/ospf_backbone_and_2_areas_HostInterface.test b/tests/module/ospf_backbone_and_2_areas_HostInterface.test new file mode 100644 index 000000000..671af3c3e --- /dev/null +++ b/tests/module/ospf_backbone_and_2_areas_HostInterface.test @@ -0,0 +1,294 @@ +%description: +Testing OSPF routing + Backbone and 2 areas + UDP communications through entire network +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; + + +network Test1 +{ + parameters: + int numIRouters = default(0); + @display("p=10,10;b=712,152"); + types: + channel C extends ThruputMeteringChannel + { + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; + } + submodules: + H1: StandardHost { + parameters: + @display("p=56,92;i=device/laptop"); + gates: + ethg[1]; + } + N1: EtherHub { + parameters: + @display("p=184,182"); + gates: + ethg[2]; + } + RA1: OSPFRouter { + gates: + ethg[2]; + } + RA1I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R1: OSPFRouter { + parameters: + @display("p=296,92"); + gates: + ethg[2]; + } + RI[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R2: OSPFRouter { + parameters: + @display("p=416,92"); + gates: + ethg[2]; + } + RA2I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + RA2: OSPFRouter { + gates: + ethg[2]; + } + N2: EtherHub { + parameters: + @display("p=532,182"); + gates: + ethg[2]; + } + H2: StandardHost { + parameters: + @display("p=660,92;i=device/laptop"); + gates: + ethg[1]; + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+ + ""+ + ""+ + ""+ + ""+ + ""); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=75,43"); + } + connections: + H1.ethg[0] <--> C <--> N1.ethg[0]; + N1.ethg[1] <--> C <--> RA1.ethg[0]; + RA1.ethg[1] <--> C <--> R1.ethg[0] if numIRouters == 0; + RA1.ethg[1] <--> C <--> RA1I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA1I[i-1].ethg[1] <--> C <--> RA1I[i].ethg[0]; + } + RA1I[numIRouters-1].ethg[1] <--> C <--> R1.ethg[0] if numIRouters > 0; + + R1.ethg[1] <--> C <--> R2.ethg[0] if numIRouters == 0; + R1.ethg[1] <--> C <--> RI[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RI[i-1].ethg[1] <--> C <--> RI[i].ethg[0]; + } + RI[numIRouters-1].ethg[1] <--> C <--> R2.ethg[0] if numIRouters > 0; + + R2.ethg[1] <--> C <--> RA2.ethg[0] if numIRouters == 0; + R2.ethg[1] <--> C <--> RA2I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA2I[i-1].ethg[1] <--> C <--> RA2I[i].ethg[0]; + } + RA2I[numIRouters-1].ethg[1] <--> C <--> RA2.ethg[0] if numIRouters > 0; + + RA2.ethg[1] <--> C <--> N2.ethg[0]; + N2.ethg[1] <--> C <--> H2.ethg[0]; +} + + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Simple test" +network = Test1 +ned-path = .;../../../../src;../../lib +tkenv-plugin-path = ../../../etc/plugins +sim-time-limit = 200s + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + +**.numUdpApps = 2 +**.udpApp[0].typename = "UDPBasicApp" +**.udpApp[0].destPort = 1234 +**.udpApp[0].messageLength = 32 bytes +**.udpApp[0].sendInterval = 1s +**.udpApp[0].startTime = 51s +**.udpApp[0].stopTime = this.startTime + 100s +**.H2.udpApp[0].destAddresses = "H1" +**.H1.udpApp[0].destAddresses = "H2" +**.udpApp[1].typename = "UDPEchoApp" +**.udpApp[1].localPort = 1234 + +**.arp.cacheTimeout = 1s + +**.numIRouters = ${0,1,2,3,5,7,8} + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/module/ospf_backbone_and_2_stub.test b/tests/module/ospf_backbone_and_2_stub.test new file mode 100644 index 000000000..201c0fa3f --- /dev/null +++ b/tests/module/ospf_backbone_and_2_stub.test @@ -0,0 +1,274 @@ +%description: +Testing OSPF routing + Backbone and 2 stub areas + UDP communications through entire network +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; + + +network Test1 +{ + parameters: + int numIRouters = default(0); + @display("p=10,10;b=712,152"); + types: + channel C extends ThruputMeteringChannel + { + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; + } + submodules: + H1: StandardHost { + parameters: + @display("p=56,92;i=device/laptop"); + gates: + ethg[1]; + } + N1: EtherHub { + parameters: + @display("p=184,182"); + gates: + ethg[2]; + } + RA1I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R1: OSPFRouter { + parameters: + @display("p=296,92"); + gates: + ethg[2]; + } + RI[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R2: OSPFRouter { + parameters: + @display("p=416,92"); + gates: + ethg[2]; + } + RA2I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + N2: EtherHub { + parameters: + @display("p=532,182"); + gates: + ethg[2]; + } + H2: StandardHost { + parameters: + @display("p=660,92;i=device/laptop"); + gates: + ethg[1]; + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+ + ""+ + ""+ + ""+ + ""+ + ""); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=75,43"); + } + connections: + H1.ethg[0] <--> C <--> N1.ethg[0]; + N1.ethg[1] <--> C <--> R1.ethg[0] if numIRouters == 0; + N1.ethg[1] <--> C <--> RA1I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA1I[i-1].ethg[1] <--> C <--> RA1I[i].ethg[0]; + } + RA1I[numIRouters-1].ethg[1] <--> C <--> R1.ethg[0] if numIRouters > 0; + + R1.ethg[1] <--> C <--> R2.ethg[0] if numIRouters == 0; + R1.ethg[1] <--> C <--> RI[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RI[i-1].ethg[1] <--> C <--> RI[i].ethg[0]; + } + RI[numIRouters-1].ethg[1] <--> C <--> R2.ethg[0] if numIRouters > 0; + + R2.ethg[1] <--> C <--> N2.ethg[0] if numIRouters == 0; + R2.ethg[1] <--> C <--> RA2I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA2I[i-1].ethg[1] <--> C <--> RA2I[i].ethg[0]; + } + RA2I[numIRouters-1].ethg[1] <--> C <--> N2.ethg[0] if numIRouters > 0; + + N2.ethg[1] <--> C <--> H2.ethg[0]; +} + + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Simple test" +network = Test1 +ned-path = .;../../../../src;../../lib +tkenv-plugin-path = ../../../etc/plugins +sim-time-limit = 200s + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + +**.numUdpApps = 2 +**.udpApp[0].typename = "UDPBasicApp" +**.udpApp[0].destPort = 1234 +**.udpApp[0].messageLength = 32 bytes +**.udpApp[0].sendInterval = 1s +**.udpApp[0].startTime = 55s +**.udpApp[0].stopTime = this.startTime + 100s +**.H2.udpApp[0].destAddresses = "H1" +**.H1.udpApp[0].destAddresses = "H2" +**.udpApp[1].typename = "UDPEchoApp" +**.udpApp[1].localPort = 1234 + +**.arp.cacheTimeout = 1s + +**.numIRouters = ${0,1,2,3,5,7,8} + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/module/ospf_backbone_and_3_areas_VirtualLink_HostInterface.test b/tests/module/ospf_backbone_and_3_areas_VirtualLink_HostInterface.test new file mode 100644 index 000000000..ec8ddd9b4 --- /dev/null +++ b/tests/module/ospf_backbone_and_3_areas_VirtualLink_HostInterface.test @@ -0,0 +1,331 @@ +%description: +Testing OSPF routing + Backbone and 3 areas, Area1 connected to Backbone through Area3 used a VirtualLink + UDP communications through entire network +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; + + +network Test1 +{ + parameters: + int numIRouters = default(0); + @display("p=10,10;b=712,152"); + types: + channel C extends ThruputMeteringChannel + { + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; + } + submodules: + H1: StandardHost { + parameters: + @display("p=56,92;i=device/laptop"); + gates: + ethg[1]; + } + N1: EtherHub { + parameters: + @display("p=184,182"); + gates: + ethg[2]; + } + RA1: OSPFRouter { + gates: + ethg[2]; + } + RA1I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R1: OSPFRouter { + parameters: + @display("p=296,92"); + gates: + ethg[2]; + } + RA3I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R3: OSPFRouter { + parameters: + @display("p=296,92"); + gates: + ethg[2]; + } + RI[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R2: OSPFRouter { + parameters: + @display("p=416,92"); + gates: + ethg[2]; + } + RA2I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + RA2: OSPFRouter { + gates: + ethg[2]; + } + N2: EtherHub { + parameters: + @display("p=532,182"); + gates: + ethg[2]; + } + H2: StandardHost { + parameters: + @display("p=660,92;i=device/laptop"); + gates: + ethg[1]; + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=75,43"); + } + connections: + H1.ethg[0] <--> C <--> N1.ethg[0]; + N1.ethg[1] <--> C <--> RA1.ethg[0]; + RA1.ethg[1] <--> C <--> R1.ethg[0] if numIRouters == 0; + RA1.ethg[1] <--> C <--> RA1I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA1I[i-1].ethg[1] <--> C <--> RA1I[i].ethg[0]; + } + RA1I[numIRouters-1].ethg[1] <--> C <--> R1.ethg[0] if numIRouters > 0; + + + R1.ethg[1] <--> C <--> R3.ethg[0] if numIRouters == 0; + R1.ethg[1] <--> C <--> RA3I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA3I[i-1].ethg[1] <--> C <--> RA3I[i].ethg[0]; + } + RA3I[numIRouters-1].ethg[1] <--> C <--> R3.ethg[0] if numIRouters > 0; + + + + R3.ethg[1] <--> C <--> R2.ethg[0] if numIRouters == 0; + R3.ethg[1] <--> C <--> RI[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RI[i-1].ethg[1] <--> C <--> RI[i].ethg[0]; + } + RI[numIRouters-1].ethg[1] <--> C <--> R2.ethg[0] if numIRouters > 0; + + R2.ethg[1] <--> C <--> RA2.ethg[0] if numIRouters == 0; + R2.ethg[1] <--> C <--> RA2I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA2I[i-1].ethg[1] <--> C <--> RA2I[i].ethg[0]; + } + RA2I[numIRouters-1].ethg[1] <--> C <--> RA2.ethg[0] if numIRouters > 0; + + RA2.ethg[1] <--> C <--> N2.ethg[0]; + N2.ethg[1] <--> C <--> H2.ethg[0]; +} + + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Simple test" +network = Test1 +ned-path = .;../../../../src;../../lib +tkenv-plugin-path = ../../../etc/plugins +sim-time-limit = 200s + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + +**.numUdpApps = 2 +**.udpApp[0].typename = "UDPBasicApp" +**.udpApp[0].destPort = 1234 +**.udpApp[0].messageLength = 32 bytes +**.udpApp[0].sendInterval = 1s +**.udpApp[0].startTime = 59s +**.udpApp[0].stopTime = this.startTime + 100s +**.H2.udpApp[0].destAddresses = "H1" +**.H1.udpApp[0].destAddresses = "H2" +**.udpApp[1].typename = "UDPEchoApp" +**.udpApp[1].localPort = 1234 + +**.arp.cacheTimeout = 1s + +**.numIRouters = ${0,1,2,3,4,5,6} + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/module/ospf_backbone_and_3_areas_with_virtual_link.test b/tests/module/ospf_backbone_and_3_areas_with_virtual_link.test new file mode 100644 index 000000000..6e1fb5644 --- /dev/null +++ b/tests/module/ospf_backbone_and_3_areas_with_virtual_link.test @@ -0,0 +1,331 @@ +%description: +Testing OSPF routing + Backbone and 3 areas, Area1 connected to Backbone through Area3 used a VirtualLink + UDP communications through entire network +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; + + +network Test1 +{ + parameters: + int numIRouters = default(0); + @display("p=10,10;b=712,152"); + types: + channel C extends ThruputMeteringChannel + { + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; + } + submodules: + H1: StandardHost { + parameters: + @display("p=56,92;i=device/laptop"); + gates: + ethg[1]; + } + N1: EtherHub { + parameters: + @display("p=184,182"); + gates: + ethg[2]; + } + RA1: OSPFRouter { + gates: + ethg[2]; + } + RA1I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R1: OSPFRouter { + parameters: + @display("p=296,92"); + gates: + ethg[2]; + } + RA3I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R3: OSPFRouter { + parameters: + @display("p=296,92"); + gates: + ethg[2]; + } + RI[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R2: OSPFRouter { + parameters: + @display("p=416,92"); + gates: + ethg[2]; + } + RA2I[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + RA2: OSPFRouter { + gates: + ethg[2]; + } + N2: EtherHub { + parameters: + @display("p=532,182"); + gates: + ethg[2]; + } + H2: StandardHost { + parameters: + @display("p=660,92;i=device/laptop"); + gates: + ethg[1]; + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=75,43"); + } + connections: + H1.ethg[0] <--> C <--> N1.ethg[0]; + N1.ethg[1] <--> C <--> RA1.ethg[0]; + RA1.ethg[1] <--> C <--> R1.ethg[0] if numIRouters == 0; + RA1.ethg[1] <--> C <--> RA1I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA1I[i-1].ethg[1] <--> C <--> RA1I[i].ethg[0]; + } + RA1I[numIRouters-1].ethg[1] <--> C <--> R1.ethg[0] if numIRouters > 0; + + + R1.ethg[1] <--> C <--> R3.ethg[0] if numIRouters == 0; + R1.ethg[1] <--> C <--> RA3I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA3I[i-1].ethg[1] <--> C <--> RA3I[i].ethg[0]; + } + RA3I[numIRouters-1].ethg[1] <--> C <--> R3.ethg[0] if numIRouters > 0; + + + + R3.ethg[1] <--> C <--> R2.ethg[0] if numIRouters == 0; + R3.ethg[1] <--> C <--> RI[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RI[i-1].ethg[1] <--> C <--> RI[i].ethg[0]; + } + RI[numIRouters-1].ethg[1] <--> C <--> R2.ethg[0] if numIRouters > 0; + + R2.ethg[1] <--> C <--> RA2.ethg[0] if numIRouters == 0; + R2.ethg[1] <--> C <--> RA2I[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RA2I[i-1].ethg[1] <--> C <--> RA2I[i].ethg[0]; + } + RA2I[numIRouters-1].ethg[1] <--> C <--> RA2.ethg[0] if numIRouters > 0; + + RA2.ethg[1] <--> C <--> N2.ethg[0]; + N2.ethg[1] <--> C <--> H2.ethg[0]; +} + + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Simple test" +network = Test1 +ned-path = .;../../../../src;../../lib +tkenv-plugin-path = ../../../etc/plugins +sim-time-limit = 200s + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + +**.numUdpApps = 2 +**.udpApp[0].typename = "UDPBasicApp" +**.udpApp[0].destPort = 1234 +**.udpApp[0].messageLength = 32 bytes +**.udpApp[0].sendInterval = 1s +**.udpApp[0].startTime = 59s +**.udpApp[0].stopTime = this.startTime + 100s +**.H2.udpApp[0].destAddresses = "H1" +**.H1.udpApp[0].destAddresses = "H2" +**.udpApp[1].typename = "UDPEchoApp" +**.udpApp[1].localPort = 1234 + +**.arp.cacheTimeout = 1s + +**.numIRouters = ${0,1,2,3,4,5,6} + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-1.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-2.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-3.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-4.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-5.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H1.udpApp[1] echoedPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] sentPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[0] rcvdPk:count 100 +%contains: results/General-6.sca +scalar Test1.H2.udpApp[1] echoedPk:count 100 +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/module/ospf_fig6_simple_fail.test b/tests/module/ospf_fig6_simple_fail.test new file mode 100644 index 000000000..5956f8829 --- /dev/null +++ b/tests/module/ospf_fig6_simple_fail.test @@ -0,0 +1,293 @@ +%description: +Testing OSPF routing + Detects bugs in OSPF on RFC2328 fig.6. network + These UDP communications don't work yet: + Area3.N10.host0 <--> N15.host0 + N12.host0 <--> Area3.H1 +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; + + +channel C extends ThruputMeteringChannel +{ + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; +} + +module OspfLan +{ + parameters: + int h; // number of hosts on the hub + @display("i=cloud"); + gates: + inout ethg[]; + submodules: + hub: EtherHub { + @display("is=s"); + } + host[h]: StandardHost { + @display("is=s"); + } + connections: + for i=0..sizeof(ethg)-1 { + hub.ethg++ <--> ethg[i]; + } + for i=0..h-1 { + hub.ethg++ <--> C <--> host[i].ethg++; + } +} + +network Fig6 +{ + parameters: + @display("p=10,10;b=704,560"); + submodules: + RT5: OSPFRouter { + parameters: + @display("p=496,144"); + gates: + ethg[6]; + } + RT6: OSPFRouter { + parameters: + @display("p=424,208"); + gates: + ethg[3]; + } + RT7: OSPFRouter { + parameters: + @display("p=496,328"); + gates: + ethg[4]; + } + RT10: OSPFRouter { + parameters: + @display("p=424,328"); + gates: + ethg[3]; + } + RT11: OSPFRouter { + parameters: + @display("p=282,404"); + gates: + ethg[2]; + } + N12: OspfLan { + parameters: + h = 1; + @display("p=620,277"); + } + N15: OspfLan { + parameters: + h = 1; + @display("p=608,356"); + } + Area2_N6: EtherHub { + parameters: + @display("p=504,467"); + } + Area2_N8: EtherHub { + parameters: + @display("p=411,467"); + } + Area3_RT12: OSPFRouter { + parameters: + @display("p=148,360"); + gates: + ethg[3]; + } + Area3_N9: EtherHub { + parameters: + @display("p=148,284"); + } + Area3_N10: OspfLan { + parameters: + h = 1; + @display("p=148,452"); + } + Area3_H1: StandardHost { + parameters: + @display("p=64,360;i=device/pc_s"); + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+"\n"+ + ""+"\n"+ + ""+"\n"+ + ""+"\n"+ + + ""+"\n"+ + ""+"\n"+ + ""+"\n"+ + + ""+"\n"+ + ""+"\n"+ + ""+"\n"+ + ""+"\n"+ + + ""+"\n"+ + ""+"\n"); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=120,43"); + } + connections allowunconnected: + Area3_RT12.ethg[1] <--> C <--> Area3_H1.ethg++; + Area3_RT12.ethg[0] <--> C <--> Area3_N9.ethg++; + Area3_RT12.ethg[2] <--> C <--> Area3_N10.ethg++; + RT11.ethg[0] <--> C <--> Area3_N9.ethg++; + Area2_N8.ethg++ <--> C <--> RT11.ethg[1]; + Area2_N8.ethg++ <--> C <--> RT10.ethg[1]; + Area2_N6.ethg++ <--> C <--> RT10.ethg[2]; + Area2_N6.ethg++ <--> C <--> RT7.ethg[1]; + + RT5.ethg[3] <--> C <--> RT7.ethg[0]; + RT5.ethg[2] <--> C <--> RT6.ethg[2]; + RT5.ethg[4] <--> C <--> N12.ethg++; + RT6.ethg[1] <--> C <--> RT10.ethg[0]; + RT7.ethg[3] <--> C <--> N12.ethg++; + RT7.ethg[2] <--> C <--> N15.ethg++; +} + + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Full network test" +network = Fig6 +ned-path = .;../../../../src;../../lib + +tkenv-plugin-path = ../../../etc/plugins + +sim-time-limit = 300s + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + + +**.arp.cacheTimeout = 1s + +*.usenew = true + +**.Area3_N10.host[0].numUdpApps = 2 +**.N15.host[0].numUdpApps = 2 +**.N12.host[0].numUdpApps = 2 +**.Area3_H1.numUdpApps = 2 + +**.udpApp[0].typename = "UDPEchoApp" +**.udpApp[0].localPort = 1234 + +**.udpApp[1..].typename = "UDPBasicApp" +**.udpApp[1..].destPort = 1234 +**.udpApp[1..].messageLength = 32 bytes +**.udpApp[1..].sendInterval = 1s +**.udpApp[1..].startTime = 100s +**.udpApp[1..].stopTime = this.startTime + 100s + +**.Area3_N10.host[0].udpApp[1].destAddresses = "N15.host[0]" +**.N15.host[0].udpApp[1].destAddresses = "Area3_N10.host[0]" +**.N12.host[0].udpApp[1].destAddresses = "Area3_H1" +**.Area3_H1.udpApp[1].destAddresses = "N12.host[0]" + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: results/General-0.sca +scalar Fig6.N12.host[0].udpApp[0] echoedPk:count 100 +%contains: results/General-0.sca +scalar Fig6.N12.host[0].udpApp[1] sentPk:count 100 +%contains: results/General-0.sca +scalar Fig6.N12.host[0].udpApp[1] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Fig6.N15.host[0].udpApp[0] echoedPk:count 100 +%contains: results/General-0.sca +scalar Fig6.N15.host[0].udpApp[1] sentPk:count 100 +%contains: results/General-0.sca +scalar Fig6.N15.host[0].udpApp[1] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Fig6.Area3_N10.host[0].udpApp[0] echoedPk:count 100 +%contains: results/General-0.sca +scalar Fig6.Area3_N10.host[0].udpApp[1] sentPk:count 100 +%contains: results/General-0.sca +scalar Fig6.Area3_N10.host[0].udpApp[1] rcvdPk:count 100 +%contains: results/General-0.sca +scalar Fig6.Area3_H1.udpApp[0] echoedPk:count 100 +%contains: results/General-0.sca +scalar Fig6.Area3_H1.udpApp[1] sentPk:count 100 +%contains: results/General-0.sca +scalar Fig6.Area3_H1.udpApp[1] rcvdPk:count 100 +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/smoke/examples-TODO.csv_off b/tests/smoke/examples-TODO.csv_off index 4467cbf3a..5860e410d 100644 --- a/tests/smoke/examples-TODO.csv_off +++ b/tests/smoke/examples-TODO.csv_off @@ -1,13 +1,20 @@ -# workingdir, args, simtimelimit, fingerprint +# workingdir, args # /examples/adhoc/ieee80211/, -f omnetpp.ini -c Ping2 -r 0 # [Config Ping2] # __interactive__ # /examples/adhoc/mf80211/, -f omnetpp.ini -c Ping2 -r 0 # [Config Ping2] # __interactive__ +# /examples/diffserv/onedomain/, -f omnetpp.ini -c Apps -r 0 # __interactive__ +# /examples/diffserv/onedomain/, -f omnetpp.ini -c Exp1 -r 0 # __interactive__ +# /examples/diffserv/onedomain/, -f omnetpp.ini -c Exp2 -r 0 # __interactive__ +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp3 -r 0 # ( Error in module (cCompoundModule) DiffservNetwork.H1 (id=2) during network setup) Unable to determine type name for submodule udpApp, missing entry DiffservNetwork.H1.udpApp[0].typename and no default value, at /home/zoli/Projects/OMNET/inet/src/nodes/inet/StandardHost.ned:69. +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp5 -r 0 # Zero time simulation + /examples/emulation/extclient/, -f omnetpp.ini -c General -r 0 # ext interface tests are not supported as they require pcap drivers and external events /examples/emulation/extserver/, -f omnetpp.ini -c Uplink_Traffic -r 0 /examples/emulation/extserver/, -f omnetpp.ini -c Downlink_Traffic -r 0 /examples/emulation/extserver/, -f omnetpp.ini -c Uplink_and_Downlink_Traffic -r 0 /examples/emulation/traceroute/, -f omnetpp.ini -c General -r 0 +# /examples/ethernet/lans/, -f defaults.ini -c General -r 0 # Skip this. The defaults.ini is just an included file. /examples/inet/hierarchical/, -f omnetpp.ini -c Hosts1280 -r 0 # cpu time limit exceeded /examples/inet/hierarchical/, -f omnetpp.ini -c Hosts9000 -r 0 # cpu time limit exceeded /examples/inet/tcpclientserver/, -f omnetpp.ini -c NSClinux__NSCfreebsd -r 0 # NSC lwip and freebsd cannot be built on Linux 64-bit platforms @@ -21,8 +28,6 @@ /examples/mpls/net37/, -f omnetpp.ini -c General -r 0 # ( Error in module (TED) R37.LSR0.ted (id=45) during network initialization) - old "NetworkConfigurator" related example /examples/mpls/testte_failure2/, -f omnetpp.ini -c General -r 0 # FAIL ( Error in module (TED) RSVPTE4.LSR1.ted (id=20) during network initialization). Model error: ASSERT: condition !remote.isUnspecified() false in function initialize, networklayer/ted/TED.cc line 86. -/examples/ospfv2/backbone/, -f omnetpp.ini -c General -r 0 # FAIL ( Error in module (OSPFRouting) Backbone.R6.ospf (id=132) at event #23916, t=45.089338342798). check_and_cast(): cannot cast (OSPF::NetworkLSA *) to type 'OSPF::RouterLSA *'. - # /examples/wireless/lan80211/, -f omnetpp-ftp.ini -c NHosts -r 0 # [Config NHosts] # __interactive__ # /examples/wireless/lan80211/, -f omnetpp-streaming.ini -c Streaming2 -r 0 # [Config Streaming2] # __interactive__ # /examples/wireless/lan80211/, -f omnetpp.ini -c Ping2 -r 0 # [Config Ping2] # __interactive__ diff --git a/tests/smoke/examples.csv b/tests/smoke/examples.csv index 51da47c26..ecb027419 100644 --- a/tests/smoke/examples.csv +++ b/tests/smoke/examples.csv @@ -1,10 +1,7 @@ -# workingdir, args, simtimelimit, fingerprint +# workingdir, args /examples/adhoc/ieee80211/, -f fingerprints.ini -c Ping1 -r 0 /examples/adhoc/ieee80211/, -f omnetpp.ini -c Ping1 -r 0 # /examples/adhoc/ieee80211/, -f omnetpp.ini -c Ping2 -r 0 # [Config Ping2] # __interactive__ -/examples/adhoc/mf80211/, -f fingerprints.ini -c Ping1 -r 0 -/examples/adhoc/mf80211/, -f omnetpp.ini -c Ping1 -r 0 -# /examples/adhoc/mf80211/, -f omnetpp.ini -c Ping2 -r 0 # [Config Ping2] # __interactive__ /examples/bgpv4/BGP2RoutersInAS/, -f omnetpp.ini -c config1 -r 0 /examples/bgpv4/BGP3Routers/, -f omnetpp.ini -c config1 -r 0 /examples/bgpv4/BGPCompleteTest/, -f omnetpp.ini -c config1 -r 0 @@ -12,10 +9,34 @@ /examples/bgpv4/BGPUpdate/, -f omnetpp.ini -c config1 -r 0 /examples/bgpv4/BGPandOSPF/, -f omnetpp.ini -c config1 -r 0 /examples/bgpv4/BGPandOSPFSimple/, -f omnetpp.ini -c config1 -r 0 -/examples/diffserv/onedomain, -f omnetpp.ini -c Exp11 -r 0 -/examples/diffserv/onedomain, -f omnetpp.ini -c Exp21 -r 0 -/examples/diffserv/onedomain, -f omnetpp.ini -c Exp31 -r 0 -/examples/diffserv/onedomain, -f omnetpp.ini -c Exp51 -r 0 +# /examples/diffserv/onedomain/, -f omnetpp.ini -c Apps -r 0 # __interactive__ +# /examples/diffserv/onedomain/, -f omnetpp.ini -c Exp1 -r 0 # __interactive__ +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp11 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp12 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp13 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp14 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp15 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp16 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp17 -r 0 +# /examples/diffserv/onedomain/, -f omnetpp.ini -c Exp2 -r 0 # __interactive__ +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp21 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp22 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp23 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp24 -r 0 +# /examples/diffserv/onedomain/, -f omnetpp.ini -c Exp3 -r 0 # ( Error in module (cCompoundModule) DiffservNetwork.H1 (id=2) during network setup) Unable to determine type name for submodule udpApp, missing entry DiffservNetwork.H1.udpApp[0].typename and no default value, at /home/zoli/Projects/OMNET/inet/src/nodes/inet/StandardHost.ned:69. +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp31 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp32 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp33 -r 0 +# /examples/diffserv/onedomain/, -f omnetpp.ini -c Exp5 -r 0 # Zero time simulation +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp51 -r 0 +/examples/diffserv/onedomain/, -f omnetpp.ini -c Exp52 -r 0 +/examples/diffserv/simple_/, -f omnetpp.ini -c VoIP -r 0 +/examples/diffserv/simple_/, -f omnetpp.ini -c WithoutQoS -r 0 +/examples/diffserv/simple_/, -f omnetpp.ini -c WithPolicing -r 0 +/examples/diffserv/simple_/, -f omnetpp.ini -c WithQueueing -r 0 +/examples/diffserv/simple_/, -f omnetpp.ini -c VoIP_WithoutQoS -r 0 +/examples/diffserv/simple_/, -f omnetpp.ini -c VoIP_WithPolicing -r 0 +/examples/diffserv/simple_/, -f omnetpp.ini -c VoIP_WithPolicingAndQueueing -r 0 # /examples/emulation/extclient/, -f omnetpp.ini -c General -r 0 # ext interface tests are not supported as they require pcap drivers and external events # /examples/emulation/extserver/, -f omnetpp.ini -c Uplink_Traffic -r 0 # ext interface tests are not supported as they require pcap drivers and external events # /examples/emulation/extserver/, -f omnetpp.ini -c Downlink_Traffic -r 0 # ext interface tests are not supported as they require pcap drivers and external events @@ -207,12 +228,17 @@ /examples/mpls/testte_routing/, -f omnetpp.ini -c General -r 0 /examples/mpls/testte_tunnel/, -f omnetpp.ini -c General -r 0 /examples/ospfv2/areas/, -f omnetpp.ini -c General -r 0 -# /examples/ospfv2/backbone/, -f omnetpp.ini -c General -r 0 #Error in module (OSPFRouting) Backbone.R6.ospf (id=132) at event #22346, t=40.111838360149) check_and_cast(): cannot cast (OSPF::NetworkLSA *) to type 'OSPF::RouterLSA *'. +/examples/ospfv2/areatests/, -f omnetpp.ini -c backbone -r 0 +/examples/ospfv2/areatests/, -f omnetpp.ini -c backboneandonestub -r 0 +/examples/ospfv2/areatests/, -f omnetpp.ini -c backboneandtwostubs -r 0 +/examples/ospfv2/backbone/, -f omnetpp.ini -c General -r 0 +/examples/ospfv2/dynamictest/, -f omnetpp.ini -c stable -r 0 +/examples/ospfv2/dynamictest/, -f omnetpp.ini -c dynamic1 -r 0 /examples/ospfv2/fulltest/, -f omnetpp.ini -c General -r 0 /examples/ospfv2/simpletest/, -f omnetpp.ini -c General -r 0 /examples/rtp/multicast1/, -f omnetpp.ini -c General -r 0 -/examples/rtp/multicast11/, -f omnetpp.ini -c General -r 0 /examples/rtp/unicast/, -f omnetpp.ini -c General -r 0 +/examples/rtp/unicast1/, -f omnetpp.ini -c General -r 0 /examples/rtp/unicast2/, -f omnetpp.ini -c General -r 0 /examples/sctp/multihomed/, -f omnetpp.ini -c General -r 0 /examples/sctp/nclients/, -f omnetpp.ini -c General -r 0 diff --git a/tests/statistical/EtherMACs_compare_twohosts_speed.test b/tests/statistical/EtherMACs_compare_twohosts_speed.test index 609e6ba26..6070e8ab8 100644 --- a/tests/statistical/EtherMACs_compare_twohosts_speed.test +++ b/tests/statistical/EtherMACs_compare_twohosts_speed.test @@ -139,7 +139,7 @@ cat("\nOMNETPP TEST RESULT:\n") cat("\nCHECK SENT PACKETS:\n") -x <- dataset$scalars[dataset$scalars$name == "sentPk:sum(packetBytes)",] +x <- dataset$scalars[dataset$scalars$name == "sentPk:count",] xx <- x[grep("_F_A.cli$",x$module)==1,] if(length(xx$value) != linecount) diff --git a/tests/statistical/EtherMacFullDuplex_twohosts_speed.test b/tests/statistical/EtherMacFullDuplex_twohosts_speed.test index 4d35468e5..185379afb 100644 --- a/tests/statistical/EtherMacFullDuplex_twohosts_speed.test +++ b/tests/statistical/EtherMacFullDuplex_twohosts_speed.test @@ -136,7 +136,7 @@ used <- loadDataset(scafile, add(type='scalar', select='name("rx channel utiliza cat("\nOMNETPP TEST RESULT: ") -if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelimit) +if(length(idle$scalars$value) == linecount & max(idle$scalars$value) <= idlelimit) { cat("IDLE OK\n") } else { @@ -146,7 +146,7 @@ if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelim cat("\nOMNETPP TEST RESULT: ") -if(length(used$scalars$value) == linecount && min(used$scalars$value) >= usedlimit) +if(length(used$scalars$value) == linecount & min(used$scalars$value) >= usedlimit) { cat("USED OK\n") } else { diff --git a/tests/statistical/EtherMac_bus_reconnect_speed.test b/tests/statistical/EtherMac_bus_reconnect_speed.test index 6b6ba6bbd..f8b756b20 100644 --- a/tests/statistical/EtherMac_bus_reconnect_speed.test +++ b/tests/statistical/EtherMac_bus_reconnect_speed.test @@ -244,7 +244,7 @@ used <- loadDataset(scafile, add(type='scalar', select='name("rx channel utiliza cat("\nOMNETPP TEST RESULT: ") -if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelimit) +if(length(idle$scalars$value) == linecount & max(idle$scalars$value) <= idlelimit) { cat("IDLE OK\n") } else { @@ -254,7 +254,7 @@ if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelim cat("\nOMNETPP TEST RESULT: ") -if(length(used$scalars$value) == linecount && min(used$scalars$value) >= usedlimit) +if(length(used$scalars$value) == linecount & min(used$scalars$value) >= usedlimit) { cat("USED OK\n") } else { diff --git a/tests/statistical/EtherMac_bus_speed.test b/tests/statistical/EtherMac_bus_speed.test index 58f00027b..eeb113a4e 100644 --- a/tests/statistical/EtherMac_bus_speed.test +++ b/tests/statistical/EtherMac_bus_speed.test @@ -155,7 +155,7 @@ used <- loadDataset(scafile, add(type='scalar', select='name("rx channel utiliza cat("\nOMNETPP TEST RESULT: ") -if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelimit) +if(length(idle$scalars$value) == linecount & max(idle$scalars$value) <= idlelimit) { cat("IDLE OK\n") } else { @@ -165,7 +165,7 @@ if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelim cat("\nOMNETPP TEST RESULT: ") -if(length(used$scalars$value) == linecount && min(used$scalars$value) >= usedlimit) +if(length(used$scalars$value) == linecount & min(used$scalars$value) >= usedlimit) { cat("USED OK\n") } else { diff --git a/tests/statistical/EtherMac_fullduplex_twohosts_speed.test b/tests/statistical/EtherMac_fullduplex_twohosts_speed.test index cefc76d3f..44f9971be 100644 --- a/tests/statistical/EtherMac_fullduplex_twohosts_speed.test +++ b/tests/statistical/EtherMac_fullduplex_twohosts_speed.test @@ -137,7 +137,7 @@ used <- loadDataset(scafile, add(type='scalar', select='name("rx channel utiliza cat("\nOMNETPP TEST RESULT: ") -if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelimit) +if(length(idle$scalars$value) == linecount & max(idle$scalars$value) <= idlelimit) { cat("IDLE OK\n") } else { @@ -147,7 +147,7 @@ if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelim cat("\nOMNETPP TEST RESULT: ") -if(length(used$scalars$value) == linecount && min(used$scalars$value) >= usedlimit) +if(length(used$scalars$value) == linecount & min(used$scalars$value) >= usedlimit) { cat("USED OK\n") } else { diff --git a/tests/statistical/EtherMac_halfduplex_twohosts_speed.test b/tests/statistical/EtherMac_halfduplex_twohosts_speed.test index 7a0606a6b..df3e4071a 100644 --- a/tests/statistical/EtherMac_halfduplex_twohosts_speed.test +++ b/tests/statistical/EtherMac_halfduplex_twohosts_speed.test @@ -132,7 +132,7 @@ used <- loadDataset(scafile, add(type='scalar', select='name("rx channel utiliza cat("\nOMNETPP TEST RESULT: ") -if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelimit) +if(length(idle$scalars$value) == linecount & max(idle$scalars$value) <= idlelimit) { cat("IDLE OK\n") } else { @@ -142,7 +142,7 @@ if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelim cat("\nOMNETPP TEST RESULT: ") -if(length(used$scalars$value) == linecount && min(used$scalars$value) >= usedlimit) +if(length(used$scalars$value) == linecount & min(used$scalars$value) >= usedlimit) { cat("USED OK\n") } else { diff --git a/tests/statistical/EtherMac_hub_reconnect_speed.test b/tests/statistical/EtherMac_hub_reconnect_speed.test index f9f2f022f..dcb725bef 100644 --- a/tests/statistical/EtherMac_hub_reconnect_speed.test +++ b/tests/statistical/EtherMac_hub_reconnect_speed.test @@ -246,7 +246,7 @@ used <- loadDataset(scafile, add(type='scalar', select='name("rx channel utiliza cat("\nOMNETPP TEST RESULT: ") -if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelimit) +if(length(idle$scalars$value) == linecount & max(idle$scalars$value) <= idlelimit) { cat("IDLE OK\n") } else { @@ -256,7 +256,7 @@ if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelim cat("\nOMNETPP TEST RESULT: ") -if(length(used$scalars$value) == linecount && min(used$scalars$value) >= usedlimit) +if(length(used$scalars$value) == linecount & min(used$scalars$value) >= usedlimit) { cat("USED OK\n") } else { diff --git a/tests/statistical/EtherMac_hub_speed.test b/tests/statistical/EtherMac_hub_speed.test index c29f5c3c2..eb066edb8 100644 --- a/tests/statistical/EtherMac_hub_speed.test +++ b/tests/statistical/EtherMac_hub_speed.test @@ -156,7 +156,7 @@ used <- loadDataset(scafile, add(type='scalar', select='name("rx channel utiliza cat("\nOMNETPP TEST RESULT: ") -if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelimit) +if(length(idle$scalars$value) == linecount & max(idle$scalars$value) <= idlelimit) { cat("IDLE OK\n") } else { @@ -166,7 +166,7 @@ if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelim cat("\nOMNETPP TEST RESULT: ") -if(length(used$scalars$value) == linecount && min(used$scalars$value) >= usedlimit) +if(length(used$scalars$value) == linecount & min(used$scalars$value) >= usedlimit) { cat("USED OK\n") } else { diff --git a/tests/statistical/EtherMac_switch_speed.test b/tests/statistical/EtherMac_switch_speed.test index 3ae5049f7..9ee8c7d7a 100644 --- a/tests/statistical/EtherMac_switch_speed.test +++ b/tests/statistical/EtherMac_switch_speed.test @@ -143,7 +143,7 @@ used <- loadDataset(scafile, add(type='scalar', select='name("rx channel utiliza cat("\nOMNETPP TEST RESULT: ") -if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelimit) +if(length(idle$scalars$value) == linecount & max(idle$scalars$value) <= idlelimit) { cat("IDLE OK\n") } else { @@ -153,7 +153,7 @@ if(length(idle$scalars$value) == linecount && max(idle$scalars$value) <= idlelim cat("\nOMNETPP TEST RESULT: ") -if(length(used$scalars$value) == linecount && min(used$scalars$value) >= usedlimit) +if(length(used$scalars$value) == linecount & min(used$scalars$value) >= usedlimit) { cat("USED OK\n") } else { diff --git a/tests/statistical/ieee80211_accesspoint_tenhost_congestion_speed_BAD.test b/tests/statistical/ieee80211_accesspoint_tenhost_congestion_speed_BAD.test index 8a518f3f3..af3e72f86 100644 --- a/tests/statistical/ieee80211_accesspoint_tenhost_congestion_speed_BAD.test +++ b/tests/statistical/ieee80211_accesspoint_tenhost_congestion_speed_BAD.test @@ -221,8 +221,8 @@ cat("\nOMNETPP TEST RESULT:\n") sink <- dataset$scalars[grep("\\.srvHost\\[\\d\\]\\.sink", dataset$scalars$module),] #print(sink) -secs <- (sink$value[sink$name == "rcvdPkBytes:count"] / sink$value[sink$name == "packetPerSec"]) -sinkRcvd <- sink[sink$name == "rcvdPkBytes:sum",] +secs <- (sink$value[sink$name == "rcvdPk:count"] / sink$value[sink$name == "packetPerSec"]) +sinkRcvd <- sink[sink$name == "rcvdPk:sum(packetBytes)",] #print(sinkRcvd) cnt <- length(sinkRcvd$value) diff --git a/tests/statistical/ieee80211_accesspoint_tenhost_speed.test b/tests/statistical/ieee80211_accesspoint_tenhost_speed.test index 575b03501..6d29b7e43 100644 --- a/tests/statistical/ieee80211_accesspoint_tenhost_speed.test +++ b/tests/statistical/ieee80211_accesspoint_tenhost_speed.test @@ -221,8 +221,8 @@ cat("\nOMNETPP TEST RESULT:\n") sink <- dataset$scalars[grep("\\.srvHost\\[\\d\\]\\.sink", dataset$scalars$module),] #print(sink) -secs <- (sink$value[sink$name == "rcvdPkBytes:count"] / sink$value[sink$name == "packetPerSec"]) -sinkRcvd <- sink[sink$name == "rcvdPkBytes:sum",] +secs <- (sink$value[sink$name == "rcvdPk:count"] / sink$value[sink$name == "packetPerSec"]) +sinkRcvd <- sink[sink$name == "rcvdPk:sum(packetBytes)",] #print(sinkRcvd) cnt <- length(sinkRcvd$value) diff --git a/tests/statistical/ieee80211_accesspoint_twohost_congestion_speed.test b/tests/statistical/ieee80211_accesspoint_twohost_congestion_speed.test index c803a6b4d..480e3a2a1 100644 --- a/tests/statistical/ieee80211_accesspoint_twohost_congestion_speed.test +++ b/tests/statistical/ieee80211_accesspoint_twohost_congestion_speed.test @@ -221,8 +221,8 @@ cat("\nOMNETPP TEST RESULT:\n") sink <- dataset$scalars[grep("\\.srvHost\\[\\d\\]\\.sink", dataset$scalars$module),] #print(sink) -secs <- (sink$value[sink$name == "rcvdPkBytes:count"] / sink$value[sink$name == "packetPerSec"]) -sinkRcvd <- sink[sink$name == "rcvdPkBytes:sum",] +secs <- (sink$value[sink$name == "rcvdPk:count"] / sink$value[sink$name == "packetPerSec"]) +sinkRcvd <- sink[sink$name == "rcvdPk:sum(packetBytes)",] #print(sinkRcvd) cnt <- length(sinkRcvd$value) diff --git a/tests/statistical/ieee80211_accesspoint_twohost_speed.test b/tests/statistical/ieee80211_accesspoint_twohost_speed.test index 4cc0c4164..f0ae6673e 100644 --- a/tests/statistical/ieee80211_accesspoint_twohost_speed.test +++ b/tests/statistical/ieee80211_accesspoint_twohost_speed.test @@ -221,8 +221,8 @@ cat("\nOMNETPP TEST RESULT:\n") sink <- dataset$scalars[grep("\\.srvHost\\[\\d\\]\\.sink", dataset$scalars$module),] #print(sink) -secs <- (sink$value[sink$name == "rcvdPkBytes:count"] / sink$value[sink$name == "packetPerSec"]) -sinkRcvd <- sink[sink$name == "rcvdPkBytes:sum",] +secs <- (sink$value[sink$name == "rcvdPk:count"] / sink$value[sink$name == "packetPerSec"]) +sinkRcvd <- sink[sink$name == "rcvdPk:sum(packetBytes)",] #print(sinkRcvd) cnt <- length(sinkRcvd$value) diff --git a/tests/statistical/ieee80211_adhoc_tenhost_congestion_speed.test b/tests/statistical/ieee80211_adhoc_tenhost_congestion_speed.test index 481ac4a2d..0290d9375 100644 --- a/tests/statistical/ieee80211_adhoc_tenhost_congestion_speed.test +++ b/tests/statistical/ieee80211_adhoc_tenhost_congestion_speed.test @@ -207,8 +207,8 @@ cat("\nOMNETPP TEST RESULT:\n") sink <- dataset$scalars[grep("\\.srvHost\\[\\d\\]\\.sink", dataset$scalars$module),] #print(sink) -secs <- (sink$value[sink$name == "rcvdPkBytes:count"] / sink$value[sink$name == "packetPerSec"]) -sinkRcvd <- sink[sink$name == "rcvdPkBytes:sum",] +secs <- (sink$value[sink$name == "rcvdPk:count"] / sink$value[sink$name == "packetPerSec"]) +sinkRcvd <- sink[sink$name == "rcvdPk:sum(packetBytes)",] #print(sinkRcvd) cnt <- length(sinkRcvd$value) diff --git a/tests/statistical/ieee80211_adhoc_tenhost_speed.test b/tests/statistical/ieee80211_adhoc_tenhost_speed.test index b0e12ca0e..544e417d3 100644 --- a/tests/statistical/ieee80211_adhoc_tenhost_speed.test +++ b/tests/statistical/ieee80211_adhoc_tenhost_speed.test @@ -207,8 +207,8 @@ cat("\nOMNETPP TEST RESULT:\n") sink <- dataset$scalars[grep("\\.srvHost\\[\\d\\]\\.sink", dataset$scalars$module),] #print(sink) -secs <- (sink$value[sink$name == "rcvdPkBytes:count"] / sink$value[sink$name == "packetPerSec"]) -sinkRcvd <- sink[sink$name == "rcvdPkBytes:sum",] +secs <- (sink$value[sink$name == "rcvdPk:count"] / sink$value[sink$name == "packetPerSec"]) +sinkRcvd <- sink[sink$name == "rcvdPk:sum(packetBytes)",] #print(sinkRcvd) cnt <- length(sinkRcvd$value) diff --git a/tests/statistical/ieee80211_adhoc_twohost_speed.test b/tests/statistical/ieee80211_adhoc_twohost_speed.test index 8d800a547..4a566cfec 100644 --- a/tests/statistical/ieee80211_adhoc_twohost_speed.test +++ b/tests/statistical/ieee80211_adhoc_twohost_speed.test @@ -207,8 +207,8 @@ cat("\nOMNETPP TEST RESULT:\n") sink <- dataset$scalars[grep("\\.srvHost\\[\\d\\]\\.sink", dataset$scalars$module),] #print(sink) -secs <- (sink$value[sink$name == "rcvdPkBytes:count"] / sink$value[sink$name == "packetPerSec"]) -sinkRcvd <- sink[sink$name == "rcvdPkBytes:sum",] +secs <- (sink$value[sink$name == "rcvdPk:count"] / sink$value[sink$name == "packetPerSec"]) +sinkRcvd <- sink[sink$name == "rcvdPk:sum(packetBytes)",] #print(sinkRcvd) cnt <- length(sinkRcvd$value) diff --git a/tests/statistical/manetrouting_transmit1.test b/tests/statistical/manetrouting_transmit1.test index 5ee95a9f2..aa193af70 100644 --- a/tests/statistical/manetrouting_transmit1.test +++ b/tests/statistical/manetrouting_transmit1.test @@ -186,7 +186,7 @@ cat("\n MANETROUTING UDP TEST RESULT:\n") cat("\n CHECKS SENT PACKETS:\n") -x <- dataset$scalars[dataset$scalars$name == "sentPkBytes:count",] +x <- dataset$scalars[dataset$scalars$name == "sentPk:count",] xx <- x[grep("\\.senderhost\\.udpApp\\[0\\]",x$module),] if(length(xx$value) != linecount) @@ -207,7 +207,7 @@ if(length(xx$value) != linecount) cat("\n CHECKS RECEIVED PACKETS:\n") -x <- dataset$scalars[dataset$scalars$name == "rcvdPkBytes:count",] +x <- dataset$scalars[dataset$scalars$name == "rcvdPk:count",] xx <- x[grep("\\.rcvrhost\\.udpApp\\[0\\]",x$module),] if(length(xx$value) != linecount) diff --git a/tests/statistical/manetrouting_transmit10.test b/tests/statistical/manetrouting_transmit10.test index 17e3ab4d5..099736b41 100644 --- a/tests/statistical/manetrouting_transmit10.test +++ b/tests/statistical/manetrouting_transmit10.test @@ -186,7 +186,7 @@ cat("\n MANETROUTING UDP TEST RESULT:\n") cat("\n CHECKS SENT PACKETS:\n") -x <- dataset$scalars[dataset$scalars$name == "sentPkBytes:count",] +x <- dataset$scalars[dataset$scalars$name == "sentPk:count",] xx <- x[grep("\\.senderhost\\.udpApp\\[0\\]",x$module),] if(length(xx$value) != linecount) @@ -207,7 +207,7 @@ if(length(xx$value) != linecount) cat("\n CHECKS RECEIVED PACKETS:\n") -x <- dataset$scalars[dataset$scalars$name == "rcvdPkBytes:count",] +x <- dataset$scalars[dataset$scalars$name == "rcvdPk:count",] xx <- x[grep("\\.rcvrhost\\.udpApp\\[0\\]",x$module),] if(length(xx$value) != linecount) diff --git a/tests/statistical/ospf_1_area_Dynamic.test b/tests/statistical/ospf_1_area_Dynamic.test new file mode 100644 index 000000000..ce10c3190 --- /dev/null +++ b/tests/statistical/ospf_1_area_Dynamic.test @@ -0,0 +1,297 @@ +%description: +Testing OSPF routing + Backbone only with n routers + UDP communications through entire backbone +%#-------------------------------------------------------------------------------------------------------------- +%testprog: opp_run +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; +import inet.world.scenario.ScenarioManager; + + +network Test1 +{ + parameters: + int numIRouters = default(0); + @display("p=10,10;b=712,152"); + types: + channel C extends ThruputMeteringChannel + { + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; + } + submodules: + H1: StandardHost { + parameters: + @display("p=56,92;i=device/laptop"); + gates: + ethg[1]; + } + N1: EtherHub { + parameters: + @display("p=184,182"); + gates: + ethg[2]; + } + R1A: OSPFRouter { + parameters: + @display("p=226,132"); + gates: + ethg[3]; + } + RA: OSPFRouter { + parameters: + @display("p=266,92"); + gates: + ethg[2]; + } + RB: OSPFRouter { + parameters: + @display("p=266,182"); + gates: + ethg[2]; + } + R1B: OSPFRouter { + parameters: + @display("p=306,132"); + gates: + ethg[3]; + } + RI[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R2: OSPFRouter { + parameters: + @display("p=416,92"); + gates: + ethg[2]; + } + N2: EtherHub { + parameters: + @display("p=532,182"); + gates: + ethg[2]; + } + H2: StandardHost { + parameters: + @display("p=660,92;i=device/laptop"); + gates: + ethg[1]; + } + scenarioManager: ScenarioManager { + parameters: + @display("p=594,50"); + script = xmldoc("scenario.xml"); +// script = xml(""); + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+ + ""+ + ""+ + ""+ + ""+ + ""); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=75,43"); + } + connections: + H1.ethg[0] <--> C <--> N1.ethg[0]; + N1.ethg[1] <--> C <--> R1A.ethg[0]; + + R1A.ethg[1] <--> C <--> RA.ethg[0]; + R1A.ethg[2] <--> C <--> RB.ethg[0]; + RA.ethg[1] <--> C <--> R1B.ethg[1]; + RB.ethg[1] <--> C <--> R1B.ethg[2]; + + R1B.ethg[0] <--> C <--> R2.ethg[0] if numIRouters == 0; + R1B.ethg[0] <--> C <--> RI[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RI[i-1].ethg[1] <--> C <--> RI[i].ethg[0]; + } + RI[numIRouters-1].ethg[1] <--> C <--> R2.ethg[0] if numIRouters > 0; + + R2.ethg[1] <--> C <--> N2.ethg[0]; + N2.ethg[1] <--> C <--> H2.ethg[0]; +} + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Simple test" +network = Test1 +tkenv-plugin-path = ../../../etc/plugins +sim-time-limit = 1200s +num-rngs = 2 + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + +**.numUdpApps = 2 +**.udpApp[0].typename = "UDPBasicApp" +**.udpApp[0].destPort = 1234 +**.udpApp[0].messageLength = 32 bytes +**.udpApp[0].sendInterval = 1s +**.udpApp[0].startTime = 100s + uniform(-0.5s, 0.5s, 1) +**.udpApp[0].stopTime = this.startTime + 999.9s +**.H2.udpApp[0].destAddresses = "H1" +**.H1.udpApp[0].destAddresses = "H2" +**.udpApp[1].typename = "UDPEchoApp" +**.udpApp[1].localPort = 1234 + +**.arp.cacheTimeout = 1s + +**.numIRouters = ${0,1,2,3,5,10,25} + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%file: scenario.xml + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%postprocess-script: check.r +#!/usr/bin/env Rscript + +options(echo=FALSE) +options(width=160) +library("omnetpp", warn.conflicts=FALSE) + + +#TEST parameters +runCount <- 7 +hostCount <- 2 +sentPk <- 1000 +echoedPk <- 960 +rcvdPk <- 960 + +# begin TEST: + +cat("\nOMNETPP TEST RESULT:\n") + +x <- loadDataset('results/General-*.sca') +ds <- x$scalars[grep("\\.H\\d\\.udpApp\\[\\d\\]$",x$scalars$module),] + +#merge runnumber column to ds: +y <- subset(x$runattrs, attrname=='runnumber') +names(y) <- c("runid","runnumber") +ds <- merge(ds,y) + +sent <- ds[ds$name == "sentPk:count",] +rcvd <- ds[ds$name == "rcvdPk:count",] +echoed <- ds[ds$name == "echoedPk:count",] + +cat("\nOSPF TEST RESULT:\n") + +sent$success = (sent$value == sentPk) +if(length(sent$value) == runCount*hostCount & min(sent$success) == TRUE) +{ + cat("SENT OK\n") +} else { + cat("SENT BAD:\n") + sent$rate = sent$value*100/sentPk + print(sent) +} + +echoed$success = (echoed$value >= echoedPk & echoed$value <= sentPk) +if(length(echoed$value) == runCount*hostCount & min(echoed$success) == TRUE) +{ + cat("ECHOED OK\n") +} else { + cat("ECHOED BAD:\n") + echoed$rate = echoed$value*100/sentPk + print(echoed) +} + +rcvd$success = ((rcvd$value >= rcvdPk) & (rcvd$value <= sentPk)) +if(length(rcvd$value) == runCount*hostCount & min(rcvd$success) == TRUE) +{ + cat("RCVD OK\n") +} else { + cat("RCVD BAD:\n") + rcvd$rate = rcvd$value*100/sentPk + print(rcvd) +} + + +cat("\n") + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: check.r.out + +OMNETPP TEST RESULT: + +OSPF TEST RESULT: +SENT OK +ECHOED OK +RCVD OK + +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/statistical/ospf_1_area_Dynamic2.test b/tests/statistical/ospf_1_area_Dynamic2.test new file mode 100644 index 000000000..e116b65e5 --- /dev/null +++ b/tests/statistical/ospf_1_area_Dynamic2.test @@ -0,0 +1,296 @@ +%description: +Testing OSPF routing + Backbone only with n routers + UDP communications through entire backbone +%#-------------------------------------------------------------------------------------------------------------- +%testprog: opp_run +%#-------------------------------------------------------------------------------------------------------------- +%file: test.ned + +import inet.linklayer.ethernet.EtherHub; +import inet.networklayer.autorouting.ipv4.IPv4NetworkConfigurator; +import inet.nodes.inet.StandardHost; +import inet.nodes.ospfv2.OSPFRouter; +import inet.util.ThruputMeteringChannel; +import inet.world.scenario.ScenarioManager; + + +network Test1 +{ + parameters: + int numIRouters = default(0); + @display("p=10,10;b=712,152"); + types: + channel C extends ThruputMeteringChannel + { + delay = 0.1us; + datarate = 100Mbps; + thruputDisplayFormat = "#N"; + } + submodules: + H1: StandardHost { + parameters: + @display("p=56,92;i=device/laptop"); + gates: + ethg[1]; + } + N1: EtherHub { + parameters: + @display("p=184,182"); + gates: + ethg[2]; + } + R1A: OSPFRouter { + parameters: + @display("p=226,132"); + gates: + ethg[3]; + } + RA: OSPFRouter { + parameters: + @display("p=266,92"); + gates: + ethg[2]; + } + RB: OSPFRouter { + parameters: + @display("p=266,182"); + gates: + ethg[2]; + } + R1B: OSPFRouter { + parameters: + @display("p=306,132"); + gates: + ethg[3]; + } + RI[numIRouters]: OSPFRouter { + gates: + ethg[2]; + } + R2: OSPFRouter { + parameters: + @display("p=416,92"); + gates: + ethg[2]; + } + N2: EtherHub { + parameters: + @display("p=532,182"); + gates: + ethg[2]; + } + H2: StandardHost { + parameters: + @display("p=660,92;i=device/laptop"); + gates: + ethg[1]; + } + scenarioManager: ScenarioManager { + parameters: + @display("p=594,50"); + script = xmldoc("scenario.xml"); +// script = xml(""); + } + configurator: IPv4NetworkConfigurator { + parameters: + config = xml(""+ + ""+ + ""+ + ""+ + ""+ + ""); + addStaticRoutes = false; + addDefaultRoutes = false; + @display("p=75,43"); + } + connections: + H1.ethg[0] <--> C <--> N1.ethg[0]; + N1.ethg[1] <--> C <--> R1A.ethg[0]; + + R1A.ethg[1] <--> C <--> RA.ethg[0]; + R1A.ethg[2] <--> C <--> RB.ethg[0]; + RA.ethg[1] <--> C <--> R1B.ethg[1]; + RB.ethg[1] <--> C <--> R1B.ethg[2]; + + R1B.ethg[0] <--> C <--> R2.ethg[0] if numIRouters == 0; + R1B.ethg[0] <--> C <--> RI[0].ethg[0] if numIRouters > 0; + for i = 1..numIRouters-1 { + RI[i-1].ethg[1] <--> C <--> RI[i].ethg[0]; + } + RI[numIRouters-1].ethg[1] <--> C <--> R2.ethg[0] if numIRouters > 0; + + R2.ethg[1] <--> C <--> N2.ethg[0]; + N2.ethg[1] <--> C <--> H2.ethg[0]; +} + +%#-------------------------------------------------------------------------------------------------------------- +%inifile: omnetpp.ini + +[General] +description = "Simple test" +network = Test1 +tkenv-plugin-path = ../../../etc/plugins +sim-time-limit = 1200s + +**.ospf.ospfConfig = xmldoc("ASConfig.xml") + +**.numUdpApps = 2 +**.udpApp[0].typename = "UDPBasicApp" +**.udpApp[0].destPort = 1234 +**.udpApp[0].messageLength = 32 bytes +**.udpApp[0].sendInterval = 1s +**.udpApp[0].startTime = 100s + uniform(-0.2s, 0.2s) +**.udpApp[0].stopTime = this.startTime + 1000s +**.H2.udpApp[0].destAddresses = "H1" +**.H1.udpApp[0].destAddresses = "H2" +**.udpApp[1].typename = "UDPEchoApp" +**.udpApp[1].localPort = 1234 + +**.arp.cacheTimeout = 1s + +**.numIRouters = ${3,3,3,3,3,3} + +%#-------------------------------------------------------------------------------------------------------------- +%file: ASConfig.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%file: scenario.xml + + + + + + + + + + + + + +%#-------------------------------------------------------------------------------------------------------------- +%postprocess-script: check.r +#!/usr/bin/env Rscript + +options(echo=FALSE) +options(width=160) +library("omnetpp", warn.conflicts=FALSE) + + +#TEST parameters +runCount <- 6 +hostCount <- 2 +sentPk <- 1000 +echoedPk <- 920 +rcvdPk <- 920 + +# begin TEST: + +cat("\nOMNETPP TEST RESULT:\n") + +x <- loadDataset('results/General-*.sca') +ds <- x$scalars[grep("\\.H\\d\\.udpApp\\[\\d\\]$",x$scalars$module),] + +#merge runnumber column to ds: +y <- subset(x$runattrs, attrname=='runnumber') +names(y) <- c("runid","runnumber") +ds <- merge(ds,y) + +sent <- ds[ds$name == "sentPk:count",] +rcvd <- ds[ds$name == "rcvdPk:count",] +echoed <- ds[ds$name == "echoedPk:count",] + +cat("\nOSPF TEST RESULT:\n") + +sent$success = (sent$value == sentPk) +if(length(sent$value) == runCount*hostCount & min(sent$success) == TRUE) +{ + cat("SENT OK\n") +} else { + cat("SENT BAD:\n") + sent$rate = sent$value*100/sentPk + print(sent) +} + +echoed$success = (echoed$value >= echoedPk & echoed$value <= sentPk) +if(length(echoed$value) == runCount*hostCount & min(echoed$success) == TRUE) +{ + cat("ECHOED OK\n") +} else { + cat("ECHOED BAD:\n") + echoed$rate = echoed$value*100/sentPk + print(echoed) +} + +rcvd$success = ((rcvd$value >= rcvdPk) & (rcvd$value <= sentPk)) +if(length(rcvd$value) == runCount*hostCount & min(rcvd$success) == TRUE) +{ + cat("RCVD OK\n") +} else { + cat("RCVD BAD:\n") + rcvd$rate = rcvd$value*100/sentPk + print(rcvd) +} + + +cat("\n") + + +%#-------------------------------------------------------------------------------------------------------------- +%contains: check.r.out + +OMNETPP TEST RESULT: + +OSPF TEST RESULT: +SENT OK +ECHOED OK +RCVD OK + +%#-------------------------------------------------------------------------------------------------------------- diff --git a/tests/statistical/tcp_nosack_moreclients_speed.test b/tests/statistical/tcp_nosack_moreclients_speed.test index 1c3ba896b..1acdf92ef 100644 --- a/tests/statistical/tcp_nosack_moreclients_speed.test +++ b/tests/statistical/tcp_nosack_moreclients_speed.test @@ -163,7 +163,7 @@ srvSent <- srv[srv$name == "bytesSent",] srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == cliCount && min(cliSent$value) == cliSentBytes) +if(length(cliSent$value) == cliCount & min(cliSent$value) == cliSentBytes) { cat("CLIENT SENT OK\n") } else { @@ -172,7 +172,7 @@ if(length(cliSent$value) == cliCount && min(cliSent$value) == cliSentBytes) print(cliSent[cliSent$value != cliSentBytes,]) } -if(length(srvRcvd$value) == srvCount && min(srvRcvd$value) == srvRcvdBytes) +if(length(srvRcvd$value) == srvCount & min(srvRcvd$value) == srvRcvdBytes) { cat("SERVER RCVD OK\n") } else { @@ -181,7 +181,7 @@ if(length(srvRcvd$value) == srvCount && min(srvRcvd$value) == srvRcvdBytes) print(srvRcvd[srvRcvd$value != srvRcvdBytes,]) } -if(length(srvSent$value) == srvCount && min(srvSent$value) == srvSentBytes) +if(length(srvSent$value) == srvCount & min(srvSent$value) == srvSentBytes) { cat("SERVER SENT OK\n") } else { @@ -190,7 +190,7 @@ if(length(srvSent$value) == srvCount && min(srvSent$value) == srvSentBytes) print(srvSent[srvSent$value != srvSentBytes,]) } -if(length(cliRcvd$value) == cliCount && min(cliRcvd$value) == cliRcvdBytes) +if(length(cliRcvd$value) == cliCount & min(cliRcvd$value) == cliRcvdBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/tcp_nosack_moreclients_speed_strict.test b/tests/statistical/tcp_nosack_moreclients_speed_strict.test index cb45ca2f8..c41a92db7 100644 --- a/tests/statistical/tcp_nosack_moreclients_speed_strict.test +++ b/tests/statistical/tcp_nosack_moreclients_speed_strict.test @@ -163,7 +163,7 @@ srvSent <- srv[srv$name == "bytesSent",] srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == cliCount && min(cliSent$value) == cliSentBytes) +if(length(cliSent$value) == cliCount & min(cliSent$value) == cliSentBytes) { cat("CLIENT SENT OK\n") } else { @@ -172,7 +172,7 @@ if(length(cliSent$value) == cliCount && min(cliSent$value) == cliSentBytes) print(cliSent[cliSent$value != cliSentBytes,]) } -if(length(srvRcvd$value) == srvCount && min(srvRcvd$value) == srvRcvdBytes) +if(length(srvRcvd$value) == srvCount & min(srvRcvd$value) == srvRcvdBytes) { cat("SERVER RCVD OK\n") } else { @@ -181,7 +181,7 @@ if(length(srvRcvd$value) == srvCount && min(srvRcvd$value) == srvRcvdBytes) print(srvRcvd[srvRcvd$value != srvRcvdBytes,]) } -if(length(srvSent$value) == srvCount && min(srvSent$value) == srvSentBytes) +if(length(srvSent$value) == srvCount & min(srvSent$value) == srvSentBytes) { cat("SERVER SENT OK\n") } else { @@ -190,7 +190,7 @@ if(length(srvSent$value) == srvCount && min(srvSent$value) == srvSentBytes) print(srvSent[srvSent$value != srvSentBytes,]) } -if(length(cliRcvd$value) == cliCount && min(cliRcvd$value) == cliRcvdBytes) +if(length(cliRcvd$value) == cliCount & min(cliRcvd$value) == cliRcvdBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/tcp_nosack_twohosts_bytestream_speed.test b/tests/statistical/tcp_nosack_twohosts_bytestream_speed.test index e1b25aa24..7cf5fdb7c 100644 --- a/tests/statistical/tcp_nosack_twohosts_bytestream_speed.test +++ b/tests/statistical/tcp_nosack_twohosts_bytestream_speed.test @@ -153,7 +153,7 @@ srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) +if(length(cliSent$value) == linecount & min(cliSent$value) == cliBytes) { cat("CLIENT SENT OK\n") } else { @@ -162,7 +162,7 @@ if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) print(cliSent[cliSent$value != cliBytes,]) } -if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) +if(length(srvRcvd$value) == linecount & min(srvRcvd$value) == cliBytes) { cat("SERVER RCVD OK\n") } else { @@ -171,7 +171,7 @@ if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) print(srvRcvd[srvRcvd$value != cliBytes,]) } -if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) +if(length(srvSent$value) == linecount & min(srvSent$value) == srvBytes) { cat("SERVER SENT OK\n") } else { @@ -180,7 +180,7 @@ if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) print(srvSent[srvSent$value != srvBytes,]) } -if(length(cliRcvd$value) == linecount && min(cliRcvd$value) == srvBytes) +if(length(cliRcvd$value) == linecount & min(cliRcvd$value) == srvBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/tcp_nosack_twohosts_object_speed.test b/tests/statistical/tcp_nosack_twohosts_object_speed.test index d7009634f..52e1adf87 100644 --- a/tests/statistical/tcp_nosack_twohosts_object_speed.test +++ b/tests/statistical/tcp_nosack_twohosts_object_speed.test @@ -153,7 +153,7 @@ srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) +if(length(cliSent$value) == linecount & min(cliSent$value) == cliBytes) { cat("CLIENT SENT OK\n") } else { @@ -162,7 +162,7 @@ if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) print(cliSent[cliSent$value != cliBytes,]) } -if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) +if(length(srvRcvd$value) == linecount & min(srvRcvd$value) == cliBytes) { cat("SERVER RCVD OK\n") } else { @@ -171,7 +171,7 @@ if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) print(srvRcvd[srvRcvd$value != cliBytes,]) } -if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) +if(length(srvSent$value) == linecount & min(srvSent$value) == srvBytes) { cat("SERVER SENT OK\n") } else { @@ -180,7 +180,7 @@ if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) print(srvSent[srvSent$value != srvBytes,]) } -if(length(cliRcvd$value) == linecount && min(cliRcvd$value) == srvBytes) +if(length(cliRcvd$value) == linecount & min(cliRcvd$value) == srvBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/tcp_nosack_twohosts_speed.test b/tests/statistical/tcp_nosack_twohosts_speed.test index 3b8d18360..aa1c5b589 100644 --- a/tests/statistical/tcp_nosack_twohosts_speed.test +++ b/tests/statistical/tcp_nosack_twohosts_speed.test @@ -151,7 +151,7 @@ srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) +if(length(cliSent$value) == linecount & min(cliSent$value) == cliBytes) { cat("CLIENT SENT OK\n") } else { @@ -160,7 +160,7 @@ if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) print(cliSent[cliSent$value != cliBytes,]) } -if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) +if(length(srvRcvd$value) == linecount & min(srvRcvd$value) == cliBytes) { cat("SERVER RCVD OK\n") } else { @@ -169,7 +169,7 @@ if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) print(srvRcvd[srvRcvd$value != cliBytes,]) } -if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) +if(length(srvSent$value) == linecount & min(srvSent$value) == srvBytes) { cat("SERVER SENT OK\n") } else { @@ -178,7 +178,7 @@ if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) print(srvSent[srvSent$value != srvBytes,]) } -if(length(cliRcvd$value) == linecount && min(cliRcvd$value) == srvBytes) +if(length(cliRcvd$value) == linecount & min(cliRcvd$value) == srvBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/tcp_nosack_twohosts_speed_strict.test b/tests/statistical/tcp_nosack_twohosts_speed_strict.test index c56667f23..6851dc7c4 100644 --- a/tests/statistical/tcp_nosack_twohosts_speed_strict.test +++ b/tests/statistical/tcp_nosack_twohosts_speed_strict.test @@ -151,7 +151,7 @@ srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) +if(length(cliSent$value) == linecount & min(cliSent$value) == cliBytes) { cat("CLIENT SENT OK\n") } else { @@ -160,7 +160,7 @@ if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) print(cliSent[cliSent$value != cliBytes,]) } -if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) +if(length(srvRcvd$value) == linecount & min(srvRcvd$value) == cliBytes) { cat("SERVER RCVD OK\n") } else { @@ -169,7 +169,7 @@ if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) print(srvRcvd[srvRcvd$value != cliBytes,]) } -if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) +if(length(srvSent$value) == linecount & min(srvSent$value) == srvBytes) { cat("SERVER SENT OK\n") } else { @@ -178,7 +178,7 @@ if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) print(srvSent[srvSent$value != srvBytes,]) } -if(length(cliRcvd$value) == linecount && min(cliRcvd$value) == srvBytes) +if(length(cliRcvd$value) == linecount & min(cliRcvd$value) == srvBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/tcp_sack_moreclients_speed.test b/tests/statistical/tcp_sack_moreclients_speed.test index 9854b9515..d29751c59 100644 --- a/tests/statistical/tcp_sack_moreclients_speed.test +++ b/tests/statistical/tcp_sack_moreclients_speed.test @@ -166,7 +166,7 @@ srvSent <- srv[srv$name == "bytesSent",] srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == cliCount && min(cliSent$value) == cliSentBytes) +if(length(cliSent$value) == cliCount & min(cliSent$value) == cliSentBytes) { cat("CLIENT SENT OK\n") } else { @@ -175,7 +175,7 @@ if(length(cliSent$value) == cliCount && min(cliSent$value) == cliSentBytes) print(cliSent[cliSent$value != cliSentBytes,]) } -if(length(srvRcvd$value) == srvCount && min(srvRcvd$value) == srvRcvdBytes) +if(length(srvRcvd$value) == srvCount & min(srvRcvd$value) == srvRcvdBytes) { cat("SERVER RCVD OK\n") } else { @@ -184,7 +184,7 @@ if(length(srvRcvd$value) == srvCount && min(srvRcvd$value) == srvRcvdBytes) print(srvRcvd[srvRcvd$value != srvRcvdBytes,]) } -if(length(srvSent$value) == srvCount && min(srvSent$value) == srvSentBytes) +if(length(srvSent$value) == srvCount & min(srvSent$value) == srvSentBytes) { cat("SERVER SENT OK\n") } else { @@ -193,7 +193,7 @@ if(length(srvSent$value) == srvCount && min(srvSent$value) == srvSentBytes) print(srvSent[srvSent$value != srvSentBytes,]) } -if(length(cliRcvd$value) == cliCount && min(cliRcvd$value) == cliRcvdBytes) +if(length(cliRcvd$value) == cliCount & min(cliRcvd$value) == cliRcvdBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/tcp_sack_moreclients_speed_strict.test b/tests/statistical/tcp_sack_moreclients_speed_strict.test index bbf065191..88aacd9cf 100644 --- a/tests/statistical/tcp_sack_moreclients_speed_strict.test +++ b/tests/statistical/tcp_sack_moreclients_speed_strict.test @@ -166,7 +166,7 @@ srvSent <- srv[srv$name == "bytesSent",] srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == cliCount && min(cliSent$value) == cliSentBytes) +if(length(cliSent$value) == cliCount & min(cliSent$value) == cliSentBytes) { cat("CLIENT SENT OK\n") } else { @@ -175,7 +175,7 @@ if(length(cliSent$value) == cliCount && min(cliSent$value) == cliSentBytes) print(cliSent[cliSent$value != cliSentBytes,]) } -if(length(srvRcvd$value) == srvCount && min(srvRcvd$value) == srvRcvdBytes) +if(length(srvRcvd$value) == srvCount & min(srvRcvd$value) == srvRcvdBytes) { cat("SERVER RCVD OK\n") } else { @@ -184,7 +184,7 @@ if(length(srvRcvd$value) == srvCount && min(srvRcvd$value) == srvRcvdBytes) print(srvRcvd[srvRcvd$value != srvRcvdBytes,]) } -if(length(srvSent$value) == srvCount && min(srvSent$value) == srvSentBytes) +if(length(srvSent$value) == srvCount & min(srvSent$value) == srvSentBytes) { cat("SERVER SENT OK\n") } else { @@ -193,7 +193,7 @@ if(length(srvSent$value) == srvCount && min(srvSent$value) == srvSentBytes) print(srvSent[srvSent$value != srvSentBytes,]) } -if(length(cliRcvd$value) == cliCount && min(cliRcvd$value) == cliRcvdBytes) +if(length(cliRcvd$value) == cliCount & min(cliRcvd$value) == cliRcvdBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/tcp_sack_twohosts_speed.test b/tests/statistical/tcp_sack_twohosts_speed.test index 3b598e4a6..2a8ec53df 100644 --- a/tests/statistical/tcp_sack_twohosts_speed.test +++ b/tests/statistical/tcp_sack_twohosts_speed.test @@ -154,7 +154,7 @@ srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) +if(length(cliSent$value) == linecount & min(cliSent$value) == cliBytes) { cat("CLIENT SENT OK\n") } else { @@ -163,7 +163,7 @@ if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) print(cliSent[cliSent$value != cliBytes,]) } -if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) +if(length(srvRcvd$value) == linecount & min(srvRcvd$value) == cliBytes) { cat("SERVER RCVD OK\n") } else { @@ -172,7 +172,7 @@ if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) print(srvRcvd[srvRcvd$value != cliBytes,]) } -if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) +if(length(srvSent$value) == linecount & min(srvSent$value) == srvBytes) { cat("SERVER SENT OK\n") } else { @@ -181,7 +181,7 @@ if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) print(srvSent[srvSent$value != srvBytes,]) } -if(length(cliRcvd$value) == linecount && min(cliRcvd$value) == srvBytes) +if(length(cliRcvd$value) == linecount & min(cliRcvd$value) == srvBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/tcp_sack_twohosts_speed_strict.test b/tests/statistical/tcp_sack_twohosts_speed_strict.test index 33bbb2520..ab39e1fab 100644 --- a/tests/statistical/tcp_sack_twohosts_speed_strict.test +++ b/tests/statistical/tcp_sack_twohosts_speed_strict.test @@ -154,7 +154,7 @@ srvRcvd <- srv[srv$name == "bytesRcvd",] cat("\nTCP SPEED TEST RESULT:\n") -if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) +if(length(cliSent$value) == linecount & min(cliSent$value) == cliBytes) { cat("CLIENT SENT OK\n") } else { @@ -163,7 +163,7 @@ if(length(cliSent$value) == linecount && min(cliSent$value) == cliBytes) print(cliSent[cliSent$value != cliBytes,]) } -if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) +if(length(srvRcvd$value) == linecount & min(srvRcvd$value) == cliBytes) { cat("SERVER RCVD OK\n") } else { @@ -172,7 +172,7 @@ if(length(srvRcvd$value) == linecount && min(srvRcvd$value) == cliBytes) print(srvRcvd[srvRcvd$value != cliBytes,]) } -if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) +if(length(srvSent$value) == linecount & min(srvSent$value) == srvBytes) { cat("SERVER SENT OK\n") } else { @@ -181,7 +181,7 @@ if(length(srvSent$value) == linecount && min(srvSent$value) == srvBytes) print(srvSent[srvSent$value != srvBytes,]) } -if(length(cliRcvd$value) == linecount && min(cliRcvd$value) == srvBytes) +if(length(cliRcvd$value) == linecount & min(cliRcvd$value) == srvBytes) { cat("CLIENT RCVD OK\n") } else { diff --git a/tests/statistical/udp_twohosts_speed.test b/tests/statistical/udp_twohosts_speed.test index 0a77fa56a..cf8b444c9 100644 --- a/tests/statistical/udp_twohosts_speed.test +++ b/tests/statistical/udp_twohosts_speed.test @@ -64,8 +64,12 @@ sim-time-limit = 20s **.numUdpApps = 2 **.udpApp[0].typename = "UDPBasicApp" **.udpApp[0].destPort = 1234 -**.udpApp[0].sendInterval = 1.7ms -**.udpApp[0].stopTime = 17s +#**.udpApp[0].sendInterval = 2ms +#**.udpApp[0].stopTime = 20s +**.host*snap.udpApp[0].sendInterval = 1.719ms #etherframe with snap and gap: 1074 bytes, 2 packets (sent, echoed): 1074*8/10000000*2 = 17.184ms +**.host*snap.udpApp[0].stopTime = 17.19s +**.udpApp[0].sendInterval = 1.706ms #etherframe and gap: 1066 bytes, 2 packets (sent, echoed): 1066*8/10000000*2 = 17.056ms +**.udpApp[0].stopTime = 17.06s **.host1.udpApp[0].destAddresses = "host2" **.host2.udpApp[0].destAddresses = "host1" **.host1snap.udpApp[0].destAddresses = "host2snap" @@ -75,6 +79,7 @@ sim-time-limit = 20s **.udpApp[1].localPort = 1234 **.host*snap.eth[*].useSNAP = true +**.host*.eth[*].queue.frameCapacity = 1 *.configurator.networkAddress = "192.168.1.0" @@ -90,7 +95,7 @@ library("omnetpp", warn.conflicts=FALSE) scafile <- 'results/General-0.sca' linecount <- 4 sentPk <- 10000 -echoedPk <- 9990 +echoedPk <- 10000 # begin TEST: @@ -99,14 +104,14 @@ dataset <- loadDataset(scafile) cat("\nOMNETPP TEST RESULT:\n") udpApp <- dataset$scalars[grep("\\.host\\d\\w*\\.udpApp\\[\\d\\]$",dataset$scalars$module),] -udpSent <- udpApp[udpApp$name == "sentPkBytes:sum",] +udpSent <- udpApp[udpApp$name == "sentPk:sum(packetBytes)",] udpRcvd <- udpApp[udpApp$name == "echoedPk:count",] cat(" UDP SPEED TEST RESULT:\n") #print(udpSent) cat(" UDP SENT ") -if(length(udpSent$value) == linecount && min(udpSent$value) >= sentPk) +if(length(udpSent$value) == linecount & min(udpSent$value) >= sentPk) { cat("OK\n") } else { @@ -117,7 +122,7 @@ if(length(udpSent$value) == linecount && min(udpSent$value) >= sentPk) #print(udpRcvd) cat(" UDP RCVD ") -if(length(udpRcvd$value) == linecount && min(udpRcvd$value) >= echoedPk) +if(length(udpRcvd$value) == linecount & min(udpRcvd$value) >= echoedPk) { cat("OK\n") } else { diff --git a/tests/traci/Car.ned b/tests/traci/Car.ned new file mode 100644 index 000000000..bfd094b7f --- /dev/null +++ b/tests/traci/Car.ned @@ -0,0 +1,89 @@ +// +// Copyright (C) 2006-2011 Christoph Sommer +// +// Documentation for these modules is at http://veins.car2x.org/ +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 +// + +package inet.tests.traci; + +import inet.base.NotificationBoard; +import inet.networklayer.common.InterfaceTable; +import inet.applications.traci.TraCITestApp; +import inet.mobility.models.TraCIMobility; +import inet.networklayer.ipv4.RoutingTable; +import inet.transport.udp.UDP; +import inet.nodes.inet.NetworkLayer; +import inet.linklayer.ieee80211.Ieee80211Nic; + +module Car +{ + parameters: + @node(); + + gates: + input radioIn @directIn; + + submodules: + notificationBoard: NotificationBoard { + parameters: + @display("p=140,462"); + } + interfaceTable: InterfaceTable { + parameters: + @display("p=140,326"); + } + app: TraCITestApp { + parameters: + @display("p=384,46"); + } + mobility: TraCIMobility { + parameters: + @display("p=60,459"); + } + routingTable: RoutingTable { + parameters: + IPForward = true; + routerId = ""; + routingFile = ""; + @display("p=60,326"); + } + udp: UDP { + parameters: + @display("p=384,146"); + } + networkLayer: NetworkLayer { + parameters: + proxyARP = false; + @display("p=304,327;q=queue"); + gates: + ifIn[1]; + ifOut[1]; + } + wlan: Ieee80211Nic { + parameters: + @display("p=304,461;q=queue"); + } + connections allowunconnected: + udp.ipOut --> networkLayer.udpIn; + udp.ipIn <-- networkLayer.udpOut; + + wlan.upperLayerOut --> networkLayer.ifIn[0]; + wlan.upperLayerIn <-- networkLayer.ifOut[0]; + + radioIn --> wlan.radioIn; +} + diff --git a/tests/traci/Highway.ned b/tests/traci/Highway.ned new file mode 100644 index 000000000..3e5ce1d7e --- /dev/null +++ b/tests/traci/Highway.ned @@ -0,0 +1,41 @@ +// +// Copyright (C) 2006-2011 Christoph Sommer +// +// Documentation for these modules is at http://veins.car2x.org/ +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 +// + +package inet.tests.traci; + +import inet.world.radio.ChannelControl; +import inet.world.traci.TraCIScenarioManagerLaunchd; + +module Highway +{ + submodules: + channelControl: ChannelControl { + parameters: + @display("p=256,128"); + } + manager: TraCIScenarioManagerLaunchd { + parameters: + @display("p=512,128"); + } +} + +network highway1 extends Highway +{ +} diff --git a/tests/traci/net.edg.xml b/tests/traci/net.edg.xml new file mode 100644 index 000000000..01f233675 --- /dev/null +++ b/tests/traci/net.edg.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/traci/net.net.xml b/tests/traci/net.net.xml new file mode 100644 index 000000000..f44d35f0a --- /dev/null +++ b/tests/traci/net.net.xml @@ -0,0 +1,1298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/traci/net.netconvert.cfg b/tests/traci/net.netconvert.cfg new file mode 100644 index 000000000..dff6a94fd --- /dev/null +++ b/tests/traci/net.netconvert.cfg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/traci/net.nod.xml b/tests/traci/net.nod.xml new file mode 100644 index 000000000..5d05da104 --- /dev/null +++ b/tests/traci/net.nod.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/traci/omnetpp.ini b/tests/traci/omnetpp.ini new file mode 100644 index 000000000..bc1792039 --- /dev/null +++ b/tests/traci/omnetpp.ini @@ -0,0 +1,63 @@ +[General] +network = highway1 +debug-on-errors = true + +cmdenv-express-mode = true +cmdenv-autoflush = true +cmdenv-status-frequency = 10000000s +tkenv-plugin-path = ../../../etc/plugins + +sim-time-limit = 6000s + +**.vector-recording = false + +**.constraintAreaMinX = 0m +**.constraintAreaMinY = 0m +**.constraintAreaMinZ = 0m +**.constraintAreaMaxX = 10672m +**.constraintAreaMaxY = 7105m +**.constraintAreaMaxZ = 0m + +**.debug = true +**.coreDebug = false +**.host*.**.channelNumber = 0 + +# channel physical parameters +*.channelControl.carrierFrequency = 2.4GHz +*.channelControl.pMax = 2.0mW +*.channelControl.sat = -110dBm +*.channelControl.alpha = 2 +*.channelControl.numChannels = 1 + +# TraCIScenarioManagerLaunchd +*.manager.updateInterval = 1s +*.manager.host = "localhost" +*.manager.port = 9999 +*.manager.moduleType = "inet.tests.traci.Car" +*.manager.moduleName = "host" +*.manager.moduleDisplayString = "" +*.manager.autoShutdown = true +*.manager.margin = 25 +*.manager.launchConfig = xmldoc("sumo-launchd.launch.xml") + +# nic settings +**.wlan.mgmt.frameCapacity = 10 +**.wlan.mgmtType = "Ieee80211MgmtAdhoc" +**.wlan.mac.address = "auto" +**.wlan.mac.maxQueueSize = 14 +**.wlan.mac.rtsThresholdBytes = 3000B +**.wlan.mac.bitrate = 2Mbps +**.wlan.mac.retryLimit = 7 +**.wlan.mac.cwMinData = 7 +**.wlan.mac.cwMinBroadcast = 31 + +**.wlan.radio.bitrate = 2Mbps +**.wlan.radio.transmitterPower = 2mW +**.wlan.radio.thermalNoise = -110dBm +**.wlan.radio.sensitivity = -85dBm +**.wlan.radio.pathLossAlpha = 2 +**.wlan.radio.snirThreshold = 4dB + +# Application layer +*.host[0].app.testNumber = ${0..9} +*.host[*].app.testNumber = -1 diff --git a/tests/traci/package.ned b/tests/traci/package.ned new file mode 100644 index 000000000..0badfb921 --- /dev/null +++ b/tests/traci/package.ned @@ -0,0 +1 @@ +package inet.tests.traci; diff --git a/tests/traci/polys.poly.xml b/tests/traci/polys.poly.xml new file mode 100644 index 000000000..c6f73acfe --- /dev/null +++ b/tests/traci/polys.poly.xml @@ -0,0 +1,3 @@ + + + diff --git a/tests/traci/routes.rou.xml b/tests/traci/routes.rou.xml new file mode 100644 index 000000000..9857a01b1 --- /dev/null +++ b/tests/traci/routes.rou.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/traci/runTest.sh b/tests/traci/runTest.sh new file mode 100755 index 000000000..5932b451c --- /dev/null +++ b/tests/traci/runTest.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +opp_run -l../../src/inet -n"../../src;." -u Cmdenv "$@" | egrep -i "^(Pass|FAIL)" diff --git a/tests/traci/sumo-launchd.launch.xml b/tests/traci/sumo-launchd.launch.xml new file mode 100644 index 000000000..1df6c0e7b --- /dev/null +++ b/tests/traci/sumo-launchd.launch.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/tests/traci/sumo.sumo.cfg b/tests/traci/sumo.sumo.cfg new file mode 100644 index 000000000..fe79ff789 --- /dev/null +++ b/tests/traci/sumo.sumo.cfg @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/tests/traci/tls.tls.xml b/tests/traci/tls.tls.xml new file mode 100644 index 000000000..84221e6a2 --- /dev/null +++ b/tests/traci/tls.tls.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + +