diff --git a/daemon/core/mobility.py b/daemon/core/mobility.py index 8335cf37..3bbb510f 100644 --- a/daemon/core/mobility.py +++ b/daemon/core/mobility.py @@ -74,6 +74,20 @@ class MobilityManager(ConfigurableManager): ''' Reset all configs. ''' self.clearconfig(nodenum=None) + + def setconfig(self, nodenum, conftype, values): + ''' Normal setconfig() with check for run-time updates for WLANs. + ''' + super(MobilityManager, self).setconfig(nodenum, conftype, values) + if self.session is None: + return + if self.session.getstate() == coreapi.CORE_EVENT_RUNTIME_STATE: + try: + n = self.session.obj(nodenum) + except KeyError: + self.session.warn("Skipping mobility configuration for unknown" + "node %d." % nodenum) + n.updatemodel(conftype, values) def register(self): ''' Register models as configurable object(s) with the Session object. @@ -254,6 +268,13 @@ class WirelessModel(Configurable): def update(self, moved, moved_netifs): raise NotImplementedError + + def updateconfig(self, values): + ''' For run-time updates of model config. + Returns True when self._positioncallback() and self.setlinkparams() + should be invoked. + ''' + return False class BasicRangeModel(WirelessModel): @@ -296,6 +317,9 @@ class BasicRangeModel(WirelessModel): if self.verbose: self.session.info("Basic range model configured for WLAN %d using" \ " range %d" % (objid, self.range)) + self.valuestolinkparams(values) + + def valuestolinkparams(self, values): self.bw = int(self.valueof("bandwidth", values)) if self.bw == 0.0: self.bw = None @@ -408,6 +432,15 @@ class BasicRangeModel(WirelessModel): c = p1[2] - p2[2] return math.hypot(math.hypot(a, b), c) + def updateconfig(self, values): + ''' Configuration has changed during runtime. + MobilityManager.setconfig() -> WlanNode.updatemodel() -> + WirelessModel.updateconfig() + ''' + self.valuestolinkparams(values) + self.range = float(self.valueof("range", values)) + return True + def linkmsg(self, netif, netif2, flags): ''' Create a wireless link/unlink API message. ''' diff --git a/daemon/core/netns/nodes.py b/daemon/core/netns/nodes.py index 942fb419..5e29eda9 100644 --- a/daemon/core/netns/nodes.py +++ b/daemon/core/netns/nodes.py @@ -222,6 +222,25 @@ class WlanNode(LxBrNet): elif model._type == coreapi.CORE_TLV_REG_MOBILITY: self.mobility = model(session=self.session, objid=self.objid, verbose=self.verbose, values=config) + + def updatemodel(self, model_name, values): + ''' Allow for model updates during runtime (similar to setmodel().) + ''' + if (self.verbose): + self.info("updating model %s" % model_name) + if self.model is None or self.model._name != model_name: + raise ValueError, "model %s not configured" % model_name + model = self.model + if model._type == coreapi.CORE_TLV_REG_WIRELESS: + if not model.updateconfig(values): + return + if self.model._positioncallback: + for netif in self.netifs(): + netif.poshook = self.model._positioncallback + if netif.node is not None: + (x,y,z) = netif.node.position.get() + netif.poshook(netif, x, y, z) + self.model.setlinkparams() def tolinkmsgs(self, flags): msgs = LxBrNet.tolinkmsgs(self, flags) diff --git a/gui/wlan.tcl b/gui/wlan.tcl index 33a84e8a..e731614e 100755 --- a/gui/wlan.tcl +++ b/gui/wlan.tcl @@ -304,6 +304,7 @@ proc wlanConfigDialogHelper { wi target apply } { global systype global plugin_img_edit global g_selected_model + global oper_mode set wlan $target set emulation_type [lindex [getEmulPlugin $target] 1] @@ -378,6 +379,10 @@ proc wlanConfigDialogHelper { wi target apply } { # remove any range circles updateRangeCircles $target 0 + if { $oper_mode == "exec" } { + # this generates Config Messages for updating the model parameters + pluginCapsInitialize $target "mobmodel" + } return }