aboutsummaryrefslogtreecommitdiffstats
path: root/vicn/resource/ns3/emulated_channel.py
diff options
context:
space:
mode:
Diffstat (limited to 'vicn/resource/ns3/emulated_channel.py')
-rw-r--r--vicn/resource/ns3/emulated_channel.py65
1 files changed, 39 insertions, 26 deletions
diff --git a/vicn/resource/ns3/emulated_channel.py b/vicn/resource/ns3/emulated_channel.py
index 5f61960c..3c090a9e 100644
--- a/vicn/resource/ns3/emulated_channel.py
+++ b/vicn/resource/ns3/emulated_channel.py
@@ -16,30 +16,33 @@
# limitations under the License.
#
+import functools
import logging
import random
+from netmodel.model.key import Key
from netmodel.model.type import Integer
from netmodel.util.socket import check_port
from vicn.core.address_mgr import AddressManager
-from vicn.core.attribute import Attribute, Multiplicity
+from vicn.core.attribute import Attribute, Multiplicity
from vicn.core.exception import ResourceNotFound
from vicn.core.requirement import Requirement
from vicn.core.resource import BaseResource
from vicn.core.resource_mgr import wait_resources
from vicn.core.task import inline_task, async_task, task
from vicn.core.task import BashTask, run_task
+from vicn.core.task import inherit_parent
from vicn.resource.channel import Channel
-from vicn.resource.linux.application import LinuxApplication as Application
+from vicn.resource.linux.application import LinuxApplication
from vicn.resource.linux.net_device import NetDevice
from vicn.resource.linux.tap_device import TapDevice
-from vicn.resource.linux.veth_pair import VethPair
+from vicn.resource.linux.veth_pair_lxc import VethPairLxc
from vicn.resource.lxd.lxc_container import LxcContainer
from vicn.resource.node import Node
log = logging.getLogger(__name__)
-class EmulatedChannel(Channel, Application):
+class EmulatedChannel(Channel, LinuxApplication):
"""EmulatedChannel resource
This resources serves as a base class for wireless channels emulated by
@@ -56,7 +59,7 @@ class EmulatedChannel(Channel, Application):
traffic and prevent loops on the bridge.
- We also need that all interfaces related to ap and stations are created
before we run the commandline (currently, dynamically adding/removing
- AP and stations is not supported by the emulator). This is made
+ AP and stations is not supported by the emulator). This is made
possible thanks to the key=True parameter, which makes sure the
attributes are processed before the __create__ is called.
@@ -66,11 +69,15 @@ class EmulatedChannel(Channel, Application):
__resource_type__ = BaseResource
- ap = Attribute(Node, description = 'AP', key = True)
+ ap = Attribute(Node, description = 'AP')
stations = Attribute(Node, description = 'List of stations',
- multiplicity = Multiplicity.OneToMany, key = True)
+ multiplicity = Multiplicity.OneToMany)
control_port = Attribute(Integer,
description = 'Control port for the simulation')
+ nb_base_stations = Attribute(Integer, description='Number of nodes emulated by the AP',
+ default=1)
+
+ __key__ = Key(ap, stations)
# Overloaded attributes
node = Attribute(requirements = [
@@ -101,20 +108,29 @@ class EmulatedChannel(Channel, Application):
# Resource lifecycle
#--------------------------------------------------------------------------
+ @inherit_parent
+ def __initialize__(self):
+ return self.__set_ap() > self.__set_stations()
+
+ @inherit_parent
@inline_task
def __get__(self):
raise ResourceNotFound
+
+ @inherit_parent
def __create__(self):
# NOTE: http://stackoverflow.com/questions/21141352/python-subprocess-
# calling-a-script-which-runs-a-background-process-hanging
# The output of the background scripts is still going to the same file
# descriptor as the child script, thus the parent script waits for it
# to finish.
- cmd = '(' + self.__app_name__ + ' ' + self._get_cmdline_params() + \
- '>/dev/null 2>&1) &'
- return BashTask(self.node, cmd)
+ def get_cmdline(channel):
+ return '(' + channel.__app_name__ + ' ' + \
+ channel._get_cmdline_params() + '>/dev/null 2>&1) &'
+ return BashTask(self.node, functools.partial(get_cmdline, self))
+ @inherit_parent
def __delete__(self):
raise NotImplementedError
@@ -123,9 +139,8 @@ class EmulatedChannel(Channel, Application):
#--------------------------------------------------------------------------
@async_task
- async def _set_ap(self, ap=None):
- if ap is None:
- ap = self.ap
+ async def __set_ap(self):
+ ap = self.ap
if ap is None:
log.info('Ignored setting ap to None...')
return
@@ -133,13 +148,13 @@ class EmulatedChannel(Channel, Application):
# Add a WiFi interface for the AP...
interfaces = list()
if isinstance(ap, LxcContainer):
- # Ideally, We need to create a VethPair for each station
+ # Ideally, We need to create a VethPairLxc for each station
# This should be monitored for the total channel bw
host = NetDevice(node = ap.node,
device_name='vhh-' + ap.name + '-' + self.name,
monitored = False,
managed = False)
- self._ap_if = VethPair(node = self.ap,
+ self._ap_if = VethPairLxc(node = self.ap,
name = 'vh-' + ap.name + '-' + self.name,
device_name = 'vh-' + ap.name + '-' + self.name,
host = host,
@@ -171,37 +186,35 @@ class EmulatedChannel(Channel, Application):
# Add interfaces to bridge
vlan = AddressManager().get('vlan', self, tag='ap')
- # AS the container has created the VethPair already without Vlan, we
+ # AS the container has created the VethPairLxc already without Vlan, we
# need to delete and recreate it
task = self.node.bridge._remove_interface(self._ap_bridged)
await run_task(task, self._state.manager)
task = self.node.bridge._add_interface(self._ap_bridged, vlan = vlan)
await run_task(task, self._state.manager)
+ task = self.node.bridge._remove_interface(self._ap_tap)
+ await run_task(task, self._state.manager)
task = self.node.bridge._add_interface(self._ap_tap, vlan = vlan)
await run_task(task, self._state.manager)
@inline_task
- def _get_ap(self):
+ def __get_ap(self):
return {'ap': None}
@inline_task
- def _get_stations(self):
+ def __get_stations(self):
return {'stations': list()}
@async_task
- async def _set_stations(self, stations=None):
- print('adding stations...')
- if stations is None:
- stations = self.stations
-
- for station in stations:
+ async def __set_stations(self):
+ for station in self.stations:
await self._add_station(station)
- def _add_stations(self, stations):
+ def __add_stations(self, stations):
raise NotImplementedError
@inline_task
- def _remove_stations(self, station):
+ def __remove_stations(self, station):
raise NotImplementedError