diff --git a/License b/License
new file mode 100644
index 0000000..4e6f27d
--- /dev/null
+++ b/License
@@ -0,0 +1,24 @@
+Copyright (C) 2013-2015 Universidad Politécnica de Madrid (UPM)
+Some parts of this code are Copyright (C) 2013-2015 DEMANES
+
+Parts copyrighted by Universidad Politécnica de Madrid (UPM) are distributed
+under a dual license scheme:
+
+- For academic uses: Licensed under GNU Affero General Public License as
+ published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any
+ later version.
+
+
+- For any other use: Licensed under the Apache License, Version 2.0.
+
+Parts copyrighted by DEMANES are distributed under the Apache License, Version 2.0.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+Terms for GNU Affero General Public License version 3 are detailed in the file
+licenses/AGPL-3.0
+
+Terms for Apache License version 2.0 are detailed in the file licenses/Apache-2.0
\ No newline at end of file
diff --git a/build.properties b/build.properties
new file mode 100644
index 0000000..9d6a9e9
--- /dev/null
+++ b/build.properties
@@ -0,0 +1,10 @@
+# Properties file for a Sun Spot Application
+#
+# build.properties
+#
+# This file is the default location for user properties that over-ride the
+# defaults in ${sunspot.home}/default.properties. See that file for a full
+# listing of the properties that may be set. This file is minimal and contains
+# only those properties that a user would generally need to set right away.
+#
+
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..914320a
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DEMANES Power Scaling -- SPOT-side v1.0]]>
+
+
+
+
\ No newline at end of file
diff --git a/build/eu/artemis/demanes/datatypes/ANES_BUNDLE.class b/build/eu/artemis/demanes/datatypes/ANES_BUNDLE.class
new file mode 100644
index 0000000..4eeb851
Binary files /dev/null and b/build/eu/artemis/demanes/datatypes/ANES_BUNDLE.class differ
diff --git a/build/eu/artemis/demanes/datatypes/ANES_URN.class b/build/eu/artemis/demanes/datatypes/ANES_URN.class
new file mode 100644
index 0000000..ea34a35
Binary files /dev/null and b/build/eu/artemis/demanes/datatypes/ANES_URN.class differ
diff --git a/build/eu/artemis/demanes/datatypes/ANES_URN_Exception.class b/build/eu/artemis/demanes/datatypes/ANES_URN_Exception.class
new file mode 100644
index 0000000..0a009bd
Binary files /dev/null and b/build/eu/artemis/demanes/datatypes/ANES_URN_Exception.class differ
diff --git a/build/eu/artemis/demanes/exceptions/ActionInvocationException.class b/build/eu/artemis/demanes/exceptions/ActionInvocationException.class
new file mode 100644
index 0000000..a8bf250
Binary files /dev/null and b/build/eu/artemis/demanes/exceptions/ActionInvocationException.class differ
diff --git a/build/eu/artemis/demanes/exceptions/InexistentActionID.class b/build/eu/artemis/demanes/exceptions/InexistentActionID.class
new file mode 100644
index 0000000..0f93c67
Binary files /dev/null and b/build/eu/artemis/demanes/exceptions/InexistentActionID.class differ
diff --git a/build/eu/artemis/demanes/exceptions/InexistentObservationID.class b/build/eu/artemis/demanes/exceptions/InexistentObservationID.class
new file mode 100644
index 0000000..8337998
Binary files /dev/null and b/build/eu/artemis/demanes/exceptions/InexistentObservationID.class differ
diff --git a/build/eu/artemis/demanes/exceptions/NonExistentKeyException.class b/build/eu/artemis/demanes/exceptions/NonExistentKeyException.class
new file mode 100644
index 0000000..75dc42a
Binary files /dev/null and b/build/eu/artemis/demanes/exceptions/NonExistentKeyException.class differ
diff --git a/build/eu/artemis/demanes/exceptions/ObservationInvocationException.class b/build/eu/artemis/demanes/exceptions/ObservationInvocationException.class
new file mode 100644
index 0000000..7a4c272
Binary files /dev/null and b/build/eu/artemis/demanes/exceptions/ObservationInvocationException.class differ
diff --git a/build/eu/artemis/demanes/exceptions/TypedRequestException.class b/build/eu/artemis/demanes/exceptions/TypedRequestException.class
new file mode 100644
index 0000000..ef65f82
Binary files /dev/null and b/build/eu/artemis/demanes/exceptions/TypedRequestException.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.class b/build/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.class
new file mode 100644
index 0000000..5efa90f
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/DEMANESResources.class b/build/eu/artemis/demanes/impl/SunSPOT/common/DEMANESResources.class
new file mode 100644
index 0000000..84ea1aa
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/DEMANESResources.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/Events.class b/build/eu/artemis/demanes/impl/SunSPOT/common/Events.class
new file mode 100644
index 0000000..d77711b
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/Events.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/MediatorProperties.class b/build/eu/artemis/demanes/impl/SunSPOT/common/MediatorProperties.class
new file mode 100644
index 0000000..61899bf
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/MediatorProperties.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/PTActionProperties.class b/build/eu/artemis/demanes/impl/SunSPOT/common/PTActionProperties.class
new file mode 100644
index 0000000..7f09e89
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/PTActionProperties.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/RadioProperties.class b/build/eu/artemis/demanes/impl/SunSPOT/common/RadioProperties.class
new file mode 100644
index 0000000..ef7930f
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/RadioProperties.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/ReasonerProperties.class b/build/eu/artemis/demanes/impl/SunSPOT/common/ReasonerProperties.class
new file mode 100644
index 0000000..b46ac0b
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/ReasonerProperties.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationContext.class b/build/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationContext.class
new file mode 100644
index 0000000..0ca06d0
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationContext.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/SystemContext.class b/build/eu/artemis/demanes/impl/SunSPOT/common/SystemContext.class
new file mode 100644
index 0000000..673739d
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/SystemContext.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.class b/build/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.class
new file mode 100644
index 0000000..066f0a5
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/common/TriggerPolicyProperties.class b/build/eu/artemis/demanes/impl/SunSPOT/common/TriggerPolicyProperties.class
new file mode 100644
index 0000000..133b080
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/common/TriggerPolicyProperties.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager$RadiogramAddress.class b/build/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager$RadiogramAddress.class
new file mode 100644
index 0000000..94400fc
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager$RadiogramAddress.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.class b/build/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.class
new file mode 100644
index 0000000..d38e72f
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/communications/RemoteManagement.class b/build/eu/artemis/demanes/impl/SunSPOT/communications/RemoteManagement.class
new file mode 100644
index 0000000..5571bc1
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/communications/RemoteManagement.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/communications/RoutingListener.class b/build/eu/artemis/demanes/impl/SunSPOT/communications/RoutingListener.class
new file mode 100644
index 0000000..d8602c8
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/communications/RoutingListener.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/datatypes/SunSPOTBundle.class b/build/eu/artemis/demanes/impl/SunSPOT/datatypes/SunSPOTBundle.class
new file mode 100644
index 0000000..ad983a6
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/datatypes/SunSPOTBundle.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/DefaultConfig.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/DefaultConfig.class
new file mode 100644
index 0000000..195bdaf
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/DefaultConfig.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/ERRORMSG.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/ERRORMSG.class
new file mode 100644
index 0000000..1e8dfbe
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/ERRORMSG.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/FuzzyDM.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/FuzzyDM.class
new file mode 100644
index 0000000..fd7c941
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/FuzzyDM.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Interp1DFuzzyDM.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Interp1DFuzzyDM.class
new file mode 100644
index 0000000..0e2dede
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Interp1DFuzzyDM.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/KEY.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/KEY.class
new file mode 100644
index 0000000..675ef0d
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/KEY.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingController.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingController.class
new file mode 100644
index 0000000..e46e6b3
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingController.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFactory.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFactory.class
new file mode 100644
index 0000000..c6ed41f
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFactory.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFuzzyLogic.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFuzzyLogic.class
new file mode 100644
index 0000000..a9b0105
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFuzzyLogic.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerInterp1FDM.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerInterp1FDM.class
new file mode 100644
index 0000000..a86d5b7
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerInterp1FDM.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Variable.class b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Variable.class
new file mode 100644
index 0000000..9be6c9e
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Variable.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/ORAMediatorForSunSPOT.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/ORAMediatorForSunSPOT.class
new file mode 100644
index 0000000..74fcd00
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/ORAMediatorForSunSPOT.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$1.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$1.class
new file mode 100644
index 0000000..726a044
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$1.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservation.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservation.class
new file mode 100644
index 0000000..e631829
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservation.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservationValue.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservationValue.class
new file mode 100644
index 0000000..6f1b82f
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservationValue.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.class
new file mode 100644
index 0000000..69bc1e1
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$1.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$1.class
new file mode 100644
index 0000000..45a7655
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$1.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$updatePowerTransmissionAction.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$updatePowerTransmissionAction.class
new file mode 100644
index 0000000..b0536f0
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$updatePowerTransmissionAction.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator.class
new file mode 100644
index 0000000..3d15559
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/ResetActuator.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/ResetActuator.class
new file mode 100644
index 0000000..a35dd1c
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/ResetActuator.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/BatteryLevelObservation.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/BatteryLevelObservation.class
new file mode 100644
index 0000000..e6ff8c2
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/BatteryLevelObservation.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservation.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservation.class
new file mode 100644
index 0000000..e3c7c71
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservation.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservationExtension.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservationExtension.class
new file mode 100644
index 0000000..7ae3949
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservationExtension.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationException.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationException.class
new file mode 100644
index 0000000..9aabe43
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationException.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactory.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactory.class
new file mode 100644
index 0000000..317ea8f
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactory.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactoryException.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactoryException.class
new file mode 100644
index 0000000..0490619
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactoryException.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationType.class b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationType.class
new file mode 100644
index 0000000..60887dd
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationType.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$1.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$1.class
new file mode 100644
index 0000000..cd0a35a
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$1.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$Engine.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$Engine.class
new file mode 100644
index 0000000..d2f7160
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$Engine.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee.class
new file mode 100644
index 0000000..3447733
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeAddMessageException.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeAddMessageException.class
new file mode 100644
index 0000000..10356e2
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeAddMessageException.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeMessage.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeMessage.class
new file mode 100644
index 0000000..6060036
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeMessage.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/logging/Level.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/logging/Level.class
new file mode 100644
index 0000000..a655604
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/logging/Level.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/logging/Logger.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/logging/Logger.class
new file mode 100644
index 0000000..cfc2733
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/logging/Logger.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NDPFactory.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NDPFactory.class
new file mode 100644
index 0000000..f160cca
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NDPFactory.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryException.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryException.class
new file mode 100644
index 0000000..4bf3e0f
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryException.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryFactoryException.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryFactoryException.class
new file mode 100644
index 0000000..d55692d
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryFactoryException.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryProtocol.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryProtocol.class
new file mode 100644
index 0000000..fa6f15d
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryProtocol.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryType.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryType.class
new file mode 100644
index 0000000..a160d00
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryType.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$1.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$1.class
new file mode 100644
index 0000000..c05169f
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$1.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$2.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$2.class
new file mode 100644
index 0000000..66f2580
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$2.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation.class
new file mode 100644
index 0000000..789a940
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDTimer.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDTimer.class
new file mode 100644
index 0000000..02a8c96
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDTimer.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NeighborsDiscoveryMgr.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NeighborsDiscoveryMgr.class
new file mode 100644
index 0000000..518415b
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NeighborsDiscoveryMgr.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1.class
new file mode 100644
index 0000000..2cfb62a
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDInformation.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDInformation.class
new file mode 100644
index 0000000..cc35500
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDInformation.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDTimer.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDTimer.class
new file mode 100644
index 0000000..468868c
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDTimer.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NeighborsDiscoveryMgr.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NeighborsDiscoveryMgr.class
new file mode 100644
index 0000000..80be928
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NeighborsDiscoveryMgr.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2.class
new file mode 100644
index 0000000..ae6b41d
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$1.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$1.class
new file mode 100644
index 0000000..1d7275b
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$1.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$NDEngine.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$NDEngine.class
new file mode 100644
index 0000000..cd72bb2
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$NDEngine.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery.class
new file mode 100644
index 0000000..3ae487e
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryCommunicationsListener.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryCommunicationsListener.class
new file mode 100644
index 0000000..a183b67
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryCommunicationsListener.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryListener.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryListener.class
new file mode 100644
index 0000000..6a29fcf
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryListener.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryRequester.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryRequester.class
new file mode 100644
index 0000000..6ec44f8
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryRequester.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborTableManager.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborTableManager.class
new file mode 100644
index 0000000..d1cfd91
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborTableManager.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDU.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDU.class
new file mode 100644
index 0000000..048bfb4
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDU.class differ
diff --git a/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDUException.class b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDUException.class
new file mode 100644
index 0000000..5870f81
Binary files /dev/null and b/build/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDUException.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/Action.class b/build/eu/artemis/demanes/reconfiguration/Action.class
new file mode 100644
index 0000000..45ef478
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/Action.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/ActionProvider.class b/build/eu/artemis/demanes/reconfiguration/ActionProvider.class
new file mode 100644
index 0000000..5716e95
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/ActionProvider.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/Actuator.class b/build/eu/artemis/demanes/reconfiguration/Actuator.class
new file mode 100644
index 0000000..e35b501
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/Actuator.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/ActuatorRegistry.class b/build/eu/artemis/demanes/reconfiguration/ActuatorRegistry.class
new file mode 100644
index 0000000..70c79c3
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/ActuatorRegistry.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/ORAMediator.class b/build/eu/artemis/demanes/reconfiguration/ORAMediator.class
new file mode 100644
index 0000000..23d6ea0
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/ORAMediator.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/Observation.class b/build/eu/artemis/demanes/reconfiguration/Observation.class
new file mode 100644
index 0000000..c89a562
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/Observation.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/ObservationProvider.class b/build/eu/artemis/demanes/reconfiguration/ObservationProvider.class
new file mode 100644
index 0000000..91ffb26
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/ObservationProvider.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/Observer.class b/build/eu/artemis/demanes/reconfiguration/Observer.class
new file mode 100644
index 0000000..6303658
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/Observer.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/ObserverRegistry.class b/build/eu/artemis/demanes/reconfiguration/ObserverRegistry.class
new file mode 100644
index 0000000..9ca6e3b
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/ObserverRegistry.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/Reasoner.class b/build/eu/artemis/demanes/reconfiguration/Reasoner.class
new file mode 100644
index 0000000..f221a0d
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/Reasoner.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/TriggerPolicy.class b/build/eu/artemis/demanes/reconfiguration/TriggerPolicy.class
new file mode 100644
index 0000000..d94cc20
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/TriggerPolicy.class differ
diff --git a/build/eu/artemis/demanes/reconfiguration/Triggerable.class b/build/eu/artemis/demanes/reconfiguration/Triggerable.class
new file mode 100644
index 0000000..828a714
Binary files /dev/null and b/build/eu/artemis/demanes/reconfiguration/Triggerable.class differ
diff --git a/doc/allclasses-frame.html b/doc/allclasses-frame.html
new file mode 100644
index 0000000..ecc9bd9
--- /dev/null
+++ b/doc/allclasses-frame.html
@@ -0,0 +1,101 @@
+
+
+
+
public class SunSPOTPowerController
+extends javax.microedition.midlet.MIDlet
+implements com.sun.spot.core.resources.transducers.ISwitchListener
+
The startApp method of this class is called by the VM to start the
+ application.
+
+ The manifest specifies this class as MIDlet-1, which means it will be
+ selected for execution.
public class SunSPOTPowerController
+extends javax.microedition.midlet.MIDlet
+implements com.sun.spot.core.resources.transducers.ISwitchListener
+
The startApp method of this class is called by the VM to start the
+ application.
+
+ The manifest specifies this class as MIDlet-1, which means it will be
+ selected for execution.
public class SunSPOTPowerController
+extends javax.microedition.midlet.MIDlet
+
The startApp method of this class is called by the VM to start the
+ application.
+
+ The manifest specifies this class as MIDlet-1, which means it will be
+ selected for execution.
public class SunSPOTPowerController
+extends javax.microedition.midlet.MIDlet
+implements com.sun.spot.core.resources.transducers.ISwitchListener
+
The startApp method of this class is called by the VM to start the
+ application.
+
+ The manifest specifies this class as MIDlet-1, which means it will be
+ selected for execution.
public class TesterForController
+extends javax.microedition.midlet.MIDlet
+
The startApp method of this class is called by the VM to start the
+ application.
+
+ The manifest specifies this class as MIDlet-1, which means it will
+ be selected for execution.
+ Get the value of the observation
+
+
+
+ As a generic way to have Observations monitor the system, this method
+ must always be called in order to have the Observation get the
+ information from the system as it is intended to do.
public eu.artemis.demanes.datatypes.ANES_URN getObservationID()
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Observation
+
+ Returns the unique identifier of this Observation.
+
+
+
+ Every Observation is uniquely identifiable via a ANES_URN
+ identifier. By obtaining this identifier, the user should be able to know
+ what property the Observation will observe, an what (sub)component of the
+ system it is observing.
+
+
+
Specified by:
+
getObservationID in interface eu.artemis.demanes.reconfiguration.Observation
public java.lang.Object getValue()
+ throws eu.artemis.demanes.exceptions.ObservationInvocationException
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Observation
+
+ Get the value of the observation
+
+
+
+ As a generic way to have Observations monitor the system, this method
+ must always be called in order to have the Observation get the
+ information from the system as it is intended to do. Any other functions
+ of the Action may exist but will get information from the system
+ component.
+
+
+
Specified by:
+
getValue in interface eu.artemis.demanes.reconfiguration.Observation
+
Returns:
an Object which represents the value of the observation. An
+ Observation may specify what type of Object is returned, but any
+ type of return value is possible.
+
Throws:
+
eu.artemis.demanes.exceptions.ObservationInvocationException - If at some point in obtaining the information from the system
+ an error occurs, an ObservationInvocationException is thrown
+ indicating that the observation failed.
public class PowerScalingMonitor
+extends java.lang.Object
+implements eu.artemis.demanes.reconfiguration.TriggerPolicy, eu.artemis.demanes.reconfiguration.Observer
+ In order for the user to obtain all Observationss which
+ provide information about the system component, this function returns an
+ array of observations which are available.
public void registerTriggerable(eu.artemis.demanes.reconfiguration.Triggerable t)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Add a Triggerable object to the collection of objects to
+ trigger whenever the policy intends to do so. If the object has already
+ been registered before, nothing changes.
+
+
+
Specified by:
+
registerTriggerable in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Resumes the trigger policy activity if it is suspended. Calling this
+ function when the trigger policy is stopped, or started has no effect.
+ Resuming may cause immediate firing of the triggerable object.
+
+
+
Specified by:
+
resume in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Runs the trigger policy. After this call, the trigger policy will
+ determine the conditions and regularity in which the triggerable object
+ will be fired. Starting may cause the immediate firing of the triggerable
+ object.
+
+
+
+ If start is invoked and the trigger policy is not in stopped state, it
+ will have no effect.
+
+
+
Specified by:
+
start in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Stops the functioning of the trigger policy. After this method is invoked
+ there will be no firing of the triggerable object which was registered.
+ Additionally the internal state of the Triggerpolicy (if any) is cleared.
+
+
+
Specified by:
+
stop in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Temporarily suspends the firing of the triggerable object. The normal
+ functioning of the trigger policy must be resumed by using the resume()
+ method.
+
+
+
Specified by:
+
suspend in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
public void unregisterTriggerable(eu.artemis.demanes.reconfiguration.Triggerable t)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Remove a Triggerable object from the collection of objects
+ to trigger whenever the policy intends to do so. If the object was not
+ registered before, nothing changes
+
+
+
Specified by:
+
unregisterTriggerable in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
+
Parameters:
t - the object that no longer needs to be triggered
Description copied from interface: eu.artemis.demanes.reconfiguration.Observer
+
+ In order for the user to obtain all Observationss which
+ provide information about the system component, this function returns an
+ array of observations which are available.
+
+
+
+ If there are no observations available this function returns null
+
+
+
Specified by:
+
getObservations in interface eu.artemis.demanes.reconfiguration.Observer
+
Returns:
an Array or Observations that may be used to obtain information
+ about the system
Static method to obtain the minimum index in the available transmission
+ powers array. It will always be 0, so this method is just to complement
+ the getMaximumPTXIndex.
+
+
Parameters:
+
channel - The channel for which the maximum index is required.
public class RoutingListener
+extends java.lang.Object
+implements com.sun.spot.multihop.radio.mhrp.interfaces.ILQRPEventListener, com.sun.spot.multihop.radio.IDataEventListener
public void setActuationProvider(eu.artemis.demanes.reconfiguration.ActionProvider ap)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's actuators.
+
+
+
+ This function specifies that an ActionProvider should be
+ used as the object to get it's Actions from. The actions can
+ be obtained by the Reasoner using the ActionProvider's interface, and the
+ obtained actions can be subsequently used to change anything in the
+ system.
+
+
+
+ If there was previously another object set as it's action provider, this
+ new object will overwrite it. There can only be one at a time.
+
+
+
Specified by:
+
setActuationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
ap - The object to be used from now on in order to get actions from
public void setObservationProvider(eu.artemis.demanes.reconfiguration.ObservationProvider op)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's observations.
+
+
+
+ By specifying that an ObservationProvider should be used as
+ the object to get it's Observations from, means that all the
+ input of the Reasoner will have to come from this object. These
+ observations can then be obtained by the Reasoner via the appropriate
+ functions from the ObservationProvider interface.
+
+
+
+ If there was already another observation provider set, this new object
+ will overwrite it. There can always only be one at a time.
+
+
+
Specified by:
+
setObservationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
op - The object to be used from now on in order to get input from
Description copied from interface: eu.artemis.demanes.reconfiguration.Triggerable
+
+ The trigger function triggers the object to do it's main purpose. The
+ trigger function is merely a generic get an object started. It receives
+ no arguments, it can be seen merely as a button that activates the
+ Triggerable object.
+
+
+
Specified by:
+
trigger in interface eu.artemis.demanes.reconfiguration.Triggerable
public void setActuationProvider(eu.artemis.demanes.reconfiguration.ActionProvider ap)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's actuators.
+
+
+
+ This function specifies that an ActionProvider should be
+ used as the object to get it's Actions from. The actions can
+ be obtained by the Reasoner using the ActionProvider's interface, and the
+ obtained actions can be subsequently used to change anything in the
+ system.
+
+
+
+ If there was previously another object set as it's action provider, this
+ new object will overwrite it. There can only be one at a time.
+
+
+
Specified by:
+
setActuationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
ap - The object to be used from now on in order to get actions from
public void setObservationProvider(eu.artemis.demanes.reconfiguration.ObservationProvider op)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's observations.
+
+
+
+ By specifying that an ObservationProvider should be used as
+ the object to get it's Observations from, means that all the
+ input of the Reasoner will have to come from this object. These
+ observations can then be obtained by the Reasoner via the appropriate
+ functions from the ObservationProvider interface.
+
+
+
+ If there was already another observation provider set, this new object
+ will overwrite it. There can always only be one at a time.
+
+
+
Specified by:
+
setObservationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
op - The object to be used from now on in order to get input from
Description copied from interface: eu.artemis.demanes.reconfiguration.Triggerable
+
+ The trigger function triggers the object to do it's main purpose. The
+ trigger function is merely a generic get an object started. It receives
+ no arguments, it can be seen merely as a button that activates the
+ Triggerable object.
+
+
+
Specified by:
+
trigger in interface eu.artemis.demanes.reconfiguration.Triggerable
public void setActuationProvider(eu.artemis.demanes.reconfiguration.ActionProvider ap)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's actuators.
+
+
+
+ This function specifies that an ActionProvider should be
+ used as the object to get it's Actions from. The actions can
+ be obtained by the Reasoner using the ActionProvider's interface, and the
+ obtained actions can be subsequently used to change anything in the
+ system.
+
+
+
+ If there was previously another object set as it's action provider, this
+ new object will overwrite it. There can only be one at a time.
+
+
+
Specified by:
+
setActuationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
ap - The object to be used from now on in order to get actions from
public void setObservationProvider(eu.artemis.demanes.reconfiguration.ObservationProvider op)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's observations.
+
+
+
+ By specifying that an ObservationProvider should be used as
+ the object to get it's Observations from, means that all the
+ input of the Reasoner will have to come from this object. These
+ observations can then be obtained by the Reasoner via the appropriate
+ functions from the ObservationProvider interface.
+
+
+
+ If there was already another observation provider set, this new object
+ will overwrite it. There can always only be one at a time.
+
+
+
Specified by:
+
setObservationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
op - The object to be used from now on in order to get input from
Description copied from interface: eu.artemis.demanes.reconfiguration.Triggerable
+
+ The trigger function triggers the object to do it's main purpose. The
+ trigger function is merely a generic get an object started. It receives
+ no arguments, it can be seen merely as a button that activates the
+ Triggerable object.
+
+
+
Specified by:
+
trigger in interface eu.artemis.demanes.reconfiguration.Triggerable
public void setActuationProvider(eu.artemis.demanes.reconfiguration.ActionProvider ap)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's actuators.
+
+
+
+ This function specifies that an ActionProvider should be
+ used as the object to get it's Actions from. The actions can
+ be obtained by the Reasoner using the ActionProvider's interface, and the
+ obtained actions can be subsequently used to change anything in the
+ system.
+
+
+
+ If there was previously another object set as it's action provider, this
+ new object will overwrite it. There can only be one at a time.
+
+
+
Specified by:
+
setActuationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
ap - The object to be used from now on in order to get actions from
public void setObservationProvider(eu.artemis.demanes.reconfiguration.ObservationProvider op)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's observations.
+
+
+
+ By specifying that an ObservationProvider should be used as
+ the object to get it's Observations from, means that all the
+ input of the Reasoner will have to come from this object. These
+ observations can then be obtained by the Reasoner via the appropriate
+ functions from the ObservationProvider interface.
+
+
+
+ If there was already another observation provider set, this new object
+ will overwrite it. There can always only be one at a time.
+
+
+
Specified by:
+
setObservationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
op - The object to be used from now on in order to get input from
Description copied from interface: eu.artemis.demanes.reconfiguration.Triggerable
+
+ The trigger function triggers the object to do it's main purpose. The
+ trigger function is merely a generic get an object started. It receives
+ no arguments, it can be seen merely as a button that activates the
+ Triggerable object.
+
+
+
Specified by:
+
trigger in interface eu.artemis.demanes.reconfiguration.Triggerable
public void setActuationProvider(eu.artemis.demanes.reconfiguration.ActionProvider ap)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's actuators.
+
+
+
+ This function specifies that an ActionProvider should be
+ used as the object to get it's Actions from. The actions can
+ be obtained by the Reasoner using the ActionProvider's interface, and the
+ obtained actions can be subsequently used to change anything in the
+ system.
+
+
+
+ If there was previously another object set as it's action provider, this
+ new object will overwrite it. There can only be one at a time.
+
+
+
Specified by:
+
setActuationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
ap - The object to be used from now on in order to get actions from
public void setObservationProvider(eu.artemis.demanes.reconfiguration.ObservationProvider op)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's observations.
+
+
+
+ By specifying that an ObservationProvider should be used as
+ the object to get it's Observations from, means that all the
+ input of the Reasoner will have to come from this object. These
+ observations can then be obtained by the Reasoner via the appropriate
+ functions from the ObservationProvider interface.
+
+
+
+ If there was already another observation provider set, this new object
+ will overwrite it. There can always only be one at a time.
+
+
+
Specified by:
+
setObservationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
op - The object to be used from now on in order to get input from
Description copied from interface: eu.artemis.demanes.reconfiguration.Triggerable
+
+ The trigger function triggers the object to do it's main purpose. The
+ trigger function is merely a generic get an object started. It receives
+ no arguments, it can be seen merely as a button that activates the
+ Triggerable object.
+
+
+
Specified by:
+
trigger in interface eu.artemis.demanes.reconfiguration.Triggerable
public void setActuationProvider(eu.artemis.demanes.reconfiguration.ActionProvider ap)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's actuators.
+
+
+
+ This function specifies that an ActionProvider should be
+ used as the object to get it's Actions from. The actions can
+ be obtained by the Reasoner using the ActionProvider's interface, and the
+ obtained actions can be subsequently used to change anything in the
+ system.
+
+
+
+ If there was previously another object set as it's action provider, this
+ new object will overwrite it. There can only be one at a time.
+
+
+
Specified by:
+
setActuationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
ap - The object to be used from now on in order to get actions from
public void setObservationProvider(eu.artemis.demanes.reconfiguration.ObservationProvider op)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's observations.
+
+
+
+ By specifying that an ObservationProvider should be used as
+ the object to get it's Observations from, means that all the
+ input of the Reasoner will have to come from this object. These
+ observations can then be obtained by the Reasoner via the appropriate
+ functions from the ObservationProvider interface.
+
+
+
+ If there was already another observation provider set, this new object
+ will overwrite it. There can always only be one at a time.
+
+
+
Specified by:
+
setObservationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
+
op - The object to be used from now on in order to get input from
Description copied from interface: eu.artemis.demanes.reconfiguration.Triggerable
+
+ The trigger function triggers the object to do it's main purpose. The
+ trigger function is merely a generic get an object started. It receives
+ no arguments, it can be seen merely as a button that activates the
+ Triggerable object.
+
+
+
Specified by:
+
trigger in interface eu.artemis.demanes.reconfiguration.Triggerable
public class ORAMediatorForSunSPOT
+extends java.lang.Object
+implements eu.artemis.demanes.reconfiguration.ORAMediator, eu.artemis.demanes.reconfiguration.ActionProvider, eu.artemis.demanes.reconfiguration.ObservationProvider
+<<<<<<< .mine
+ Query the Observations that can be obtained from this ObservationProvider
+=======
+ Query the Observations that can be obtained from this ObservationProvider
+
+
+
+ The ObservationProvider.getValue(ANES_URN) function requires a ANES_URN
+ argument which identifies which observation to obtain.
+>>>>>>> .r409
+
+ Get the value of a specific Observation in order to monitor
+<<<<<<< .mine
+ the system
+=======
+ the system
+
+
+
+ By calling this function, the user can specify that an Observation with a
+ specific identifier should be invoked.
+>>>>>>> .r409
+
public void setTriggeringPolicy(eu.artemis.demanes.reconfiguration.TriggerPolicy triggerPolicy)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ORAMediator
+
+ Set an object with the TriggerPolicy as the current
+ triggering policy. This policy object defines the when the
+ reconfiguration reasoner should be triggered. For example if the reasoner
+ should be triggered periodically or if a threshold is reached.
+
+
+
+ There can only be one triggering policy at a time, so if this function is
+ called when another triggering policy is set, this function overwrites
+ it.
+
+
+
Specified by:
+
setTriggeringPolicy in interface eu.artemis.demanes.reconfiguration.ORAMediator
Description copied from interface: eu.artemis.demanes.reconfiguration.ActionProvider
+
+ Query the Actions that can be invoked using this ActionProvider
+
+
+
+ The ActionProvider.invoke(ANES_URN, ANES_BUNDLE) function requires a
+ ANES_URN argument which identifies which action to invoke. By using this
+ function the user gets an array which indicate what the relevant
+ ANES_URNs can be used as a valid argument.
+
+
+
+ If there are no possible actions that can be invokes, this function will
+ return null.
+
+
+
Specified by:
+
getActions in interface eu.artemis.demanes.reconfiguration.ActionProvider
+
Returns:
+
an Array of ANES_URNs that can be invoked using this
+ ActionProvider.
Description copied from interface: eu.artemis.demanes.reconfiguration.ActionProvider
+
+ Invokes a specific Action in order to modify the system
+
+
+
+ By calling this function, the user can specify that an Action with a
+ specific identifier should be invoked. This results internally in
+ invoking the corresponding Action.
+
+
+
Specified by:
+
invoke in interface eu.artemis.demanes.reconfiguration.ActionProvider
+
Parameters:
+
id - In order to resolve which Action to invoke, the identity of
+ the corresponding Action should be provided. To obtain a list
+ of available actions from this ActionProvider, use the
+ ActionProvider.getActions() function.
+
arguments - The arguments may indicate a specification of how the action
+ should be invoked. For instance in order to modify a parameter
+ of a component, the new parameter value can be one of the
+ elements in the argument list.
+
Throws:
+
eu.artemis.demanes.exceptions.InexistentActionID - If the provided id can not be resolved by the ActionProvider,
+ an exception is thrown, indicating that the this identifier
+ does not exist. (As far as this ActionProvider concerns)
+
eu.artemis.demanes.exceptions.ActionInvocationException - Is thrown if the invoked action cannot successfully complete.
Description copied from interface: eu.artemis.demanes.reconfiguration.ObservationProvider
+
+ Query the Observations that can be obtained from this ObservationProvider
+
+
+
+ The ObservationProvider.getValue(ANES_URN) function requires a ANES_URN
+ argument which identifies which observation to obtain. By using this
+ function the user gets an array which indicate what the relevant
+ ANES_URNs can be used as a valid argument.
+
+
+
+ If there are no possible observations that can be obtained, this function
+ will return null.
+
+
+
Specified by:
+
getObservations in interface eu.artemis.demanes.reconfiguration.ObservationProvider
public java.lang.Object getValue(eu.artemis.demanes.datatypes.ANES_URN id)
+ throws eu.artemis.demanes.exceptions.InexistentObservationID,
+ eu.artemis.demanes.exceptions.ObservationInvocationException
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObservationProvider
+
+ Get the value of a specific Observation in order to monitor
+ the system
+
+
+
+ By calling this function, the user can specify that an Observation with a
+ specific identifier should be invoked. This results internally in
+ invoking the corresponding Observation.
+
+
+
Specified by:
+
getValue in interface eu.artemis.demanes.reconfiguration.ObservationProvider
+
Parameters:
+
id - In order to resolve which Observation to invoke, the identity
+ of the corresponding Observation should be provided. To obtain a list of
+ available observations from this ObservationProvider, use the
+ ObservationProvider.getObservations() function.
+
Throws:
+
eu.artemis.demanes.exceptions.InexistentObservationID - If the provided id can not be resolved by
+ the ObservationProvider, an exception is thrown, indicating that the this
+ identifier does not exist. (As far as this ObservationProvider concerns)
+
eu.artemis.demanes.exceptions.ObservationInvocationException - Is thrown if the observation
+ cannot successfully obtain it's information.
public void registerObserver(eu.artemis.demanes.reconfiguration.Observer observer)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObserverRegistry
+
+ Add a Observer object to the collection of observers by
+ which the ReasoningEngine can monitor the system. If the observer has
+ already been registered before, nothing changes.
+
+
+
Specified by:
+
registerObserver in interface eu.artemis.demanes.reconfiguration.ObserverRegistry
public void unregisterObserver(eu.artemis.demanes.reconfiguration.Observer observer)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObserverRegistry
+
+ Remove a Observer object from the collection of observers.
+ This function should be called before the observer is destroyed. If the
+ object was not registered before, nothing happens.
+
+
+
Specified by:
+
unregisterObserver in interface eu.artemis.demanes.reconfiguration.ObserverRegistry
public void registerActuator(eu.artemis.demanes.reconfiguration.Actuator actuator)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ActuatorRegistry
+
+ Add a Actuator object to the collection of actuators by
+ which the ReasoningEngine can modify the system. If the actuator has
+ already been registered before, nothing changes.
+
+
+
Specified by:
+
registerActuator in interface eu.artemis.demanes.reconfiguration.ActuatorRegistry
public void unregisterActuator(eu.artemis.demanes.reconfiguration.Actuator actuator)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ActuatorRegistry
+
+ Remove a Actuator object from the collection of actuators.
+ This function should be called before the actuator is destroyed. If the
+ object was not registered before, nothing happens.
+
+
+
Specified by:
+
unregisterActuator in interface eu.artemis.demanes.reconfiguration.ActuatorRegistry
public class ORAMediatorForSunSPOT
+extends java.lang.Object
+implements eu.artemis.demanes.reconfiguration.ORAMediator, eu.artemis.demanes.reconfiguration.ActionProvider, eu.artemis.demanes.reconfiguration.ObservationProvider
public void setTriggeringPolicy(eu.artemis.demanes.reconfiguration.TriggerPolicy triggerPolicy)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ORAMediator
+
+ Set an object with the TriggerPolicy as the current
+ triggering policy. This policy object defines the when the
+ reconfiguration reasoner should be triggered. For example if the reasoner
+ should be triggered periodically or if a threshold is reached.
+
+
+
+ There can only be one triggering policy at a time, so if this function is
+ called when another triggering policy is set, this function overwrites
+ it.
+
+
+
Specified by:
+
setTriggeringPolicy in interface eu.artemis.demanes.reconfiguration.ORAMediator
Description copied from interface: eu.artemis.demanes.reconfiguration.ActionProvider
+
+ Query the Actions that can be invoked using this ActionProvider
+
+
+
+ The ActionProvider.invoke(ANES_URN, ANES_BUNDLE) function requires a
+ ANES_URN argument which identifies which action to invoke. By using this
+ function the user gets an array which indicate what the relevant
+ ANES_URNs can be used as a valid argument.
+
+
+
+ If there are no possible actions that can be invokes, this function will
+ return null.
+
+
+
Specified by:
+
getActions in interface eu.artemis.demanes.reconfiguration.ActionProvider
+
Returns:
+
an Array of ANES_URNs that can be invoked using this
+ ActionProvider.
Description copied from interface: eu.artemis.demanes.reconfiguration.ActionProvider
+
+ Invokes a specific Action in order to modify the system
+
+
+
+ By calling this function, the user can specify that an Action with a
+ specific identifier should be invoked. This results internally in
+ invoking the corresponding Action.
+
+
+
Specified by:
+
invoke in interface eu.artemis.demanes.reconfiguration.ActionProvider
+
Parameters:
+
id - In order to resolve which Action to invoke, the identity of
+ the corresponding Action should be provided. To obtain a list
+ of available actions from this ActionProvider, use the
+ ActionProvider.getActions() function.
+
arguments - The arguments may indicate a specification of how the action
+ should be invoked. For instance in order to modify a parameter
+ of a component, the new parameter value can be one of the
+ elements in the argument list.
+
Throws:
+
eu.artemis.demanes.exceptions.InexistentActionID - If the provided id can not be resolved by the ActionProvider,
+ an exception is thrown, indicating that the this identifier
+ does not exist. (As far as this ActionProvider concerns)
+
eu.artemis.demanes.exceptions.ActionInvocationException - Is thrown if the invoked action cannot successfully complete.
Description copied from interface: eu.artemis.demanes.reconfiguration.ObservationProvider
+
+ Query the Observations that can be obtained from this ObservationProvider
+
+
+
+ The ObservationProvider.getValue(ANES_URN) function requires a ANES_URN
+ argument which identifies which observation to obtain. By using this
+ function the user gets an array which indicate what the relevant
+ ANES_URNs can be used as a valid argument.
+
+
+
+ If there are no possible observations that can be obtained, this function
+ will return null.
+
+
+
Specified by:
+
getObservations in interface eu.artemis.demanes.reconfiguration.ObservationProvider
public java.lang.Object getValue(eu.artemis.demanes.datatypes.ANES_URN id)
+ throws eu.artemis.demanes.exceptions.InexistentObservationID,
+ eu.artemis.demanes.exceptions.ObservationInvocationException
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObservationProvider
+
+ Get the value of a specific Observation in order to monitor
+ the system
+
+
+
+ By calling this function, the user can specify that an Observation with a
+ specific identifier should be invoked. This results internally in
+ invoking the corresponding Observation.
+
+
+
Specified by:
+
getValue in interface eu.artemis.demanes.reconfiguration.ObservationProvider
+
Parameters:
+
id - In order to resolve which Observation to invoke, the identity
+ of the corresponding Observation should be provided. To obtain a list of
+ available observations from this ObservationProvider, use the
+ ObservationProvider.getObservations() function.
+
Throws:
+
eu.artemis.demanes.exceptions.InexistentObservationID - If the provided id can not be resolved by
+ the ObservationProvider, an exception is thrown, indicating that the this
+ identifier does not exist. (As far as this ObservationProvider concerns)
+
eu.artemis.demanes.exceptions.ObservationInvocationException - Is thrown if the observation
+ cannot successfully obtain it's information.
public void registerObserver(eu.artemis.demanes.reconfiguration.Observer observer)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObserverRegistry
+
+ Add a Observer object to the collection of observers by
+ which the ReasoningEngine can monitor the system. If the observer has
+ already been registered before, nothing changes.
+
+
+
Specified by:
+
registerObserver in interface eu.artemis.demanes.reconfiguration.ObserverRegistry
public void unregisterObserver(eu.artemis.demanes.reconfiguration.Observer observer)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObserverRegistry
+
+ Remove a Observer object from the collection of observers.
+ This function should be called before the observer is destroyed. If the
+ object was not registered before, nothing happens.
+
+
+
Specified by:
+
unregisterObserver in interface eu.artemis.demanes.reconfiguration.ObserverRegistry
public void registerActuator(eu.artemis.demanes.reconfiguration.Actuator actuator)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ActuatorRegistry
+
+ Add a Actuator object to the collection of actuators by
+ which the ReasoningEngine can modify the system. If the actuator has
+ already been registered before, nothing changes.
+
+
+
Specified by:
+
registerActuator in interface eu.artemis.demanes.reconfiguration.ActuatorRegistry
public void unregisterActuator(eu.artemis.demanes.reconfiguration.Actuator actuator)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ActuatorRegistry
+
+ Remove a Actuator object from the collection of actuators.
+ This function should be called before the actuator is destroyed. If the
+ object was not registered before, nothing happens.
+
+
+
Specified by:
+
unregisterActuator in interface eu.artemis.demanes.reconfiguration.ActuatorRegistry
public class ORAMediatorForSunSPOT
+extends java.lang.Object
+implements eu.artemis.demanes.reconfiguration.ORAMediator, eu.artemis.demanes.reconfiguration.ActionProvider, eu.artemis.demanes.reconfiguration.ObservationProvider
+ Query the Actions that can be invoked using this ActionProvider
+
+
+
+ The ActionProvider.invoke(ANES_URN, ANES_BUNDLE) function requires a
+ ANES_URN argument which identifies which action to invoke.
+ Query the Observations that can be obtained from this ObservationProvider
+
+
+
+ The ObservationProvider.getValue(ANES_URN) function requires a ANES_URN
+ argument which identifies which observation to obtain.
+ Get the value of a specific Observation in order to monitor
+ the system
+
+
+
+ By calling this function, the user can specify that an Observation with a
+ specific identifier should be invoked.
+ Invokes a specific Action in order to modify the system
+
+
+
+ By calling this function, the user can specify that an Action with a
+ specific identifier should be invoked.
public void setTriggeringPolicy(eu.artemis.demanes.reconfiguration.TriggerPolicy triggerPolicy)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ORAMediator
+
+ Set an object with the TriggerPolicy as the current
+ triggering policy. This policy object defines the when the
+ reconfiguration reasoner should be triggered. For example if the reasoner
+ should be triggered periodically or if a threshold is reached.
+
+
+
+ There can only be one triggering policy at a time, so if this function is
+ called when another triggering policy is set, this function overwrites
+ it.
+
+
+
Specified by:
+
setTriggeringPolicy in interface eu.artemis.demanes.reconfiguration.ORAMediator
Description copied from interface: eu.artemis.demanes.reconfiguration.ActionProvider
+
+ Query the Actions that can be invoked using this ActionProvider
+
+
+
+ The ActionProvider.invoke(ANES_URN, ANES_BUNDLE) function requires a
+ ANES_URN argument which identifies which action to invoke. By using this
+ function the user gets an array which indicate what the relevant
+ ANES_URNs can be used as a valid argument.
+
+
+
+ If there are no possible actions that can be invokes, this function will
+ return null.
+
+
+
Specified by:
+
getActions in interface eu.artemis.demanes.reconfiguration.ActionProvider
+
Returns:
an Array of ANES_URNs that can be invoked using this
+ ActionProvider.
Description copied from interface: eu.artemis.demanes.reconfiguration.ActionProvider
+
+ Invokes a specific Action in order to modify the system
+
+
+
+ By calling this function, the user can specify that an Action with a
+ specific identifier should be invoked. This results internally in
+ invoking the corresponding Action.
+
+
+
Specified by:
+
invoke in interface eu.artemis.demanes.reconfiguration.ActionProvider
+
Parameters:
id - In order to resolve which Action to invoke, the identity of
+ the corresponding Action should be provided. To obtain a list
+ of available actions from this ActionProvider, use the
+ ActionProvider.getActions() function.
arguments - The arguments may indicate a specification of how the action
+ should be invoked. For instance in order to modify a parameter
+ of a component, the new parameter value can be one of the
+ elements in the argument list.
+
Throws:
+
eu.artemis.demanes.exceptions.InexistentActionID - If the provided id can not be resolved by the ActionProvider,
+ an exception is thrown, indicating that the this identifier
+ does not exist. (As far as this ActionProvider concerns)
+
eu.artemis.demanes.exceptions.ActionInvocationException - Is thrown if the invoked action cannot successfully complete.
Description copied from interface: eu.artemis.demanes.reconfiguration.ObservationProvider
+
+ Query the Observations that can be obtained from this ObservationProvider
+
+
+
+ The ObservationProvider.getValue(ANES_URN) function requires a ANES_URN
+ argument which identifies which observation to obtain. By using this
+ function the user gets an array which indicate what the relevant
+ ANES_URNs can be used as a valid argument.
+
+
+
+ If there are no possible observations that can be obtained, this function
+ will return null.
+
+
+
Specified by:
+
getObservations in interface eu.artemis.demanes.reconfiguration.ObservationProvider
public java.lang.Object getValue(eu.artemis.demanes.datatypes.ANES_URN id)
+ throws eu.artemis.demanes.exceptions.InexistentObservationID,
+ eu.artemis.demanes.exceptions.ObservationInvocationException
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObservationProvider
+
+ Get the value of a specific Observation in order to monitor
+ the system
+
+
+
+ By calling this function, the user can specify that an Observation with a
+ specific identifier should be invoked. This results internally in
+ invoking the corresponding Observation.
+
+
+
Specified by:
+
getValue in interface eu.artemis.demanes.reconfiguration.ObservationProvider
+
Parameters:
id - In order to resolve which Observation to invoke, the identity
+ of the corresponding Observation should be provided. To obtain
+ a list of available observations from this
+ ObservationProvider, use the ObservationProvider.getObservations()
+ function.
+
Throws:
+
eu.artemis.demanes.exceptions.InexistentObservationID - If the provided id can not be resolved by the
+ ObservationProvider, an exception is thrown, indicating that
+ the this identifier does not exist. (As far as this
+ ObservationProvider concerns)
+
eu.artemis.demanes.exceptions.ObservationInvocationException - Is thrown if the observation cannot successfully obtain it's
+ information.
public void registerObserver(eu.artemis.demanes.reconfiguration.Observer observer)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObserverRegistry
+
+ Add a Observer object to the collection of observers by
+ which the ReasoningEngine can monitor the system. If the observer has
+ already been registered before, nothing changes.
+
+
+
Specified by:
+
registerObserver in interface eu.artemis.demanes.reconfiguration.ObserverRegistry
public void unregisterObserver(eu.artemis.demanes.reconfiguration.Observer observer)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObserverRegistry
+
+ Remove a Observer object from the collection of observers.
+ This function should be called before the observer is destroyed. If the
+ object was not registered before, nothing happens.
+
+
+
Specified by:
+
unregisterObserver in interface eu.artemis.demanes.reconfiguration.ObserverRegistry
public void registerActuator(eu.artemis.demanes.reconfiguration.Actuator actuator)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ActuatorRegistry
+
+ Add a Actuator object to the collection of actuators by
+ which the ReasoningEngine can modify the system. If the actuator has
+ already been registered before, nothing changes.
+
+
+
Specified by:
+
registerActuator in interface eu.artemis.demanes.reconfiguration.ActuatorRegistry
public void unregisterActuator(eu.artemis.demanes.reconfiguration.Actuator actuator)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ActuatorRegistry
+
+ Remove a Actuator object from the collection of actuators.
+ This function should be called before the actuator is destroyed. If the
+ object was not registered before, nothing happens.
+
+
+
Specified by:
+
unregisterActuator in interface eu.artemis.demanes.reconfiguration.ActuatorRegistry
public class ORAMediatorForSunSPOT
+extends java.lang.Object
+implements eu.artemis.demanes.reconfiguration.ORAMediator, eu.artemis.demanes.reconfiguration.ActionProvider, eu.artemis.demanes.reconfiguration.ObservationProvider
+ Query the Actions that can be invoked using this ActionProvider
+
+
+
+ The ActionProvider.invoke(ANES_URN, ANES_BUNDLE) function requires a
+ ANES_URN argument which identifies which action to invoke.
+ Query the Observations that can be obtained from this ObservationProvider
+
+
+
+ The ObservationProvider.getValue(ANES_URN) function requires a ANES_URN
+ argument which identifies which observation to obtain.
+ Get the value of a specific Observation in order to monitor
+ the system
+
+
+
+ By calling this function, the user can specify that an Observation with a
+ specific identifier should be invoked.
+ Invokes a specific Action in order to modify the system
+
+
+
+ By calling this function, the user can specify that an Action with a
+ specific identifier should be invoked.
public void setTriggeringPolicy(eu.artemis.demanes.reconfiguration.TriggerPolicy triggerPolicy)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ORAMediator
+
+ Set an object with the TriggerPolicy as the current
+ triggering policy. This policy object defines the when the
+ reconfiguration reasoner should be triggered. For example if the reasoner
+ should be triggered periodically or if a threshold is reached.
+
+
+
+ There can only be one triggering policy at a time, so if this function is
+ called when another triggering policy is set, this function overwrites
+ it.
+
+
+
Specified by:
+
setTriggeringPolicy in interface eu.artemis.demanes.reconfiguration.ORAMediator
Description copied from interface: eu.artemis.demanes.reconfiguration.ActionProvider
+
+ Query the Actions that can be invoked using this ActionProvider
+
+
+
+ The ActionProvider.invoke(ANES_URN, ANES_BUNDLE) function requires a
+ ANES_URN argument which identifies which action to invoke. By using this
+ function the user gets an array which indicate what the relevant
+ ANES_URNs can be used as a valid argument.
+
+
+
+ If there are no possible actions that can be invokes, this function will
+ return null.
+
+
+
Specified by:
+
getActions in interface eu.artemis.demanes.reconfiguration.ActionProvider
+
Returns:
+
an Array of ANES_URNs that can be invoked using this
+ ActionProvider.
Description copied from interface: eu.artemis.demanes.reconfiguration.ActionProvider
+
+ Invokes a specific Action in order to modify the system
+
+
+
+ By calling this function, the user can specify that an Action with a
+ specific identifier should be invoked. This results internally in
+ invoking the corresponding Action.
+
+
+
Specified by:
+
invoke in interface eu.artemis.demanes.reconfiguration.ActionProvider
+
Parameters:
+
id - In order to resolve which Action to invoke, the identity of
+ the corresponding Action should be provided. To obtain a list
+ of available actions from this ActionProvider, use the
+ ActionProvider.getActions() function.
+
arguments - The arguments may indicate a specification of how the action
+ should be invoked. For instance in order to modify a parameter
+ of a component, the new parameter value can be one of the
+ elements in the argument list.
+
Throws:
+
eu.artemis.demanes.exceptions.InexistentActionID - If the provided id can not be resolved by the ActionProvider,
+ an exception is thrown, indicating that the this identifier
+ does not exist. (As far as this ActionProvider concerns)
+
eu.artemis.demanes.exceptions.ActionInvocationException - Is thrown if the invoked action cannot successfully complete.
Description copied from interface: eu.artemis.demanes.reconfiguration.ObservationProvider
+
+ Query the Observations that can be obtained from this ObservationProvider
+
+
+
+ The ObservationProvider.getValue(ANES_URN) function requires a ANES_URN
+ argument which identifies which observation to obtain. By using this
+ function the user gets an array which indicate what the relevant
+ ANES_URNs can be used as a valid argument.
+
+
+
+ If there are no possible observations that can be obtained, this function
+ will return null.
+
+
+
Specified by:
+
getObservations in interface eu.artemis.demanes.reconfiguration.ObservationProvider
public java.lang.Object getValue(eu.artemis.demanes.datatypes.ANES_URN id)
+ throws eu.artemis.demanes.exceptions.InexistentObservationID,
+ eu.artemis.demanes.exceptions.ObservationInvocationException
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObservationProvider
+
+ Get the value of a specific Observation in order to monitor
+ the system
+
+
+
+ By calling this function, the user can specify that an Observation with a
+ specific identifier should be invoked. This results internally in
+ invoking the corresponding Observation.
+
+
+
Specified by:
+
getValue in interface eu.artemis.demanes.reconfiguration.ObservationProvider
+
Parameters:
+
id - In order to resolve which Observation to invoke, the identity
+ of the corresponding Observation should be provided. To obtain a list of
+ available observations from this ObservationProvider, use the
+ ObservationProvider.getObservations() function.
+
Throws:
+
eu.artemis.demanes.exceptions.InexistentObservationID - If the provided id can not be resolved by
+ the ObservationProvider, an exception is thrown, indicating that the this
+ identifier does not exist. (As far as this ObservationProvider concerns)
+
eu.artemis.demanes.exceptions.ObservationInvocationException - Is thrown if the observation
+ cannot successfully obtain it's information.
public void registerObserver(eu.artemis.demanes.reconfiguration.Observer observer)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObserverRegistry
+
+ Add a Observer object to the collection of observers by
+ which the ReasoningEngine can monitor the system. If the observer has
+ already been registered before, nothing changes.
+
+
+
Specified by:
+
registerObserver in interface eu.artemis.demanes.reconfiguration.ObserverRegistry
public void unregisterObserver(eu.artemis.demanes.reconfiguration.Observer observer)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ObserverRegistry
+
+ Remove a Observer object from the collection of observers.
+ This function should be called before the observer is destroyed. If the
+ object was not registered before, nothing happens.
+
+
+
Specified by:
+
unregisterObserver in interface eu.artemis.demanes.reconfiguration.ObserverRegistry
public void registerActuator(eu.artemis.demanes.reconfiguration.Actuator actuator)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ActuatorRegistry
+
+ Add a Actuator object to the collection of actuators by
+ which the ReasoningEngine can modify the system. If the actuator has
+ already been registered before, nothing changes.
+
+
+
Specified by:
+
registerActuator in interface eu.artemis.demanes.reconfiguration.ActuatorRegistry
public void unregisterActuator(eu.artemis.demanes.reconfiguration.Actuator actuator)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.ActuatorRegistry
+
+ Remove a Actuator object from the collection of actuators.
+ This function should be called before the actuator is destroyed. If the
+ object was not registered before, nothing happens.
+
+
+
Specified by:
+
unregisterActuator in interface eu.artemis.demanes.reconfiguration.ActuatorRegistry
public class PowerScalingMonitor
+extends java.lang.Object
+implements eu.artemis.demanes.reconfiguration.TriggerPolicy, eu.artemis.demanes.reconfiguration.Observer
+ In order for the user to obtain all Observationss which
+ provide information about the system component, this function returns an
+ array of observations which are available.
public void registerTriggerable(eu.artemis.demanes.reconfiguration.Triggerable t)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Add a Triggerable object to the collection of objects to
+ trigger whenever the policy intends to do so. If the object has already
+ been registered before, nothing changes.
+
+
+
Specified by:
+
registerTriggerable in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Resumes the trigger policy activity if it is suspended. Calling this
+ function when the trigger policy is stopped, or started has no effect.
+ Resuming may cause immediate firing of the triggerable object.
+
+
+
Specified by:
+
resume in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Runs the trigger policy. After this call, the trigger policy will
+ determine the conditions and regularity in which the triggerable object
+ will be fired. Starting may cause the immediate firing of the triggerable
+ object.
+
+
+
+ If start is invoked and the trigger policy is not in stopped state, it
+ will have no effect.
+
+
+
Specified by:
+
start in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Stops the functioning of the trigger policy. After this method is invoked
+ there will be no firing of the triggerable object which was registered.
+ Additionally the internal state of the Triggerpolicy (if any) is cleared.
+
+
+
Specified by:
+
stop in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Temporarily suspends the firing of the triggerable object. The normal
+ functioning of the trigger policy must be resumed by using the resume()
+ method.
+
+
+
Specified by:
+
suspend in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
public void unregisterTriggerable(eu.artemis.demanes.reconfiguration.Triggerable t)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Remove a Triggerable object from the collection of objects
+ to trigger whenever the policy intends to do so. If the object was not
+ registered before, nothing changes
+
+
+
Specified by:
+
unregisterTriggerable in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
+
Parameters:
+
t - the object that no longer needs to be triggered
Description copied from interface: eu.artemis.demanes.reconfiguration.Observer
+
+ In order for the user to obtain all Observationss which
+ provide information about the system component, this function returns an
+ array of observations which are available.
+
+
+
+ If there are no observations available this function returns null
+
+
+
Specified by:
+
getObservations in interface eu.artemis.demanes.reconfiguration.Observer
+
Returns:
+
an Array or Observations that may be used to obtain information
+ about the system
+ In order for the user to obtain all Actions by which a
+ system component may be changed, this function returns an array of
+ actions which are available.
Description copied from interface: eu.artemis.demanes.reconfiguration.Actuator
+
+ In order for the user to obtain all Actions by which a
+ system component may be changed, this function returns an array of
+ actions which are available.
+
+
+
+ If there are no actions available this function returns null
+
+
+
Specified by:
+
getActions in interface eu.artemis.demanes.reconfiguration.Actuator
+
Returns:
an Array or Actions that may be invoked to reconfigure the system
public class NodeDegreeObservation
+extends java.lang.Object
+implements eu.artemis.demanes.reconfiguration.Observation, NodeDegreeObservationExtension
public eu.artemis.demanes.datatypes.ANES_URN getObservationID()
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Observation
+
+ Returns the unique identifier of this Observation.
+
+
+
+ Every Observation is uniquely identifiable via a ANES_URN
+ identifier. By obtaining this identifier, the user should be able to know
+ what property the Observation will observe, an what (sub)component of the
+ system it is observing.
+
+
+
Specified by:
+
getObservationID in interface eu.artemis.demanes.reconfiguration.Observation
public java.lang.Object getValue()
+ throws eu.artemis.demanes.exceptions.ObservationInvocationException
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Observation
+
+ Get the value of the observation
+
+
+
+ As a generic way to have Observations monitor the system, this method
+ must always be called in order to have the Observation get the
+ information from the system as it is intended to do. Any other functions
+ of the Action may exist but will get information from the system
+ component.
+
+
+
Specified by:
+
getValue in interface eu.artemis.demanes.reconfiguration.Observation
+
Returns:
+
an Object which represents the value of the observation. An
+ Observation may specify what type of Object is returned, but any
+ type of return value is possible.
+
Throws:
+
eu.artemis.demanes.exceptions.ObservationInvocationException - If at some point in obtaining the information from the system
+ an error occurs, an ObservationInvocationException is thrown
+ indicating that the observation failed.
+ In order for the user to obtain all Observationss which
+ provide information about the system component, this function returns an
+ array of observations which are available.
Description copied from interface: eu.artemis.demanes.reconfiguration.Observer
+
+ In order for the user to obtain all Observationss which
+ provide information about the system component, this function returns an
+ array of observations which are available.
+
+
+
+ If there are no observations available this function returns null
+
+
+
Specified by:
+
getObservations in interface eu.artemis.demanes.reconfiguration.Observer
+
Returns:
an Array or Observations that may be used to obtain information
+ about the system
public void setActuationProvider(eu.artemis.demanes.reconfiguration.ActionProvider ap)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's actuators.
+
+
+
+ This function specifies that an ActionProvider should be
+ used as the object to get it's Actions from. The actions can
+ be obtained by the Reasoner using the ActionProvider's interface, and the
+ obtained actions can be subsequently used to change anything in the
+ system.
+
+
+
+ If there was previously another object set as it's action provider, this
+ new object will overwrite it. There can only be one at a time.
+
+
+
Specified by:
+
setActuationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
ap - The object to be used from now on in order to get actions from
public void setObservationProvider(eu.artemis.demanes.reconfiguration.ObservationProvider op)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.Reasoner
+
+ Sets the object that will provide this Reasoner with it's observations.
+
+
+
+ By specifying that an ObservationProvider should be used as
+ the object to get it's Observations from, means that all the
+ input of the Reasoner will have to come from this object. These
+ observations can then be obtained by the Reasoner via the appropriate
+ functions from the ObservationProvider interface.
+
+
+
+ If there was already another observation provider set, this new object
+ will overwrite it. There can always only be one at a time.
+
+
+
Specified by:
+
setObservationProvider in interface eu.artemis.demanes.reconfiguration.Reasoner
+
Parameters:
op - The object to be used from now on in order to get input from
Description copied from interface: eu.artemis.demanes.reconfiguration.Triggerable
+
+ The trigger function triggers the object to do it's main purpose. The
+ trigger function is merely a generic get an object started. It receives
+ no arguments, it can be seen merely as a button that activates the
+ Triggerable object.
+
+
+
Specified by:
+
trigger in interface eu.artemis.demanes.reconfiguration.Triggerable
public void registerTriggerable(eu.artemis.demanes.reconfiguration.Triggerable t)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Add a Triggerable object to the collection of objects to
+ trigger whenever the policy intends to do so. If the object has already
+ been registered before, nothing changes.
+
+
+
Specified by:
+
registerTriggerable in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Resumes the trigger policy activity if it is suspended. Calling this
+ function when the trigger policy is stopped, or started has no effect.
+ Resuming may cause immediate firing of the triggerable object.
+
+
+
Specified by:
+
resume in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Runs the trigger policy. After this call, the trigger policy will
+ determine the conditions and regularity in which the triggerable object
+ will be fired. Starting may cause the immediate firing of the triggerable
+ object.
+
+
+
+ If start is invoked and the trigger policy is not in stopped state, it
+ will have no effect.
+
+
+
Specified by:
+
start in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Stops the functioning of the trigger policy. After this method is invoked
+ there will be no firing of the triggerable object which was registered.
+ Additionally the internal state of the Triggerpolicy (if any) is cleared.
+
+
+
Specified by:
+
stop in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Temporarily suspends the firing of the triggerable object. The normal
+ functioning of the trigger policy must be resumed by using the resume()
+ method.
+
+
+
Specified by:
+
suspend in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
public void unregisterTriggerable(eu.artemis.demanes.reconfiguration.Triggerable t)
+
Description copied from interface: eu.artemis.demanes.reconfiguration.TriggerPolicy
+
+ Remove a Triggerable object from the collection of objects
+ to trigger whenever the policy intends to do so. If the object was not
+ registered before, nothing changes
+
+
+
Specified by:
+
unregisterTriggerable in interface eu.artemis.demanes.reconfiguration.TriggerPolicy
+
Parameters:
t - the object that no longer needs to be triggered
Note: Although some parts should be considered to be accessed in a
+ synchronized way allowing different callers for the marquee, the actual usage
+ does not require it.
Note: Although some parts should be considered to be accessed in a
+ synchronized way allowing different callers for the marquee, the actual usage
+ does not require it.
Note: Although some parts should be considered to be accessed in a
+ synchronized way allowing different callers for the marquee, the actual usage
+ does not require it.
Note: Although some parts should be considered to be accessed in a
+ synchronized way allowing different callers for the marquee, the actual usage
+ does not require it.
The Level class defines a set of standard logging levels that can be used to
+ control logging output. The logging Level objects are ordered and are
+ specified by ordered integers. Enabling logging at a given level also enables
+ logging at all higher levels.
+
+
+ Clients should normally use the predefined Level constants such as
+ Level.SEVERE.
+
+
+
+ The levels in descending order are:
+
+
+
+
SEVERE (highest value)
+
WARNING
+
INFO
+
CONFIG
+
FINE
+
FINER
+
FINEST (lowest value)
+
+
+
+ In addition there is a level OFF that can be used to turn off logging, and a
+ level ALL that can be used to enable logging of all messages.
+
+
+
+ It is possible for third parties to define additional logging levels by
+ subclassing Level. In such cases subclasses should take care to chose unique
+ integer level values and to ensure that they maintain the Object uniqueness
+ property across serialization by defining a suitable readResolve method.
+
protected Level(java.lang.String name,
+ int value)
+
Create a named Level with a given integer value.
+
+ Note that this constructor is "protected" to allow subclassing. In
+ general clients of logging should use one of the constant Level objects
+ such as SEVERE or FINEST. However, if clients need to add new logging
+ levels, they may subclass Level and define new constants.
+
+
Parameters:
+
name - the name of the Level, for example "SEVERE".
The Level class defines a set of standard logging levels that can be used to
+ control logging output. The logging Level objects are ordered and are
+ specified by ordered integers. Enabling logging at a given level also enables
+ logging at all higher levels.
+
+
+ Clients should normally use the predefined Level constants such as
+ Level.SEVERE.
+
+
+
+ The levels in descending order are:
+
+
+
+
SEVERE (highest value)
+
WARNING
+
INFO
+
CONFIG
+
FINE
+
FINER
+
FINEST (lowest value)
+
+
+
+ In addition there is a level OFF that can be used to turn off logging, and a
+ level ALL that can be used to enable logging of all messages.
+
+
+
+ It is possible for third parties to define additional logging levels by
+ subclassing Level. In such cases subclasses should take care to chose unique
+ integer level values and to ensure that they maintain the Object uniqueness
+ property across serialization by defining a suitable readResolve method.
+
protected Level(java.lang.String name,
+ int value)
+
Create a named Level with a given integer value.
+
+ Note that this constructor is "protected" to allow subclassing. In
+ general clients of logging should use one of the constant Level objects
+ such as SEVERE or FINEST. However, if clients need to add new logging
+ levels, they may subclass Level and define new constants.
+
+
Parameters:
+
name - the name of the Level, for example "SEVERE".
The Level class defines a set of standard logging levels that can be
+ used to control logging output. The logging Level objects are ordered and
+ are specified by ordered integers. Enabling logging at a given level also
+ enables logging at all higher levels.
+
+
+ Clients should normally use the predefined Level constants such as Level.SEVERE.
+
+
+
+ The levels in descending order are:
+
+
+
+
SEVERE (highest value)
+
WARNING
+
INFO
+
CONFIG
+
FINE
+
FINER
+
FINEST (lowest value)
+
+
+
+ In addition there is a level OFF that can be used to turn off logging, and a
+ level ALL that can be used to enable logging of all messages.
+
+
+
+ It is possible for third parties to define additional logging levels by
+ subclassing Level. In such cases subclasses should take care to chose unique
+ integer level values and to ensure that they maintain the Object uniqueness
+ property across serialization by defining a suitable readResolve method.
+
protected Level(java.lang.String name,
+ int value)
+
Create a named Level with a given integer value.
+
+ Note that this constructor is "protected" to allow subclassing. In
+ general clients of logging should use one of the constant Level objects
+ such as SEVERE or FINEST. However, if clients need to add new logging
+ levels, they may subclass Level and define new constants.
+
Parameters:
name - the name of the Level, for example "SEVERE".
The Level class defines a set of standard logging levels that can be used to
+ control logging output. The logging Level objects are ordered and are
+ specified by ordered integers. Enabling logging at a given level also enables
+ logging at all higher levels.
+
+
+ Clients should normally use the predefined Level constants such as
+ Level.SEVERE.
+
+
+
+ The levels in descending order are:
+
+
+
+
SEVERE (highest value)
+
WARNING
+
INFO
+
CONFIG
+
FINE
+
FINER
+
FINEST (lowest value)
+
+
+
+ In addition there is a level OFF that can be used to turn off logging, and a
+ level ALL that can be used to enable logging of all messages.
+
+
+
+ It is possible for third parties to define additional logging levels by
+ subclassing Level. In such cases subclasses should take care to chose unique
+ integer level values and to ensure that they maintain the Object uniqueness
+ property across serialization by defining a suitable readResolve method.
+
protected Level(java.lang.String name,
+ int value)
+
Create a named Level with a given integer value.
+
+ Note that this constructor is "protected" to allow subclassing. In
+ general clients of logging should use one of the constant Level objects
+ such as SEVERE or FINEST. However, if clients need to add new logging
+ levels, they may subclass Level and define new constants.
+
+
Parameters:
+
name - the name of the Level, for example "SEVERE".
Protected method to construct a logger with a default configuration.
+
+ The logger will be initially configured for ALL messages done to
+ System.out.
Protected method to construct a logger with a default configuration.
+
+ The logger will be initially configured for ALL messages done to
+ System.out.
Protected method to construct a logger with a default configuration.
+
+ The logger will be initially configured for ALL messages done to
+ System.out.
A NDPFactory is a factory method to provide a Neighbor Discovery Protocol
+ manager selected accordingly to the instance requested. See
+ NeighborDiscoveryType for further information regarding the current
+ available managers.
+
+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
+
+
Overview
+
The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
+
+
+
Package
+
Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+
Interfaces (italic)
+
Classes
+
Enums
+
Exceptions
+
Errors
+
Annotation Types
+
+
+
+
Class/Interface
+
Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+
Class inheritance diagram
+
Direct Subclasses
+
All Known Subinterfaces
+
All Known Implementing Classes
+
Class/interface declaration
+
Class/interface description
+
+
+
Nested Class Summary
+
Field Summary
+
Constructor Summary
+
Method Summary
+
+
+
Field Detail
+
Constructor Detail
+
Method Detail
+
+
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+
Annotation Type
+
Each annotation type has its own separate page with the following sections:
+
+
Annotation Type declaration
+
Annotation Type description
+
Required Element Summary
+
Optional Element Summary
+
Element Detail
+
+
+
+
Enum
+
Each enum has its own separate page with the following sections:
+
+
Enum declaration
+
Enum description
+
Enum Constant Summary
+
Enum Constant Detail
+
+
+
+
Tree (Class Hierarchy)
+
There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+
Deprecated API
+
The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+
Index
+
The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+
Prev/Next
+
These links take you to the next or previous class, interface, package, or related page.
+
+
+
Frames/No Frames
+
These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+
All Classes
+
The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+
Serialized Form
+
Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
+
+
Overview
+
The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
+
+
+
Package
+
Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+
Interfaces (italic)
+
Classes
+
Enums
+
Exceptions
+
Errors
+
Annotation Types
+
+
+
+
Class/Interface
+
Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+
Class inheritance diagram
+
Direct Subclasses
+
All Known Subinterfaces
+
All Known Implementing Classes
+
Class/interface declaration
+
Class/interface description
+
+
+
Nested Class Summary
+
Field Summary
+
Constructor Summary
+
Method Summary
+
+
+
Field Detail
+
Constructor Detail
+
Method Detail
+
+
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+
Annotation Type
+
Each annotation type has its own separate page with the following sections:
+
+
Annotation Type declaration
+
Annotation Type description
+
Required Element Summary
+
Optional Element Summary
+
Element Detail
+
+
+
+
Enum
+
Each enum has its own separate page with the following sections:
+
+
Enum declaration
+
Enum description
+
Enum Constant Summary
+
Enum Constant Detail
+
+
+
+
Tree (Class Hierarchy)
+
There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+
Deprecated API
+
The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+
Index
+
The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+
Prev/Next
+
These links take you to the next or previous class, interface, package, or related page.
+
+
+
Frames/No Frames
+
These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+
All Classes
+
The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+
Serialized Form
+
Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
+
+
Overview
+
The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
+
+
+
Package
+
Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+
Interfaces (italic)
+
Classes
+
Enums
+
Exceptions
+
Errors
+
Annotation Types
+
+
+
+
Class/Interface
+
Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+
Class inheritance diagram
+
Direct Subclasses
+
All Known Subinterfaces
+
All Known Implementing Classes
+
Class/interface declaration
+
Class/interface description
+
+
+
Nested Class Summary
+
Field Summary
+
Constructor Summary
+
Method Summary
+
+
+
Field Detail
+
Constructor Detail
+
Method Detail
+
+
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+
Annotation Type
+
Each annotation type has its own separate page with the following sections:
+
+
Annotation Type declaration
+
Annotation Type description
+
Required Element Summary
+
Optional Element Summary
+
Element Detail
+
+
+
+
Enum
+
Each enum has its own separate page with the following sections:
+
+
Enum declaration
+
Enum description
+
Enum Constant Summary
+
Enum Constant Detail
+
+
+
+
Tree (Class Hierarchy)
+
There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+
Deprecated API
+
The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+
Index
+
The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+
Prev/Next
+
These links take you to the next or previous class, interface, package, or related page.
+
+
+
Frames/No Frames
+
These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+
All Classes
+
The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+
Serialized Form
+
Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
+
+
Overview
+
The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
+
+
+
Package
+
Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+
Interfaces (italic)
+
Classes
+
Enums
+
Exceptions
+
Errors
+
Annotation Types
+
+
+
+
Class/Interface
+
Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+
Class inheritance diagram
+
Direct Subclasses
+
All Known Subinterfaces
+
All Known Implementing Classes
+
Class/interface declaration
+
Class/interface description
+
+
+
Nested Class Summary
+
Field Summary
+
Constructor Summary
+
Method Summary
+
+
+
Field Detail
+
Constructor Detail
+
Method Detail
+
+
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+
Annotation Type
+
Each annotation type has its own separate page with the following sections:
+
+
Annotation Type declaration
+
Annotation Type description
+
Required Element Summary
+
Optional Element Summary
+
Element Detail
+
+
+
+
Enum
+
Each enum has its own separate page with the following sections:
+
+
Enum declaration
+
Enum description
+
Enum Constant Summary
+
Enum Constant Detail
+
+
+
+
Tree (Class Hierarchy)
+
There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+
Deprecated API
+
The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+
Index
+
The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+
Prev/Next
+
These links take you to the next or previous class, interface, package, or related page.
+
+
+
Frames/No Frames
+
These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+
All Classes
+
The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+
Serialized Form
+
Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
Note: Although some parts should be considered to be accessed in a
+ synchronized way allowing different callers for the marquee, the actual usage
+ does not require it.
+
+
Marquee() - Constructor for class eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.Marquee
Note: Although some parts should be considered to be accessed in a
+ synchronized way allowing different callers for the marquee, the actual usage
+ does not require it.
+
+
Marquee() - Constructor for class eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.Marquee
Note: Although some parts should be considered to be accessed in a
+ synchronized way allowing different callers for the marquee, the actual usage
+ does not require it.
+
+
Marquee() - Constructor for class eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.Marquee
Note: Although some parts should be considered to be accessed in a
+ synchronized way allowing different callers for the marquee, the actual usage
+ does not require it.
+
+
Marquee() - Constructor for class eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.Marquee
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to Non-frame version.
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to Non-frame version.
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to Non-frame version.
+
+
+
diff --git a/doc/stylesheet.css b/doc/stylesheet.css
new file mode 100644
index 0000000..cebb4fd
--- /dev/null
+++ b/doc/stylesheet.css
@@ -0,0 +1,574 @@
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+
+@import url('resources/fonts/dejavu.css');
+
+body {
+ background-color:#ffffff;
+ color:#353833;
+ font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
+ font-size:14px;
+ margin:0;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#4A6782;
+}
+a:hover, a:focus {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+a:active {
+ text-decoration:none;
+ color:#4A6782;
+}
+a[name] {
+ color:#353833;
+}
+a[name]:hover {
+ text-decoration:none;
+ color:#353833;
+}
+pre {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+}
+h1 {
+ font-size:20px;
+}
+h2 {
+ font-size:18px;
+}
+h3 {
+ font-size:16px;
+ font-style:italic;
+}
+h4 {
+ font-size:13px;
+}
+h5 {
+ font-size:12px;
+}
+h6 {
+ font-size:11px;
+}
+ul {
+ list-style-type:disc;
+}
+code, tt {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+ margin-top:8px;
+ line-height:1.4em;
+}
+dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+}
+table tr td dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ vertical-align:top;
+ padding-top:4px;
+}
+sup {
+ font-size:8px;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:11px;
+ z-index:200;
+ margin-top:-9px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#bb7a2a;
+}
+.tab {
+ background-color:#0066FF;
+ color:#ffffff;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:11px;
+ margin:0;
+}
+.topNav {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.bottomNav {
+ margin-top:10px;
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav {
+ background-color:#dee3e9;
+ float:left;
+ width:100%;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+ text-transform:uppercase;
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding: 5px 6px;
+ text-transform:uppercase;
+}
+ul.subNavList li{
+ list-style:none;
+ float:left;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#FFFFFF;
+ text-decoration:none;
+ text-transform:uppercase;
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#bb7a2a;
+ text-transform:uppercase;
+}
+.navBarCell1Rev {
+ background-color:#F8981D;
+ color:#253441;
+ margin: auto 5px;
+}
+.skipNav {
+ position:absolute;
+ top:auto;
+ left:-9999px;
+ overflow:hidden;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexHeader {
+ margin:10px;
+ position:relative;
+}
+.indexHeader span{
+ margin-right:15px;
+}
+.indexHeader h1 {
+ font-size:13px;
+}
+.title {
+ color:#2c4557;
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 15px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:13px;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:12px;
+}
+.indexContainer h2 {
+ font-size:13px;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+ padding-top:2px;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:12px;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:5px 0 10px 0px;
+ font-size:14px;
+ font-family:'DejaVu Sans Mono',monospace;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:15px;
+ line-height:1.4;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #ededed;
+ background-color:#f8f8f8;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#ffffff;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {
+ width:100%;
+ border-left:1px solid #EEE;
+ border-right:1px solid #EEE;
+ border-bottom:1px solid #EEE;
+}
+.overviewSummary, .memberSummary {
+ padding:0px;
+}
+.overviewSummary caption, .memberSummary caption, .typeSummary caption,
+.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#253441;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ padding-top:10px;
+ padding-left:1px;
+ margin:0px;
+ white-space:pre;
+}
+.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
+.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,
+.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
+.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
+.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
+.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,
+.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
+.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {
+ color:#FFFFFF;
+}
+.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
+.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ padding-bottom:7px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ border: none;
+ height:16px;
+}
+.memberSummary caption span.activeTableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ height:16px;
+}
+.memberSummary caption span.tableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#4D7A97;
+ height:16px;
+}
+.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {
+ padding-top:0px;
+ padding-left:0px;
+ padding-right:0px;
+ background-image:none;
+ float:none;
+ display:inline;
+}
+.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
+.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {
+ display:none;
+ width:5px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .activeTableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .tableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ background-color:#4D7A97;
+ float:left;
+
+}
+.overviewSummary td, .memberSummary td, .typeSummary td,
+.useSummary td, .constantsSummary td, .deprecatedSummary td {
+ text-align:left;
+ padding:0px 0px 12px 10px;
+ width:100%;
+}
+th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,
+td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{
+ vertical-align:top;
+ padding-right:0px;
+ padding-top:8px;
+ padding-bottom:3px;
+}
+th.colFirst, th.colLast, th.colOne, .constantsSummary th {
+ background:#dee3e9;
+ text-align:left;
+ padding:8px 3px 3px 7px;
+}
+td.colFirst, th.colFirst {
+ white-space:nowrap;
+ font-size:13px;
+}
+td.colLast, th.colLast {
+ font-size:13px;
+}
+td.colOne, th.colOne {
+ font-size:13px;
+}
+.overviewSummary td.colFirst, .overviewSummary th.colFirst,
+.overviewSummary td.colOne, .overviewSummary th.colOne,
+.memberSummary td.colFirst, .memberSummary th.colFirst,
+.memberSummary td.colOne, .memberSummary th.colOne,
+.typeSummary td.colFirst{
+ width:25%;
+ vertical-align:top;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+ font-weight:bold;
+}
+.tableSubHeadingColor {
+ background-color:#EEEEFF;
+}
+.altColor {
+ background-color:#FFFFFF;
+}
+.rowColor {
+ background-color:#EEEEEF;
+}
+/*
+Content styles
+*/
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ font-style:normal;
+}
+
+div.block {
+ font-size:14px;
+ font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
+}
+
+td.colLast div {
+ padding-top:0px;
+}
+
+
+td.colLast a {
+ padding-bottom:3px;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:10px;
+}
+.block {
+ display:block;
+ margin:3px 10px 2px 0px;
+ color:#474747;
+}
+.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,
+.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,
+.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {
+ font-weight:bold;
+}
+.deprecationComment, .emphasizedPhrase, .interfaceName {
+ font-style:italic;
+}
+
+div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,
+div.block div.block span.interfaceName {
+ font-style:normal;
+}
+
+div.contentContainer ul.blockList li.blockList h2{
+ padding-bottom:0px;
+}
diff --git a/j2meclasses/eu/artemis/demanes/datatypes/ANES_BUNDLE.class b/j2meclasses/eu/artemis/demanes/datatypes/ANES_BUNDLE.class
new file mode 100644
index 0000000..b4d902b
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/datatypes/ANES_BUNDLE.class differ
diff --git a/j2meclasses/eu/artemis/demanes/datatypes/ANES_URN.class b/j2meclasses/eu/artemis/demanes/datatypes/ANES_URN.class
new file mode 100644
index 0000000..65d3209
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/datatypes/ANES_URN.class differ
diff --git a/j2meclasses/eu/artemis/demanes/datatypes/ANES_URN_Exception.class b/j2meclasses/eu/artemis/demanes/datatypes/ANES_URN_Exception.class
new file mode 100644
index 0000000..7614910
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/datatypes/ANES_URN_Exception.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/ActionInvocationException.class b/j2meclasses/eu/artemis/demanes/exceptions/ActionInvocationException.class
new file mode 100644
index 0000000..cfc0a86
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/ActionInvocationException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/InexistentActionID.class b/j2meclasses/eu/artemis/demanes/exceptions/InexistentActionID.class
new file mode 100644
index 0000000..85efed1
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/InexistentActionID.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/InexistentObservationID.class b/j2meclasses/eu/artemis/demanes/exceptions/InexistentObservationID.class
new file mode 100644
index 0000000..2b51f62
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/InexistentObservationID.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/InvalidContentException.class b/j2meclasses/eu/artemis/demanes/exceptions/InvalidContentException.class
new file mode 100644
index 0000000..5c2bf1f
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/InvalidContentException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/MissingArgumentAnnotationException.class b/j2meclasses/eu/artemis/demanes/exceptions/MissingArgumentAnnotationException.class
new file mode 100644
index 0000000..ee966ae
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/MissingArgumentAnnotationException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/NonExistentKeyException.class b/j2meclasses/eu/artemis/demanes/exceptions/NonExistentKeyException.class
new file mode 100644
index 0000000..4f99e4e
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/NonExistentKeyException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/ObservationInvocationException.class b/j2meclasses/eu/artemis/demanes/exceptions/ObservationInvocationException.class
new file mode 100644
index 0000000..5191130
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/ObservationInvocationException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationAccessorException.class b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationAccessorException.class
new file mode 100644
index 0000000..42107b4
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationAccessorException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationException.class b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationException.class
new file mode 100644
index 0000000..5e67885
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationLinkException.class b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationLinkException.class
new file mode 100644
index 0000000..abe060d
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationLinkException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationURNException.class b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationURNException.class
new file mode 100644
index 0000000..cec0797
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationURNException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationValueTypeException.class b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationValueTypeException.class
new file mode 100644
index 0000000..dd0e6c3
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/ParameterizationValueTypeException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/ReconfigurationAnnotationException.class b/j2meclasses/eu/artemis/demanes/exceptions/ReconfigurationAnnotationException.class
new file mode 100644
index 0000000..a0c74ab
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/ReconfigurationAnnotationException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/ReconfigurationAnnotationURNException.class b/j2meclasses/eu/artemis/demanes/exceptions/ReconfigurationAnnotationURNException.class
new file mode 100644
index 0000000..907e91f
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/ReconfigurationAnnotationURNException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/TaskLifeCycleException.class b/j2meclasses/eu/artemis/demanes/exceptions/TaskLifeCycleException.class
new file mode 100644
index 0000000..534e118
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/TaskLifeCycleException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/TaskManagerException.class b/j2meclasses/eu/artemis/demanes/exceptions/TaskManagerException.class
new file mode 100644
index 0000000..bf8fb9f
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/TaskManagerException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/TaskRegistryException.class b/j2meclasses/eu/artemis/demanes/exceptions/TaskRegistryException.class
new file mode 100644
index 0000000..67e7e58
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/TaskRegistryException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/exceptions/TypedRequestException.class b/j2meclasses/eu/artemis/demanes/exceptions/TypedRequestException.class
new file mode 100644
index 0000000..27585b9
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/exceptions/TypedRequestException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController$1.class
new file mode 100644
index 0000000..8a36946
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.class
new file mode 100644
index 0000000..fad61a5
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/TriggerPolicy/PowerScalingMonitor$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/TriggerPolicy/PowerScalingMonitor$1.class
new file mode 100644
index 0000000..194f227
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/TriggerPolicy/PowerScalingMonitor$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/TriggerPolicy/PowerScalingMonitor.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/TriggerPolicy/PowerScalingMonitor.class
new file mode 100644
index 0000000..cecf9b3
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/TriggerPolicy/PowerScalingMonitor.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/DEMANESResources.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/DEMANESResources.class
new file mode 100644
index 0000000..63d67aa
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/DEMANESResources.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/Events.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/Events.class
new file mode 100644
index 0000000..b6e44e3
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/Events.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/MediatorProperties.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/MediatorProperties.class
new file mode 100644
index 0000000..3113bec
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/MediatorProperties.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/PTActionProperties.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/PTActionProperties.class
new file mode 100644
index 0000000..a0461ad
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/PTActionProperties.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/RadioProperties.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/RadioProperties.class
new file mode 100644
index 0000000..b6f1eb0
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/RadioProperties.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/ReasonerProperties.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/ReasonerProperties.class
new file mode 100644
index 0000000..35b4d03
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/ReasonerProperties.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationContext.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationContext.class
new file mode 100644
index 0000000..5b352e2
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationContext.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationResources.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationResources.class
new file mode 100644
index 0000000..f0ae6f2
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationResources.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/SystemContext.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/SystemContext.class
new file mode 100644
index 0000000..990c006
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/SystemContext.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.class
new file mode 100644
index 0000000..0176fd7
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/TriggerPolicyProperties.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/TriggerPolicyProperties.class
new file mode 100644
index 0000000..68f331d
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/common/TriggerPolicyProperties.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationListener.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationListener.class
new file mode 100644
index 0000000..bb21bb9
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationListener.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager$RadiogramAddress.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager$RadiogramAddress.class
new file mode 100644
index 0000000..04ea6ae
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager$RadiogramAddress.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager$Receiver.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager$Receiver.class
new file mode 100644
index 0000000..c332daf
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager$Receiver.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.class
new file mode 100644
index 0000000..7a9e4e6
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/RemoteManagement.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/RemoteManagement.class
new file mode 100644
index 0000000..4ea241b
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/RemoteManagement.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/RoutingListener.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/RoutingListener.class
new file mode 100644
index 0000000..22dced3
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/communications/RoutingListener.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/datatypes/SunSPOTBundle.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/datatypes/SunSPOTBundle.class
new file mode 100644
index 0000000..57eb082
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/datatypes/SunSPOTBundle.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/deepSleepManagement/IDeepSleepAware.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/deepSleepManagement/IDeepSleepAware.class
new file mode 100644
index 0000000..eead93c
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/deepSleepManagement/IDeepSleepAware.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/DefaultConfig.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/DefaultConfig.class
new file mode 100644
index 0000000..94937dc
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/DefaultConfig.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/ERRORMSG.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/ERRORMSG.class
new file mode 100644
index 0000000..03e65c4
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/ERRORMSG.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/FuzzyDM.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/FuzzyDM.class
new file mode 100644
index 0000000..f164937
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/FuzzyDM.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Interp1DFuzzyDM.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Interp1DFuzzyDM.class
new file mode 100644
index 0000000..7bf7697
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Interp1DFuzzyDM.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/KEY.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/KEY.class
new file mode 100644
index 0000000..05bfcfc
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/KEY.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingController.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingController.class
new file mode 100644
index 0000000..fdf20e0
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingController.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFactory.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFactory.class
new file mode 100644
index 0000000..86c3e00
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFactory.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFuzzyLogic.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFuzzyLogic.class
new file mode 100644
index 0000000..6192d3f
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFuzzyLogic.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerInterp1FDM.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerInterp1FDM.class
new file mode 100644
index 0000000..a57de03
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerInterp1FDM.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/TestFuzzyDM.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/TestFuzzyDM.class
new file mode 100644
index 0000000..b5ce7c7
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/TestFuzzyDM.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Variable.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Variable.class
new file mode 100644
index 0000000..d65ccd2
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Variable.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/ORAMediatorForSunSPOT.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/ORAMediatorForSunSPOT.class
new file mode 100644
index 0000000..1042824
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/ORAMediatorForSunSPOT.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PTAct.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PTAct.class
new file mode 100644
index 0000000..dbefb36
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PTAct.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$1.class
new file mode 100644
index 0000000..2d057fa
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservation.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservation.class
new file mode 100644
index 0000000..02ffea4
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservation.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservationValue.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservationValue.class
new file mode 100644
index 0000000..3c5a919
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor$ReasonObservationValue.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.class
new file mode 100644
index 0000000..675eded
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerTransmissionActuator$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerTransmissionActuator$1.class
new file mode 100644
index 0000000..483c153
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerTransmissionActuator$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerTransmissionActuator$updatePowerTransmissionAction.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerTransmissionActuator$updatePowerTransmissionAction.class
new file mode 100644
index 0000000..f99ec9f
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerTransmissionActuator$updatePowerTransmissionAction.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerTransmissionActuator.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerTransmissionActuator.class
new file mode 100644
index 0000000..692ac3f
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerTransmissionActuator.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$1.class
new file mode 100644
index 0000000..69bb85d
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$updatePowerTransmissionAction.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$updatePowerTransmissionAction.class
new file mode 100644
index 0000000..fa69e9d
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator$updatePowerTransmissionAction.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator.class
new file mode 100644
index 0000000..4cc19e1
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/ResetActuator.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/ResetActuator.class
new file mode 100644
index 0000000..5578c66
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/ResetActuator.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/BatteryLevelObservation.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/BatteryLevelObservation.class
new file mode 100644
index 0000000..87ae8b0
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/BatteryLevelObservation.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservation.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservation.class
new file mode 100644
index 0000000..bde9f29
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservation.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservationExtension.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservationExtension.class
new file mode 100644
index 0000000..adf3d8e
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservationExtension.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationException.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationException.class
new file mode 100644
index 0000000..2543f2a
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactory.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactory.class
new file mode 100644
index 0000000..faa6942
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactory.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactoryException.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactoryException.class
new file mode 100644
index 0000000..0c6f5eb
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactoryException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationType.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationType.class
new file mode 100644
index 0000000..30ff506
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationType.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestController.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestController.class
new file mode 100644
index 0000000..8cda252
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestController.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestObserver$TestObservation1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestObserver$TestObservation1.class
new file mode 100644
index 0000000..faf6300
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestObserver$TestObservation1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestObserver$TestObservation2.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestObserver$TestObservation2.class
new file mode 100644
index 0000000..663d56d
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestObserver$TestObservation2.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestObserver.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestObserver.class
new file mode 100644
index 0000000..dab0b87
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestObserver.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestReasoner.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestReasoner.class
new file mode 100644
index 0000000..737207a
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestReasoner.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestTriggerPolicy$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestTriggerPolicy$1.class
new file mode 100644
index 0000000..2a78538
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestTriggerPolicy$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestTriggerPolicy.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestTriggerPolicy.class
new file mode 100644
index 0000000..bfd12d7
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/tests/TestTriggerPolicy.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$1.class
new file mode 100644
index 0000000..6d00a82
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$Engine.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$Engine.class
new file mode 100644
index 0000000..da46b86
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee$Engine.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee.class
new file mode 100644
index 0000000..909e0cb
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeAddMessageException.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeAddMessageException.class
new file mode 100644
index 0000000..2b395e9
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeAddMessageException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeMessage.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeMessage.class
new file mode 100644
index 0000000..0c0305a
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeMessage.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/LEDArray.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/LEDArray.class
new file mode 100644
index 0000000..b33ba7b
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/LEDArray.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Marquee$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Marquee$1.class
new file mode 100644
index 0000000..82bdd09
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Marquee$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Marquee$Engine.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Marquee$Engine.class
new file mode 100644
index 0000000..f99bd24
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Marquee$Engine.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Marquee.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Marquee.class
new file mode 100644
index 0000000..27432b8
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Marquee.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/MarqueeAddMessageException.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/MarqueeAddMessageException.class
new file mode 100644
index 0000000..1541d73
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/MarqueeAddMessageException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/MarqueeMessage.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/MarqueeMessage.class
new file mode 100644
index 0000000..6b060ae
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/MarqueeMessage.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Switch.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Switch.class
new file mode 100644
index 0000000..b439307
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/hal/Switch.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/logging/Level.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/logging/Level.class
new file mode 100644
index 0000000..73870b0
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/logging/Level.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/logging/Logger.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/logging/Logger.class
new file mode 100644
index 0000000..59b304c
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/logging/Logger.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NDPFactory.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NDPFactory.class
new file mode 100644
index 0000000..c8e4cb0
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NDPFactory.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryException.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryException.class
new file mode 100644
index 0000000..246212d
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryFactoryException.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryFactoryException.class
new file mode 100644
index 0000000..46b7d31
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryFactoryException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryProtocol.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryProtocol.class
new file mode 100644
index 0000000..cbc270b
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryProtocol.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryType.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryType.class
new file mode 100644
index 0000000..286630f
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryType.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$1.class
new file mode 100644
index 0000000..3d37a0a
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$2.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$2.class
new file mode 100644
index 0000000..f533248
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation$2.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation.class
new file mode 100644
index 0000000..e5b936d
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDInformation.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDTimer.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDTimer.class
new file mode 100644
index 0000000..4163494
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NDTimer.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NeighborsDiscoveryMgr.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NeighborsDiscoveryMgr.class
new file mode 100644
index 0000000..c28a876
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1$NeighborsDiscoveryMgr.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1.class
new file mode 100644
index 0000000..757ea97
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDInformation.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDInformation.class
new file mode 100644
index 0000000..94e7d9a
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDInformation.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDTimer.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDTimer.class
new file mode 100644
index 0000000..288d3e3
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NDTimer.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NeighborsDiscoveryMgr.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NeighborsDiscoveryMgr.class
new file mode 100644
index 0000000..92fb993
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2$NeighborsDiscoveryMgr.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2.class
new file mode 100644
index 0000000..9c9b899
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$1.class
new file mode 100644
index 0000000..e6b64bf
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$NDEngine.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$NDEngine.class
new file mode 100644
index 0000000..fc66f86
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery$NDEngine.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery.class
new file mode 100644
index 0000000..b5ba1ab
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryCommunicationsListener.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryCommunicationsListener.class
new file mode 100644
index 0000000..8160c33
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryCommunicationsListener.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryListener.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryListener.class
new file mode 100644
index 0000000..b6160d8
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryListener.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryOriginal$1.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryOriginal$1.class
new file mode 100644
index 0000000..1f137c2
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryOriginal$1.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryOriginal.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryOriginal.class
new file mode 100644
index 0000000..a26583c
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryOriginal.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryRequester.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryRequester.class
new file mode 100644
index 0000000..1b014de
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryRequester.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborTableManager.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborTableManager.class
new file mode 100644
index 0000000..64ef71c
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborTableManager.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDU.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDU.class
new file mode 100644
index 0000000..0247a75
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDU.class differ
diff --git a/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDUException.class b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDUException.class
new file mode 100644
index 0000000..5f6e6cd
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDUException.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/Action.class b/j2meclasses/eu/artemis/demanes/reconfiguration/Action.class
new file mode 100644
index 0000000..5ad79dd
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/Action.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/ActionProvider.class b/j2meclasses/eu/artemis/demanes/reconfiguration/ActionProvider.class
new file mode 100644
index 0000000..653fd9a
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/ActionProvider.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/Actuator.class b/j2meclasses/eu/artemis/demanes/reconfiguration/Actuator.class
new file mode 100644
index 0000000..08dfb43
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/Actuator.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/ActuatorRegistry.class b/j2meclasses/eu/artemis/demanes/reconfiguration/ActuatorRegistry.class
new file mode 100644
index 0000000..cc42a2f
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/ActuatorRegistry.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/ORAMediator.class b/j2meclasses/eu/artemis/demanes/reconfiguration/ORAMediator.class
new file mode 100644
index 0000000..89d6eed
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/ORAMediator.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/Observation.class b/j2meclasses/eu/artemis/demanes/reconfiguration/Observation.class
new file mode 100644
index 0000000..42af3ff
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/Observation.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/ObservationProvider.class b/j2meclasses/eu/artemis/demanes/reconfiguration/ObservationProvider.class
new file mode 100644
index 0000000..85935e7
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/ObservationProvider.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/Observer.class b/j2meclasses/eu/artemis/demanes/reconfiguration/Observer.class
new file mode 100644
index 0000000..309c744
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/Observer.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/ObserverRegistry.class b/j2meclasses/eu/artemis/demanes/reconfiguration/ObserverRegistry.class
new file mode 100644
index 0000000..dc6a6bd
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/ObserverRegistry.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/Reason.class b/j2meclasses/eu/artemis/demanes/reconfiguration/Reason.class
new file mode 100644
index 0000000..559370d
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/Reason.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/Reasoner.class b/j2meclasses/eu/artemis/demanes/reconfiguration/Reasoner.class
new file mode 100644
index 0000000..6e34533
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/Reasoner.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/TriggerPolicy.class b/j2meclasses/eu/artemis/demanes/reconfiguration/TriggerPolicy.class
new file mode 100644
index 0000000..7544269
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/TriggerPolicy.class differ
diff --git a/j2meclasses/eu/artemis/demanes/reconfiguration/Triggerable.class b/j2meclasses/eu/artemis/demanes/reconfiguration/Triggerable.class
new file mode 100644
index 0000000..48597fd
Binary files /dev/null and b/j2meclasses/eu/artemis/demanes/reconfiguration/Triggerable.class differ
diff --git a/licences/APGL-3.0 b/licences/APGL-3.0
new file mode 100644
index 0000000..dba13ed
--- /dev/null
+++ b/licences/APGL-3.0
@@ -0,0 +1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+.
diff --git a/licences/Apache-2.0 b/licences/Apache-2.0
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/licences/Apache-2.0
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/licences/License b/licences/License
new file mode 100644
index 0000000..4e6f27d
--- /dev/null
+++ b/licences/License
@@ -0,0 +1,24 @@
+Copyright (C) 2013-2015 Universidad Politécnica de Madrid (UPM)
+Some parts of this code are Copyright (C) 2013-2015 DEMANES
+
+Parts copyrighted by Universidad Politécnica de Madrid (UPM) are distributed
+under a dual license scheme:
+
+- For academic uses: Licensed under GNU Affero General Public License as
+ published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any
+ later version.
+
+
+- For any other use: Licensed under the Apache License, Version 2.0.
+
+Parts copyrighted by DEMANES are distributed under the Apache License, Version 2.0.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+Terms for GNU Affero General Public License version 3 are detailed in the file
+licenses/AGPL-3.0
+
+Terms for Apache License version 2.0 are detailed in the file licenses/Apache-2.0
\ No newline at end of file
diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
new file mode 100644
index 0000000..1493d29
--- /dev/null
+++ b/nbproject/private/private.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ file:/home/grys/NetBeansProjects/Release%20Version/PowerScaling@SunSPOT/src/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.java
+ file:/home/grys/NetBeansProjects/Release%20Version/PowerScaling@SunSPOT/License
+ file:/home/grys/NetBeansProjects/Release%20Version/PowerScaling@SunSPOT/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.java
+ file:/home/grys/NetBeansProjects/Release%20Version/PowerScaling@SunSPOT/src/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.java
+ file:/home/grys/NetBeansProjects/Release%20Version/PowerScaling@SunSPOT/src/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.java
+ file:/home/grys/NetBeansProjects/Release%20Version/PowerScaling@SunSPOT/src/eu/artemis/demanes/datatypes/ANES_BUNDLE.java
+
+
+
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000..ee6eeb9
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,88 @@
+
+
+
+ org.netbeans.modules.ant.freeform
+
+
+ PowerScaling@SunSPOT
+
+ ${user.home}/.sunspot.properties
+ build.properties
+ ${sunspot.home}/default.properties
+
+
+
+
+ java
+ src
+
+
+
+
+ jar-app
+
+
+ clean
+
+
+ deploy
+ run
+
+
+ clean
+ jar-app
+
+
+ javadoc
+
+
+
+ folder
+ build
+ jar-app
+
+
+
+
+
+ src
+
+
+ build.xml
+
+
+
+
+
+
+
+
+
+
+ deploy
+
+
+
+ jar-deploy
+
+
+
+
+
+
+
+
+ src
+ ${sunspot.bootclasspath}
+ ${user.home}/SunSPOT/sdk-teal-120517/lib/edemo_device.jar;${user.home}/SunSPOT/sdk-teal-120517/lib/espot_device.jar;${user.home}/SunSPOT/sdk-teal-120517/lib/ieee_802_15_4_common.jar;${user.home}/SunSPOT/sdk-teal-120517/lib/ipv6_common.jar;${user.home}/SunSPOT/sdk-teal-120517/lib/multihop_common.jar;${user.home}/SunSPOT/sdk-teal-120517/lib/ota_espot_common.jar;${user.home}/SunSPOT/sdk-teal-120517/lib/spot_core_common.jar;${user.home}/SunSPOT/sdk-teal-120517/lib/spot_core_device.jar
+ build
+ 1.4
+
+
+
+
diff --git a/resources/CR_FDM_ND_v1.ini b/resources/CR_FDM_ND_v1.ini
new file mode 100644
index 0000000..96717d7
--- /dev/null
+++ b/resources/CR_FDM_ND_v1.ini
@@ -0,0 +1,16 @@
+NumInputs=1
+NumOutputs=1
+
+VarID_1=e_nd
+VarType_1=IN
+VarMIN_1=-2
+VarMAX_1=2
+
+VarID_2=du_cr
+VarType_2=OUT
+VarMIN_2=-1
+VarMAX_2=1
+
+NumPoints=5
+e_nd=-1.5, -0.1, 0.0, 1.0, 1.5
+du_cr=-1.0, -1.0, 0.0, 1.0, 1.0
diff --git a/resources/META-INF/MANIFEST.MF b/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..6409376
--- /dev/null
+++ b/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+MIDlet-Name: PowerScalingSunSPOT
+MIDlet-Version: 1.0.0
+MIDlet-Vendor: UNIVERSIDAD POLITECNICA DE MADRID (UPM)
+MIDlet-Description: Power Scaling Controller for CMS Pilot in DEMANES Project
+MIDlet-1: PowerScalingSunSPOT, , eu.artemis.demanes.impl.SunSPOT.SunSPOTPowerController
+MicroEdition-Profile: IMP-1.0
+MicroEdition-Configuration: CLDC-1.1
diff --git a/resources/NDr_FDM_E_v1.ini b/resources/NDr_FDM_E_v1.ini
new file mode 100644
index 0000000..efce7d9
--- /dev/null
+++ b/resources/NDr_FDM_E_v1.ini
@@ -0,0 +1,16 @@
+NumInputs=1
+NumOutputs=1
+
+VarID_1=e_E
+VarType_1=IN
+VarMIN_1=-2
+VarMAX_1=2
+
+VarID_2=du_nd
+VarType_2=OUT
+VarMIN_2=-1
+VarMAX_2=1
+
+NumPoints=5
+e_E=-1.5, -1.0, 0.0, 1.0, 1.5
+du_nd=-1.0, -1.0, 0.0, 1.0, 1.0
diff --git a/resources/reconfiguration.conf b/resources/reconfiguration.conf
new file mode 100644
index 0000000..93992e0
--- /dev/null
+++ b/resources/reconfiguration.conf
@@ -0,0 +1 @@
+trigger.interval=5000
diff --git a/src/eu/artemis/demanes/datatypes/ANES_BUNDLE.java b/src/eu/artemis/demanes/datatypes/ANES_BUNDLE.java
new file mode 100644
index 0000000..6320073
--- /dev/null
+++ b/src/eu/artemis/demanes/datatypes/ANES_BUNDLE.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.datatypes;
+
+import eu.artemis.demanes.exceptions.NonExistentKeyException;
+import eu.artemis.demanes.exceptions.TypedRequestException;
+
+/**
+ * ANES_BUNDLE (for SunSPOT)
+ *
+ * @author DEMANES
+ * @version 0.1
+ * @since 27 nov. 2013
+ *
+ * @author Néstor Lucas Martínez
+ * @version 0.2
+ */
+
+public interface ANES_BUNDLE {
+
+ public ANES_BUNDLE clone();
+
+ public boolean containsKey(String key);
+
+ public boolean containsKey(String key, Class clazz);
+
+ public Object get(String key) throws NonExistentKeyException;
+
+ public Object get(String key, Class clazz) throws TypedRequestException,
+ NonExistentKeyException;
+
+ public Class getType(String key) throws NonExistentKeyException;
+
+ public void put(String key, Object value);
+
+}
diff --git a/src/eu/artemis/demanes/datatypes/ANES_URN.java b/src/eu/artemis/demanes/datatypes/ANES_URN.java
new file mode 100644
index 0000000..cb1fe59
--- /dev/null
+++ b/src/eu/artemis/demanes/datatypes/ANES_URN.java
@@ -0,0 +1,184 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.datatypes;
+
+import com.sun.spot.espot.peripheral.ota.URL;
+
+/**
+ * ANES_URN (for SunSPOT)
+ *
+ * @author DEMANES
+ * @version 0.1
+ * @since 27 nov. 2013
+ *
+ * @author Néstor Lucas Martínez
+ * @version 0.2
+ */
+
+public class ANES_URN {
+
+ private static final String DEMANES_NID = "demanes";
+ private static final String URN_PREFIX = "urn:";
+
+ /**
+ * Creates an instance of ANES_URN and throws a runtime exception if its
+ * syntax is not valid.
+ *
+ * @param text The text of the URN
+ * @return The URN created
+ * @throws ANES_URN_Exception the exception generated if the syntax is not
+ * correct.
+ */
+ public static ANES_URN create(final String text) throws ANES_URN_Exception {
+ return new ANES_URN(text);
+ }
+
+ /**
+ * Is it a valid ANES_URN?
+ *
+ * @param text The text to validate
+ * @return Yes of no
+ */
+ public static boolean isValid(final String text) {
+ return text.toLowerCase().startsWith(URN_PREFIX + DEMANES_NID);
+ }
+
+ /**
+ * The basic information container for this type.
+ */
+ private final String urn;
+
+ /**
+ * Public constructor.
+ *
+ * @param text The text of the URN
+ * @throws ANES_URN_Exception If syntax is not correct
+ */
+ public ANES_URN(final String text) throws ANES_URN_Exception {
+ this.urn = text;
+ }
+
+ /**
+ * Public constructor.
+ *
+ * @param nid The namespace ID
+ * @param nss The namespace specific string
+ */
+ public ANES_URN(final String nid, final String nss) {
+ this.urn = URN_PREFIX + nid + ":" + nss;
+ }
+
+ /**
+ * @param urn
+ * @return
+ */
+ public int compareTo(final ANES_URN urn) {
+ return this.urn.compareTo(urn.urn);
+ }
+
+ /**
+ * @param obj
+ * @return
+ */
+ public boolean equals(final Object obj) {
+ if (this.getClass().equals(obj.getClass())) {
+ return this.urn.equalsIgnoreCase(((ANES_URN) obj).toString());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @return
+ */
+ public int hashCode() {
+ return this.urn.hashCode();
+ }
+
+ /**
+ * Whether this URN has params?
+ *
+ * @return Has them?
+ */
+ public boolean hasParams() {
+ return this.urn.indexOf("?") != -1;
+ }
+
+ /**
+ * Is this ANES_URN empty?
+ *
+ * @return true if this ANES_URN is empty, false otherwise.
+ */
+ public boolean isEmpty() {
+ return this.urn.length() == 0;
+ }
+
+ /**
+ * Does it match the pattern?
+ *
+ * @param pattern The pattern to match
+ * @return Yes of no
+ */
+ public boolean matches(final String pattern) {
+ return this.urn.regionMatches(true, 0, pattern, 0, pattern.length());
+ }
+
+ /**
+ * Get namespace ID.
+ *
+ * @return Namespace ID
+ */
+ public String nid() {
+ if (this.urn.toLowerCase().startsWith(URN_PREFIX)) {
+ return this.urn.substring(URN_PREFIX.length(), this.urn.indexOf(":", URN_PREFIX.length()));
+ }
+ else {
+ return "";
+ }
+ }
+
+ /**
+ * Get namespace specific string.
+ *
+ * @return Namespace specific string
+ */
+ public String nss() {
+ if (this.urn.toLowerCase().startsWith(URN_PREFIX + DEMANES_NID)) {
+ return this.urn.substring((URN_PREFIX + DEMANES_NID).length(), this.urn.indexOf(":", (URN_PREFIX + DEMANES_NID).length()));
+ }
+ else {
+ return "";
+ } }
+
+ /**
+ * Returns a string representation of this object.
+ *
+ * @return A string representation of this object.
+ */
+ public String toString() {
+ return this.urn;
+ }
+
+ /**
+ * Convert it to URL.
+ *
+ * @return The URL
+ */
+ public URL toURL() {
+ return new URL(this.urn);
+ }
+
+}
diff --git a/src/eu/artemis/demanes/datatypes/ANES_URN_Exception.java b/src/eu/artemis/demanes/datatypes/ANES_URN_Exception.java
new file mode 100644
index 0000000..24c0260
--- /dev/null
+++ b/src/eu/artemis/demanes/datatypes/ANES_URN_Exception.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.datatypes;
+
+/**
+ * ANES_URN_Exception
+ *
+ * @author DEMANES
+ * @version 0.1
+ * @since 27 nov. 2013
+ */
+public class ANES_URN_Exception extends Exception {
+ public ANES_URN_Exception() {
+ super();
+ }
+
+ public ANES_URN_Exception(String e) {
+ super(e);
+ }
+}
diff --git a/src/eu/artemis/demanes/exceptions/ActionInvocationException.java b/src/eu/artemis/demanes/exceptions/ActionInvocationException.java
new file mode 100644
index 0000000..83800d1
--- /dev/null
+++ b/src/eu/artemis/demanes/exceptions/ActionInvocationException.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.exceptions;
+
+import eu.artemis.demanes.datatypes.ANES_URN;
+
+/**
+ * An ActionInvocationException is thrown to indicate that an error occurred
+ * during the invocation of an {@linkplain Action}. The original exception is
+ * added as a cause.
+ *
+ * @see eu.artemis.demanes.reconfiguration.Action#invoke
+ *
+ * @author leeuwencjv
+ * @version 0.1
+ * @since 9 apr. 2014
+ *
+ */
+public class ActionInvocationException extends Exception {
+
+ private static final long serialVersionUID = -4022985095456964143L;
+
+ /**
+ * @param urn
+ * The URN of the Action that threw the exception when invoking
+ * @param e
+ * The original exception that occurred during invocation
+ */
+ public ActionInvocationException(ANES_URN urn, Exception e) {
+ super("Error while invokin Action with urn " + urn + "\n" + e.toString());
+ }
+
+}
diff --git a/src/eu/artemis/demanes/exceptions/InexistentActionID.java b/src/eu/artemis/demanes/exceptions/InexistentActionID.java
new file mode 100644
index 0000000..42514ab
--- /dev/null
+++ b/src/eu/artemis/demanes/exceptions/InexistentActionID.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.exceptions;
+
+import eu.artemis.demanes.datatypes.ANES_URN;
+
+/**
+ * An InexistentActionID is thrown when an Action is referenced using a ANES_URN
+ * that is unknown to the receiver object.
+ *
+ * @author leeuwencjv
+ * @version 0.1
+ * @since 9 apr. 2014
+ *
+ */
+public class InexistentActionID extends Exception {
+
+ private static final long serialVersionUID = 1996097768538949995L;
+
+ /**
+ * @param id
+ */
+ public InexistentActionID(ANES_URN id) {
+ super("No action available with id " + id);
+ }
+
+}
diff --git a/src/eu/artemis/demanes/exceptions/InexistentObservationID.java b/src/eu/artemis/demanes/exceptions/InexistentObservationID.java
new file mode 100644
index 0000000..ef90338
--- /dev/null
+++ b/src/eu/artemis/demanes/exceptions/InexistentObservationID.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.exceptions;
+
+import eu.artemis.demanes.datatypes.ANES_URN;
+
+/**
+ * An InexistentObservationID is thrown when an Observation is referenced using
+ * a ANES_URN that is unknown to the receiver object.
+ *
+ * @author leeuwencjv
+ * @version 0.1
+ * @since 9 apr. 2014
+ *
+ */
+public class InexistentObservationID extends Exception {
+
+ private static final long serialVersionUID = -8562339554192680556L;
+
+ /**
+ * @param id
+ */
+ public InexistentObservationID(ANES_URN id) {
+ super("No observation available with id " + id);
+ }
+
+}
diff --git a/src/eu/artemis/demanes/exceptions/NonExistentKeyException.java b/src/eu/artemis/demanes/exceptions/NonExistentKeyException.java
new file mode 100644
index 0000000..1941f17
--- /dev/null
+++ b/src/eu/artemis/demanes/exceptions/NonExistentKeyException.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.exceptions;
+
+/**
+ * NonExistentKeyException
+ *
+ * @author leeuwencjv
+ * @version 0.1
+ * @since 10 apr. 2014
+ *
+ */
+public class NonExistentKeyException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7933005603571177441L;
+
+ public NonExistentKeyException(String key) {
+ super("Non existent key " + key + " in bundle");
+ }
+
+}
diff --git a/src/eu/artemis/demanes/exceptions/ObservationInvocationException.java b/src/eu/artemis/demanes/exceptions/ObservationInvocationException.java
new file mode 100644
index 0000000..296ce26
--- /dev/null
+++ b/src/eu/artemis/demanes/exceptions/ObservationInvocationException.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.exceptions;
+
+import eu.artemis.demanes.datatypes.ANES_URN;
+
+/**
+ * An ObservationInvocationException is thrown to indicate that an error
+ * occurred during the invocation of an {@linkplain Observation}. The original
+ * exception is added as a cause.
+ *
+ * @see eu.artemis.demanes.reconfiguration.Observation#getValue
+ *
+ * @author leeuwencjv
+ * @version 0.1
+ * @since 9 apr. 2014
+ *
+ */
+public class ObservationInvocationException extends Exception {
+
+ private static final long serialVersionUID = 4874935197610473240L;
+
+ /**
+ * @param urn
+ * the URN of the Observation that threw the exception when
+ * invoking
+ * @param e
+ * the original exception that occurred during invocation
+ */
+ public ObservationInvocationException(ANES_URN urn, Exception e) {
+ super("Error while invoking Observation with urn " + urn + "\n" + e.toString());
+ }
+
+}
diff --git a/src/eu/artemis/demanes/exceptions/TypedRequestException.java b/src/eu/artemis/demanes/exceptions/TypedRequestException.java
new file mode 100644
index 0000000..8a55707
--- /dev/null
+++ b/src/eu/artemis/demanes/exceptions/TypedRequestException.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.exceptions;
+
+/**
+ * TypedRequestException
+ *
+ * @author leeuwencjv
+ * @version 0.1
+ * @since 10 apr. 2014
+ *
+ */
+public class TypedRequestException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2614277490603022155L;
+
+ public TypedRequestException(Class foundType, Class requestedType) {
+ super("Unexpected type " + foundType.getName()
+ + " encountered, when type " + requestedType.getName()
+ + " was requested.");
+ }
+
+ public TypedRequestException(Class requestedType,
+ ClassCastException cause) {
+ super("Error in casting value to " + requestedType.getName() + "\n" +
+ cause.toString());
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.java b/src/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.java
new file mode 100644
index 0000000..0dc42e9
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/SunSPOTPowerController.java
@@ -0,0 +1,368 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ *
+ */
+package eu.artemis.demanes.impl.SunSPOT;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.core.resources.transducers.ISwitch;
+import com.sun.spot.core.resources.transducers.ISwitchListener;
+import com.sun.spot.core.resources.transducers.LEDColor;
+import com.sun.spot.core.resources.transducers.SwitchEvent;
+import com.sun.spot.core.util.Properties;
+import com.sun.spot.multihop.radio.LowPan;
+import com.sun.spot.multihop.radio.mhrp.lqrp.LQRPManager;
+import eu.artemis.demanes.impl.SunSPOT.common.RadioProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.ReconfigurationContext;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemProperties;
+import eu.artemis.demanes.impl.SunSPOT.communications.RemoteManagement;
+import eu.artemis.demanes.impl.SunSPOT.communications.RoutingListener;
+import eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner.PowerScalingControllerFactory;
+import eu.artemis.demanes.impl.SunSPOT.reconfiguration.ORAMediatorForSunSPOT;
+import eu.artemis.demanes.impl.SunSPOT.reconfiguration.PowerScalingMonitor.PowerScalingMonitor;
+import eu.artemis.demanes.impl.SunSPOT.reconfiguration.actions.PowerTransmissionActuator;
+import eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.Marquee;
+import eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.MarqueeAddMessageException;
+import eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.MarqueeMessage;
+import eu.artemis.demanes.reconfiguration.ORAMediator;
+import eu.artemis.demanes.reconfiguration.Reasoner;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.microedition.midlet.MIDlet;
+import javax.microedition.midlet.MIDletStateChangeException;
+import javax.microedition.rms.RecordEnumeration;
+import javax.microedition.rms.RecordStore;
+import javax.microedition.rms.RecordStoreException;
+
+/**
+ * The startApp method of this class is called by the VM to start the
+ * application.
+ *
+ * The manifest specifies this class as MIDlet-1, which means it will be
+ * selected for execution.
+ *
+ * @author Néstor Lucas Martínez
+ * @author Yuanjiang Huang
+ * @version 1.0.0
+ */
+public class SunSPOTPowerController extends MIDlet implements ISwitchListener {
+
+ private static Properties reconfigurationProperties;
+ private SystemContext context;
+ private Integer marqueeMessageID;
+ private MarqueeMessage midletMessage;
+
+ protected void startApp() throws MIDletStateChangeException {
+
+ // The switches each have a tag: "SW1" for the left, and "SW2" for the right
+ ISwitch sw1 = (ISwitch) Resources.lookup(ISwitch.class, "SW1");
+ ISwitch sw2 = (ISwitch) Resources.lookup(ISwitch.class, "SW2");
+
+ sw1.addISwitchListener(this);
+ sw2.addISwitchListener(this);
+
+ // Initalize private attributes
+ midletMessage = new MarqueeMessage();
+
+ // This is just a guide for the basic deployment of components
+ // STEP 1.1
+ // Define the context variables the system.
+ // NOTE: The asignment of properties can be done in a separate class.
+ reconfigurationProperties = init();
+
+ // STEP 1.2
+ // Create a System context.
+ context = new SystemContext();
+
+ // STEP 1.3
+ // First midlet marquee
+ try {
+ midletMessage.setMessageAtPosition(0, LEDColor.GREEN);
+ SystemContext.getMarquee().setStatusIndicator(Marquee.STATUS_IS_STANDBY);
+ marqueeMessageID = (Integer) SystemContext.getMarquee().addMessage(midletMessage);
+ SystemContext.getMarquee().setUpdatingInterval(1);
+ } catch (MarqueeAddMessageException ex) {
+ SystemContext.getMarquee().setStatusIndicator(Marquee.STATUS_IS_NOT_READY);
+ }
+
+ // STEP 1.4
+ // If connected to an USB port then print license and dump record store history
+ midletMessage.setMessageAtPosition(0, LEDColor.WHITE);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+ if (SystemContext.isUSBConnected()) {
+ printLicense();
+ dumpRecordHistory();
+ }
+ midletMessage.setMessageAtPosition(0, LEDColor.GREEN);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+
+ // STEP 2
+ midletMessage.setMessageAtPosition(1, LEDColor.WHITE);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+ // Instantiate the components of the system.
+ // NOTE: Please, pay attention to the order of creation of the objects.
+ // For the reconfiguration components...
+
+ // STEP 2.1
+ // Create the observers...
+ PowerScalingMonitor powerScalingMonitor = new PowerScalingMonitor(context, reconfigurationProperties);
+
+ // ... and the actuators
+ PowerTransmissionActuator ptactuator = new PowerTransmissionActuator(reconfigurationProperties);
+ context.setPTACT(ptactuator);
+
+ // Notify user through marquee
+ midletMessage.setMessageAtPosition(1, LEDColor.GREEN);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+
+ // STEP 2.2
+ // Create the reasoner
+ midletMessage.setMessageAtPosition(2, LEDColor.WHITE);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+
+ //PowerScalingController pscontroller = new PowerScalingController(reconfigurationContext);
+ //Reasoner reasoner = PowerScalingControllerFactory.getInstance("PTjFuzzyLogic", reconfigurationContext);
+ //Reasoner reasoner = PowerScalingControllerFactory.getInstance("PTSimple", reconfigurationContext);
+ Reasoner reasoner = PowerScalingControllerFactory.getInstance("PTInterp1DFDM", reconfigurationProperties);
+
+ midletMessage.setMessageAtPosition(2, LEDColor.GREEN);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+
+ // Create the trigger policy...
+ // ... already done because in our case is the same as the PowerScalingMonitor
+ midletMessage.setMessageAtPosition(3, LEDColor.WHITE);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+
+ // Create the mediator
+ // This can also be recoded for using a Mediator factory
+ // This can be modified to pass some context information if required.
+ ORAMediator mediator = new ORAMediatorForSunSPOT();
+
+ midletMessage.setMessageAtPosition(3, LEDColor.GREEN);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+
+ // STEP 3
+ // Register and start the components of the system.
+ // For the reconfiguration components...
+ midletMessage.setMessageAtPosition(4, LEDColor.WHITE);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+
+ // Register the observers in the mediator
+ mediator.registerObserver(powerScalingMonitor);
+
+ // Register the actuators in the mediator
+ mediator.registerActuator(ptactuator);
+
+ // Register the reasoner in the mediator;
+ mediator.setReasoner(reasoner);
+
+ // Register the trigger policy in the mediator;
+ mediator.setTriggeringPolicy(powerScalingMonitor); // At this point the mediator starts the trigger policy after setting it.
+
+ midletMessage.setMessageAtPosition(4, LEDColor.GREEN);
+ SystemContext.getMarquee().updateMessage(marqueeMessageID, midletMessage);
+
+ // Everything is launched an running properly
+ SystemContext.getMarquee().setStatusIndicator(Marquee.STATUS_IS_READY);
+ SystemContext.getMarquee().setUpdatingInterval(Marquee.MINIMUM_INTERVAL);
+ SystemContext.getMarquee().clearMarquee();
+
+ // This is just for blinking in routing activities
+ RoutingListener rl = new RoutingListener();
+ LQRPManager.getInstance().addLQRPListener(rl);
+ LowPan.getInstance().addDataEventListener(rl);
+
+ // STEP 4
+ // Launch remote management thread
+ (new Thread(new RemoteManagement(reconfigurationProperties))).start();
+ }
+
+ protected void pauseApp() {
+ // This is not currently called by the Squawk VM
+ }
+
+ /**
+ * Called if the MIDlet is terminated by the system. It is not called if
+ * MIDlet.notifyDestroyed() was called.
+ *
+ * @param unconditional If true the MIDlet must cleanup and release all
+ * resources.
+ */
+ protected void destroyApp(boolean unconditional) throws MIDletStateChangeException { }
+
+ private Properties init() {
+ // STEP 1
+ // Sets the spot to use the minimum power of transmission
+ //((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).setOutputPower(RadioProperties.MINIMUM_POWER_TRANSMISSION);
+
+ // STEP 2
+ // Create default properties
+ ReconfigurationContext reconfigurationContext = new ReconfigurationContext();
+ reconfigurationProperties = new Properties(reconfigurationContext.getProperties());
+
+ // STEP 3.1
+ // Add system properties
+ if (System.getProperty(SystemProperties.SPOT_URN_NSS) != null) {
+ reconfigurationProperties.setProperty(SystemProperties.SPOT_URN_NSS, System.getProperty(SystemProperties.SPOT_URN_NSS));
+ }
+
+ if (System.getProperty(SystemProperties.LOG_LEVEL) != null) {
+ reconfigurationProperties.setProperty(SystemProperties.LOG_LEVEL, System.getProperty(SystemProperties.LOG_LEVEL));
+ }
+
+ if (System.getProperty(SystemProperties.LOG_DESTINATION) != null) {
+ reconfigurationProperties.setProperty(SystemProperties.LOG_DESTINATION, System.getProperty(SystemProperties.LOG_DESTINATION));
+ }
+
+ // STEP 3.2
+ // Add other system properties
+ reconfigurationProperties.setProperty(SystemProperties.BASESTATION_ADDR_PROPERTY, SystemProperties.DEFAULT_BS_ADDRESS);
+ reconfigurationProperties.setProperty(SystemProperties.BASESTATION_PORT, Integer.toString(SystemProperties.DEFAULT_BS_PORT));
+ reconfigurationProperties.setProperty(SystemProperties.EXECUTION_CONTEXT, Integer.toString(SystemProperties.DEFAULT_EXECUTION_CONTEXT));
+ reconfigurationProperties.setProperty(SystemProperties.REMOTE_MANAGEMENT_PORT, Integer.toString(SystemProperties.DEFAULT_REMOTE_MANAGEMENT_PORT));
+
+ // STEP 4
+ // Add running environment properties
+ reconfigurationProperties.setProperty("reset", "true");
+ reconfigurationProperties.setProperty("ptx", Integer.toString(RadioProperties.MINIMUM_POWER_TRANSMISSION));
+ reconfigurationProperties.setProperty("reasoning.status", "started");
+
+ // STEP 5
+ // Load properties file
+ InputStream reconfFile = this.getClass().getResourceAsStream("/reconfiguration.conf");
+
+ if (reconfFile != null) {
+ try {
+ reconfigurationProperties.load(reconfFile);
+ } catch (IOException ex) {
+ // Do nothing
+ }
+ }
+
+ // STEP 6
+ // Update calculated properties
+ reconfigurationProperties = reconfigurationContext.updateProperties(reconfigurationProperties);
+
+ // STEP 7
+ // Return
+ return reconfigurationProperties;
+ }
+
+ private void printLicense() {
+ System.out.println("Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).\n"
+ + "Some parts Copyright 2013-2015 DEMANES.\n"
+ + "\n"
+ + "Authors:\n"
+ + " José-Fernan Martínez Ortega\n"
+ + " Vicente Hernández Díaz\n"
+ + " Néstor Lucas Martínez\n"
+ + " Yuanjiang Huang\n"
+ + " Raúl del Toro Matamoros\n"
+ + "\n"
+ + "Parts copyrighted by Universidad Politécnica de Madrid (UPM) are distributed\n"
+ + "under a dual license scheme:\n"
+ + "\n"
+ + " - For academic uses: Licensed under GNU Affero General Public License as\n"
+ + " published by the Free Software Foundation, either\n"
+ + " version 3 of the License, or (at your option) any\n"
+ + " later version.\n"
+ + " \n"
+ + " - For any other use: Licensed under the Apache License, Version 2.0.\n"
+ + "\n"
+ + "Parts copyrighted by DEMANES are distributed under the Apache License, Version 2.0.\n"
+ + "\n"
+ + "Unless required by applicable law or agreed to in writing, software\n"
+ + "distributed under the License is distributed on an \"AS IS\" BASIS,\n"
+ + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
+ + " \n"
+ + "You can get a copy of the license terms in licences/LICENSE.\n"
+ + "\n.");
+ }
+
+ private void dumpRecordHistory() {
+ synchronized (this) {
+ String[] recordStoreList = RecordStore.listRecordStores();
+ if ((recordStoreList != null) && (recordStoreList.length > 0)) {
+ for (int recordStoreIndex = 0; recordStoreIndex < recordStoreList.length; recordStoreIndex++) {
+ try {
+ RecordStore recordStore = RecordStore.openRecordStore(recordStoreList[recordStoreIndex], false);
+ System.out.println("Accessing record store \"" + recordStoreList[recordStoreIndex] + "\" with " + recordStore.getNumRecords() + " records");
+ RecordEnumeration recordEnumeration = recordStore.enumerateRecords(null, null, true);
+ while (recordEnumeration.hasNextElement()) {
+ ByteArrayInputStream bais = new ByteArrayInputStream(recordEnumeration.nextRecord());
+ DataInputStream dis = new DataInputStream(bais);
+
+ byte[] in = new byte[dis.available()];
+ dis.read(in);
+ System.out.println(new String(in));
+ }
+ System.out.println("Read " + recordStore.getNumRecords() + " records");
+ recordStore.closeRecordStore();
+ } catch (RecordStoreException ex) {
+ System.err.println("Exception trying to access record store " + recordStoreList[recordStoreIndex]);
+ ex.printStackTrace();
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ } else {
+ System.out.println("No record stores found!!!");
+ }
+ }
+ }
+
+ private void deleteRecordHistory() {
+ synchronized (this) {
+ String[] recordStoreList = RecordStore.listRecordStores();
+ if ((recordStoreList != null) && (recordStoreList.length
+ > 0)) {
+ for (int recordStoreIndex = 0; recordStoreIndex < recordStoreList.length; recordStoreIndex++) {
+ try {
+ RecordStore.deleteRecordStore(recordStoreList[recordStoreIndex]);
+ } catch (RecordStoreException ex) {
+ System.err.println("Exception trying to access record store " + recordStoreList[recordStoreIndex]);
+ ex.printStackTrace();
+ }
+ }
+ } else {
+ System.out.println("No record stores found!!!");
+ }
+ }
+ }
+
+ public void switchPressed(SwitchEvent evt) {
+ if (SystemContext.isUSBConnected()) {
+ deleteRecordHistory();
+ System.out.println("Records deleted");
+ }
+ }
+
+ public void switchReleased(SwitchEvent evt) {
+
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/DEMANESResources.java b/src/eu/artemis/demanes/impl/SunSPOT/common/DEMANESResources.java
new file mode 100644
index 0000000..d736f61
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/DEMANESResources.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+/**
+ * DEMANES {@code Obervation} and {@code Action} resource URN
+ *
+ * @author Vicente HErnández Dí
+ * @version 1.0.0
+ */
+public class DEMANESResources {
+ /** Battery Level Observation URN. */
+ public static final String BLObservationURN = "urn:demanes:cmsdemo:observation:BLObservation";
+ /** Node Degree Observation URN. */
+ public static final String NDObservationURN = "urn:demanes:cmsdemo:observation:NDObservation";
+ /** Power Transmission Action URN. */
+ public static final String PTActionURN = "urn:demanes:cmsdemo:action:updatePowerTransmission";
+ /** Trigger Reason Observation URN. */
+ public static final String TriggerReasonURN = "urn:demanes:cmsdemo:observation:TriggerReason";
+ /** Trigger Reason Value Observation URN. */
+ public static final String TriggerReasonValueURN = "urn:demanes:cmsdemo:observation:TriggerReasonValue";
+
+ /** Variable name for DELTA CR. */
+ public static final String DELTA_CR_KEY = "delta_cr";
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/Events.java b/src/eu/artemis/demanes/impl/SunSPOT/common/Events.java
new file mode 100644
index 0000000..da13cb4
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/Events.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+
+/**
+ * Events urns used by the {@code PowerScalingMonitor}.
+ *
+ * @author Vicente Hernández Dí
+ * @version 1.0.0
+ */
+public class Events{
+ /** Battery Level Event. */
+ public static final String BL_EVENT = "urn:demanes:events:battLevelEvent";
+ /** Node Degree EVent. */
+ public static final String ND_EVENT = "urn:demanes:events:nodeDegreeEvent";
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/MediatorProperties.java b/src/eu/artemis/demanes/impl/SunSPOT/common/MediatorProperties.java
new file mode 100644
index 0000000..521550e
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/MediatorProperties.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+/**
+ *
+ * @author Néstor Lucas Martínez
+ */
+public class MediatorProperties {
+ /** Behaviour of the update list. */
+ public static final String UPDATE_LIST_BEHAVIOUR_PROPERTY = "mediator.updatelistbehaviour";
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/PTActionProperties.java b/src/eu/artemis/demanes/impl/SunSPOT/common/PTActionProperties.java
new file mode 100644
index 0000000..62cf39b
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/PTActionProperties.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+/**
+ *
+ * @author Néstor Lucas Martínez
+ */
+public class PTActionProperties {
+ /** CR0 value. */
+ public static final String CR0_PROPERTY = "CR0";
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/RadioProperties.java b/src/eu/artemis/demanes/impl/SunSPOT/common/RadioProperties.java
new file mode 100644
index 0000000..36cd24a
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/RadioProperties.java
@@ -0,0 +1,168 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.ieee_802_15_4_radio.IRadioPolicyManager;
+import com.sun.squawk.util.Arrays;
+
+/**
+ *
+ * @author Néstor Lucas Martínez <nestor.lucas@upm.es>
+ */
+public class RadioProperties {
+ // CONSTANTS
+ /** The sorted array of general available transmission powers. */
+ private final static int[] availablePTX = {-32, -31, -30, -25, -22, -19, -17, -15, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0};
+
+ /** The sorted array of general available transmission powers for channel 26. They are restricted due to FCC regulations. */
+ private final static int[] availablePTXChannel26 = {-32, -31, -30, -25, -22, -19, -17, -15, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3};
+
+ /** The minimum power of transmission in dBm. */
+ public final static int MINIMUM_POWER_TRANSMISSION = -32;
+
+ /** The maximum power of transmission in dBm. */
+ public final static int MAXIMUM_POWER_TRANSMISSION = 0;
+
+ /** ERROR CONSTANT. */
+ public final static int RADIO_PROPERTIES_ERROR = -1;
+
+ /**
+ * Static method to obtain the maximum index in the available transmission
+ * powers array.
+ *
+ * @param channel The channel for which the maximum index is required.
+ * @return The maximum index fir the requested channel.
+ */
+ public static int getMaximumPTXIndex(int channel) {
+ if (channel == 26) {
+ return availablePTXChannel26.length - 1;
+ }
+ else
+ return availablePTX.length - 1;
+ }
+
+ /**
+ * Static method to obtain the minimum index in the available transmission
+ * powers array. It will always be 0, so this method is just to complement
+ * the getMaximumPTXIndex.
+ *
+ * @param channel The channel for which the maximum index is required.
+ * @return The maximum index fir the requested channel.
+ */
+ public static int getMinimumPTXIndex(int channel) {
+ // The minimum index is always 0. It could have been coded as a constant,
+ // but this way it keeps coherence with the getMaximumPTXIndex method.
+ return 0;
+ }
+
+ /**
+ * Static method to obtain the index of a given power of transmission
+ * related to the REAL available ones.
+ *
+ * @param channel The channel for which the request is done.
+ * @param ptx The transmission power which is asked for
+ * @return The index of the transmission power in the list
+ */
+ public static int getPTXIndex(int channel, int ptx) {
+ // This must be improved to consider the chance of being invoked with values not listed.
+ if (channel == 26) {
+ return Arrays.binarySearch(availablePTXChannel26, ptx);
+ }
+ else {
+ return Arrays.binarySearch(availablePTX, ptx);
+ }
+ }
+
+ /**
+ * Static method to obtain the transmission power given an index.
+ *
+ * @param channel The chanel for which the request is done.
+ * @param index The index of the desired transmission power.
+ * @return The desire transmission power, or RADIO_PROPERTIES_ERROR if the index is out of bounds.
+ */
+ public static int getPTXatIndex(int channel, int index) {
+ if (channel == 26) {
+ if ((index < 0) || (index > availablePTXChannel26.length)) {
+ return RADIO_PROPERTIES_ERROR;
+ }
+ return availablePTXChannel26[index];
+ }
+ else {
+ if ((index < 0) || (index > availablePTX.length)) {
+ return RADIO_PROPERTIES_ERROR;
+ }
+ return availablePTX[index];
+ }
+ }
+
+ /**
+ * Static method to obtain the actual radio channel in use.
+ *
+ * @return The actual radio channel in use.
+ */
+ public static int getRadioChannel() {
+ return ((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getChannelNumber();
+ }
+
+ /**
+ * Static method to obtain the actual transmission power.
+ *
+ * @return The actual transmission power.
+ */
+ public static int getPTX() {
+ return ((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower();
+ }
+
+ /**
+ * Static method to get the maximum available transmission power in
+ * the specified channel.
+ *
+ * @param channel The channel.
+ * @return The maximum transmission power in the channel, in dBm.
+ */
+ public static int getMaximumPTX(int channel) {
+ if (channel == 26) {
+ return availablePTXChannel26[availablePTXChannel26.length - 1];
+ }
+ else {
+ return availablePTX[availablePTX.length - 1];
+ }
+ }
+
+ /**
+ * Static method to get the minimum available transmission power in
+ * the specified channel.
+ *
+ * @param channel The channel.
+ * @return The minimum transmission power in the channel, in dBm.
+ */
+ public static int getMinimumPTX(int channel) {
+ if (channel == 26) {
+ return availablePTXChannel26[0];
+ }
+ else {
+ return availablePTX[0];
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/ReasonerProperties.java b/src/eu/artemis/demanes/impl/SunSPOT/common/ReasonerProperties.java
new file mode 100644
index 0000000..8a1adb7
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/ReasonerProperties.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+/**
+ * Names of the properties used in the reasoner.
+ *
+ * @author Vicente Hernández Díaz
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class ReasonerProperties {
+
+ // following parameters are used in the controller
+ public static final String KE_PROPERTY = "kE";
+ public static final String KdeltaND_PROPERTY = "kdeltaND";
+ public static final String NDinitPROPERTY = "ND";
+ public static final String NDRefPROPERTY = "NDRef";
+ public static final String ND_R_PROPERTY = "ND_R";
+
+ public static final String KND_PROPERTY = "k_ND";
+ public static final String KCR_PROPERTY = "k_CR";
+ public static final String E_CR_PROPERTY = "E_cr";
+ public static final String E_CR_FACTOR_PROPERTY = "E_cr_factor";
+
+ public static final String e_ND_ID_PROPERTY = "e_ND";
+ public static final String e_E_ID_PROPERTY = "e_E";
+ public static final String du_ND_ID_PROPERTY = "du_ND";
+ public static final String du_CR_ID_PROPERTY = "du_CR";
+
+ public static final String FDM_PRIM_CONFIG_PROPERTY = "FDM_Prim_Prop_File";
+ public static final String FDM_SEC_CONFIG_PROPERTY = "FDM_Sec_Prop_File";
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationContext.java b/src/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationContext.java
new file mode 100644
index 0000000..963ca3b
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/ReconfigurationContext.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.core.util.Properties;
+import com.sun.spot.espot.peripheral.ESpot;
+
+/**
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class ReconfigurationContext {
+
+ private static final int DEFAULT_K_DELTA_ND = 1;
+ private static final int DEFAULT_ND_INIT = 1;
+ private static final int DEFAULT_ND_REF = 1;
+ private static final double DEFAULT_K_CR = 1.0;
+ private static final double DEFAULT_E_CR_FACTOR = 0.2;
+ private static final String DEFAULT_E_ND_ID = "e_nd";
+ private static final String DEFAULT_E_E_ID = "e_E";
+ private static final String DEFAULT_DU_ND_ID = "du_nd";
+ private static final String DEFAULT_DU_CR_ID = "du_cr";
+ private static final String DEFAULT_FDM_PRIM_CONFIG = "/CR_FDM_ND_v1.ini";
+ private static final String DEFAULT_FDM_SEC_CONFIG = "/NDr_FDM_E_v1.ini";
+ private static final int DEFAULT_TRIGGER_INTERVAL = 2000;
+ private static final int DEFAULT_KSI_ND = 1;
+ private static final int DEFAULT_ND_MIN = 1;
+ private static final int DEFAULT_DELTA_ND_MIN = 1;
+ private static final int DEFAULT_DELTA_CR_MIN = 1;
+
+ private Properties defaultProperties;
+
+ public ReconfigurationContext() {
+ defaultProperties = new Properties();
+
+ defaultProperties.setProperty(ReasonerProperties.E_CR_FACTOR_PROPERTY, Double.toString(DEFAULT_E_CR_FACTOR));
+ defaultProperties.setProperty(ReasonerProperties.KdeltaND_PROPERTY, Integer.toString(DEFAULT_K_DELTA_ND));
+ defaultProperties.setProperty(ReasonerProperties.NDRefPROPERTY, Integer.toString(DEFAULT_ND_REF));
+ defaultProperties.setProperty(ReasonerProperties.NDinitPROPERTY, Integer.toString(DEFAULT_ND_REF));
+ defaultProperties.setProperty(ReasonerProperties.KCR_PROPERTY, Double.toString(DEFAULT_K_CR));
+
+ defaultProperties.setProperty(ReasonerProperties.FDM_PRIM_CONFIG_PROPERTY, "/CR_FDM_ND_v1.ini");
+ defaultProperties.setProperty(ReasonerProperties.FDM_SEC_CONFIG_PROPERTY, "/NDr_FDM_E_v1.ini");
+ defaultProperties.setProperty(ReasonerProperties.e_E_ID_PROPERTY, DEFAULT_E_E_ID);
+ defaultProperties.setProperty(ReasonerProperties.e_ND_ID_PROPERTY, DEFAULT_E_ND_ID);
+ defaultProperties.setProperty(ReasonerProperties.du_CR_ID_PROPERTY, DEFAULT_DU_CR_ID);
+ defaultProperties.setProperty(ReasonerProperties.du_ND_ID_PROPERTY, DEFAULT_DU_ND_ID);
+
+ defaultProperties.setProperty(TriggerPolicyProperties.KSI_ND_PROPERTY, Integer.toString(DEFAULT_KSI_ND));
+ defaultProperties.setProperty(TriggerPolicyProperties.ND_MIN_PROPERTY, Integer.toString(DEFAULT_ND_MIN));
+ defaultProperties.setProperty(TriggerPolicyProperties.CR_MAX_PROPERTY, Integer.toString(RadioProperties.getMaximumPTXIndex(RadioProperties.getRadioChannel())));
+ defaultProperties.setProperty(TriggerPolicyProperties.CR_MIN_PROPERTY, Integer.toString(RadioProperties.getMinimumPTXIndex(RadioProperties.getRadioChannel())));
+ defaultProperties.setProperty(TriggerPolicyProperties.DELTA_ND_MIN_PROPERTY, Integer.toString(DEFAULT_DELTA_ND_MIN));
+ defaultProperties.setProperty(TriggerPolicyProperties.DELTA_CR_MIN_PROPERTY, Integer.toString(DEFAULT_DELTA_CR_MIN));
+ defaultProperties.setProperty(TriggerPolicyProperties.TRIGGER_INTERVAL_PROPERTY, Integer.toString(DEFAULT_TRIGGER_INTERVAL));
+
+ updateProperties(defaultProperties);
+ }
+
+ public Properties getProperties() {
+ return this.defaultProperties;
+ }
+
+ public Properties updateProperties(Properties properties) {
+ double E_cr;
+ double E_cr_factor;
+ double kE;
+ double k_ND;
+ int kdeltaND;
+ int ND_Ref;
+ int ND_R;
+
+ E_cr_factor = Double.parseDouble(properties.getProperty(ReasonerProperties.E_CR_FACTOR_PROPERTY, Double.toString(DEFAULT_E_CR_FACTOR)));
+ ND_Ref = Integer.parseInt(properties.getProperty(ReasonerProperties.NDRefPROPERTY, Integer.toString(DEFAULT_ND_REF)));
+ kdeltaND = Integer.parseInt(properties.getProperty(ReasonerProperties.KdeltaND_PROPERTY, Integer.toString(DEFAULT_K_DELTA_ND)));
+
+ E_cr = (((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getMaximumCapacity()) * E_cr_factor;
+ kE = 2.0 / E_cr;
+ k_ND = 2.0 / ND_Ref;
+ ND_R = ND_Ref + kdeltaND;
+
+ properties.setProperty(ReasonerProperties.E_CR_PROPERTY, Double.toString(E_cr));
+ properties.setProperty(ReasonerProperties.KE_PROPERTY, Double.toString(kE));
+ properties.setProperty(ReasonerProperties.ND_R_PROPERTY, Integer.toString(ND_R));
+ properties.setProperty(ReasonerProperties.KND_PROPERTY, Double.toString(k_ND));
+
+ return properties;
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/SystemContext.java b/src/eu/artemis/demanes/impl/SunSPOT/common/SystemContext.java
new file mode 100644
index 0000000..8e46964
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/SystemContext.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.espot.peripheral.ESpot;
+import eu.artemis.demanes.impl.SunSPOT.communications.CommunicationManager;
+import eu.artemis.demanes.impl.SunSPOT.reconfiguration.actions.PowerTransmissionActuator;
+import eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.Marquee;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+
+/**
+ * System Context defines all the objects in the system context that are
+ * accesible to other objects.
+ *
+ * @author Néstor Lucas Martínez
+ */
+public class SystemContext {
+ private static final CommunicationManager communicationManager = new CommunicationManager();
+ private static final Logger logger = new Logger();
+ private static final Marquee marquee = new Marquee();
+
+ private static final boolean USBStatus = ((ESpot) Resources.lookup(ESpot.class)).getUsbPowerDaemon().isUsbPowered();
+ private static final Level logLevel = Level.INFO;
+
+ private PowerTransmissionActuator ptact;
+
+ /**
+ *
+ */
+ public SystemContext() {
+ marquee.start();
+ }
+
+ /**
+ * Get the communication manager of the system.
+ *
+ * @return The Communication Manager of the system.
+ */
+ public CommunicationManager getCommunicationManager() {
+ return this.communicationManager;
+ }
+
+ /**
+ * Get the logger of the system.
+ *
+ * @return The logger of the system.
+ */
+ public static Logger getLogger() {
+ return logger;
+ }
+
+ /**
+ * Get the LED Marquee of the system.
+ *
+ * @return The LED Marquee.
+ */
+ public static Marquee getMarquee() {
+ return marquee;
+ }
+
+ /**
+ * Check if the system is USB connected.
+ *
+ * @return Tru if the mote is USB powered, false otherwise.
+ */
+ public static boolean isUSBConnected() {
+ return USBStatus;
+ }
+
+ /**
+ * Check if debug mode is active.
+ *
+ * @return True if debug mode is active, false otherwise.
+ */
+ public static boolean isDebugActive() {
+ return (logLevel.intValue() <= Level.DEBUG.intValue());
+ }
+
+ /**
+ * Set the Transmission Power Actuator for the system.
+ *
+ * @param ptact The transmission power actuator for the system.
+ */
+ public void setPTACT(PowerTransmissionActuator ptact) {
+ this.ptact = ptact;
+ }
+
+ /**
+ * Get the Transmission Power Actuator of the system.
+ *
+ * @return The transmision power actuator of the system.
+ */
+ public PowerTransmissionActuator getPTACT() {
+ return this.ptact;
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.java b/src/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.java
new file mode 100644
index 0000000..5b23dcf
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/SystemProperties.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.espot.peripheral.ESpot;
+import com.sun.spot.ieee_802_15_4_radio.util.IEEEAddress;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+
+/**
+ * Properties used by the system.
+ *
+ * @author Néstor Lucas Martínez
+ */
+public class SystemProperties {
+ private final static ESpot espot = (ESpot) Resources.lookup(ESpot.class);
+
+ // PROPERTIES NAMES
+ /** The SunSPOT property name for its IEEE address, "spot.address". */
+ public final static String IEEE_ADDRESS = "spot.address";
+
+ /** The SunSPOT property name for the NSS part for construction any URN, "urn.nss.spotpart". */
+ public final static String SPOT_URN_NSS = "urn.nss.spotpart";
+
+ /** The log level property name, "log.level". */
+ public final static String LOG_LEVEL = "log.level";
+
+ /** The log destination property name, "log.destination". */
+ public final static String LOG_DESTINATION = "log.destination";
+
+ /** Base station address. */
+ public final static String BASESTATION_ADDR_PROPERTY = "basestation.address";
+
+ /** Base station port. */
+ public final static String BASESTATION_PORT = "basestation.port";
+
+ /** Execution context. */
+ public final static String EXECUTION_CONTEXT = "execution.context";
+
+ /** Remote management port .*/
+ public final static String REMOTE_MANAGEMENT_PORT = "remotemng.port";
+
+
+ // DEFAULT VALUES
+ /** The SunSPOT IEEE Address. */
+ public final static String IEEE_ADDRESS_VALUE = IEEEAddress.toDottedHex(espot.getIEEEAddress());
+
+ /** The default value for the NSS part for construction any URN, "SunSPOT" + last four bytes of IEEE address. */
+ public final static String SPOT_URN_NSS_VALUE = "sunspot" + IEEE_ADDRESS_VALUE.substring(IEEE_ADDRESS_VALUE.length() - 4);
+
+ /** The default log level (ALL) for the whole application. */
+ public final static String LOG_LEVEL_VALUE = Level.ALL.toString();
+
+ /** The default log destination (STDOUT) for the whole application. */
+ public final static String LOG_DESTINATION_VALUE = String.valueOf(Logger.SYSTEM_OUTPUT);
+
+ /** The first LED index for the LEDs array. */
+ public final static int FIRST_LED = 0;
+
+ /** The last LED index for the LEDs array. */
+ public final static int LAST_LED = 7;
+
+ /** Default base station address for Den Haag video. */
+ public final static String DEFAULT_BS_ADDRESS = "0014.4F01.0000.7B23";
+
+ /** Default base station address in {@code Long} format. */
+ public final static long DEFAULT_BS_ADDRESSS_LONG = IEEEAddress.toLong(DEFAULT_BS_ADDRESS);
+
+ /** Default base station port. */
+ public final static int DEFAULT_BS_PORT = 100;
+
+ /** Execution context: CMS. */
+ public final static byte EXECUTION_CONTEXT_CMS = 0x01;
+
+ /** Execution context: Experimental. */
+ public final static byte EXECUTION_CONTEXT_EXPERIMENTAL = 0x02;
+
+ /** Default execution context. */
+ public final static byte DEFAULT_EXECUTION_CONTEXT = EXECUTION_CONTEXT_CMS;
+
+ /** Default remote management port. */
+ public final static int DEFAULT_REMOTE_MANAGEMENT_PORT = 201;
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/common/TriggerPolicyProperties.java b/src/eu/artemis/demanes/impl/SunSPOT/common/TriggerPolicyProperties.java
new file mode 100644
index 0000000..9a4a7e6
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/common/TriggerPolicyProperties.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.common;
+
+/**
+ * Properties used by the Power Scaling Monitor ({@code TriggerPolicy}).
+ *
+ * @author Néstor Lucas Martínez
+ */
+public class TriggerPolicyProperties {
+
+ public static final String TRIGGER_INTERVAL_PROPERTY = "trigger.interval";
+
+ // following parameters are used in the trigger rules
+ public static final String KSI_ND_PROPERTY = "KSI_ND";
+ public static final String ND_MIN_PROPERTY = "ND_MIN";
+ public static final String CR_MAX_PROPERTY = "CR_MAX";
+ public static final String CR_MIN_PROPERTY = "CR_MIN";
+ public static final String DELTA_ND_MIN_PROPERTY = "DELTA_ND_MIN";
+ public static final String DELTA_CR_MIN_PROPERTY = "DELTA_CR_MIN";
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.java b/src/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.java
new file mode 100644
index 0000000..d5b59f9
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/communications/CommunicationManager.java
@@ -0,0 +1,201 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.communications;
+
+import com.sun.spot.ieee_802_15_4_radio.util.IEEEAddress;
+import com.sun.spot.multihop.io.j2me.radiogram.Radiogram;
+import com.sun.spot.multihop.io.j2me.radiogram.RadiogramConnection;
+import com.sun.spot.multihop.radio.NoRouteException;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import javax.microedition.io.Connector;
+
+/**
+ * Manager for the communications. All communications with other resources
+ * should be done through this class.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class CommunicationManager {
+
+ /** Unicast communication mode. */
+ public static final int MODE_UNICAST = 0x00;
+ /** Anycast communication mode. NOT IMPLEMENTED. */
+ public static final int MODE_ANYCAST = 0x01;
+ /** Multicast communication mode. NOT IMPLEMENTED. */
+ public static final int MODE_MULTICAST = 0x02;
+ /** Broadcast communication mode. */
+ public static final int MODE_BROADCAST = 0x03;
+
+ /** Message priority normal. */
+ public static final int PRIORITY_NORMAL = 0x00;
+
+ /** Message importance normal. */
+ public static final int IMPORTANCE_NORMAL = 0x00;
+
+ /**
+ *
+ */
+ public CommunicationManager() { }
+
+ /**
+ * Sends a message to a specified destination using the specified
+ * mode, priority and importance.
+ *
+ * @param message The message to be sent.
+ * @param size The size of the message to be sent.
+ * @param mode The mode to be used for the communication.
+ * @param destination The message destination.
+ * @param priority The message priority.
+ * @param importance The message importance.
+ * @return True if the message is sent, false otherwise.
+ */
+ public boolean send(ByteArrayOutputStream message, int size, int mode, String destination, int priority, int importance) {
+ RadiogramConnection connection = null;
+ Radiogram radiogram;
+ RadiogramAddress destinationAddress;
+
+ destinationAddress = resolveDestination(destination);
+
+ try {
+ switch (mode) {
+ case MODE_BROADCAST:
+ connection = (RadiogramConnection) Connector.open("radiogram://broadcast:" + destinationAddress.getPort());
+ radiogram = (Radiogram) connection.newDatagram(connection.getMaximumLength());
+ break;
+ case MODE_UNICAST:
+ connection = (RadiogramConnection) Connector.open("radiogram://" + destinationAddress.getAddressAsString() + ":" + destinationAddress.getPort());
+ radiogram = (Radiogram) connection.newDatagram(connection.getMaximumLength());
+ break;
+
+ default: // Default mode is unicast
+ connection = (RadiogramConnection) Connector.open("radiogram://broadcast:" + destinationAddress.getPort());
+ radiogram = (Radiogram) connection.newDatagram(connection.getMaximumLength());
+ }
+
+ radiogram.reset();
+ radiogram.write(message.toByteArray());
+ connection.send(radiogram);
+ return true;
+ } catch (NoRouteException ex) {
+ SystemContext.getLogger().warning("--- No route found to: " + destinationAddress.getAddressAsString());
+ } catch (IOException ex) {
+ if (SystemContext.isUSBConnected() & SystemContext.isDebugActive()) {
+ ex.printStackTrace();
+ }
+ } finally {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (IOException ex) {
+ if (SystemContext.isUSBConnected() & SystemContext.isDebugActive()) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Resolves the specified destination address.
+ *
+ * @param destination The destination address to be resolved.
+ * @return The resolved address.
+ */
+ public RadiogramAddress resolveDestination(String destination) {
+ RadiogramAddress radiogramAddress;
+
+ radiogramAddress = new RadiogramAddress();
+
+ radiogramAddress.setPort(Integer.parseInt(destination.substring(destination.lastIndexOf(':') + 1)));
+ radiogramAddress.setAddress(IEEEAddress.toLong(destination.substring(0, destination.lastIndexOf(':'))));
+
+ return radiogramAddress;
+ }
+
+ /**
+ * Inner class implementing a RadiogramAddress.
+ */
+ class RadiogramAddress {
+
+ private long address;
+ private int port;
+
+ /**
+ * Get the MAC address as a {@code Long} object.
+ *
+ * @return The MAC address.
+ */
+ public long getAddressAsLong() {
+ return address;
+ }
+
+ /**
+ * Get the MAC address as a {@code String}.
+ *
+ * @return The MAC address.
+ */
+ public String getAddressAsString() {
+ return IEEEAddress.toDottedHex(this.address);
+ }
+
+ /**
+ * Set the MAC address specified as a {@code Long} object.
+ *
+ * @param address The MAC address.
+ */
+ public void setAddress(long address) {
+ this.address = address;
+ }
+
+ /**
+ * Set the MAC address specified as a {@code String}.
+ *
+ * @param address The MAC address.
+ */
+ public void setAddress(String address) {
+ this.address = IEEEAddress.toLong(address);
+ }
+
+ /**
+ * Get the port.
+ *
+ * @return The port.
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Set the port.
+ *
+ * @param port The port.
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/communications/RemoteManagement.java b/src/eu/artemis/demanes/impl/SunSPOT/communications/RemoteManagement.java
new file mode 100644
index 0000000..cf1c562
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/communications/RemoteManagement.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.communications;
+
+import com.sun.spot.core.util.Properties;
+import com.sun.spot.multihop.io.j2me.radiogram.Radiogram;
+import com.sun.spot.multihop.io.j2me.radiogram.RadiogramConnection;
+import com.sun.squawk.util.StringTokenizer;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemProperties;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import java.io.IOException;
+import javax.microedition.io.Connector;
+
+/**
+ *
+ * @author Néstor Lucas Martínez <nestor.lucas@upm.es>
+ */
+public class RemoteManagement implements Runnable {
+ private final Logger logger;
+ private final Properties reconfigurationProperties;
+ private int rmport;
+
+ public RemoteManagement(Properties properties) {
+ this.logger = SystemContext.getLogger();
+ this.reconfigurationProperties = properties;
+ }
+
+ public void run() {
+ rmport = Integer.parseInt(reconfigurationProperties.getProperty(SystemProperties.REMOTE_MANAGEMENT_PORT, Integer.toString(SystemProperties.DEFAULT_REMOTE_MANAGEMENT_PORT)));
+
+ RadiogramConnection connection = null;
+ Radiogram radiogram;
+
+ while (true) {
+ try {
+ if (connection == null) {
+ connection = (RadiogramConnection) Connector.open("radiogram://:" + rmport);
+ }
+
+ radiogram = (Radiogram) connection.newDatagram(connection.getMaximumLength());
+ radiogram.reset();
+
+ connection.receive(radiogram);
+
+ byte[] message = new byte[radiogram.getLength()];
+ radiogram.readFully(message);
+ String parameterizationString = new String(message);
+
+ logger.info("Received parameterization radiogram:" + parameterizationString);
+
+ // Parse parameters
+ StringTokenizer parametersTokens = new StringTokenizer(parameterizationString, ",");
+ while (parametersTokens.hasMoreElements()) {
+ String token = (String) parametersTokens.nextElement();
+ String property = token.substring(0, token.indexOf(':'));
+ String value = token.substring(token.indexOf(':') + 1, token.length());
+ logger.info("Parsing parameter " + property + " with value " + value);
+ reconfigurationProperties.setProperty(property, value);
+ }
+
+ reconfigurationProperties.setProperty("reset", "true");
+
+ } catch (IOException ex) {
+ logger.warning("ERROR: Parameterization communication error.");
+ }
+ }
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/communications/RoutingListener.java b/src/eu/artemis/demanes/impl/SunSPOT/communications/RoutingListener.java
new file mode 100644
index 0000000..8bf6147
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/communications/RoutingListener.java
@@ -0,0 +1,137 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.communications;
+
+import com.sun.spot.core.resources.transducers.LEDColor;
+import com.sun.spot.ieee_802_15_4_radio.util.IEEEAddress;
+import com.sun.spot.multihop.radio.IDataEventListener;
+import com.sun.spot.multihop.radio.mhrp.interfaces.ILQRPEventListener;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+
+/**
+ * {@code RoutingListener} implements a listener for routing events, so they
+ * can be notified to the user through a LED marquee.
+ *
+ * @author Néstor Lucas Martínez
+ */
+public class RoutingListener implements ILQRPEventListener, IDataEventListener {
+
+ private static final LEDColor RREQ_COLOR = LEDColor.WHITE;
+ private static final LEDColor RREP_COLOR = LEDColor.GREEN;
+ private static final LEDColor RERR_COLOR = LEDColor.RED;
+ private static final LEDColor DATA_COLOR = LEDColor.BLUE;
+
+ /**
+ *
+ */
+ public RoutingListener() { }
+
+ /**
+ * Method called when a RREQ is sent.
+ *
+ * @param originator Route request originator.
+ * @param destination Route request destination.
+ * @param hopCount Number of hops to the destination.
+ * @param routeCost Cost to the destination.
+ */
+ public void RREQSent(long originator, long destination, int hopCount, double routeCost) {
+ SystemContext.getMarquee().blinkActivity1(RREQ_COLOR);
+ }
+
+ /**
+ * Method called when a RREP is sent.
+ *
+ * @param originator Route request originator.
+ * @param destination Route request destination.
+ * @param hopCount Number of hops to the destination.
+ * @param routeCost Cost to the destination.
+ */
+ public void RREPSent(long originator, long destination, int hopCount, double routeCost) {
+ SystemContext.getMarquee().blinkActivity1(RREP_COLOR);
+ }
+
+ /**
+ * Method called when a RERR is sent.
+ *
+ * @param originator Route request originator.
+ * @param destination Route request destination.
+ */
+ public void RERRSent(long originator, long destination) {
+ SystemContext.getMarquee().blinkActivity1(RERR_COLOR);
+ }
+
+ /**
+ * Method called when a RREQ is received.
+ *
+ * @param originator Route request originator.
+ * @param destination Route request destination.
+ * @param lastHop Route request last hop.
+ * @param hopCount Number of hops to the destination.
+ * @param routeCost Cost to the destination.
+ */
+ public void RREQReceived(long originator, long destination, long lastHop, int hopCount, double routeCost) {
+ SystemContext.getMarquee().blinkActivity2(RREQ_COLOR);
+ }
+
+ /**
+ * Method called when a RREP is received.
+ *
+ * @param originator Route request originator.
+ * @param destination Route request destination.
+ * @param lastHop Route request last hop.
+ * @param hopCount Number of hops to the destination.
+ * @param routeCost Cost to the destination.
+ */
+ public void RREPReceived(long originator, long destination, long lastHop, int hopCount, double routeCost) {
+ SystemContext.getMarquee().blinkActivity2(RREP_COLOR);
+ }
+
+ /**
+ * Method called when a RERR is received.
+ *
+ * @param originator Route request originator.
+ * @param destination Route request destination.
+ */
+ public void RERRReceived(long originator, long destination) {
+ SystemContext.getMarquee().blinkActivity2(RERR_COLOR);
+ }
+
+ /**
+ * Method that is called when data is forwarded through this physical node.
+ *
+ * @param lastHop previous node on the multi hop path from which the packet was received.
+ * @param nextHop next node on the multi hop path to which the packet is sent.
+ * @param originator original sender of the packet.
+ * @param destination final destination of the packet.
+ */
+ public void notifyForward(long lastHop, long nextHop, long originator, long destination) {
+ SystemContext.getMarquee().blinkActivity1(DATA_COLOR);
+ SystemContext.getMarquee().blinkActivity2(DATA_COLOR);
+
+ SystemContext.getLogger().log(Level.DEBUG, "Forwarding message from " + IEEEAddress.toDottedHex(originator)
+ + " to " + IEEEAddress.toDottedHex(destination)
+ + " received from " + IEEEAddress.toDottedHex(lastHop)
+ + " and being forwarded through " + IEEEAddress.toDottedHex(nextHop));
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/datatypes/SunSPOTBundle.java b/src/eu/artemis/demanes/impl/SunSPOT/datatypes/SunSPOTBundle.java
new file mode 100644
index 0000000..4bfe1c3
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/datatypes/SunSPOTBundle.java
@@ -0,0 +1,155 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.datatypes;
+
+import eu.artemis.demanes.datatypes.ANES_BUNDLE;
+import eu.artemis.demanes.exceptions.NonExistentKeyException;
+import eu.artemis.demanes.exceptions.TypedRequestException;
+import java.util.Hashtable;
+
+/**
+ * Implementation of the {@link ANES_BUNDLE} for the SunSPOT architecture.
+ *
+ * @author Néstor Lucas Martínez
+ * @author Vicente Hernández Díaz
+ * @version 1.0.0
+ */
+public class SunSPOTBundle implements ANES_BUNDLE{
+ private Hashtable bundleMap;
+
+ /**
+ * Public constructor.
+ *
+ * @see {@link ANES_BUNDLE}
+ */
+ public SunSPOTBundle() {
+ this.bundleMap = new Hashtable();
+ }
+
+ /**
+ * Creates and returns a copy of this object.
+ *
+ * @return A clone of this instance.
+ */
+ public ANES_BUNDLE clone() {
+ return this.clone();
+ }
+
+ /**
+ * Returns true if this map contains a mapping for the specified key.
+ *
+ * @param key Key whose presence in this map is to be tested.
+ * @return True if this map contains a mapping for the specified key.
+ */
+ public boolean containsKey(String key) {
+ return this.bundleMap.containsKey(key);
+ }
+
+ /**
+ * Returns true if this map contains a mapping for the specified key and
+ * the object linked is of the specified class.
+ *
+ * @param key Key whose presence in this map is to be tested.
+ * @param clazz Class whose type is to be tested.
+ * @return True if this map contains a mapping for the specified key and matches the specified class.
+ */
+ public boolean containsKey(String key, Class clazz) {
+ if (this.bundleMap.containsKey(key)) {
+ if (this.bundleMap.get(key).getClass().equals(clazz)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the value to which the specified key is mapped.
+ *
+ * @param key Key whose associated value is to be returned.
+ * @return The value to which the specified key is mapped.
+ * @throws NonExistentKeyException When key is not found in this map.
+ */
+ public Object get(String key) throws NonExistentKeyException {
+ if (this.bundleMap.containsKey(key)) {
+ return this.bundleMap.get(key);
+ }
+ else {
+ throw new NonExistentKeyException(key);
+ }
+ }
+
+ /**
+ * Returns the value to which the specified key is mapped if it is of the
+ * same class as the specified class.
+ *
+ * @param key Key whose associated value is to be returned.
+ * @param clazz Class whose type is to be checked.
+ * @return The value to which the specified key is mapped.
+ * @throws TypedRequestException When class does not match.
+ * @throws NonExistentKeyException When key is not found in this map.
+ */
+ public Object get(String key, Class clazz) throws TypedRequestException, NonExistentKeyException {
+ if (this.bundleMap.containsKey(key)) {
+ if (this.bundleMap.get(key).getClass().equals(clazz)) {
+ return this.bundleMap.get(key);
+ }
+ else {
+ throw new TypedRequestException(this.bundleMap.get(key).getClass(), clazz);
+ }
+ }
+ else {
+ throw new NonExistentKeyException(key);
+ }
+ }
+
+ /**
+ * Returns the type of the object associated to the specified key.
+ *
+ * @param key Key whose associated value type is to be returned
+ * @return The class of the objected associated to the specified key.
+ * @throws NonExistentKeyException When key is not found in the map.
+ */
+ public Class getType(String key) throws NonExistentKeyException {
+ if (this.bundleMap.containsKey(key)) {
+ return this.bundleMap.get(key).getClass();
+ }
+ else {
+ throw new NonExistentKeyException(key);
+ }
+ }
+
+ /**
+ * Associates the specified value with the specified key in this map.
+ *
+ * @param key Key with which the specified value is to be associated.
+ * @param value Value to be associated with the specified key.
+ */
+ public void put(String key, Object value) {
+ this.bundleMap.put(key, value);
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/DefaultConfig.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/DefaultConfig.java
new file mode 100644
index 0000000..3338823
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/DefaultConfig.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+import com.sun.spot.core.util.Properties;
+
+/**
+ * Class with the definition of basics keys for the configuration file
+ * It also contains the description of the format for values.
+ *
+ * @author Ra&uacte;l del Toro Matamoros
+ * @version 1.0.0
+ */
+public class DefaultConfig {
+ public Properties defaultProp;
+
+ public DefaultConfig(){
+
+ this.defaultProp = new Properties();
+
+ this.defaultProp.setProperty(KEY.NUMBER_OF_INPUTS, "1");
+ this.defaultProp.setProperty(KEY.NUMBER_OF_OUTPUTS, "1");
+ this.defaultProp.setProperty(KEY.VAR_ID + KEY.VAR_DELIM + "1", "X");
+ this.defaultProp.setProperty(KEY.VAR_TYPE + KEY.VAR_DELIM + "1", KEY.VAR_TYPE_IN);
+ this.defaultProp.setProperty(KEY.VAR_MIN + KEY.VAR_DELIM + "1", "-1.0");
+ this.defaultProp.setProperty(KEY.VAR_MAX + KEY.VAR_DELIM + "1", "1.0");
+ this.defaultProp.setProperty(KEY.VAR_ID + KEY.VAR_DELIM + "2", "Y");
+ this.defaultProp.setProperty(KEY.VAR_TYPE + KEY.VAR_DELIM + "2", KEY.VAR_TYPE_OUT);
+ this.defaultProp.setProperty(KEY.VAR_MIN + KEY.VAR_DELIM + "2", "-1.0");
+ this.defaultProp.setProperty(KEY.VAR_MAX + KEY.VAR_DELIM + "2", "1.0");
+ this.defaultProp.setProperty(KEY.NUMBER_OF_POINTS, "2");
+ //this.put("X", "-1.0, 1.0");
+ }
+
+ public Properties getProp(){
+ return this.defaultProp;
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/ERRORMSG.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/ERRORMSG.java
new file mode 100644
index 0000000..3125539
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/ERRORMSG.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+/**
+ * Class for error messages description.
+ *
+ * @author Raúl del Toro Matamoros
+ * @version 1.0.0
+ */
+public final class ERRORMSG {
+
+ private static String LAST_ERRORMSG = "No error";
+
+ public static final String DELIM = " - ";
+
+ public static final String CONFIG_FILE = "Reasoning function configuration file error";
+ public static final String CONFIG_FILE_KEYNUMBERS = CONFIG_FILE + DELIM + "Invalid number of properties";
+ public static final String CONFIG_FILE_KEYNOTFOUND = CONFIG_FILE + DELIM + "Property not found";
+ public static final String CONFIG_FILE_VALUE_NOTVALID = CONFIG_FILE + DELIM + "Invalid value for key";
+ public static final String CONFIG_FILE_POINTS_ROW_HEADER_NOTFOUND = CONFIG_FILE + DELIM + "Invalid or not found header for points array";
+ public static final String CONFIG_FILE_POINTS_COLUMN = CONFIG_FILE + DELIM + "Points array has missing column data";
+ public static final String CONFIG_FILE_POINTS_VALUE_NOTVALID = CONFIG_FILE + DELIM + "Invalid value in points array";
+ public static final String CONFIG_FILE_POINTS_VALUES_UNSORTED = CONFIG_FILE + DELIM + "Unsorted value in points array";
+
+ public static final String REASONING_FUNCTION = "Reasoning function error";
+ public static final String VARIABLE_ID_NOTFOUND = REASONING_FUNCTION + DELIM + "Variable ID was not found";
+ public static final String VARIABLE_ERROR_ACCESS = REASONING_FUNCTION + DELIM + "Variable ID is not accessible";
+
+
+ public static void setErrorMSG(String ErrorMsg){
+ LAST_ERRORMSG = ErrorMsg;
+ }
+ public static void ErrorPrint(String ErrorMsg){
+ System.err.println(ErrorMsg);
+ }
+
+ public static String getLastErrorMSG(){
+ return LAST_ERRORMSG;
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/FuzzyDM.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/FuzzyDM.java
new file mode 100644
index 0000000..520d5f9
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/FuzzyDM.java
@@ -0,0 +1,109 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+import com.sun.spot.core.util.Properties;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * FuzzyDM
+ *
+ * This is an interface to a decision making function.
+ *
+ * @author Raúl del Toro Matamoros
+ * @version 1.0.0
+ */
+public interface FuzzyDM {
+
+ /**
+ * Load Inference System from a storage device
+ *
+ * @param resourceID
+ * @throws java.io.IOException
+ */
+
+ public void load(InputStream resourceID) throws IOException;
+
+ public void load(Properties config) throws IOException;
+
+ /*
+ * Returns IDs or names of input variables
+ */
+ public Enumeration getInputsID();
+
+ /*
+ * Returns IDs or names of output variables
+ */
+ public Enumeration getOutputsID();
+
+ /*
+ * Set input variable
+ */
+ public boolean setInput(String inputID, Object inputVal);
+
+ /*
+ * Set input variable
+ */
+ public boolean setInput(String inputID, double inputVal);
+
+ /*
+ * Get output variable
+ */
+ public Object getOutput(String outputID);
+
+ /*
+ * Get inputs variable set
+ */
+ public Hashtable getInputsSet();
+
+ /*
+ * Get outputs variable set
+ */
+ public Hashtable getOutputsSet();
+
+ /*
+ * Set normalization factor for the input and output variables
+ */
+ public boolean setNormFactors(Hashtable normFactors);
+
+ public boolean setNormFactors(String inputID, double inputVal);
+
+ /*
+ * Normalize input variables
+ * It returns normalized values
+ */
+ //public void normInputs();
+
+ /*
+ * Denormalize output variables
+ * It returns denormalized values
+ */
+ //public void denormOutputs();
+
+ /*
+ * Perform inference calculations
+ */
+ public void evaluate();
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Interp1DFuzzyDM.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Interp1DFuzzyDM.java
new file mode 100644
index 0000000..367c3a1
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Interp1DFuzzyDM.java
@@ -0,0 +1,516 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import com.sun.spot.core.util.Properties;
+import com.sun.squawk.util.StringTokenizer;
+
+/**
+ *
+ * @author Raúl del Toro Matamoros
+ * @version 1.0.0
+ */
+public final class Interp1DFuzzyDM implements FuzzyDM{
+
+ // The minimum expected numbers of field stored in the function configuration file
+ private int DEFAULT_NUM_CONFIG_FIELDS;
+
+ // Basics keys for the function configuration file
+ private Properties CONFIG_KEYS_DEFAULT;
+
+ private Hashtable varInputs;
+ private Hashtable varOutputs;
+
+ private int NumInputs;
+ private int NumOutputs;
+ private int NumPoints;
+
+ // It stores the points array as table of double[].
+ // The key for each array is the VarID
+ private Hashtable PointsArray;
+
+ public Interp1DFuzzyDM(String PropFileName) throws IOException {
+
+ // Initialization of the basics keys for the function configuration file
+ DefaultConfig default_config = new DefaultConfig();
+ this.CONFIG_KEYS_DEFAULT = new Properties(default_config.getProp());
+
+ InputStream ResourceID = this.CONFIG_KEYS_DEFAULT.getClass().getResourceAsStream(PropFileName);
+
+ //this.Configuration = new Hashtable();
+ this.varInputs = new Hashtable();
+ this.varOutputs = new Hashtable();
+
+ this.PointsArray = new Hashtable();
+
+ if (ResourceID != null)
+ this.load(ResourceID);
+ }
+
+ public Interp1DFuzzyDM(InputStream ResourceID) throws IOException {
+
+ // Initialization of the basics keys for the function configuration file
+ DefaultConfig default_config = new DefaultConfig();
+ this.CONFIG_KEYS_DEFAULT = new Properties(default_config.getProp());
+
+ //this.Configuration = new Hashtable();
+ this.varInputs = new Hashtable();
+ this.varOutputs = new Hashtable();
+
+ this.PointsArray = new Hashtable();
+
+ this.load(ResourceID);
+ }
+
+ public Interp1DFuzzyDM(Properties config) throws IOException {
+
+ // Initialization of the basics keys for the function configuration file
+ DefaultConfig default_config = new DefaultConfig();
+ this.CONFIG_KEYS_DEFAULT = new Properties(default_config.getProp());
+
+ //this.Configuration = new Hashtable();
+ this.varInputs = new Hashtable();
+ this.varOutputs = new Hashtable();
+
+ this.PointsArray = new Hashtable();
+
+ this.load(config);
+ }
+
+ public void load(InputStream ResourceID) throws IOException{
+
+ Properties config = new Properties();
+
+ Enumeration prop_key;
+ String prop_key_name;
+
+ // Temporal table to store properties
+ Hashtable config_temp = new Hashtable();
+
+ DEFAULT_NUM_CONFIG_FIELDS = this.CONFIG_KEYS_DEFAULT.size();
+
+ config.load(ResourceID);
+
+ // Copy properties in a temporal Hashtable
+ for (prop_key = config.propertyNames(); prop_key.hasMoreElements();){
+ prop_key_name = prop_key.nextElement().toString();
+
+ config_temp.put(prop_key_name, config.getProperty(prop_key_name));
+ }
+
+ // Check number of fields in the configuration file
+ if (config_temp.size() < DEFAULT_NUM_CONFIG_FIELDS )
+ throw new IOException(ERRORMSG.CONFIG_FILE_KEYNUMBERS);
+
+ checkConfigProp(config_temp);
+
+ if ((this.NumInputs + this.NumOutputs) > 0)
+ checkVarProp(config_temp, this.NumInputs + this.NumOutputs);
+
+ if (this.NumPoints > 0){
+ checkPointsArray(config_temp, this.varInputs.keys());
+ checkPointsArray(config_temp, this.varOutputs.keys());
+ }
+ }
+
+ public void load(Properties config) throws IOException{
+
+ Enumeration prop_key;
+ String prop_key_name;
+
+ // Temporal table to store properties
+ Hashtable config_temp = new Hashtable();
+
+ DEFAULT_NUM_CONFIG_FIELDS = this.CONFIG_KEYS_DEFAULT.size();
+
+ // Copy properties to a temporal Hashtable
+ for (prop_key = config.propertyNames(); prop_key.hasMoreElements();){
+ prop_key_name = prop_key.nextElement().toString();
+
+ config_temp.put(prop_key_name, config.getProperty(prop_key_name));
+ }
+
+ // Check number of fields in the configuration file
+ if (config_temp.size() < DEFAULT_NUM_CONFIG_FIELDS )
+ throw new IOException(ERRORMSG.CONFIG_FILE_KEYNUMBERS);
+
+ checkConfigProp(config_temp);
+
+ if ((this.NumInputs + this.NumOutputs) > 0)
+ checkVarProp(config_temp, this.NumInputs + this.NumOutputs);
+
+ if (this.NumPoints > 0){
+ checkPointsArray(config_temp, this.varInputs.keys());
+ checkSortedPointsArray((String)this.varInputs.keys().nextElement());
+ checkPointsArray(config_temp, this.varOutputs.keys());
+ }
+ }
+
+ /*
+ * Function to check the description of the property keys in the configuration file
+ * and the number of properties.
+ */
+ private void checkConfigProp(Hashtable config_prop) throws IOException {
+ int config_size = config_prop.size();
+ int exp_config_size;
+ String prop_key_name;
+ Enumeration prop_key;
+
+ // Checking properties description
+ for (prop_key = this.CONFIG_KEYS_DEFAULT.keys(); prop_key.hasMoreElements();){
+ prop_key_name = prop_key.nextElement().toString();
+
+ checkProp(config_prop, prop_key_name, false);
+ }
+
+ // Checking number of properties
+ // Storing configuration in memory
+ try{
+ this.NumInputs = Integer.parseInt(checkProp(config_prop, KEY.NUMBER_OF_INPUTS, true));
+ this.NumOutputs = Integer.parseInt(checkProp(config_prop, KEY.NUMBER_OF_OUTPUTS, true));
+ this.NumPoints = Integer.parseInt(checkProp(config_prop, KEY.NUMBER_OF_POINTS, true));
+ } catch(NumberFormatException ex){
+ throw new IOException(ERRORMSG.CONFIG_FILE_VALUE_NOTVALID);
+ }
+
+ exp_config_size = DEFAULT_NUM_CONFIG_FIELDS + 5 * (this.NumInputs + this.NumOutputs) - 8;
+
+ if (config_size < exp_config_size){
+ throw new IOException(ERRORMSG.CONFIG_FILE_KEYNUMBERS);
+ }
+ }
+
+ // Checking properties for each variable and storing the values
+ private void checkVarProp(Hashtable config_prop, int var_number) throws IOException {
+ String prop_key_name, prop_value;
+ Object prev_val;
+
+ // Checking properties for the input and output variables
+ for (int nvar = 1; nvar <= var_number; nvar++){
+ String var_type;
+ String var_id;
+
+ prop_key_name = KEY.VAR_TYPE + KEY.VAR_DELIM + Integer.toString(nvar);
+ var_type = checkProp(config_prop, prop_key_name, true);
+
+ Variable singlevar = new Variable(var_type);
+
+ String[] var_keys = {KEY.VAR_MIN, KEY.VAR_MAX};
+ for (int key = 0; key < var_keys.length; key++){
+ prop_key_name = var_keys[key] + KEY.VAR_DELIM + Integer.toString(nvar);
+
+ prop_value = checkProp(config_prop, prop_key_name, true);
+
+ try{
+ singlevar.put(var_keys[key], prop_value);
+ } catch(NumberFormatException ex){
+ throw new IOException(ERRORMSG.CONFIG_FILE_VALUE_NOTVALID + " - " + prop_value);
+ }
+ }
+
+ singlevar.setNumber(nvar);
+
+ prop_key_name = KEY.VAR_ID + KEY.VAR_DELIM + Integer.toString(nvar);
+ var_id = checkProp(config_prop, prop_key_name, true);
+
+ singlevar.setVarID(var_id);
+
+ prev_val = var_type.equals(KEY.VAR_TYPE_IN) ? this.varInputs.put(var_id, singlevar) : this.varOutputs.put(var_id, singlevar);
+ }
+ }
+
+ private String checkProp(Hashtable config_prop, String prop_key_name, boolean removeprop) throws IOException{
+
+ String prop_value = (String) config_prop.get(prop_key_name);
+
+ if (prop_value == null){
+ throw new IOException(ERRORMSG.CONFIG_FILE_KEYNOTFOUND + ERRORMSG.DELIM + prop_key_name);
+ }
+
+ if (removeprop)
+ config_prop.remove(prop_key_name);
+
+ return prop_value.trim();
+ }
+
+ // Checking and storing the points array
+ private void checkPointsArray(Hashtable config_prop, Enumeration varIDs) throws IOException{
+ double[] singlerow;
+ double prev_value;
+ int csize = this.NumPoints;
+ StringTokenizer rowdata;
+ String singlevalue;
+
+ while (varIDs.hasMoreElements()){
+ String rowid = varIDs.nextElement().toString();
+ String stringdata = checkProp(config_prop, rowid, true);
+ // Columns counter
+ int ncol = 0;
+
+ if (stringdata == null){
+ throw new IOException(ERRORMSG.CONFIG_FILE_POINTS_ROW_HEADER_NOTFOUND);
+ }
+
+ rowdata = new StringTokenizer(stringdata, KEY.POINTS_ROW_DELIM);
+
+ singlerow = new double[csize];
+
+ while(rowdata.hasMoreTokens()){
+ singlevalue = rowdata.nextToken();
+
+ try{
+ singlerow[ncol] = Double.parseDouble(singlevalue.trim());
+
+ } catch(NumberFormatException ex){
+ throw new IOException(ERRORMSG.CONFIG_FILE_POINTS_VALUE_NOTVALID + ERRORMSG.DELIM + singlevalue);
+ }
+
+ ncol++;
+ }
+
+ if (ncol != csize)
+ throw new IOException(ERRORMSG.CONFIG_FILE_POINTS_COLUMN + ERRORMSG.DELIM + stringdata);
+
+ this.PointsArray.put(rowid, singlerow);
+ }
+ }
+
+ // Checking if points array are sorted
+ private void checkSortedPointsArray(String varID) throws IOException{
+ double[] X;
+
+ X = (double [])this.PointsArray.get(varID);
+
+ for (int ncol = 1; ncol < X.length; ncol++){
+ if ((X[ncol] - X[ncol - 1]) < 0){
+ throw new IOException(ERRORMSG.CONFIG_FILE_POINTS_VALUES_UNSORTED + ERRORMSG.DELIM + varID);
+ }
+ }
+ }
+
+ public Enumeration getInputsID() {
+ //To change body of generated methods, choose Tools | Templates.
+ return this.varInputs.keys();
+ }
+
+ public Enumeration getOutputsID() {
+ return this.varOutputs.keys();
+ }
+
+ public boolean setInput(String inputID, Object inputVal) {
+ Variable single_var = ((Variable)this.varInputs.get(inputID));
+
+ if (single_var != null)
+ single_var.setValue(inputVal);
+ else {
+ //ERRORMSG.setErrorMSG(ERRORMSG.VARIABLE_ID_NOTFOUND);
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean setInput(String inputID, double inputVal) {
+ Variable single_var = ((Variable)this.varInputs.get(inputID));
+
+ if (single_var != null)
+ single_var.setValue(inputVal);
+ else {
+ //ERRORMSG.setErrorMSG(ERRORMSG.VARIABLE_ID_NOTFOUND);
+ return false;
+ }
+
+ return true;
+ }
+
+ public Object getOutput(String outputID) {
+ //return new Double(((Variable) this.varOutputs.get(outputID)).getValue());
+ Variable single_var = ((Variable)this.varOutputs.get(outputID));
+
+ if (single_var != null)
+ return new Double(single_var.getValue());
+ /*
+ else
+ ERRORMSG.ErrorPrint(ERRORMSG.VARIABLE_ID_NOTFOUND);
+ */
+
+ return null;
+ }
+
+ public Hashtable getInputsSet() {
+ Hashtable result = new Hashtable();
+ Enumeration varIDs;
+ String varid;
+
+ for (varIDs = this.varInputs.keys(); varIDs.hasMoreElements();){
+ varid = (String)varIDs.nextElement();
+ result.put(varid, new Double(((Variable) this.varInputs.get(varid)).getValue()));
+ }
+
+ return result;
+ }
+
+ public Hashtable getOutputsSet() {
+ Hashtable result = new Hashtable();
+ Enumeration varIDs;
+ String varid;
+
+ for (varIDs = this.varOutputs.keys(); varIDs.hasMoreElements();){
+ varid = (String)varIDs.nextElement();
+ result.put(varid, new Double(((Variable) this.varOutputs.get(varid)).getValue()));
+ }
+
+ return result;
+ }
+
+ public boolean setNormFactors(String varID, double normVal) {
+ Variable varprop = (Variable) this.varInputs.get(varID);
+
+ if (varprop == null)
+ varprop = (Variable) this.varOutputs.get(varID);
+
+ if (varprop != null)
+ varprop.setKnorm(normVal);
+ else {
+ //ERRORMSG.setErrorMSG(ERRORMSG.VARIABLE_ID_NOTFOUND);
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean setNormFactors(Hashtable normFactors) {
+ Enumeration varIDs;
+ Variable varprop;
+ String varid;
+ Object new_value;
+
+ for (varIDs = normFactors.keys(); varIDs.hasMoreElements();){
+ varid = varIDs.nextElement().toString();
+ new_value = normFactors.get(varid);
+
+ varprop = (Variable) this.varInputs.get(varid);
+ if (varprop == null)
+ varprop = (Variable) this.varOutputs.get(varid);
+
+ if (varprop != null)
+ varprop.setKnorm(new_value);
+ else {
+ //ERRORMSG.setErrorMSG(ERRORMSG.VARIABLE_ID_NOTFOUND);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * Normalize input variables
+ */
+ private void normInputs() {
+ Enumeration varIDs;
+ String varid;
+
+ for (varIDs = this.varInputs.keys(); varIDs.hasMoreElements();){
+ varid = varIDs.nextElement().toString();
+ ((Variable) this.varInputs.get(varid)).normVar();
+ }
+ }
+
+ /*
+ * Denormalize output variables
+ */
+ private void denormOutputs() {
+ Enumeration varIDs;
+ String varid;
+
+ for (varIDs = this.varOutputs.keys(); varIDs.hasMoreElements();){
+ varid = varIDs.nextElement().toString();
+ ((Variable) this.varOutputs.get(varid)).denormVar();
+ }
+ }
+
+ public void evaluate() {
+ // This function will interpolate the input based on X, Y points
+ //double[] X = {0.0, 1.0, 3.0, 6.0};
+ //double[] Y = {0.0, 1.0, 3.0, 6.0};
+ double[] X;
+ double[] Y;
+ String outputid;
+ int xsize = this.NumPoints;
+
+ Enumeration output_keys;
+
+ this.normInputs();
+
+ for (output_keys = this.varOutputs.keys(); output_keys.hasMoreElements();){
+
+ outputid = output_keys.nextElement().toString();
+
+ Y = (double [])this.PointsArray.get(outputid);
+
+ //for (Enumeration values = this.varInputs.elements(); values.hasMoreElements(); ) {
+ String inputid = this.varInputs.keys().nextElement().toString();
+
+ X = (double [])this.PointsArray.get(inputid);
+
+ double xi = ((Variable)this.varInputs.elements().nextElement()).getValueNorm();
+ //}
+ double yi = Interp1D(xi, X, xsize, Y);
+
+ ((Variable) this.varOutputs.get(outputid)).setValueNorm(yi);
+
+ ((Variable) this.varOutputs.get(outputid)).denormVar();
+ }
+
+ //this.denormOutputs();
+
+
+ }
+
+ // This function interpolates the input xi based on X, Y points array
+ // X is a vector ordered increasingly
+ private double Interp1D(double xi, double[] X, int xsize, double[] Y) {
+ double yi = 0.0;
+
+ if (xi <= X[0]){
+ yi = Y[0];
+ }
+ else if (xi >= X[xsize - 1]){
+ yi = Y[xsize - 1];
+ }
+ else {
+ for (int j = 0; j < xsize - 1; j++){
+ if ((xi > X[j]) && (xi <= X[j + 1])) {
+ yi = Y[j] + (xi - X[j]) * (Y[j + 1] - Y[j]) / (X[j + 1] - X[j]);
+ break;
+ }
+ }
+ }
+
+ return yi;
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/KEY.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/KEY.java
new file mode 100644
index 0000000..f42b7a8
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/KEY.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+/**
+ * Class for keys and constants definition.
+ *
+ * @author Ra&uacte;l del Toro Matamoros
+ * @version 1.0.0
+ */
+public final class KEY {
+
+ // KEYS DEFINITION
+ public static final String NUMBER_OF_INPUTS = "NumInputs";
+ public static final String NUMBER_OF_OUTPUTS = "NumOutputs";
+ public static final String VAR_ID = "VarID";
+ public static final String VAR_TYPE = "VarType";
+ public static final String VAR_MIN = "VarMIN";
+ public static final String VAR_MAX = "VarMAX";
+ public static final String NUMBER_OF_POINTS = "NumPoints";
+ public static final String POINTS_ARRAY = "PointsArray";
+ //public static final String VAR_PROP = "VarProp";
+
+ // OTHER CONSTANTS DEFINITION
+ public static final String POINTS_ROW_DELIM = ", ";
+ public static final String VAR_DELIM = "_";
+ public static final String VAR_TYPE_IN = "IN";
+ public static final String VAR_TYPE_OUT = "OUT";
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingController.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingController.java
new file mode 100644
index 0000000..da69def
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingController.java
@@ -0,0 +1,445 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.core.util.Properties;
+import com.sun.spot.ieee_802_15_4_radio.IRadioPolicyManager;
+import com.sun.squawk.util.NotImplementedYetException;
+import eu.artemis.demanes.datatypes.ANES_BUNDLE;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.datatypes.ANES_URN_Exception;
+import eu.artemis.demanes.exceptions.ActionInvocationException;
+import eu.artemis.demanes.exceptions.InexistentActionID;
+import eu.artemis.demanes.exceptions.InexistentObservationID;
+import eu.artemis.demanes.exceptions.ObservationInvocationException;
+import eu.artemis.demanes.impl.SunSPOT.common.DEMANESResources;
+import eu.artemis.demanes.impl.SunSPOT.common.Events;
+import eu.artemis.demanes.impl.SunSPOT.common.ReasonerProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemProperties;
+import eu.artemis.demanes.impl.SunSPOT.datatypes.SunSPOTBundle;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.reconfiguration.ActionProvider;
+import eu.artemis.demanes.reconfiguration.ObservationProvider;
+import eu.artemis.demanes.reconfiguration.Reasoner;
+
+/**
+ *
+ * This object class models the fuzzy logic controller that will make decisions
+ * whenever trigger is called.
+ *
+ * @author Vicente Hernández Díaz
+ * @author Yuanjiang Huang
+ * UNIVERSIDAD POLITECNICA DE MADRID (UPM)
+ * DEMANES 2014
+ * @version 1.0
+ */
+public class PowerScalingController implements Reasoner {
+
+ private ActionProvider actionsProv = null;
+ private ObservationProvider obsProv = null;
+ private Properties props = null;
+ private double kE;
+ private double kdeltaND;
+ private int ND;
+ private double k_ND;
+ private double k_CR;
+ private final Logger logger;
+
+ // delta_cr is the output of the whole controller
+ private double delta_cr;
+
+ /**
+ * Public constructor using reconfiguration properties {@code props}.
+ *
+ * @param props The reconfiguration properties.
+ */
+ public PowerScalingController(Properties props) {
+
+ logger = SystemContext.getLogger();
+
+ if (props == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No properties specified.");
+ throw new IllegalArgumentException("PowerScalingController: No properties specified.");
+ }
+
+ this.props = props;
+
+ this.delta_cr = 0;
+
+ //Extract mandatory properties from parameter into class attributtes.
+ String property = props.getProperty(ReasonerProperties.KE_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No kE provided");
+ throw new IllegalArgumentException("PowerScalingController: No kE provided");
+ }
+ try {
+ kE = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for kE is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for kE is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KdeltaND_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No kdeltaND provided");
+ throw new IllegalArgumentException("PowerScalingController: No kdeltaND provided");
+ }
+ try {
+ kdeltaND = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for kdeltaND is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for kdeltaND is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.NDinitPROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No ND provided");
+ throw new IllegalArgumentException("PowerScalingController: No ND provided");
+ }
+ try {
+ ND = Integer.parseInt(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for ND is not an integer: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for ND is not an integer: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KND_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No k_ND provided");
+ throw new IllegalArgumentException("PowerScalingController: No k_ND provided");
+ }
+ try {
+ k_ND = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for k_ND is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for k_ND is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KCR_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No k_CR provided");
+ throw new IllegalArgumentException("PowerScalingController: No k_CR provided");
+ }
+ try {
+ k_CR = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for k_CR is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for k_CR is not a double: " + property);
+ }
+ logger.log(Level.DEBUG, "PowerScalingController: An instance of PowerScalingController has been successfully instantiated.");
+ logger.log(Level.DEBUG, "PowerScalingController: Controller attributes: ND-> " + ND + ", kE->" + kE + ", kdeltaND->" + kdeltaND + ", k_CR->" + k_CR + ", k_ND->" + k_ND + ").");
+ }
+
+ /**
+ * Set the {@link ActuationProvider} for this {@code Reasoner}.
+ *
+ * @param ap The {@link ActuationProvider}
+ */
+ public void setActuationProvider(ActionProvider ap) {
+ if (ap == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.setActuationProvider: Action provider is null.");
+ throw new IllegalArgumentException("PowerScalingController.setActuationProvider: Action provider is null.");
+ }
+ actionsProv = ap;
+ logger.log(Level.DEBUG, "PowerScalingController.setActuationProvider: An action provider has been registered.");
+ }
+
+ /**
+ * Set the {@link ObservationProvider} for this {@code Reasoner}.
+ *
+ * @param op The {@link ObservationProvider}
+ */
+ public void setObservationProvider(ObservationProvider op) {
+ if (op == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.setObservationProvider: Observation provider is null.");
+ throw new IllegalArgumentException("PowerScalingController.setObservationProvider: Observation provider is null.");
+ }
+ obsProv = op;
+ logger.log(Level.DEBUG, "PowerScalingController.setObservationProvider: An observation provider has been registered.");
+ }
+
+ /**
+ * Used to fire the {@link Reasoner}.
+ */
+ public void trigger() {
+ try {
+ ANES_URN event = (ANES_URN) obsProv.getValue(ANES_URN.create(DEMANESResources.TriggerReasonURN));
+ Object value = (Object) obsProv.getValue(ANES_URN.create(DEMANESResources.TriggerReasonValueURN));
+
+ this.trigger(event, value);
+ } catch (ANES_URN_Exception ex) {
+ ex.printStackTrace();
+ } catch (InexistentObservationID ex) {
+ ex.printStackTrace();
+ } catch (ObservationInvocationException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Used to fire the {@link Reasoner}. This is a proposed extension to
+ * the DEMANES middleware reasoning middleware.
+ *
+ * @param urn {@link ANES_URN} for the reason.
+ * @param value Value of the reason.
+ */
+ public void trigger(ANES_URN urn, Object value) {
+ // BEGIN values for recording at the end of the trigger.
+ long timestamp = System.currentTimeMillis();
+ int nodeDegree = -1;
+ double batteryLevel = -1;
+ int delta_nd = Integer.MIN_VALUE;
+ int transmissionPower = ((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower();
+
+ try {
+ nodeDegree = ((Integer) obsProv.getValue(ANES_URN.create(DEMANESResources.NDObservationURN))).intValue();
+ batteryLevel = ((Double) obsProv.getValue(ANES_URN.create(DEMANESResources.BLObservationURN))).doubleValue();
+ } catch (ANES_URN_Exception ex) {
+
+ } catch (InexistentObservationID ex) {
+
+ } catch (ObservationInvocationException ex) {
+
+ }
+
+ if (urn == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: No URN provided.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: No URN provided.");
+ }
+
+ try {
+ if (!urn.equals(ANES_URN.create(Events.BL_EVENT))
+ && !urn.equals(ANES_URN.create(Events.ND_EVENT))) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Invalid URN value: " + urn);
+ throw new IllegalArgumentException("PowerScalingController.trigger: Invalid URN value: " + urn);
+ }
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: ANES_URN.create failed when using Events enum values.");
+ throw new IllegalStateException("PowerScalingController.trigger: ANES_URN.create failed when using Events enum values.");
+ }
+
+ if (value == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: No value provided.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: No value provided.");
+ }
+ if (this.actionsProv == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The method trigger has been called but no action provider has been set yet");
+ throw new IllegalStateException("PowerScalingController.trigger: The method trigger has been called but no action provider has been set yet");
+ }
+ if (this.obsProv == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The method trigger has been called but no observation provider has been set yet");
+ throw new IllegalStateException("PowerScalingController.trigger: The method trigger has been called but no observation provider has been set yet");
+ }
+
+ try {
+
+ if (urn.equals(ANES_URN.create(Events.BL_EVENT))) {
+ if (!(value instanceof Double)) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The error is not a double object.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: The error is not a double object.");
+ }
+ double error = ((Double) value).doubleValue();
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: A BL_EVENT has been triggered. Value: " + value + " | Error: " + error);
+ int errorND = this.runSecondaryLoop(error);
+ // FOR LOGGING PURPOSES ONLY
+ delta_nd = errorND + nodeDegree - ND;
+ // FOR LOGGING PURPOSES ONLY
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Output from secondary loop (ND error): " + errorND);
+ this.runPrimaryLoop(errorND);
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Output from primary loop (deltaCR): " + this.delta_cr);
+ }
+ if (urn.equals(ANES_URN.create(Events.ND_EVENT))) {
+ if (!(value instanceof Integer)) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The error is not an integer object.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: The error is not an integer object.");
+ }
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: A ND_EVENT has been triggered. Value: " + value);
+ int error = ((Integer) value).intValue();
+ this.runPrimaryLoop(error);
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Output from primary loop (deltaCR): " + this.delta_cr);
+ }
+ } catch (ANES_URN_Exception ex) {
+ // This exception can not occur at this point as it has been tested.
+ }
+
+ ANES_BUNDLE bundle = new SunSPOTBundle();
+
+ bundle.put(DEMANESResources.DELTA_CR_KEY, new Double(this.delta_cr));
+
+ try {
+ this.actionsProv.invoke(ANES_URN.create(DEMANESResources.PTActionURN), bundle);
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: ANES_URN.create failed when using DEMANESResources enum values.");
+ throw new IllegalStateException("PowerScalingController.trigger: ANES_URN.create failed when using DEMANESResources enum values.");
+ } catch (InexistentActionID ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: No ActionID: " + ex.getMessage());
+ throw new IllegalStateException("PowerScalingController.trigger: No ActionID: " + ex.getMessage());
+ } catch (ActionInvocationException ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Exception when invoking action: " + ex.getMessage());
+ throw new IllegalStateException("PowerScalingController.trigger: Exception when invoking action: " + ex.getMessage());
+ }
+
+ StringBuffer recordInformation = new StringBuffer();
+ recordInformation.append(SystemProperties.IEEE_ADDRESS_VALUE);
+ recordInformation.append(",");
+ recordInformation.append(timestamp);
+ recordInformation.append(",");
+ recordInformation.append(nodeDegree);
+ recordInformation.append(",");
+ recordInformation.append(transmissionPower);
+ recordInformation.append(",");
+ recordInformation.append(batteryLevel);
+ recordInformation.append(",");
+ recordInformation.append(delta_cr);
+ recordInformation.append(",");
+ if (delta_nd != Integer.MIN_VALUE) {
+ recordInformation.append(delta_nd);
+ } else{
+ recordInformation.append("NaN");
+ }
+ recordInformation.append(",");
+ recordInformation.append(urn.toString());
+ recordInformation.append(",");
+ recordInformation.append(value.toString());
+
+ synchronized (this) {
+ logger.setDestination(Logger.RECORD);
+ logger.info(recordInformation.toString());
+ logger.setDestination(Logger.SYSTEM_OUTPUT);
+ }
+ logger.info(recordInformation.toString());
+ }
+
+ /**
+ * Function of Decision Making.
+ *
+ * @param val Entry value.
+ * @return Response.
+ */
+ private double FDM(double val) {
+ if (val >= 0.5) {
+ return 1;
+ }
+
+ if (val <= -0.5) {
+ return -1;
+ }
+
+ if ((val >= -0.25) && (val <= 0.25)) {
+ return 0;
+ }
+
+ if ((val > -0.5) && (val < -0.25)) {
+ return 4 * val + 1;
+ }
+
+ if ((val < 0.5) && (val > 0.25)) {
+ return 4 * val - 1;
+ }
+
+ throw new IllegalArgumentException("Error in val parameter for FDM: " + val);
+ }
+
+ /**
+ * Get the Node Degree (Number of neighbors).
+ *
+ * @return The node degree.
+ * @throws ANES_URN_Exception If the {@link ANES_URN} to the {@link Observation} is not valid.
+ * @throws InexistentObservationID If the {@link Observation} is not registered.
+ * @throws ObservationInvocationException If there is any other error calling the {@link Observation}.
+ */
+ private int getND() throws ANES_URN_Exception, InexistentObservationID, ObservationInvocationException {
+ Object o = obsProv.getValue(new ANES_URN(DEMANESResources.NDObservationURN));
+ if (!(o instanceof Integer)) {
+ throw new IllegalStateException("The observed node degree is not an integer.");
+ }
+ return ((Integer) o).intValue();
+ }
+
+ /**
+ * Run the reconfiguration algorithm primary loop.
+ *
+ * @param error The error used as an entry value.
+ */
+ private void runPrimaryLoop(int error) {
+
+ double e1 = error * k_ND;
+ double delta_u1 = FDM(e1);
+
+ // set the output
+ this.delta_cr = delta_u1 * k_CR;
+ }
+
+ /**
+ * Run the reconfiguration algorithm secondary loop.
+ *
+ * @param error The error used as an entry value.
+ */
+ private int runSecondaryLoop(double error) {
+ /*
+ 1.- Calculate e2=ke * eE.
+ eE is the parameter value.
+ ke is a property.
+ */
+ /*
+ In the future, we should replace by a FuzzyDM implementation.
+ */
+ double e2 = error * kE;
+ /*
+ 2.- Calculate increment of U2 = the output from FDM2.
+ */
+ double incrU2 = this.FDM(e2);
+
+ /*
+ 3.- Calculate increment of Node Degree = increment of U2 * KincrND.
+ */
+ int incrND = (int) Math.ceil(incrU2 * kdeltaND);
+ logger.info("PowerScalingController secondary loop incrND = " + incrND);
+
+ /*
+ 4.- We get the new value for the node degree reference.
+ */
+ int NDRef = ND + incrND;
+ props.setProperty(ReasonerProperties.ND_R_PROPERTY, Integer.toString(NDRef));
+
+ try {
+ /*
+ 5.- We need to get ND observation to run the Primary Loop
+ */
+ return NDRef - getND();
+
+ /*
+ End of FuzzyDM implementation
+ */
+ } catch (ANES_URN_Exception ex) {
+ throw new IllegalStateException("Error in URN: " + DEMANESResources.BLObservationURN + "Message: " + ex.getMessage());
+ } catch (InexistentObservationID ex) {
+ throw new IllegalStateException("No existent ObservationID: " + ex.getMessage());
+ } catch (ObservationInvocationException ex) {
+ throw new IllegalStateException("Error when observing the node degree: " + ex.getMessage());
+ }
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFactory.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFactory.java
new file mode 100644
index 0000000..41710f8
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFactory.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+import com.sun.spot.core.util.Properties;
+import eu.artemis.demanes.reconfiguration.Reasoner;
+
+/**
+ * Factory to create an object of the specified Power Scaling Controller.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class PowerScalingControllerFactory {
+
+ /**
+ * Creates an instance of the requested Power Scaling Controller.
+ *
+ * @param what Descriptor of the Power Scaling Controller to instantiate.
+ * @param props Reconfiguration properties.
+ * @return A Power Scaling Controller object as requested.
+ */
+ public static Reasoner getInstance( String what, Properties props ){
+ Reasoner result = null;
+
+ if ( what.equalsIgnoreCase("PTSimple"))
+ result = new PowerScalingController(props);
+
+ if ( what.equalsIgnoreCase("PTjFuzzyLogic"))
+ result = new PowerScalingControllerFuzzyLogic(props);
+
+ if ( what.equalsIgnoreCase("PTInterp1DFDM"))
+ result = new PowerScalingControllerInterp1FDM(props);
+
+ return result;
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFuzzyLogic.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFuzzyLogic.java
new file mode 100644
index 0000000..b2c9911
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerFuzzyLogic.java
@@ -0,0 +1,374 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+
+import com.sun.spot.core.util.Properties;
+import com.sun.squawk.util.NotImplementedYetException;
+import eu.artemis.demanes.datatypes.ANES_BUNDLE;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.datatypes.ANES_URN_Exception;
+import eu.artemis.demanes.exceptions.ActionInvocationException;
+import eu.artemis.demanes.exceptions.InexistentActionID;
+import eu.artemis.demanes.exceptions.InexistentObservationID;
+import eu.artemis.demanes.exceptions.ObservationInvocationException;
+import eu.artemis.demanes.impl.SunSPOT.common.DEMANESResources;
+import eu.artemis.demanes.impl.SunSPOT.common.Events;
+import eu.artemis.demanes.impl.SunSPOT.common.ReasonerProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.datatypes.SunSPOTBundle;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.reconfiguration.ActionProvider;
+import eu.artemis.demanes.reconfiguration.ObservationProvider;
+import eu.artemis.demanes.reconfiguration.Reasoner;
+
+/**
+ *
+ * This object class models the fuzzy logic controller that will make decisions
+ * whenever trigger is called.
+ *
+ * @author Vicente Hernández Díaz
+ * @author Yuanjiang Huang
+ * UNIVERSIDAD POLITECNICA DE MADRID (UPM)
+ * DEMANES 2014
+ * @version 1.0
+ */
+
+public class PowerScalingControllerFuzzyLogic implements Reasoner{
+ private ActionProvider actionsProv = null;
+ private ObservationProvider obsProv = null;
+ private Properties props = null;
+ private double kE;
+ private double kdeltaND;
+ private int ND;
+ private double k_ND;
+ private double k_CR;
+ private final Logger logger;
+
+ // delta_cr is the output of the whole controller
+ private double delta_cr;
+
+ /**
+ * Public constructor using reconfiguration properties {@code props}.
+ *
+ * @param props The reconfiguration properties.
+ */
+ public PowerScalingControllerFuzzyLogic(Properties props) {
+
+ logger = SystemContext.getLogger();
+
+ if (props == null) {
+ logger.log(Level.DEBUG,"PowerScalingController: No properties specified.");
+ throw new IllegalArgumentException("PowerScalingController: No properties specified.");
+ }
+
+ this.props = props;
+
+ this.delta_cr = 0;
+
+ //Extract mandatory properties from parameter into class attributtes.
+ String property = props.getProperty(ReasonerProperties.KE_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG,"PowerScalingController: No kE provided");
+ throw new IllegalArgumentException("PowerScalingController: No kE provided");
+ }
+ try {
+ kE = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG,"PowerScalingController: The value for kE is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for kE is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KdeltaND_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG,"PowerScalingController: No kdeltaND provided");
+ throw new IllegalArgumentException("PowerScalingController: No kdeltaND provided");
+ }
+ try {
+ kdeltaND = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG,"PowerScalingController: The value for kdeltaND is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for kdeltaND is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.NDinitPROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG,"PowerScalingController: No ND provided");
+ throw new IllegalArgumentException("PowerScalingController: No ND provided");
+ }
+ try {
+ ND = Integer.parseInt(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG,"PowerScalingController: The value for ND is not an integer: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for ND is not an integer: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KND_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG,"PowerScalingController: No k_ND provided");
+ throw new IllegalArgumentException("PowerScalingController: No k_ND provided");
+ }
+ try {
+ k_ND = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG,"PowerScalingController: The value for k_ND is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for k_ND is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KCR_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG,"PowerScalingController: No k_CR provided");
+ throw new IllegalArgumentException("PowerScalingController: No k_CR provided");
+ }
+ try {
+ k_CR = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG,"PowerScalingController: The value for k_CR is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for k_CR is not a double: " + property);
+ }
+ logger.log(Level.DEBUG, "PowerScalingController: An instance of PowerScalingController has been successfully instantiated.");
+ logger.log(Level.DEBUG, "PowerScalingController: Controller attributes: ND-> "+ND+", kE->"+kE+", kdeltaND->"+kdeltaND+", k_CR->"+k_CR+", k_ND->"+k_ND+").");
+
+
+ // Extraer de las propiedades el nombre del fichero .ini del primary loop
+ // Extraer de las propiedades el nombre del fichero .ini del secondary loop
+ // Abres el InputStream #1 y el InputStream #2
+ }
+
+ /**
+ * Set the {@link ActuationProvider} for this {@code Reasoner}.
+ *
+ * @param ap The {@link ActuationProvider}
+ */
+ public void setActuationProvider(ActionProvider ap) {
+ if (ap == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.setActuationProvider: Action provider is null.");
+ throw new IllegalArgumentException("PowerScalingController.setActuationProvider: Action provider is null.");
+ }
+ actionsProv = ap;
+ logger.log(Level.DEBUG, "PowerScalingController.setActuationProvider: An action provider has been registered.");
+ }
+
+ /**
+ * Set the {@link ObservationProvider} for this {@code Reasoner}.
+ *
+ * @param op The {@link ObservationProvider}
+ */
+ public void setObservationProvider(ObservationProvider op) {
+ if (op == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.setObservationProvider: Observation provider is null.");
+ throw new IllegalArgumentException("PowerScalingController.setObservationProvider: Observation provider is null.");
+ }
+ obsProv = op;
+ logger.log(Level.DEBUG, "PowerScalingController.setObservationProvider: An observation provider has been registered.");
+ }
+
+ /**
+ * Used to fire the {@link Reasoner}.
+ */
+ public void trigger() {
+ try {
+ ANES_URN event = (ANES_URN) obsProv.getValue(ANES_URN.create(DEMANESResources.TriggerReasonURN));
+ Object value = (Object) obsProv.getValue(ANES_URN.create(DEMANESResources.TriggerReasonValueURN));
+
+ this.trigger(event, value);
+ } catch (ANES_URN_Exception ex) {
+ ex.printStackTrace();
+ } catch (InexistentObservationID ex) {
+ ex.printStackTrace();
+ } catch (ObservationInvocationException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Used to fire the {@link Reasoner}. This is a proposed extension to
+ * the DEMANES middleware reasoning middleware.
+ *
+ * @param urn {@link ANES_URN} for the reason.
+ * @param value Value of the reason.
+ */
+ public void trigger(ANES_URN urn, Object value) {
+ if (urn == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: No URN provided.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: No URN provided.");
+ }
+
+ try {
+ if (!urn.equals(ANES_URN.create(Events.BL_EVENT))
+ && !urn.equals(ANES_URN.create(Events.ND_EVENT))) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Invalid URN value: " + urn);
+ throw new IllegalArgumentException("PowerScalingController.trigger: Invalid URN value: " + urn);
+ }
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: ANES_URN.create failed when using Events enum values.");
+ throw new IllegalStateException("PowerScalingController.trigger: ANES_URN.create failed when using Events enum values.");
+ }
+
+ if (value == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: No value provided." );
+ throw new IllegalArgumentException("PowerScalingController.trigger: No value provided.");
+ }
+ if (this.actionsProv == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The method trigger has been called but no action provider has been set yet");
+ throw new IllegalStateException("PowerScalingController.trigger: The method trigger has been called but no action provider has been set yet");
+ }
+ if (this.obsProv == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The method trigger has been called but no observation provider has been set yet");
+ throw new IllegalStateException("PowerScalingController.trigger: The method trigger has been called but no observation provider has been set yet");
+ }
+
+ try {
+
+ if (urn.equals(ANES_URN.create(Events.BL_EVENT))) {
+ if (!(value instanceof Double)) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The error is not a double object.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: The error is not a double object.");
+ }
+ double error = ((Double) value).doubleValue();
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: A BL_EVENT has been triggered. Value: " + value);
+ int errorND = this.runSecondaryLoop(error);
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Output from secondary loop (ND error): " + errorND);
+ this.runPrimaryLoop(errorND);
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Output from primary loop (deltaCR): " + this.delta_cr);
+ }
+ if (urn.equals(ANES_URN.create(Events.ND_EVENT))) {
+ if (!(value instanceof Integer)) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The error is not an integer object.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: The error is not an integer object.");
+ }
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: A ND_EVENT has been triggered. Value: " + value);
+ int error = ((Integer) value).intValue();
+ this.runPrimaryLoop(error);
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Output from primary loop (deltaCR): " + this.delta_cr);
+ }
+ } catch (ANES_URN_Exception ex) {
+ // This exception can not occur at this point as it has been tested.
+ }
+
+ ANES_BUNDLE bundle = new SunSPOTBundle();
+
+ bundle.put(DEMANESResources.DELTA_CR_KEY, new Double(this.delta_cr));
+
+ try {
+ this.actionsProv.invoke(ANES_URN.create(DEMANESResources.PTActionURN), bundle);
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: ANES_URN.create failed when using DEMANESResources enum values.");
+ throw new IllegalStateException("PowerScalingController.trigger: ANES_URN.create failed when using DEMANESResources enum values.");
+ } catch (InexistentActionID ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: No ActionID: "+ex.getMessage());
+ throw new IllegalStateException("PowerScalingController.trigger: No ActionID: "+ex.getMessage());
+ } catch (ActionInvocationException ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Exception when invoking action: "+ex.getMessage());
+ throw new IllegalStateException("PowerScalingController.trigger: Exception when invoking action: "+ex.getMessage());
+ }
+
+ }
+
+ private double FDM(double val) {
+ if (val >= 0.5) {
+ return 1;
+ }
+
+ if (val <= -0.5) {
+ return -1;
+ }
+
+ if ((val >= -0.25) && (val <= 0.25)) {
+ return 0;
+ }
+
+ if (val > -0.5) {
+ return 4 * val + 1;
+ }
+
+ if (val < 0.5) {
+ return 4 * val - 1;
+ }
+
+ throw new IllegalArgumentException("Error in val parameter for FDM: " + val);
+ }
+
+ private int getND() throws ANES_URN_Exception, InexistentObservationID, ObservationInvocationException {
+ Object o = obsProv.getValue(new ANES_URN(DEMANESResources.NDObservationURN));
+ if ( !(o instanceof Integer))
+ throw new IllegalStateException("The observed node degree is not an integer.");
+ return ((Integer)o).intValue();
+ }
+
+ private void runPrimaryLoop(int error) {
+
+ double e1 = error * k_ND;
+ double delta_u1 = FDM(e1);
+
+ // set the output
+ this.delta_cr = delta_u1 * k_CR;
+
+ }
+
+ private int runSecondaryLoop(double error) {
+ /*
+ 1.- Calculate e2=ke * eE.
+ eE is the parameter value.
+ ke is a property.
+ */
+ /*
+ In the future, we should replace by a FuzzyDM implementation.
+ */
+ double e2 = error * kE;
+
+ /*
+ 2.- Calculate increment of U2 = the output from FDM2.
+ */
+ double incrU2 = this.FDM(e2);
+
+ /*
+ 3.- Calculate increment of Node Degree = increment of U2 * KincrND.
+ */
+ int incrND = (int) Math.ceil(incrU2 * kdeltaND);
+
+ /*
+ 4.- We get the new value for the node degree reference.
+ */
+ int NDRef = ND + incrND;
+ props.setProperty(ReasonerProperties.ND_R_PROPERTY, Integer.toString(NDRef));
+
+ try {
+ /*
+ 5.- We need to get ND observation to run the Primary Loop
+ */
+ return NDRef - getND();
+
+ /*
+ End of FuzzyDM implementation
+ */
+ } catch (ANES_URN_Exception ex) {
+ throw new IllegalStateException("Error in URN: "+DEMANESResources.BLObservationURN+ "Message: "+ex.getMessage());
+ } catch (InexistentObservationID ex) {
+ throw new IllegalStateException("No existent ObservationID: "+ex.getMessage());
+ } catch (ObservationInvocationException ex) {
+ throw new IllegalStateException("Error when observing the node degree: "+ex.getMessage());
+ }
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerInterp1FDM.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerInterp1FDM.java
new file mode 100644
index 0000000..463084e
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/PowerScalingControllerInterp1FDM.java
@@ -0,0 +1,518 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.core.util.Properties;
+import com.sun.spot.ieee_802_15_4_radio.IRadioPolicyManager;
+import com.sun.squawk.util.NotImplementedYetException;
+import eu.artemis.demanes.datatypes.ANES_BUNDLE;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.datatypes.ANES_URN_Exception;
+import eu.artemis.demanes.exceptions.ActionInvocationException;
+import eu.artemis.demanes.exceptions.InexistentActionID;
+import eu.artemis.demanes.exceptions.InexistentObservationID;
+import eu.artemis.demanes.exceptions.ObservationInvocationException;
+import eu.artemis.demanes.impl.SunSPOT.common.DEMANESResources;
+import eu.artemis.demanes.impl.SunSPOT.common.Events;
+import eu.artemis.demanes.impl.SunSPOT.common.ReasonerProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemProperties;
+import eu.artemis.demanes.impl.SunSPOT.datatypes.SunSPOTBundle;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.reconfiguration.ActionProvider;
+import eu.artemis.demanes.reconfiguration.ObservationProvider;
+import eu.artemis.demanes.reconfiguration.Reasoner;
+import java.io.IOException;
+
+/**
+ *
+ * This object class models the fuzzy logic controller that will make decisions
+ * whenever trigger is called.
+ *
+ * @author Vicente Hernández Díaz
+ * @author Yuanjiang Huang
+ * @author Raúl del Toro Matamoros
+ * UNIVERSIDAD POLITECNICA DE MADRID (UPM)
+ * DEMANES 2014
+ * @version 1.0
+ */
+public class PowerScalingControllerInterp1FDM implements Reasoner {
+
+ private ActionProvider actionsProv = null;
+ private ObservationProvider obsProv = null;
+ private Properties props = null;
+ private double kE;
+ private double kdeltaND;
+ private int ND;
+ private double k_ND;
+ private double k_CR;
+ private final Logger logger;
+ private FuzzyDM FDM_Prim_Loop;
+ private FuzzyDM FDM_Sec_Loop;
+
+ // delta_cr is the output of the whole controller
+ private double delta_cr;
+
+ /**
+ * Public constructor using reconfiguration properties {@code props}.
+ *
+ * @param props The reconfiguration properties.
+ */
+ public PowerScalingControllerInterp1FDM(Properties props) {
+
+ logger = SystemContext.getLogger();
+
+ if (props == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No properties specified.");
+ throw new IllegalArgumentException("PowerScalingController: No properties specified.");
+ }
+
+ this.props = props;
+
+ this.delta_cr = 0;
+
+ //Extract mandatory properties from parameter into class attributtes.
+ String property = props.getProperty(ReasonerProperties.KE_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No kE provided");
+ throw new IllegalArgumentException("PowerScalingController: No kE provided");
+ }
+ try {
+ kE = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for kE is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for kE is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KdeltaND_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No kdeltaND provided");
+ throw new IllegalArgumentException("PowerScalingController: No kdeltaND provided");
+ }
+ try {
+ kdeltaND = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for kdeltaND is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for kdeltaND is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.NDinitPROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No ND provided");
+ throw new IllegalArgumentException("PowerScalingController: No ND provided");
+ }
+ try {
+ ND = Integer.parseInt(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for ND is not an integer: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for ND is not an integer: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KND_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No k_ND provided");
+ throw new IllegalArgumentException("PowerScalingController: No k_ND provided");
+ }
+ try {
+ k_ND = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for k_ND is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for k_ND is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KCR_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No k_CR provided");
+ throw new IllegalArgumentException("PowerScalingController: No k_CR provided");
+ }
+ try {
+ k_CR = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for k_CR is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for k_CR is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.FDM_PRIM_CONFIG_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No FDM_Prim_Prop_File provided");
+ throw new IllegalArgumentException("PowerScalingController: No FDM_Prim_Prop_File provided");
+ }
+ try {
+ FDM_Prim_Loop = new Interp1DFuzzyDM(property);
+ } catch (IOException ex) {
+ logger.log(Level.DEBUG, "PowerScalingController: " + ex.getMessage());
+ throw new IllegalArgumentException("PowerScalingController: " + ex.getMessage());
+ }
+ property = props.getProperty(ReasonerProperties.FDM_SEC_CONFIG_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No FDM_Sec_Prop_File provided");
+ throw new IllegalArgumentException("PowerScalingController: No FDM_Sec_Prop_File provided");
+ }
+ try {
+ FDM_Sec_Loop = new Interp1DFuzzyDM(property);
+ System.err.print(FDM_Sec_Loop);
+ } catch (IOException ex) {
+ String errmsg = "PowerScalingController: " + ex.getMessage();
+ logger.log(Level.DEBUG, errmsg);
+ throw new IllegalArgumentException(errmsg);
+ }
+ property = props.getProperty(ReasonerProperties.du_CR_ID_PROPERTY);
+ if (property == null) {
+ String errmsg = "PowerScalingController: No " + ReasonerProperties.du_CR_ID_PROPERTY + " provided";
+ logger.log(Level.DEBUG, errmsg);
+ throw new IllegalArgumentException(errmsg);
+ }
+ property = props.getProperty(ReasonerProperties.du_ND_ID_PROPERTY);
+ if (property == null) {
+ String errmsg = "PowerScalingController: No " + ReasonerProperties.du_ND_ID_PROPERTY + " provided";
+ logger.log(Level.DEBUG, errmsg);
+ throw new IllegalArgumentException(errmsg);
+ }
+ property = props.getProperty(ReasonerProperties.e_E_ID_PROPERTY);
+ if (property == null) {
+ String errmsg = "PowerScalingController: No " + ReasonerProperties.e_E_ID_PROPERTY + " provided";
+ logger.log(Level.DEBUG, errmsg);
+ throw new IllegalArgumentException(errmsg);
+ }
+ property = props.getProperty(ReasonerProperties.e_ND_ID_PROPERTY);
+ if (property == null) {
+ String errmsg = "PowerScalingController: No " + ReasonerProperties.e_ND_ID_PROPERTY + " provided";
+ logger.log(Level.DEBUG, errmsg);
+ throw new IllegalArgumentException(errmsg);
+ }
+ logger.log(Level.DEBUG, "PowerScalingController: An instance of PowerScalingController has been successfully instantiated.");
+ logger.log(Level.DEBUG, "PowerScalingController: Controller attributes: ND-> " + ND + ", kE->" + kE + ", kdeltaND->" + kdeltaND + ", k_CR->" + k_CR + ", k_ND->" + k_ND + ").");
+ }
+
+ /**
+ * Set the {@link ActuationProvider} for this {@code Reasoner}.
+ *
+ * @param ap The {@link ActuationProvider}
+ */
+ public void setActuationProvider(ActionProvider ap) {
+ if (ap == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.setActuationProvider: Action provider is null.");
+ throw new IllegalArgumentException("PowerScalingController.setActuationProvider: Action provider is null.");
+ }
+ actionsProv = ap;
+ logger.log(Level.DEBUG, "PowerScalingController.setActuationProvider: An action provider has been registered.");
+ }
+
+ /**
+ * Set the {@link ObservationProvider} for this {@code Reasoner}.
+ *
+ * @param op The {@link ObservationProvider}
+ */
+ public void setObservationProvider(ObservationProvider op) {
+ if (op == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.setObservationProvider: Observation provider is null.");
+ throw new IllegalArgumentException("PowerScalingController.setObservationProvider: Observation provider is null.");
+ }
+ obsProv = op;
+ logger.log(Level.DEBUG, "PowerScalingController.setObservationProvider: An observation provider has been registered.");
+ }
+
+ /**
+ * Used to fire the {@link Reasoner}.
+ */
+ public void trigger() {
+ try {
+ ANES_URN event = (ANES_URN) obsProv.getValue(ANES_URN.create(DEMANESResources.TriggerReasonURN));
+ Object value = (Object) obsProv.getValue(ANES_URN.create(DEMANESResources.TriggerReasonValueURN));
+
+ this.trigger(event, value);
+ } catch (ANES_URN_Exception ex) {
+ ex.printStackTrace();
+ } catch (InexistentObservationID ex) {
+ ex.printStackTrace();
+ } catch (ObservationInvocationException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Used to fire the {@link Reasoner}. This is a proposed extension to
+ * the DEMANES middleware reasoning middleware.
+ *
+ * @param urn {@link ANES_URN} for the reason.
+ * @param value Value of the reason.
+ */
+ public void trigger(ANES_URN urn, Object value) {
+ // BEGIN values for recording at the end of the trigger.
+ long timestamp = System.currentTimeMillis();
+ int nodeDegree = -1;
+ double batteryLevel = -1;
+ double delta_nd = Double.NaN;
+ int transmissionPower = ((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower();
+
+ try {
+ nodeDegree = ((Integer) obsProv.getValue(ANES_URN.create(DEMANESResources.NDObservationURN))).intValue();
+ batteryLevel = ((Double) obsProv.getValue(ANES_URN.create(DEMANESResources.BLObservationURN))).doubleValue();
+ } catch (ANES_URN_Exception ex) {
+
+ } catch (InexistentObservationID ex) {
+
+ } catch (ObservationInvocationException ex) {
+
+ }
+
+ if (urn == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: No URN provided.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: No URN provided.");
+ }
+
+ try {
+ if (!urn.equals(ANES_URN.create(Events.BL_EVENT))
+ && !urn.equals(ANES_URN.create(Events.ND_EVENT))) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Invalid URN value: " + urn);
+ throw new IllegalArgumentException("PowerScalingController.trigger: Invalid URN value: " + urn);
+ }
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: ANES_URN.create failed when using Events enum values.");
+ throw new IllegalStateException("PowerScalingController.trigger: ANES_URN.create failed when using Events enum values.");
+ }
+
+ if (value == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: No value provided.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: No value provided.");
+ }
+ if (this.actionsProv == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The method trigger has been called but no action provider has been set yet");
+ throw new IllegalStateException("PowerScalingController.trigger: The method trigger has been called but no action provider has been set yet");
+ }
+ if (this.obsProv == null) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The method trigger has been called but no observation provider has been set yet");
+ throw new IllegalStateException("PowerScalingController.trigger: The method trigger has been called but no observation provider has been set yet");
+ }
+
+ try {
+
+ if (urn.equals(ANES_URN.create(Events.BL_EVENT))) {
+ if (!(value instanceof Double)) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The error is not a double object.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: The error is not a double object.");
+ }
+ double error = ((Double) value).doubleValue();
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: A BL_EVENT has been triggered. Value: " + value + " | Error: " + error);
+ int errorND = this.runSecondaryLoop(error);
+ // FOR LOGGING PURPOSES ONLY
+ delta_nd = errorND + nodeDegree - ND;
+ // FOR LOGGING PURPOSES ONLY
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Output from secondary loop (ND error): " + errorND);
+ this.runPrimaryLoop(errorND);
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Output from primary loop (deltaCR): " + this.delta_cr);
+ }
+ if (urn.equals(ANES_URN.create(Events.ND_EVENT))) {
+ if (!(value instanceof Double)) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: The error is not an integer object.");
+ throw new IllegalArgumentException("PowerScalingController.trigger: The error is not an integer object.");
+ }
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: A ND_EVENT has been triggered. Value: " + value);
+ double error = ((Double) value).doubleValue();
+ this.runPrimaryLoop(error);
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Output from primary loop (deltaCR): " + this.delta_cr);
+ }
+ } catch (ANES_URN_Exception ex) {
+ // This exception can not occur at this point as it has been tested.
+ }
+
+ ANES_BUNDLE bundle = new SunSPOTBundle();
+
+ bundle.put(DEMANESResources.DELTA_CR_KEY, new Double(this.delta_cr));
+
+ try {
+ this.actionsProv.invoke(ANES_URN.create(DEMANESResources.PTActionURN), bundle);
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: ANES_URN.create failed when using DEMANESResources enum values.");
+ throw new IllegalStateException("PowerScalingController.trigger: ANES_URN.create failed when using DEMANESResources enum values.");
+ } catch (InexistentActionID ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: No ActionID: " + ex.getMessage());
+ throw new IllegalStateException("PowerScalingController.trigger: No ActionID: " + ex.getMessage());
+ } catch (ActionInvocationException ex) {
+ logger.log(Level.DEBUG, "PowerScalingController.trigger: Exception when invoking action: " + ex.getMessage());
+ throw new IllegalStateException("PowerScalingController.trigger: Exception when invoking action: " + ex.getMessage());
+ }
+
+ StringBuffer recordInformation = new StringBuffer();
+ recordInformation.append(SystemProperties.IEEE_ADDRESS_VALUE);
+ recordInformation.append(",");
+ recordInformation.append(timestamp);
+ recordInformation.append(",");
+ recordInformation.append(nodeDegree);
+ recordInformation.append(",");
+ recordInformation.append(transmissionPower);
+ recordInformation.append(",");
+ recordInformation.append(batteryLevel);
+ recordInformation.append(",");
+ recordInformation.append(delta_cr);
+ recordInformation.append(",");
+ if (delta_nd != Double.NaN) {
+ recordInformation.append(delta_nd);
+ } else {
+ recordInformation.append("NaN");
+ }
+ recordInformation.append(",");
+ recordInformation.append(urn.toString());
+ recordInformation.append(",");
+ recordInformation.append(value.toString());
+
+ synchronized (this) {
+ logger.setDestination(Logger.RECORD);
+ logger.info(recordInformation.toString());
+ logger.setDestination(Logger.SYSTEM_OUTPUT);
+ }
+ logger.info(recordInformation.toString());
+ }
+
+ private int getND() throws ANES_URN_Exception, InexistentObservationID, ObservationInvocationException {
+ Object o = obsProv.getValue(new ANES_URN(DEMANESResources.NDObservationURN));
+ if (!(o instanceof Integer)) {
+ throw new IllegalStateException("The observed node degree is not an integer.");
+ }
+ return ((Integer) o).intValue();
+ }
+
+ private void runPrimaryLoop(double error) {
+
+ String e_ND_ID = this.props.getProperty(ReasonerProperties.e_ND_ID_PROPERTY);
+ String du_CR_ID = this.props.getProperty(ReasonerProperties.du_CR_ID_PROPERTY);
+
+ // read the property each time it needs. This is for the runtime reconfiguration of the parameters.
+ String property = props.getProperty(ReasonerProperties.KND_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No k_ND provided");
+ throw new IllegalArgumentException("PowerScalingController: No k_ND provided");
+ }
+ try {
+ k_ND = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for k_ND is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for k_ND is not a double: " + property);
+ }
+
+ property = props.getProperty(ReasonerProperties.KCR_PROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No k_CR provided");
+ throw new IllegalArgumentException("PowerScalingController: No k_CR provided");
+ }
+ try {
+ k_CR = Double.parseDouble(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for k_CR is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for k_CR is not a double: " + property);
+ }
+
+ // 1- Setting normalization factors
+ if (!this.FDM_Prim_Loop.setNormFactors(e_ND_ID, this.k_ND)) {
+ throw new IllegalStateException(ERRORMSG.VARIABLE_ERROR_ACCESS + ERRORMSG.DELIM + e_ND_ID);
+ }
+ if (!this.FDM_Prim_Loop.setNormFactors(du_CR_ID, this.k_CR)) {
+ throw new IllegalStateException(ERRORMSG.VARIABLE_ERROR_ACCESS + ERRORMSG.DELIM + du_CR_ID);
+ }
+
+ // 2- Setting the input
+ if (!this.FDM_Prim_Loop.setInput(e_ND_ID, error)) {
+ throw new IllegalStateException(ERRORMSG.VARIABLE_ERROR_ACCESS + ERRORMSG.DELIM + e_ND_ID);
+ }
+
+ // 3- "Reasoning": normalization, inference process & denormalization
+ this.FDM_Prim_Loop.evaluate();
+
+ // 4- Getting the output
+ this.delta_cr = ((Double) this.FDM_Prim_Loop.getOutput(du_CR_ID)).doubleValue();
+
+ }
+
+ private int runSecondaryLoop(double error) {
+
+ String e_E_ID = this.props.getProperty(ReasonerProperties.e_E_ID_PROPERTY);
+ String du_ND_ID = this.props.getProperty(ReasonerProperties.du_ND_ID_PROPERTY);
+
+ /*
+ 1.- Setting normalization factors
+ */
+ if (!this.FDM_Sec_Loop.setNormFactors(e_E_ID, this.kE)) {
+ throw new IllegalStateException(ERRORMSG.VARIABLE_ERROR_ACCESS + ERRORMSG.DELIM + e_E_ID);
+ }
+ if (!this.FDM_Sec_Loop.setNormFactors(du_ND_ID, this.kdeltaND)) {
+ throw new IllegalStateException(ERRORMSG.VARIABLE_ERROR_ACCESS + ERRORMSG.DELIM + du_ND_ID);
+ }
+
+ /*
+ 2.- Setting the input
+ */
+ if (!this.FDM_Sec_Loop.setInput(e_E_ID, (double) error)) {
+ throw new IllegalStateException(ERRORMSG.VARIABLE_ERROR_ACCESS + ERRORMSG.DELIM + e_E_ID);
+ }
+
+ /*
+ 3.- "Reasoning" to calculate increment U2 = the output from FDM2
+ Normalization -> inference process -> denormalization
+ */
+ this.FDM_Sec_Loop.evaluate();
+
+ /*
+ 4.- Calculates increment of Node Degree = increment of U2 * KincrND.
+ */
+ int incrND = (int) Math.ceil(((Double) this.FDM_Sec_Loop.getOutput(du_ND_ID)).doubleValue());
+
+ logger.info("PowerScalingController secondary loop incrND = " + incrND);
+
+ /*
+ 5.- We get the new value for the node degree reference.
+ */
+ String property = props.getProperty(ReasonerProperties.NDRefPROPERTY);
+ if (property == null) {
+ logger.log(Level.DEBUG, "PowerScalingController: No NDRef provided");
+ throw new IllegalArgumentException("PowerScalingController: No NDRef provided");
+ }
+ try {
+ ND = Integer.parseInt(property);
+ } catch (NumberFormatException e) {
+ logger.log(Level.DEBUG, "PowerScalingController: The value for NDRef is not a double: " + property);
+ throw new IllegalArgumentException("PowerScalingController: The value for NDRef is not a double: " + property);
+ }
+
+ int ND_R = ND + incrND;
+ props.setProperty(ReasonerProperties.ND_R_PROPERTY, Integer.toString(ND_R));
+
+ try {
+ /*
+ 6.- We need to get ND observation to run the Primary Loop
+ */
+ return ND_R - getND();
+
+ /*
+ End of FuzzyDM implementation
+ */
+ } catch (ANES_URN_Exception ex) {
+ throw new IllegalStateException("Error in URN: " + DEMANESResources.BLObservationURN + "Message: " + ex.getMessage());
+ } catch (InexistentObservationID ex) {
+ throw new IllegalStateException("No existent ObservationID: " + ex.getMessage());
+ } catch (ObservationInvocationException ex) {
+ throw new IllegalStateException("Error when observing the node degree: " + ex.getMessage());
+ }
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Variable.java b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Variable.java
new file mode 100644
index 0000000..1449e3b
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/fuzzyReasoner/Variable.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.fuzzyReasoner;
+
+import java.util.Hashtable;
+
+/**
+ * @author Raúl del Toro Matamoros
+ * @version 1.0.0
+ */
+public class Variable {
+ public static final String VAR_VALUE = "VarValue";
+ public static final String VAR_VALUE_NORM = "VarValueNorm";
+ public static final String VAR_KNORM = "VarKnorm";
+ public static final String VAR_NUMBER = "VarNumber";
+
+ private Hashtable Prop;
+
+ public Variable(String VarType){
+ this.Prop = new Hashtable();
+
+ this.Prop.put(KEY.VAR_ID, "VAR_ID");
+ this.Prop.put(KEY.VAR_MIN, new Double(Double.NEGATIVE_INFINITY));
+ this.Prop.put(KEY.VAR_MAX, new Double(Double.POSITIVE_INFINITY));
+ // "IN" or "OUT"
+ this.Prop.put(KEY.VAR_TYPE, VarType);
+ this.Prop.put(VAR_VALUE, new Double(Double.NaN));
+ this.Prop.put(VAR_VALUE_NORM, new Double(Double.NaN));
+ this.Prop.put(VAR_KNORM, new Double(1.0));
+ this.Prop.put(VAR_NUMBER, new Integer(1));
+ }
+
+ public void setVarID(String Var_ID){
+ this.Prop.put(KEY.VAR_ID, new String(Var_ID));
+ }
+
+ public void setKnorm(Object Knorm){
+ this.Prop.put(VAR_KNORM, Double.valueOf((Knorm.toString()).trim()));
+ }
+
+ public void setKnorm(double Knorm){
+ this.Prop.put(VAR_KNORM, new Double(Knorm));
+ }
+
+ public double getValue(){
+ return ((Double)this.Prop.get(VAR_VALUE)).doubleValue();
+ }
+
+ public double getValueNorm(){
+ return ((Double)this.Prop.get(VAR_VALUE_NORM)).doubleValue();
+ }
+
+ public void setValue(Object VarValue){
+ this.Prop.put(VAR_VALUE, Double.valueOf((VarValue.toString()).trim()));
+ }
+
+ public void setValue(double VarValue){
+ this.Prop.put(VAR_VALUE, Double.valueOf(VarValue));
+ }
+
+ public void setNumber(int VarNumber){
+ this.Prop.put(VAR_NUMBER, new Integer(VarNumber));
+ }
+
+ public void setValueNorm(Double VarValue){
+ this.Prop.put(VAR_VALUE_NORM, new Double(VarValue.doubleValue()));
+ }
+
+ public void setValueNorm(double VarValue){
+ this.Prop.put(VAR_VALUE_NORM, new Double(VarValue));
+ }
+
+ public void normVar(){
+ double Knorm;
+ Double var_value;
+
+ Knorm = ((Double)this.Prop.get(VAR_KNORM)).doubleValue();
+ var_value = (Double)this.Prop.get(VAR_VALUE);
+
+ if (!var_value.isNaN())
+ this.Prop.put(VAR_VALUE_NORM, Double.valueOf((var_value.doubleValue()) * Knorm));
+ }
+
+ public void denormVar(){
+ double Knorm;
+ Double var_value;
+
+ Knorm = ((Double)this.Prop.get(VAR_KNORM)).doubleValue();
+ var_value = (Double)this.Prop.get(VAR_VALUE_NORM);
+
+ if (!var_value.isNaN())
+ this.Prop.put(VAR_VALUE, Double.valueOf((var_value.doubleValue()) * Knorm));
+ }
+
+ public void put(String key, String value) {
+ this.Prop.put(key, Double.valueOf(value));
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/ORAMediatorForSunSPOT.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/ORAMediatorForSunSPOT.java
new file mode 100644
index 0000000..cede6ba
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/ORAMediatorForSunSPOT.java
@@ -0,0 +1,394 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration;
+
+import com.sun.spot.core.util.Properties;
+import eu.artemis.demanes.datatypes.ANES_BUNDLE;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.exceptions.ActionInvocationException;
+import eu.artemis.demanes.exceptions.InexistentActionID;
+import eu.artemis.demanes.exceptions.InexistentObservationID;
+import eu.artemis.demanes.exceptions.ObservationInvocationException;
+import eu.artemis.demanes.impl.SunSPOT.common.MediatorProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.reconfiguration.Action;
+import eu.artemis.demanes.reconfiguration.ActionProvider;
+import eu.artemis.demanes.reconfiguration.Actuator;
+import eu.artemis.demanes.reconfiguration.ORAMediator;
+import eu.artemis.demanes.reconfiguration.Observation;
+import eu.artemis.demanes.reconfiguration.ObservationProvider;
+import eu.artemis.demanes.reconfiguration.Observer;
+import eu.artemis.demanes.reconfiguration.Reasoner;
+import eu.artemis.demanes.reconfiguration.TriggerPolicy;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * An object of class {@code ORAMediatorForSunSPOT} acts as a mediator
+ * between the {@link TriggerPolicy}, the {@link Reasoner}, a set of
+ * {@link Observer} objects and a set of {@link Actuator} objects.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class ORAMediatorForSunSPOT implements ORAMediator, ActionProvider, ObservationProvider {
+
+ private static final String UPDATE_LIST_DYNAMIC_BEHAVIOUR = "dynamic";
+ private static final String UPDATE_LIST_STATIC_BEHAVIOUR = "static";
+
+ private static final String DEFAULT_UPDATE_LIST_BEHAVIOUR = UPDATE_LIST_STATIC_BEHAVIOUR;
+
+ private Reasoner reasoner;
+ private TriggerPolicy triggerPolicy;
+ private Hashtable actionMap;
+ private Hashtable observationMap;
+ private Vector actuators;
+ private Vector observers;
+ private Vector actions;
+ private Vector observations;
+
+ private Logger logger;
+
+ private String updateListBehaviour;
+
+ /**
+ * Public constructor.
+ */
+ public ORAMediatorForSunSPOT() {
+ this.reasoner = null;
+ this.triggerPolicy = null;
+ this.actionMap = new Hashtable();
+ this.observationMap = new Hashtable();
+ this.actuators = new Vector();
+ this.observers = new Vector();
+ this.actions = new Vector();
+ this.observations = new Vector();
+ this.logger = SystemContext.getLogger();
+
+ this.updateListBehaviour = DEFAULT_UPDATE_LIST_BEHAVIOUR;
+ }
+
+ /**
+ * Public constructor using a set of reasoning {@code properties}.
+ *
+ * @param properties The reasoning properties.
+ */
+ public ORAMediatorForSunSPOT(Properties properties) {
+ this();
+
+ this.updateListBehaviour = properties.getProperty(MediatorProperties.UPDATE_LIST_BEHAVIOUR_PROPERTY, DEFAULT_UPDATE_LIST_BEHAVIOUR);
+ }
+
+ /**
+ * Set the {@link Reasoner} associated to this ORA Mediator.
+ *
+ * @param reasoner The reasoner.
+ */
+ public void setReasoner(Reasoner reasoner) {
+ logger.info("Setting reasoner " + reasoner.getClass().getName());
+
+ // First unregister the current reasoner from the triggerPolicy
+ if (this.triggerPolicy != null) {
+ this.triggerPolicy.unregisterTriggerable(this.reasoner);
+ }
+
+ // Set the actuation provider of the reasoner to the current ORAMediator
+ if (reasoner != null) {
+ reasoner.setActuationProvider((ActionProvider) this);
+ reasoner.setObservationProvider((ObservationProvider) this);
+ }
+
+ // Set current reasoner
+ this.reasoner = reasoner;
+
+ // Register the reasoner with the TriggerPolicy
+ if (this.triggerPolicy != null) {
+ this.triggerPolicy.registerTriggerable(reasoner);
+ }
+ }
+
+ /**
+ * Set the {@link TriggerPolicy} associated to this ORA Mediator.
+ *
+ * @param triggerPolicy The TriggerPolicy
+ */
+ public void setTriggeringPolicy(TriggerPolicy triggerPolicy) {
+ logger.info("Setting trigger policy " + triggerPolicy.getClass().getName());
+
+ // First unregister the current reasoner from the old triggerPolicy
+ if (this.triggerPolicy != null) {
+ this.triggerPolicy.stop();
+ this.triggerPolicy.unregisterTriggerable(this.reasoner);
+ }
+
+ // Set current reasoner
+ this.triggerPolicy = triggerPolicy;
+
+ // Register the reasoner with the new TriggerPolicy
+ if (this.triggerPolicy != null) {
+ this.triggerPolicy.registerTriggerable(this.reasoner);
+ this.triggerPolicy.start();
+ }
+ }
+
+ /**
+ * Get a list of {@link Action} objects registered in this ORA Mediator.
+ *
+ * @return Array of ANES_URN of the registered {@link Action} objects.
+ */
+ public Vector getActions() {
+
+ if (this.updateListBehaviour.equalsIgnoreCase(UPDATE_LIST_DYNAMIC_BEHAVIOUR)) {
+ actions.removeAllElements();
+
+ Enumeration actuatorList = actuators.elements();
+
+ // Loop through the actuator array.
+ while (actuatorList.hasMoreElements()) {
+ Actuator actuator = (Actuator) actuatorList.nextElement();
+
+ Enumeration actionList = actuator.getActions().elements();
+
+ // For each actuator, get the list of actuations.
+ while (actionList.hasMoreElements()) {
+ Action action = (Action) actionList.nextElement();
+
+ // Add the action to the action map.
+ // The key is the urn string, and the value is the action itself
+ logger.debug("Adding action to map: " + action.getActionID().toString() + " -> " + action.getClass().getName());
+ observationMap.put(action.getActionID(), action);
+
+ // Add the observation ANES_URN to the observation array
+ actions.addElement(action.getActionID());
+ }
+ }
+ }
+ return this.actions;
+ }
+
+ /**
+ * Invoke a resource {@link Action} identified by its {@link ANES_URN}
+ * passing the {@link ANES_BUNDLE} set of arguments.
+ *
+ * @param id The urn of the invoked {@link Action} resource.
+ * @param arguments The set of arguments for the action.
+ * @throws InexistentActionID If no action is registered with the requested id.
+ * @throws ActionInvocationException If there is any other exception when invoking the {@link Action}
+ */
+ public void invoke(ANES_URN id, ANES_BUNDLE arguments) throws InexistentActionID, ActionInvocationException {
+ logger.debug("Requested invocation for urn " + id.toString().trim());
+
+ if (this.updateListBehaviour.equalsIgnoreCase(UPDATE_LIST_DYNAMIC_BEHAVIOUR)) {
+ // Update the observations array.
+ getActions();
+ }
+
+ if (actionMap.containsKey(id)) {
+ logger.debug("Requested invocation urn found... processing...");
+ try {
+ ((Action) actionMap.get(id)).invoke(arguments);
+ } catch (Exception e) {
+ throw new ActionInvocationException(id, e);
+ }
+ } else {
+ logger.debug("Requested invocation urn NOT FOUND... throwing exception");
+ throw new InexistentActionID(id);
+ }
+
+ }
+
+ /**
+ * Get the list of registered {@link Observation} objects in this ORA
+ * Mediator.
+ *
+ * @return Array of ANES_URN of the registered {@link Observation} objects.
+ */
+ public Vector getObservations() {
+ if (this.updateListBehaviour.equalsIgnoreCase(UPDATE_LIST_DYNAMIC_BEHAVIOUR)) {
+ observations.removeAllElements();
+
+ Enumeration observerList = observers.elements();
+
+ // Loop through the observer array.
+ while (observerList.hasMoreElements()) {
+ Observer observer = (Observer) observerList.nextElement();
+
+ Enumeration observationList = observer.getObservations().elements();
+
+ // For each observer, get the list of observations.
+ while (observationList.hasMoreElements()) {
+ Observation observation = (Observation) observationList.nextElement();
+
+ // Add the observation to the observation map.
+ // The key is the urn string, and the value is the observation itself
+ logger.debug("Adding observation to map: " + observation.getObservationID().toString() + " -> " + observation.getClass().getName());
+ observationMap.put(observation.getObservationID(), observation);
+
+ // Add the observation ANES_URN to the observation array
+ observations.addElement(observation.getObservationID());
+ }
+ }
+ }
+ return this.observations;
+ }
+
+ /**
+ * Get value observed by the {@link Observation} identified by the
+ * {@link ANES_URN} passed as its id.
+ *
+ * @param id The {@link ANES_URN} for the queried {@link Observation}
+ * @return The value provided by the {@link Observation}.
+ * @throws InexistentObservationID If no observation corresponds to the requested ID.
+ * @throws ObservationInvocationException If there is any other exception querying the observation.
+ */
+ public Object getValue(ANES_URN id) throws InexistentObservationID, ObservationInvocationException {
+ logger.debug("Requested getValue for urn " + id.toString().trim());
+
+ if (this.updateListBehaviour.equalsIgnoreCase(UPDATE_LIST_DYNAMIC_BEHAVIOUR)) {
+ // Update the observations array.
+ getObservations();
+ }
+
+ if (observationMap.containsKey(id)) {
+ logger.debug("Requested getValue urn found... processing...");
+ try {
+ return ((Observation) observationMap.get(id)).getValue();
+ } catch (Exception e) {
+ throw new ObservationInvocationException(id, e);
+ }
+ } else {
+ logger.debug("Requested getValue urn NOT FOUND... throwing exception");
+ throw new InexistentObservationID(id);
+ }
+ }
+
+ /**
+ * Register an {@link Observer} in the ORA Mediator.
+ *
+ * @param observer The {@link Observer} to be registered.
+ */
+ public void registerObserver(Observer observer) {
+
+ if (!observers.contains(observer)) {
+ logger.info("Registering observer: " + observer.getClass().getName());
+ this.observers.addElement(observer);
+
+ Enumeration observationList = observer.getObservations().elements();
+
+ while (observationList.hasMoreElements()) {
+ Observation observation = (Observation) observationList.nextElement();
+
+ logger.info("Adding observation to map: " + observation.getObservationID().toString() + " -> " + observation.getClass().getName());
+ observationMap.put(observation.getObservationID(), observation);
+ observations.addElement(observation.getObservationID());
+ }
+ } else {
+ logger.info("Registering observer: Observer " + observer.getClass().getName() + " already registered.");
+ }
+ }
+
+ /**
+ * Removes an {@link Observer} from the ORA Mediator.
+ *
+ * @param observer The {@link Observer} to be removed.
+ */
+ public void unregisterObserver(Observer observer) {
+ if (observers.contains(observer)) {
+ logger.info("Unregistering observer: " + observer.getClass().getName());
+
+ Enumeration observationList = observer.getObservations().elements();
+
+ while (observationList.hasMoreElements()) {
+ Observation observation = (Observation) observationList.nextElement();
+
+ if (observationMap.containsKey(observation.getObservationID())) {
+ logger.info("Removing observation from map: " + observation.getObservationID().toString() + " -> " + observation.getClass().getName());
+ observationMap.remove(observation.getObservationID());
+ }
+
+ if (observations.contains(observation)) {
+ observations.removeElement(observation);
+ }
+ }
+
+ this.observers.removeElement(observer);
+ } else {
+ logger.info("Unregistering observer: Observer " + observer.getClass().getName() + " is not registered.");
+ }
+ }
+
+ /**
+ * Register an {@link Actuator} in the ORA Mediator.
+ *
+ * @param actuator The {@link Actuator} to be registered.
+ */
+ public void registerActuator(Actuator actuator) {
+ if (!actuators.contains(actuator)) {
+ logger.info("Registering actuator: " + actuator.getClass().getName());
+ this.actuators.addElement(actuator);
+
+ Enumeration actionList = actuator.getActions().elements();
+
+ while (actionList.hasMoreElements()) {
+ Action action = (Action) actionList.nextElement();
+
+ logger.info("Adding action to map: " + action.getActionID().toString() + " -> " + action.getClass().getName());
+ actionMap.put(action.getActionID(), action);
+ actions.addElement(action.getActionID());
+ }
+ } else {
+ logger.info("Registering actuator: Actuator " + actuator.getClass().getName() + " already registered.");
+ }
+ }
+
+ /**
+ * Removes an {@link Actuator} from the ORA Mediator.
+ *
+ * @param actuator The {@link Actuator} to be removed.
+ */
+ public void unregisterActuator(Actuator actuator) {
+ if (actuators.contains(actuator)) {
+ logger.info("Unregistering actuator: " + actuator.getClass().getName());
+
+ Enumeration actionList = actuator.getActions().elements();
+
+ while (actionList.hasMoreElements()) {
+ Action action = (Action) actionList.nextElement();
+
+ if (actionMap.containsKey(action.getActionID())) {
+ logger.info("Removing action from map: " + action.getActionID().toString() + " -> " + action.getClass().getName());
+ actionMap.remove(action.getActionID());
+ }
+
+ if (actions.contains(action)) {
+ actions.removeElement(action);
+ }
+ }
+
+ this.actuators.removeElement(actuator);
+ } else {
+ logger.info("Unregistering actuator: Actuator " + actuator.getClass().getName() + " is not registered.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.java
new file mode 100644
index 0000000..3654e1f
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/PowerScalingMonitor/PowerScalingMonitor.java
@@ -0,0 +1,755 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.PowerScalingMonitor;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.core.resources.transducers.LEDColor;
+import com.sun.spot.core.util.Properties;
+import com.sun.spot.core.util.Utils;
+import com.sun.spot.espot.peripheral.ESpot;
+import com.sun.spot.ieee_802_15_4_radio.IRadioPolicyManager;
+import com.sun.spot.ieee_802_15_4_radio.util.IEEEAddress;
+import com.sun.spot.multihop.radio.mhrp.lqrp.LQRPManager;
+import com.sun.squawk.util.MathUtils;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.datatypes.ANES_URN_Exception;
+import eu.artemis.demanes.exceptions.ObservationInvocationException;
+import eu.artemis.demanes.impl.SunSPOT.common.DEMANESResources;
+import eu.artemis.demanes.impl.SunSPOT.common.Events;
+import eu.artemis.demanes.impl.SunSPOT.common.RadioProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.ReasonerProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.TriggerPolicyProperties;
+import eu.artemis.demanes.impl.SunSPOT.communications.CommunicationManager;
+import eu.artemis.demanes.impl.SunSPOT.reconfiguration.actions.ResetActuator;
+import eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations.BatteryLevelObservation;
+import eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations.NodeDegreeObservation;
+import eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations.NodeDegreeObservationExtension;
+import eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.MarqueeAddMessageException;
+import eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.MarqueeMessage;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.reconfiguration.Observation;
+import eu.artemis.demanes.reconfiguration.Observer;
+import eu.artemis.demanes.reconfiguration.TriggerPolicy;
+import eu.artemis.demanes.reconfiguration.Triggerable;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * Power Scaling Monitor is a {@link TriggerPolicy} that fires the
+ * {@link Reasoner} when certain conditions occur. At the same time it is also a
+ * {@link Observer} that provides the required {@link Observations} for the
+ * reasoning.
+ *
+ * @author Vicente Hernández Díz
+ * @author Yuanjiang Huang
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class PowerScalingMonitor implements TriggerPolicy, Observer {
+
+ public static final int STARTED = 1;
+ public static final int CREATED = 2;
+ public static final int SUSPENDED = 3;
+ public static final int DIED = 4;
+
+ private static final long DEFAULT_INTERVAL = 1000;
+
+ private static final LEDColor ND_COLOR = LEDColor.TEAL;
+ private static final LEDColor BATTERY_COLOR = LEDColor.ORANGE;
+ private static final LEDColor PTX_COLOR = LEDColor.MAGENTA;
+
+ private int state;
+
+ private Vector triggerables;
+ private Properties reconfigurationProperties;
+
+ private long interval;
+ private Observation ND;
+ private Observation BL;
+ private Observation reasonObservation;
+ private Observation reasonObservationValue;
+
+ private ANES_URN cause = null;
+ private double error;
+ private Vector observationList;
+
+ private Logger logger;
+
+ private int CR_at_previous_k; // CR(k-1)
+
+ private double ND_Error_at_previous_k; // e(k-1)
+ private int dcr_at_previous_k; // dcr(k-1)
+ private int CR_at_previous_k2; // CR(k-2)
+ private int ND_R_previous_k; // ND_R(k-1)
+ private int NDRef_at_previous_k; // NDRef(k-1) -- Used only for updating the value after an external updating of the parameter
+
+ // fixed parameters for the controller
+ private double KSI_ND;
+ private int ND_MIN;
+ private int CR_MAX;
+ private int delta_ND_min;
+ private double k_e;
+ private double alpha_KSI_ND;
+ private int DELTA_CR_MIN;
+ private double E_cr;
+
+ private int ND_at_k;
+ private int count;
+ private boolean CR_at_previous_k2_is_ready; // CR(k-2) is ready only after 2 rounds triggery policy.
+ private int triggeryRuleCount;
+
+ private SystemContext context;
+
+ private LQRPManager routingManager;
+
+ private MarqueeMessage nodeDegreeMessage;
+ private MarqueeMessage batteryLevelMessage;
+ private MarqueeMessage transmissionPowerMessage;
+
+ private Integer nodeDegreeMessageID;
+ private Integer batteryLevelMessageID;
+ private Integer transmissionPowerMessageID;
+
+ public PowerScalingMonitor(SystemContext context, Properties reconfigurationProperties) {
+ this.triggerables = new Vector();
+ this.state = PowerScalingMonitor.CREATED;
+ this.reconfigurationProperties = reconfigurationProperties;
+ this.context = context;
+
+ this.routingManager = LQRPManager.getInstance();
+
+ this.logger = SystemContext.getLogger();
+
+ this.CR_at_previous_k = Integer.MAX_VALUE;
+ this.CR_at_previous_k2 = Integer.MAX_VALUE;
+ dcr_at_previous_k = Integer.MAX_VALUE;
+ this.count = 3;
+ this.CR_at_previous_k2_is_ready = false; // CR(k-2)
+ this.triggeryRuleCount = 1; //record the triggery rule execution times
+
+ String property;
+ property = reconfigurationProperties.getProperty(TriggerPolicyProperties.ND_MIN_PROPERTY);
+ ND_MIN = Integer.parseInt(property);
+
+ property = reconfigurationProperties.getProperty(TriggerPolicyProperties.CR_MAX_PROPERTY);
+ CR_MAX = Integer.parseInt(property);
+
+ property = reconfigurationProperties.getProperty(TriggerPolicyProperties.DELTA_ND_MIN_PROPERTY);
+ delta_ND_min = Integer.parseInt(property);
+
+ property = reconfigurationProperties.getProperty(ReasonerProperties.KE_PROPERTY);
+ k_e = Double.parseDouble(property);
+
+ property = reconfigurationProperties.getProperty(TriggerPolicyProperties.KSI_ND_PROPERTY);
+ KSI_ND = Double.parseDouble(property);
+
+ property = reconfigurationProperties.getProperty(TriggerPolicyProperties.DELTA_CR_MIN_PROPERTY);
+ DELTA_CR_MIN = Integer.parseInt(property);
+
+ // obtain the critical battery level
+ property = reconfigurationProperties.getProperty(ReasonerProperties.E_CR_PROPERTY);
+ E_cr = Double.parseDouble(property);
+
+ // Read the ND_Ref property
+ property = reconfigurationProperties.getProperty(ReasonerProperties.NDRefPROPERTY);
+ NDRef_at_previous_k = Integer.parseInt(property);
+
+ try {
+ this.cause = ANES_URN.create(Events.BL_EVENT);
+ } catch (ANES_URN_Exception ex) {
+ this.cause = null;
+ }
+ error = 0;
+
+ this.interval = Long.parseLong(reconfigurationProperties.getProperty(TriggerPolicyProperties.TRIGGER_INTERVAL_PROPERTY, String.valueOf(DEFAULT_INTERVAL)));
+ logger.debug("Monitor interval set to " + interval + " milliseconds");
+
+ observationList = new Vector();
+ ND = new NodeDegreeObservation(reconfigurationProperties, DEMANESResources.NDObservationURN);
+ ((NodeDegreeObservation) ND).start();
+ BL = new BatteryLevelObservation(reconfigurationProperties, DEMANESResources.BLObservationURN);
+ reasonObservation = new ReasonObservation();
+ reasonObservationValue = new ReasonObservationValue();
+ addObservation(ND);
+ addObservation(BL);
+ addObservation(reasonObservation);
+ addObservation(reasonObservationValue);
+
+ try {
+ nodeDegreeMessage = new MarqueeMessage();
+ batteryLevelMessage = new MarqueeMessage();
+ transmissionPowerMessage = new MarqueeMessage();
+ nodeDegreeMessageID = (Integer) SystemContext.getMarquee().addMessage(nodeDegreeMessage);
+ batteryLevelMessageID = (Integer) SystemContext.getMarquee().addMessage(batteryLevelMessage);
+ transmissionPowerMessageID = (Integer) SystemContext.getMarquee().addMessage(transmissionPowerMessage);
+ } catch (MarqueeAddMessageException ex) {
+ // DO NOTHING
+ }
+
+ }
+
+ public void registerTriggerable(Triggerable t) {
+ this.triggerables.addElement(t);
+ }
+
+ public void resume() {
+
+ if (this.state == PowerScalingMonitor.SUSPENDED) {
+ this.state = PowerScalingMonitor.STARTED;
+ }
+
+ }
+
+ public void start() {
+
+ if (this.state != PowerScalingMonitor.CREATED) {
+ return;
+ }
+
+ this.state = PowerScalingMonitor.STARTED;
+
+ new Thread(
+ new Runnable() {
+ public void run() {
+ short sequenceNumber = 0;
+
+ showOnMarqueeBinary(ND_at_k, ND_COLOR, nodeDegreeMessage, nodeDegreeMessageID);
+ showOnMarqueeBinary(((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower() - RadioProperties.MINIMUM_POWER_TRANSMISSION, PTX_COLOR, transmissionPowerMessage, transmissionPowerMessageID);
+ showOnMarqueePercentage(((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getAvailableCapacity(),
+ ((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getMaximumCapacity(),
+ BATTERY_COLOR,
+ batteryLevelMessage,
+ batteryLevelMessageID);
+
+ logger.info("Status monitoring message sent!");
+ logger.info("Number of neighbors at k: " + ND_at_k);
+ logger.info("PTX at k: " + (((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower() - RadioProperties.MINIMUM_POWER_TRANSMISSION));
+
+ while (true) {
+ sequenceNumber++;
+ if (reconfigurationProperties.getProperty("reset").equalsIgnoreCase("true")) {
+ logger.info("#> RESETING transmission values");
+ reconfigurationProperties.setProperty("reset", "false");
+
+ int ptx = Integer.parseInt(reconfigurationProperties.getProperty("ptx"));
+
+ ((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).setOutputPower(ptx);
+ CR_at_previous_k = Integer.MAX_VALUE;
+ CR_at_previous_k2 = Integer.MAX_VALUE;
+ dcr_at_previous_k = Integer.MAX_VALUE;
+ count = 3;
+ CR_at_previous_k2_is_ready = false; // CR(k-2)
+
+ ((ResetActuator) context.getPTACT()).reset();
+ }
+
+ ((NodeDegreeObservation) ND).updateNodeDegree();
+
+ interval = Long.parseLong(reconfigurationProperties.getProperty(TriggerPolicyProperties.TRIGGER_INTERVAL_PROPERTY, String.valueOf(DEFAULT_INTERVAL)));
+ logger.debug("Monitor interval set to " + interval + " milliseconds");
+
+ Utils.sleep(interval - 500);
+
+ if (reconfigurationProperties.getProperty("reasoning.status").equalsIgnoreCase("started")) {
+
+ switch (getState()) {
+ case PowerScalingMonitor.STARTED:
+ if (triggerRules()) {
+ ((Triggerable) triggerables.firstElement()).trigger();
+ }
+ break;
+ case PowerScalingMonitor.DIED:
+ state = PowerScalingMonitor.CREATED;
+ break;
+ case PowerScalingMonitor.SUSPENDED:
+ break;
+ case PowerScalingMonitor.CREATED:
+ break;
+ default:
+ break;
+ }
+
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DataOutputStream daos = new DataOutputStream(baos);
+
+ String destination = reconfigurationProperties.getProperty(SystemProperties.BASESTATION_ADDR_PROPERTY, SystemProperties.DEFAULT_BS_ADDRESS);
+ String port = reconfigurationProperties.getProperty(SystemProperties.BASESTATION_PORT, Integer.toString(SystemProperties.DEFAULT_BS_PORT));
+
+ daos = getStatusMessage(sequenceNumber, destination);
+ recordStatus(sequenceNumber, destination);
+
+ showOnMarqueeBinary(ND_at_k, ND_COLOR, nodeDegreeMessage, nodeDegreeMessageID);
+ showOnMarqueeBinary(((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower() - RadioProperties.MINIMUM_POWER_TRANSMISSION, PTX_COLOR, transmissionPowerMessage, transmissionPowerMessageID);
+ showOnMarqueePercentage(((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getAvailableCapacity(),
+ ((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getMaximumCapacity(),
+ BATTERY_COLOR,
+ batteryLevelMessage,
+ batteryLevelMessageID);
+
+ (context.getCommunicationManager()).send(baos, 0, CommunicationManager.MODE_UNICAST, destination + ":" + port, 0, 0);
+ logger.info("Status monitoring message sent!");
+ logger.info("Number of neighbors at k: " + ND_at_k);
+ logger.info("PTX at k: " + (((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower() - RadioProperties.MINIMUM_POWER_TRANSMISSION));
+ }
+ }
+
+ private void showOnMarqueeBinary(int value, LEDColor color, MarqueeMessage message, Integer messageID) {
+ if (value > MathUtils.pow(2, MarqueeMessage.MESSAGE_LENGTH)) {
+ value = (byte) MathUtils.pow(2, MarqueeMessage.MESSAGE_LENGTH);
+ }
+ for (int index = 0; index < MarqueeMessage.MESSAGE_LENGTH; index++) {
+ int remainder = value % 2;
+
+ if (remainder == 1) {
+ message.setMessageAtPosition((MarqueeMessage.MESSAGE_LENGTH - 1) - index, color);
+ } else {
+ message.setMessageAtPosition((MarqueeMessage.MESSAGE_LENGTH - 1) - index, new LEDColor(0, 0, 0));
+ }
+ value = value / 2;
+ }
+ SystemContext.getMarquee().updateMessage(messageID, message);
+ }
+
+ private void showOnMarqueePercentage(double actual, double maximum, LEDColor color, MarqueeMessage message, Integer messageID) {
+ double percentage = actual * 100 / maximum;
+ int totalLights = 0;
+ if (percentage > 80) {
+ totalLights = 5;
+ } else if (percentage > 60) {
+ totalLights = 4;
+ } else if (percentage > 40) {
+ totalLights = 3;
+ } else if (percentage > 20) {
+ totalLights = 2;
+ } else if (percentage > 0) {
+ totalLights = 1;
+ } else {
+ totalLights = 0;
+ }
+
+ for (int index = 0; index < totalLights; index++) {
+ message.setMessageAtPosition(index, color);
+ }
+
+ SystemContext.getMarquee().updateMessage(messageID, message);
+ }
+ }
+ ).start();
+ }
+
+ private boolean triggerRules() {
+
+ int ND_R_at_k = Integer.MAX_VALUE;
+ int NDRef;
+ String property = null;
+ boolean result = false;
+
+ try {
+
+ // The nd_real indicates the current ND
+ ND_at_k = Integer.parseInt(ND.getValue().toString());
+ logger.debug("triggerRules: ND read as " + ND_at_k);
+
+ // The bl_real indicates the current power transmission in dBm
+ double bl_real = Double.parseDouble(BL.getValue().toString());
+ logger.debug("triggerRules: BL read as " + bl_real);
+
+ // PLEASE, THE LOAD OF THE PARAMETERS MUST BE DONE IN A SEPARATE METHOD.
+ // ALSO IT MUST BE SPLITTED INTO FIXED AND DYNAMIC PARAMETERS.
+ // obtain the node degree reference
+ property = reconfigurationProperties.getProperty(ReasonerProperties.ND_R_PROPERTY);
+ ND_R_at_k = Integer.parseInt(property);
+ logger.debug("PSMonitor: Parsed property " + ReasonerProperties.ND_R_PROPERTY + " as " + ND_R_at_k);
+
+ // The following lines load the parameters that the trigger rules need
+ property = reconfigurationProperties.getProperty(TriggerPolicyProperties.KSI_ND_PROPERTY);
+ double KSI_ND = Double.parseDouble(property);
+
+ // --------------------------------------------------------------
+ // CALCULATION of variables requiered for the triggering policy
+ // ----------------------------------------------------------------
+ // Node Degree error at k
+ double e_ND = ND_R_at_k - ND_at_k;
+ // Baterry Level error at k
+ double e_BL = E_cr - bl_real;
+
+ // Communication Range at k
+ int CR_at_k = ((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower();
+
+ logger.info("triggerRules: read CR_at_k = " + CR_at_k);
+ // now use the index
+ CR_at_k = RadioProperties.getPTXIndex(RadioProperties.getRadioChannel(), CR_at_k);
+
+ logger.info("triggerRules: convert CR_at_k into index, now CR_at_k = " + CR_at_k);
+
+ logger.info("Run the triggery rule: " + this.triggeryRuleCount);
+ this.triggeryRuleCount++;
+
+ // If previous Communication Range is Integer.MAX_VALUE, this means
+ // that this is the first reading of the Communication Range, so the
+ // previous value of the Communication Range should be set to the
+ // actual one.
+ // And other variables are initialized here.
+ if (CR_at_previous_k == Integer.MAX_VALUE) {
+
+ CR_at_previous_k = CR_at_k;
+ CR_at_previous_k2 = Integer.MAX_VALUE;
+ ND_Error_at_previous_k = e_ND;
+ ND_R_previous_k = ND_R_at_k; // ND reference
+ }
+
+ this.count--;
+ if (this.count == 0) {
+ this.CR_at_previous_k2_is_ready = true;
+ logger.info("dcr_at_previous_k2 now available !"); //dcr_at_previous_k2 now is valid
+ }
+ if (this.CR_at_previous_k2_is_ready) {
+
+ // To calcuate dcr = cr(k-1) - cr(k-2), use the index, other than real values
+ dcr_at_previous_k = CR_at_previous_k - CR_at_previous_k2;
+
+ logger.info("calcuate dcr_at_previous_k, CR_at_previous_k = " + CR_at_previous_k);
+ logger.info("calcuate dcr_at_previous_k, CR_at_previous_k2 = " + CR_at_previous_k2);
+ // CR_at_previous_k2 = CR_at_previous_k;
+ }
+
+ // Filtered Communication Range
+ int CR_f = MathUtils.round((CR_at_k + CR_at_previous_k) / 2);
+
+ CR_at_previous_k2 = CR_at_previous_k;
+ CR_at_previous_k = CR_at_k;
+
+ // Checking the rules in the order specified by the
+ // reconfiguration algorithm v10.
+ // ----------------------------------------------------------------
+ // The first rule:
+ // ----------------------------------------------------------------
+ // Updating power transmission when the reference value has been adapted.
+ //(Rule No. 1 or secondary loop execution)
+ if ((Math.abs(e_ND) <= KSI_ND)
+ && (CR_f >= CR_MAX)
+ && ((ND_R_previous_k != ND_R_at_k) || (e_ND < ND_Error_at_previous_k))) {
+ double previous_e_ND = e_ND;
+ // e_ND = -1 * alpha_KSI_ND * KSI_ND_at_k;
+ e_ND = -1 * (alpha_KSI_ND * DELTA_CR_MIN + DELTA_CR_MIN);
+
+ logger.info("triggerRules 1st triggered");
+
+ logger.info("triggerPolicy.SaturationRule1: e_ND adjusted to " + e_ND + " when CR_f is " + CR_f + " and previous e_ND was " + previous_e_ND + " with KSI_ND_at_k being " + KSI_ND);
+ }
+
+ // ----------------------------------------------------------------
+ // The second rule:
+ // ----------------------------------------------------------------
+ logger.info("ND_Error_at_previous_k = " + ND_Error_at_previous_k);
+ logger.info("e_ND = " + e_ND);
+ logger.info("dcr_at_previous_k = " + dcr_at_previous_k);
+ logger.info("ND_Error_at_previous_k = " + ND_Error_at_previous_k);
+ logger.info("dcr_at_previous_k = " + dcr_at_previous_k);
+ logger.info("CR_at_previous_k = " + CR_at_previous_k);
+ logger.info("CR_at_previous_k2 = " + CR_at_previous_k2);
+ logger.info("DELTA_CR_MIN = " + DELTA_CR_MIN);
+ logger.info("KSI_ND = " + KSI_ND);
+
+ if (((ND_Error_at_previous_k * e_ND > 0) && (dcr_at_previous_k == 0))
+ || ((e_ND < -KSI_ND) && (ND_Error_at_previous_k > KSI_ND) && (dcr_at_previous_k == DELTA_CR_MIN))
+ || ((e_ND > KSI_ND) && (ND_Error_at_previous_k < -KSI_ND) && (dcr_at_previous_k == -DELTA_CR_MIN))) {
+
+ result = false;
+
+ logger.info("triggerRules 2nd triggered: DO NOTHING ");
+
+ } else {
+ // When the error in ND is greater than the tolerance at k or the
+ // ND is below the minimum, then the primary loop must be triggered.
+ if ((Math.abs(e_ND) > KSI_ND) || (ND_at_k < ND_MIN)) {
+ try {
+ this.cause = ANES_URN.create(Events.ND_EVENT);
+ this.error = e_ND;
+ result = true;
+ logger.info("triggerRules 2nd rule triggered: ND event");
+ } catch (ANES_URN_Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ // updating
+ ND_Error_at_previous_k = e_ND; // e(k-1) update at this point
+ ND_R_previous_k = ND_R_at_k; // ND_R(k-1) update at this point
+
+ // ----------------------------------------------------------------
+ // The third rule:
+ // ----------------------------------------------------------------
+ // When the battery reaches some critical value, then the secondary
+ // loop must be executed.
+ if (Math.abs(e_BL) <= 1.0 / k_e) {
+
+ try {
+ this.cause = ANES_URN.create(Events.BL_EVENT);
+ this.error = e_BL;
+ result = true;
+ logger.info("triggerRules 3rd rule trigger");
+ } catch (ANES_URN_Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ // EXTRA RULE to update the ND_R value upon a modification of the ND_Ref property
+ property = reconfigurationProperties.getProperty(ReasonerProperties.NDRefPROPERTY);
+ NDRef = Integer.parseInt(property);
+ if (NDRef != NDRef_at_previous_k) {
+ try {
+ this.cause = ANES_URN.create(Events.BL_EVENT);
+ this.error = e_BL;
+ result = true;
+ logger.info("NDRef updated -> trigger 2nd loop for updating ND_r");
+ } catch (ANES_URN_Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ NDRef_at_previous_k = NDRef;
+
+ } catch (ObservationInvocationException ex) {
+ ex.printStackTrace();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ return result;
+ }
+
+ public void stop() {
+
+ if (this.state == PowerScalingMonitor.STARTED) {
+ this.state = PowerScalingMonitor.DIED;
+ }
+
+ }
+
+ public void suspend() {
+
+ if (this.state == PowerScalingMonitor.STARTED) {
+ this.state = PowerScalingMonitor.SUSPENDED;
+ }
+ }
+
+ public void unregisterTriggerable(Triggerable t) {
+
+ for (int cursor = 0; cursor < triggerables.size(); cursor++) {
+ if (((Triggerable) triggerables.elementAt(cursor)).equals(t)) {
+ triggerables.removeElementAt(cursor);
+ break;
+ }
+ }
+
+ }
+
+ public Vector getObservations() {
+ return observationList;
+ }
+
+ private void addObservation(Observation observation) {
+ this.observationList.addElement(observation);
+ }
+
+ public void setState(int state) {
+ this.state = state;
+ }
+
+ public int getState() {
+ return this.state;
+ }
+
+ public void setInterval(long interval) {
+ this.interval = interval;
+ }
+
+ private DataOutputStream getStatusMessage(int sequenceNumber, String destination) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DataOutputStream daos = new DataOutputStream(baos);
+
+ try {
+ switch (Byte.parseByte(reconfigurationProperties.getProperty(SystemProperties.EXECUTION_CONTEXT, Integer.toString(SystemProperties.DEFAULT_EXECUTION_CONTEXT)))) {
+ case SystemProperties.EXECUTION_CONTEXT_CMS:
+ String ABATurn = "urn:dmns:abat";
+ String MBATurn = "urn:dmns:mbat";
+ String NDEGurn = "urn:dmns:ndeg";
+ String NPTXurn = "urn:dmns:nptx";
+ String SYSIDurn = "urn:dmns:sysid";
+ String IEEELocalAddress = IEEEAddress.toDottedHex(((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getIEEEAddress());
+
+ daos.writeByte(0xA0);
+ daos.writeByte(0x02);
+ daos.writeShort(sequenceNumber);
+ daos.writeByte(0xFF);
+ daos.write("urn:dmns:log?".getBytes(), 0, 13);
+ daos.writeByte(SYSIDurn.length());
+ daos.write(SYSIDurn.getBytes(), 0, SYSIDurn.length());
+ daos.writeByte(IEEELocalAddress.length());
+ daos.write(IEEELocalAddress.getBytes(), 0, IEEELocalAddress.length());
+ daos.writeByte(ABATurn.length());
+ daos.write(ABATurn.getBytes(), 0, ABATurn.length());
+ daos.writeByte(0x08); // Length of double
+ daos.writeDouble((((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getAvailableCapacity()));
+ daos.writeByte(MBATurn.length());
+ daos.write(MBATurn.getBytes(), 0, MBATurn.length());
+ daos.writeByte(0x08);
+ daos.writeDouble((((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getMaximumCapacity()));
+ daos.writeByte(NDEGurn.length());
+ daos.write(NDEGurn.getBytes(), 0, NDEGurn.length());
+ daos.writeByte(0x04);
+ daos.writeInt(ND_at_k);
+ daos.writeByte(NPTXurn.length());
+ daos.write(NPTXurn.getBytes(), 0, NPTXurn.length());
+ daos.writeByte(1);
+ daos.writeByte(((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower());
+ break;
+ case SystemProperties.EXECUTION_CONTEXT_EXPERIMENTAL:
+ daos.writeLong(sequenceNumber);
+ daos.writeLong(System.currentTimeMillis());
+ daos.writeByte(ND_at_k);
+ daos.writeDouble((((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getMaximumCapacity()));
+ daos.writeDouble((((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getAvailableCapacity()));
+ daos.writeByte(((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower());
+ daos.writeByte(Integer.parseInt(reconfigurationProperties.getProperty(ReasonerProperties.ND_R_PROPERTY)));
+ daos.writeByte(Integer.parseInt(reconfigurationProperties.getProperty(TriggerPolicyProperties.KSI_ND_PROPERTY)));
+ daos.writeDouble(Double.parseDouble(reconfigurationProperties.getProperty(ReasonerProperties.KCR_PROPERTY)));
+ daos.writeDouble(Double.parseDouble(reconfigurationProperties.getProperty(ReasonerProperties.E_CR_PROPERTY)));
+ routingManager.findRoute(IEEEAddress.toLong(destination), null, Long.valueOf(sequenceNumber));
+ Utils.sleep(500);
+ daos.writeLong(routingManager.getRouteInfo(IEEEAddress.toLong(destination)).nextHop);
+ break;
+ default:
+ break;
+ }
+ } catch (IOException ex) {
+ return null;
+ }
+
+ return daos;
+ }
+
+ public void recordStatus(int sequenceNumber, String destination) {
+ try {
+ Vector neighborList = ((NodeDegreeObservationExtension) ND).getNeighborList();
+ StringBuffer csvdata = new StringBuffer();
+ csvdata.append(sequenceNumber);
+ csvdata.append(',');
+ csvdata.append(System.currentTimeMillis());
+ csvdata.append(',');
+ csvdata.append(ND_at_k);
+ csvdata.append(',');
+ csvdata.append((((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getMaximumCapacity()));
+ csvdata.append(',');
+ csvdata.append((((ESpot) Resources.lookup(ESpot.class)).getPowerController().getBattery().getAvailableCapacity()));
+ csvdata.append(',');
+ csvdata.append(((IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class)).getOutputPower());
+ csvdata.append(',');
+ csvdata.append(Integer.parseInt(reconfigurationProperties.getProperty(ReasonerProperties.ND_R_PROPERTY)));
+ csvdata.append(',');
+ csvdata.append(Integer.parseInt(reconfigurationProperties.getProperty(TriggerPolicyProperties.KSI_ND_PROPERTY)));
+ csvdata.append(',');
+ csvdata.append(Double.parseDouble(reconfigurationProperties.getProperty(ReasonerProperties.KCR_PROPERTY)));
+ csvdata.append(',');
+ csvdata.append(Double.parseDouble(reconfigurationProperties.getProperty(ReasonerProperties.E_CR_PROPERTY)));
+ csvdata.append(',');
+ csvdata.append(IEEEAddress.toDottedHex(routingManager.getRouteInfo(IEEEAddress.toLong(destination)).nextHop));
+ csvdata.append(',');
+ for (int i = 0; i < neighborList.size(); i++) {
+ csvdata.append((String) neighborList.elementAt(i));
+ csvdata.append(',');
+ }
+
+ logger.setDestination(Logger.RECORD);
+ ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
+ DataOutputStream daos2 = new DataOutputStream(baos2);
+ daos2.write(csvdata.toString().getBytes());
+ logger.log(Level.ALL, baos2);
+ logger.setDestination(Logger.SYSTEM_OUTPUT);
+ } catch (IOException ex) {
+ // Do nothing
+ }
+ }
+
+ // PRIVATE CLASSES
+ private class ReasonObservation implements Observation {
+
+ /**
+ * Gets the ID of an observation.
+ *
+ * @return the ANES_URN of observation.
+ */
+ public ANES_URN getObservationID() {
+ try {
+ return ANES_URN.create(DEMANESResources.TriggerReasonURN);
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.SEVERE, "NodeDegreeObservation.getObservationID: ANES_URN.create reported and error with DEMANESResources.BLObservationURN.");
+ return null;
+ }
+ }
+
+ /**
+ * Get the reason {@link ANES_URN}.
+ *
+ * @return The reason {@link ANES_URN}.
+ * @throws ObservationInvocationException
+ */
+ public Object getValue() throws ObservationInvocationException {
+ return cause;
+ }
+ }
+
+ private class ReasonObservationValue implements Observation {
+
+ /**
+ * Gets the ID of an observation.
+ *
+ * @return the ANES_URN of observation.
+ */
+ public ANES_URN getObservationID() {
+ try {
+ return ANES_URN.create(DEMANESResources.TriggerReasonValueURN);
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.SEVERE, "NodeDegreeObservation.getObservationID: ANES_URN.create reported and error with DEMANESResources.BLObservationURN.");
+ return null;
+ }
+ }
+
+ /**
+ * Get the reason error value.
+ *
+ * @return The reason error value.
+ * @throws ObservationInvocationException
+ */
+ public Object getValue() throws ObservationInvocationException {
+ return Double.valueOf(error);
+ }
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator.java
new file mode 100644
index 0000000..736162a
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/PowerTransmissionActuator.java
@@ -0,0 +1,187 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.actions;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.core.util.Properties;
+import com.sun.spot.ieee_802_15_4_radio.IRadioPolicyManager;
+import com.sun.squawk.util.MathUtils;
+import eu.artemis.demanes.datatypes.ANES_BUNDLE;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.datatypes.ANES_URN_Exception;
+import eu.artemis.demanes.exceptions.ActionInvocationException;
+import eu.artemis.demanes.exceptions.NonExistentKeyException;
+import eu.artemis.demanes.impl.SunSPOT.common.DEMANESResources;
+import eu.artemis.demanes.impl.SunSPOT.common.PTActionProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.RadioProperties;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.reconfiguration.Action;
+import eu.artemis.demanes.reconfiguration.Actuator;
+import java.util.Vector;
+
+/**
+ * PowerTransmissionActuator
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0
+ */
+public class PowerTransmissionActuator implements Actuator, ResetActuator {
+
+ private Action updatePowerTransmission;
+ private Vector actions;
+
+ private final Logger logger;
+
+ public PowerTransmissionActuator(Properties contextProperties) {
+ this.actions = new Vector();
+
+ this.logger = SystemContext.getLogger();
+
+ // Create the required actions for this actuator
+ updatePowerTransmission = new updatePowerTransmissionAction(contextProperties);
+
+ // Add the recently created actions to the actions list
+ this.actions.addElement(updatePowerTransmission);
+ }
+
+ /**
+ * Get the list of actions provided by this actuator.
+ *
+ * @return A Vector containing the list of actions.
+ */
+ public Vector getActions() {
+ return this.actions;
+ }
+
+ /**
+ * Reset the transmission power to the initial value.
+ */
+ public void reset() {
+ ((ResetActuator) updatePowerTransmission).reset();
+ }
+
+ /**
+ * Implements the action to update the transmission power.
+ */
+ private static class updatePowerTransmissionAction implements Action, ResetActuator {
+
+ private static IRadioPolicyManager radioPolicyManager;
+ private static int radioChannel;
+ private static final String DEFAULT_URN = DEMANESResources.PTActionURN;
+ private static String DEFAULT_CR0;
+
+ private static ANES_URN urn;
+ private static double cr;
+ private static double CR0;
+
+ private Logger logger;
+
+ private updatePowerTransmissionAction(Properties contextProperties) {
+ logger = SystemContext.getLogger();
+
+ radioPolicyManager = (IRadioPolicyManager) Resources.lookup(IRadioPolicyManager.class);
+ radioChannel = RadioProperties.getRadioChannel();
+
+ DEFAULT_CR0 = Double.toString(RadioProperties.getMinimumPTXIndex(radioChannel));
+ CR0 = Double.parseDouble(contextProperties.getProperty(PTActionProperties.CR0_PROPERTY, DEFAULT_CR0));
+
+ try {
+ urn = new ANES_URN(DEFAULT_URN);
+ } catch (ANES_URN_Exception ex) {
+ urn = null;
+ if (logger.getLevel().intValue() <= Level.DEBUG.intValue()) {
+ ex.printStackTrace();
+ }
+ }
+
+ cr = 0;
+ }
+
+ /**
+ * Resets the Power Transmission Actuator.
+ */
+ public void reset() {
+ cr = 0;
+ }
+
+ /**
+ * Get the {@code ANES_URN} for this actuator.
+ *
+ * @return The {@code ANES_URN}.
+ */
+ public ANES_URN getActionID() {
+ return updatePowerTransmissionAction.urn;
+ }
+
+ /**
+ * Invokes the actuator, thus executing the corresponding action.
+ *
+ * @param arguments The set of arguments required for the action.
+ * @throws ActionInvocationException
+ */
+ public void invoke(ANES_BUNDLE arguments) throws ActionInvocationException {
+ double delta_cr;
+ double CRsplat;
+ int powerTransmissionIndex;
+
+ logger.debug("PTAction invoked... Actual cr = " + cr);
+
+ if (arguments.containsKey(DEMANESResources.DELTA_CR_KEY)) {
+ try {
+ delta_cr = ((Double) arguments.get(DEMANESResources.DELTA_CR_KEY)).doubleValue();
+ } catch (NonExistentKeyException ex) {
+ delta_cr = Double.NaN;
+ }
+
+ logger.debug("PTAction delta_cr argument: " + delta_cr);
+
+ if (delta_cr != Double.NaN) {
+ // Update cr
+ cr += delta_cr;
+
+ // Update CR
+ CRsplat = cr + CR0;
+
+ // calculate actual power transmission
+ powerTransmissionIndex = (int) MathUtils.round(CRsplat);
+
+ if (powerTransmissionIndex > RadioProperties.getMaximumPTXIndex(radioChannel)) {
+ powerTransmissionIndex = RadioProperties.getMaximumPTXIndex(radioChannel);
+ cr -= delta_cr;
+ }
+
+ if (powerTransmissionIndex < RadioProperties.getMinimumPTXIndex(radioChannel)) {
+ powerTransmissionIndex = RadioProperties.getMinimumPTXIndex(radioChannel);
+ cr -= delta_cr;
+ }
+
+ radioPolicyManager.setOutputPower(RadioProperties.getPTXatIndex(radioChannel, powerTransmissionIndex));
+
+ logger.debug("PTAction new CR* = " + CRsplat + " rounded to " + powerTransmissionIndex);
+ logger.debug("PTAction output power read: " + radioPolicyManager.getOutputPower());
+ }
+ }
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/ResetActuator.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/ResetActuator.java
new file mode 100644
index 0000000..61b92dd
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/actions/ResetActuator.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.actions;
+
+/**
+ * Extends the {@link Actuator} interface to include a method to reset
+ * its actions to the initial state.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public interface ResetActuator {
+
+ /**
+ * Resets the actuator to its initial state.
+ */
+ public void reset();
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/BatteryLevelObservation.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/BatteryLevelObservation.java
new file mode 100644
index 0000000..90345de
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/BatteryLevelObservation.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licenses/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.core.util.Properties;
+import com.sun.spot.espot.peripheral.Battery;
+import com.sun.spot.espot.peripheral.Battery8;
+import com.sun.spot.espot.peripheral.ESpot;
+import com.sun.spot.espot.peripheral.IPowerController;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.datatypes.ANES_URN_Exception;
+import eu.artemis.demanes.exceptions.ObservationInvocationException;
+import eu.artemis.demanes.impl.SunSPOT.common.DEMANESResources;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.reconfiguration.Observation;
+
+/**
+ * {@code BatteryLevelObservation} provides the battery level.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class BatteryLevelObservation implements Observation {
+ private ANES_URN urn;
+ private Battery8 battery8;
+ private Battery battery;
+ private boolean rev6;
+ private Logger logger;
+
+ /**
+ * Public constructor for {@code BatteryLevelObservation}.
+ *
+ * @param properties The set of reconfiguration properties.
+ * @param urn The urn for the observation.
+ */
+ public BatteryLevelObservation(Properties properties, String urn) {
+ ESpot espot = (ESpot) Resources.lookup(ESpot.class);
+ IPowerController powerController = espot.getPowerController();
+ try {
+ this.battery8 = (Battery8) powerController.getBattery();
+ this.rev6 = true;
+ }
+ catch (RuntimeException exception) {
+ this.battery = (Battery) powerController.getBattery();
+ this.rev6=false;
+ }
+
+ this.logger = SystemContext.getLogger();
+ }
+
+ /**
+ * Gets the ID of an observation.
+ *
+ * @return the ANES_URN of observation.
+ */
+ public ANES_URN getObservationID() {
+ try {
+ return ANES_URN.create(DEMANESResources.BLObservationURN);
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.SEVERE, "NodeDegreeObservation.getObservationID: ANES_URN.create reported and error with DEMANESResources.BLObservationURN.");
+ return null;
+ }
+ }
+
+ /**
+ * Get the batteries remaining capacity in mAh.
+ *
+ * @return the capacity in milliampere-hour.
+ * @throws ObservationInvocationException
+ */
+ public Object getValue() throws ObservationInvocationException {
+ if (rev6) {
+ return Double.valueOf(this.battery8.getAvailableCapacity());
+ } else {
+ return Double.valueOf(this.battery.getAvailableCapacity());
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservation.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservation.java
new file mode 100644
index 0000000..38afc24
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservation.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations;
+
+import com.sun.spot.core.util.Properties;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.datatypes.ANES_URN_Exception;
+import eu.artemis.demanes.exceptions.ObservationInvocationException;
+import eu.artemis.demanes.impl.SunSPOT.common.DEMANESResources;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.NDPFactory;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.NeighborDiscoveryFactoryException;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.NeighborDiscoveryProtocol;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.NeighborDiscoveryType;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.ondemand.OnDemandNeighborDiscovery;
+import eu.artemis.demanes.reconfiguration.Observation;
+import java.util.Vector;
+
+/**
+ * Node Degree Observation provides the number of active neighbors.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class NodeDegreeObservation implements Observation, NodeDegreeObservationExtension {
+
+ private final Logger logger;
+ private NeighborDiscoveryProtocol nodeDegreeManager;
+
+ /**
+ * Public constructor for the Node Degree Observation.
+ *
+ * @param properties The set of reconfiguration properties.
+ * @param urn The urn for the observation.
+ */
+ public NodeDegreeObservation(Properties properties, String urn) {
+ this.logger = SystemContext.getLogger();
+ try {
+ nodeDegreeManager = NDPFactory.getInstance(NeighborDiscoveryType.ON_DEMAND_NODE_DEGREE);
+ } catch (NeighborDiscoveryFactoryException ex) {
+ logger.severe("Unable to create the requested nodeDegreeManager");
+ }
+ }
+
+ /**
+ * Starts the on demand neighbor discovery required to keep updated the
+ * table of active neighbors.
+ */
+ public void start() {
+ ((OnDemandNeighborDiscovery) this.nodeDegreeManager).start();
+ }
+
+ /**
+ * Get the observation {@link ANES_URN} urn.
+ *
+ * @return The observatio ANES urn.
+ */
+ public ANES_URN getObservationID() {
+ try {
+ return ANES_URN.create(DEMANESResources.NDObservationURN);
+ } catch (ANES_URN_Exception ex) {
+ logger.log(Level.SEVERE, "NodeDegreeObservation.getObservationID: ANES_URN.create reported and error with DEMANESResources.NDObservationURN.");
+ return null;
+ }
+ }
+
+ /**
+ * Get the observed value, in this case the number of active neighbors.
+ *
+ * @return The observation value, that is, the number of active neighbors.
+ * @throws ObservationInvocationException
+ */
+ public Object getValue() throws ObservationInvocationException {
+ return new Integer((int) nodeDegreeManager.getNodeDegree());
+ }
+
+ /**
+ * Updates the active neighbors table.
+ */
+ public void updateNodeDegree() {
+ nodeDegreeManager.doNeighborDiscovery();
+ }
+
+ /**
+ * Get the list of active neighbors.
+ *
+ * @return The list of active neighbors.
+ */
+ public Vector getNeighborList() {
+ return nodeDegreeManager.getNeighborList();
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservationExtension.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservationExtension.java
new file mode 100644
index 0000000..31aea6c
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/NodeDegreeObservationExtension.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations;
+
+import java.util.Vector;
+
+/**
+ * Interface to extend the functionality of the basic NodeDegreeObservation.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public interface NodeDegreeObservationExtension {
+
+ /**
+ * Retrieves the list of active neighbors.
+ *
+ * @return The list of active neighbors.
+ */
+ public Vector getNeighborList();
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationException.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationException.java
new file mode 100644
index 0000000..facd50f
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationException.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations;
+
+import eu.artemis.demanes.reconfiguration.Observation;
+
+/**
+ * Thrown when the {@code Observation} catches an error.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+class ObservationException extends Exception {
+
+ /**
+ * Constructs a {@code ObservationException} with the specified
+ * detail message.
+ *
+ * @param observation The detail message.
+ */
+ public ObservationException(String message, Observation observation) {
+ super(observation.getClass().toString() + ": " + message);
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactory.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactory.java
new file mode 100644
index 0000000..57866fc
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactory.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations;
+
+import com.sun.spot.core.util.Properties;
+import eu.artemis.demanes.reconfiguration.Observation;
+
+/**
+ * An ObservationFactory is a factory method to provide an {@link Observation}
+ * selected accordingly to the instance requested. See{@link ObservationType}
+ * for further information regarding the current available observations.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class ObservationFactory {
+
+ /**
+ * A factory to create instances of requested observations.
+ *
+ * @param observationType The type of observation to be created.
+ * @param properties Properties used by the observation.
+ * @param urn URN associated to the observation
+ * @return The observation object.
+ * @throws ObservationFactoryException
+ */
+ public static Observation getInstance(ObservationType observationType, Properties properties, String urn) throws ObservationFactoryException {
+ switch (observationType.hashCode()) {
+ case ObservationType.NODE_DEGREE_OBSERVATION_CODE:
+ return new NodeDegreeObservation(properties, urn);
+ case ObservationType.BATTERY_LEVEL_OBSERVATION_CODE:
+ return new BatteryLevelObservation(properties, urn);
+ default:
+ throw new ObservationFactoryException(observationType.toString());
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactoryException.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactoryException.java
new file mode 100644
index 0000000..bb49728
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationFactoryException.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations;
+
+/**
+ * Thrown when the {@code ObservationFactory} tries to instantiate an
+ * observation not implemented.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+class ObservationFactoryException extends Exception {
+
+ /**
+ * Constructs a {@code ObservationFactoryException} with the specified
+ * detail message.
+ *
+ * @param observationType The detail message.
+ */
+ public ObservationFactoryException(String observationType) {
+ super("Unknown " + observationType + " requested.");
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationType.java b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationType.java
new file mode 100644
index 0000000..23af0dc
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/reconfiguration/observations/ObservationType.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.reconfiguration.observations;
+
+/**
+ * Observation type for use in the {@code ObservationFactory}.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class ObservationType {
+
+ /** Node degree observation descriptive string. */
+ public static final String NODE_DEGREE_OBSERVATION_STRING = "Node Degree Observation";
+ /** Battery level observation descriptive string. */
+ public static final String BATTERY_LEVEL_OBSERVATION_STRING = "Battery Level Observation";
+
+ /** Node degree observation code. */
+ public static final int NODE_DEGREE_OBSERVATION_CODE = 0xA1;
+ /** Battery level observation code. */
+ public static final int BATTERY_LEVEL_OBSERVATION_CODE = 0xA2;
+
+ /** Node degree observation type. */
+ public static final ObservationType NODE_DEGREE_OBSERVATION = new ObservationType(NODE_DEGREE_OBSERVATION_STRING, NODE_DEGREE_OBSERVATION_CODE);
+ /** Battery level observation type. */
+ public static final ObservationType BATTERY_LEVEL_OBSERVATION = new ObservationType(BATTERY_LEVEL_OBSERVATION_STRING, BATTERY_LEVEL_OBSERVATION_CODE);
+
+ private String name;
+ private int code;
+
+ /**
+ * Protected constructor of an observation with a descriptive string
+ * {@code name} and identificative {@code code}.
+ *
+ * @param name The descriptive string of the observation.
+ * @param code The identificative code of the observation.
+ */
+ protected ObservationType(String name, int code) {
+ this.name = name;
+ this.code = code;
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param obj The reference object with which to compare.
+ * @return True if this object is the same as the obj argument, false otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final ObservationType other = (ObservationType) obj;
+ if (this.code != other.code) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ *
Returns a hash code value for the object. This method is supported
+ * for the benefit of hash tables such as those provided by HashMap.
+ *
+ *
+ *
The general contract of hashCode is:
+ *
+ *
Whenever it is invoked on the same object more than once during an
+ * execution of a Java application, the hashCode method must consistently
+ * return the same integer, provided no information used in equals
+ * comparisons on the object is modified. This integer need not remain
+ * consistent from one execution of an application to another execution of
+ * the same application.
+ *
If two objects are equal according to the equals(Object) method,
+ * then calling the hashCode method on each of the two objects must produce
+ * the same integer result.
+ *
It is not required that if two objects are unequal according to the
+ * equals(java.lang.Object) method, then calling the hashCode method on each
+ * of the two objects must produce distinct integer results. However, the
+ * programmer should be aware that producing distinct integer results for
+ * unequal objects may improve the performance of hash tables.
+ *
+ *
+ *
As much as is reasonably practical, the hashCode method defined by
+ * class Object does return distinct integers for distinct objects. (This
+ * is typically implemented by converting the internal address of the object
+ * into an integer, but this implementation technique is not required by the
+ * JavaTM programming language.)
+ *
+ *
+ * @return A hash code value for this object.
+ */
+ public int hashCode() {
+ return this.code;
+ }
+
+ /**
+ * Returns a string representation of the object, in this case the
+ * descriptive string of the observation type.
+ *
+ * @return A string representation of the object.
+ */
+ public String toString() {
+ return this.name;
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee.java
new file mode 100644
index 0000000..bead780
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/Marquee.java
@@ -0,0 +1,276 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee;
+
+import com.sun.spot.core.resources.Resources;
+import com.sun.spot.core.resources.transducers.ITriColorLEDArray;
+import com.sun.spot.core.resources.transducers.LEDColor;
+import com.sun.spot.core.util.Utils;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ *
+ * Note: Although some parts should be considered to be accessed in a
+ * synchronized way allowing different callers for the marquee, the actual usage
+ * does not require it.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class Marquee {
+
+ /** Color used for signaling a "NOT READY" message. */
+ public static final LEDColor STATUS_IS_NOT_READY = LEDColor.RED;
+ /** Color used for signaling a "READY" message. */
+ public static final LEDColor STATUS_IS_READY = LEDColor.GREEN;
+ /** Color used for signaling a "STANDBY" message. */
+ public static final LEDColor STATUS_IS_STANDBY = LEDColor.YELLOW;
+
+ /** Minimum interval time in milliseconds for rotating the messages. */
+ public static final long MINIMUM_INTERVAL = 3000;
+ /** Blink interval time in milliseconds. */
+ public static final long BLINK_INTERVAL = 200;
+
+ private static final int STATUS_INDICATOR_LED_POSITION = 0;
+ private static final int ACTIVITY_1_LED_POSITION = 1;
+ private static final int ACTIVITY_2_LED_POSITION = 2;
+
+ private Hashtable messages;
+ private long updatingInterval;
+ private boolean useStatusIndicator;
+ private LEDColor statusIndicator;
+ private int messageIdCounter;
+ private boolean running;
+ private boolean paused;
+
+ private ITriColorLEDArray LEDs;
+
+ private Thread engineThread;
+
+ private SystemContext context;
+
+ /**
+ * Public constructor for a new marquee. The created marquee will have no
+ * message and will be stopped until {@link eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee.Marquee#start()}
+ * is called.
+ */
+ public Marquee() {
+ this.messages = new Hashtable();
+ this.updatingInterval = MINIMUM_INTERVAL;
+ this.useStatusIndicator = true;
+ this.statusIndicator = STATUS_IS_NOT_READY;
+ this.messageIdCounter = 0;
+ this.running = false;
+ this.paused = false;
+
+ this.LEDs = (ITriColorLEDArray) Resources.lookup(ITriColorLEDArray.class);
+ }
+
+ /**
+ * Get the updating interval time being used in the marquee.
+ *
+ * @return The updating interval time.
+ */
+ public long getUpdatingInterval() {
+ return updatingInterval;
+ }
+
+ /**
+ * Set the updating interval time to be used in the marquee.
+ *
+ * @param updatingInterval The updating interval time.
+ */
+ public void setUpdatingInterval(long updatingInterval) {
+ this.updatingInterval = updatingInterval;
+ }
+
+ /**
+ * Activates the status indicator.
+ */
+ public void activateStatusIndicator() {
+ this.useStatusIndicator = true;
+ }
+
+ /**
+ * Deactivates the status indicator.
+ */
+ public void deactivateStatusIndicator() {
+ this.useStatusIndicator = false;
+ }
+
+ /**
+ * Add a {@code message} to the marquee.
+ *
+ * @param message The message.
+ * @return The ID of the message for further references.
+ * @throws MarqueeAddMessageException When the message can not be added to
+ * the marquee.
+ */
+ public Object addMessage(MarqueeMessage message) throws MarqueeAddMessageException {
+ if (messageIdCounter == Integer.MAX_VALUE) {
+ throw new MarqueeAddMessageException("Reached maximum number of messages available.");
+ }
+
+ messageIdCounter++;
+ Integer key = Integer.valueOf(messageIdCounter);
+ messages.put(key, message);
+
+ return (Object) key;
+ }
+
+ /**
+ * Update a message referenced by {@code key} reference ID with the new
+ * {@code message}.
+ *
+ * @param key The reference key ID.
+ * @param message The new message.
+ */
+ public void updateMessage(Object key, MarqueeMessage message) {
+ messages.put(key, message);
+ }
+
+ /**
+ * Remeve a message referenced by {@code key} refernce ID from the marquee.
+ *
+ * @param key The reference key ID.
+ */
+ public void removeMessage(Object key) {
+ messages.remove(key);
+ }
+
+ /**
+ * Clears de marquee.
+ */
+ public void clearMarquee() {
+ messages.clear();
+ LEDs.setRGB(0, 0, 0);
+ }
+
+ /**
+ * Starts the marquee.
+ */
+ public void start() {
+ if (!this.running) {
+ this.running = true;
+ this.paused = false;
+ this.LEDs.setOn();
+ this.engineThread = new Thread(new Engine());
+ this.engineThread.start();
+ }
+ }
+
+ /**
+ * Pauses the marquee.
+ */
+ public void pause() {
+ paused = true;
+ }
+
+ /**
+ * Unpauses the marquee.
+ */
+ public void unpause() {
+ paused = false;
+ }
+
+ /**
+ * Stops the marquee.
+ */
+ public void stop() {
+ if (this.running) {
+ this.paused = true;
+ this.running = false;
+ }
+ try {
+ this.engineThread.join();
+ this.LEDs.setOff();
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Sets the color of the status indicator according to {@code status}.
+ *
+ * @param status The new status color for the status indicator.
+ */
+ public void setStatusIndicator(LEDColor status) {
+ this.statusIndicator = status;
+ }
+
+ /**
+ * Blinks the first activity LED indicator using the {@code activityColor}
+ * color.
+ *
+ * @param activityColor The color for the blink.
+ */
+ public void blinkActivity1(LEDColor activityColor) {
+ LEDs.getLED(ACTIVITY_1_LED_POSITION).setColor(activityColor);
+ try{Thread.sleep(BLINK_INTERVAL);} catch(InterruptedException ie){}
+ LEDs.getLED(ACTIVITY_1_LED_POSITION).setRGB(0, 0, 0);
+ }
+
+ /**
+ * Blinks the second activity LED indicator using the {@code activityColor}
+ * color.
+ *
+ * @param activityColor The color for the blink.
+ */
+ public void blinkActivity2(LEDColor activityColor) {
+ LEDs.getLED(ACTIVITY_2_LED_POSITION).setColor(activityColor);
+ try{Thread.sleep(BLINK_INTERVAL);} catch(InterruptedException ie){}
+ LEDs.getLED(ACTIVITY_2_LED_POSITION).setRGB(0, 0, 0);
+ }
+
+ private class Engine implements Runnable {
+
+ public void run() {
+ MarqueeMessage message;
+
+ LEDs.setOn();
+
+ while (running) {
+ while (!paused) {
+ try {
+ LEDs.getLED(STATUS_INDICATOR_LED_POSITION).setColor(statusIndicator);
+
+ if (!messages.isEmpty()) {
+ Enumeration messageList = messages.keys();
+ while (messageList.hasMoreElements()) {
+ message = (MarqueeMessage) messages.get(messageList.nextElement());
+ for (int index = 0; index < MarqueeMessage.MESSAGE_LENGTH; index++) {
+ LEDs.getLED(index + 3).setColor(message.getMessage()[index]);
+ }
+ Utils.sleep(updatingInterval);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ Utils.sleep(Long.MAX_VALUE);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeAddMessageException.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeAddMessageException.java
new file mode 100644
index 0000000..212cf36
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeAddMessageException.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee;
+
+/**
+ * Thrown when an error occurs trying to add a new message to the marquee.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class MarqueeAddMessageException extends Exception {
+
+ /**
+ * Constructs a {@code MarqueeAddMessageException}.
+ */
+ public MarqueeAddMessageException() {
+ super("Exception trying to add a message to the marquee.");
+ }
+
+ /**
+ * Constructs a {@code MarqueeAddMessageException} with the specified
+ * detail message.
+ *
+ * @param s The detail message.
+ */
+ public MarqueeAddMessageException(String s) {
+ super("Exception trying to add a message to the marquee: " + s);
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeMessage.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeMessage.java
new file mode 100644
index 0000000..35f3d7a
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/LEDMarquee/MarqueeMessage.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.LEDMarquee;
+
+import com.sun.spot.core.resources.transducers.LEDColor;
+
+/**
+ * A Marquee Message.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class MarqueeMessage {
+ /** Message length */
+ public static final int MESSAGE_LENGTH = 5;
+
+ private static final byte STATIC = 0x01;
+ private static final byte PROGRESS_BAR = 0x02;
+
+ private LEDColor[] message;
+ private byte messageType;
+
+ /**
+ * Public constructor of the LED marquee using a default blank message.
+ */
+ public MarqueeMessage() {
+ this.message = new LEDColor[MESSAGE_LENGTH];
+ for (int index=0; index < MESSAGE_LENGTH; index++)
+ this.message[index] = new LEDColor(0,0,0);
+ }
+
+ /**
+ * Public constructor of the LED marquee with a {@code message}.
+ *
+ * @param message The initial message.
+ */
+ public MarqueeMessage(LEDColor[] message) {
+ this.message = message;
+ }
+
+ /**
+ * Get the message shown in the marquee.
+ *
+ * @return The message.
+ */
+ public LEDColor[] getMessage() {
+ return message;
+ }
+
+ /**
+ * Set the message to be shown in the marquee.
+ *
+ * @param message The message.
+ */
+ public void setMessage(LEDColor[] message) {
+ this.message = message;
+ }
+
+ /**
+ * Set a new indicator @code color} at postition {@code position} of the
+ * message.
+ *
+ * @param position The position.
+ * @param color The color.
+ */
+ public void setMessageAtPosition(int position, LEDColor color) {
+ this.message[position] = color;
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/logging/Level.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/logging/Level.java
new file mode 100644
index 0000000..7959c52
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/logging/Level.java
@@ -0,0 +1,179 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.logging;
+
+/**
+ * The Level class defines a set of standard logging levels that can be used to
+ * control logging output. The logging Level objects are ordered and are
+ * specified by ordered integers. Enabling logging at a given level also enables
+ * logging at all higher levels.
+ *
+ *
+ * Clients should normally use the predefined Level constants such as
+ * Level.SEVERE.
+ *
+ *
+ *
+ * The levels in descending order are:
+ *
+ *
+ *
+ *
SEVERE (highest value)
+ *
WARNING
+ *
INFO
+ *
CONFIG
+ *
FINE
+ *
FINER
+ *
FINEST (lowest value)
+ *
+ *
+ *
+ * In addition there is a level OFF that can be used to turn off logging, and a
+ * level ALL that can be used to enable logging of all messages.
+ *
+ *
+ *
+ * It is possible for third parties to define additional logging levels by
+ * subclassing Level. In such cases subclasses should take care to chose unique
+ * integer level values and to ensure that they maintain the Object uniqueness
+ * property across serialization by defining a suitable readResolve method.
+ *
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class Level {
+
+ private final String name;
+ private final int value;
+
+ /**
+ * ALL indicates that all messages should be logged.
+ */
+ public static Level ALL = new Level("ALL", 0);
+ /**
+ * FINEST indicates a highly detailed tracing message.
+ */
+ public static Level FINEST = new Level("FINEST", 1);
+ /**
+ * FINER indicates a fairly detailed tracing message.
+ */
+ public static Level FINER = new Level("FINER", 2);
+ /**
+ * FINE is a message level providing tracing information.
+ */
+ public static Level FINE = new Level("FINE", 3);
+ /**
+ * DEBUG is a message level for debugging information.
+ */
+ public static Level DEBUG = new Level("DEBUG", 4);
+ /**
+ * CONFIG is a message level for static configuration messages.
+ */
+ public static Level CONFIG = new Level("CONFIG", 5);
+ /**
+ * INFO is a message level for informational messages.
+ */
+ public static Level INFO = new Level("INFO", 6);
+ /**
+ * WARNING is a message level indicating a potential problem.
+ */
+ public static Level WARNING = new Level("WARNING", 7);
+ /**
+ * SEVERE is a message level indicating a serious failure.
+ */
+ public static Level SEVERE = new Level("SEVERE", 8);
+ /**
+ * OFF is a special level that can be used to turn off logging.
+ */
+ public static Level OFF = new Level("OFF", Integer.MAX_VALUE);
+
+ /**
+ * Create a named Level with a given integer value.
+ *
+ * Note that this constructor is "protected" to allow subclassing. In
+ * general clients of logging should use one of the constant Level objects
+ * such as SEVERE or FINEST. However, if clients need to add new logging
+ * levels, they may subclass Level and define new constants.
+ *
+ * @param name the name of the Level, for example "SEVERE".
+ * @param value an integer value for the level.
+ */
+ protected Level(String name, int value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Generate a hashcode.
+ *
+ * @return a hashcode based on the level value.
+ */
+ public int hashCode() {
+ int hash = 5;
+ hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0);
+ hash = 41 * hash + this.value;
+ return hash;
+ }
+
+ /**
+ * Compare two objects for value equality.
+ *
+ * @param ox the reference object with which to compare.
+ * @return true if and only if the two objects have the same level value.
+ */
+ public boolean equals(Object ox) {
+ if (this.getClass().equals(ox.getClass())) {
+ return ((Level) ox).getName().equalsIgnoreCase(this.name) && ((Level) ox).intValue() == this.value;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Return the non-localized string name of the Level.
+ *
+ * @return non-localized name
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Get the integer value for this level. This integer value can be used for
+ * efficient ordering comparisons between Level objects.
+ *
+ * @return the integer value for this level.
+ */
+ public int intValue() {
+ return this.value;
+ }
+
+ /**
+ * Returns a string representation of this Level.
+ *
+ * @return the non-localized name of the Level, for example "INFO".
+ */
+ public String toString() {
+ return this.name;
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/logging/Logger.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/logging/Logger.java
new file mode 100644
index 0000000..db89a6f
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/logging/Logger.java
@@ -0,0 +1,402 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.logging;
+
+import com.sun.spot.core.util.PrettyPrint;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+import javax.microedition.rms.RecordStore;
+import javax.microedition.rms.RecordStoreException;
+import javax.microedition.rms.RecordStoreFullException;
+
+/**
+ * Logging operations are done through this class.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class Logger {
+
+ /**
+ * SYSTEM_OUTPUT indicates that the log is going to be done to System.out.
+ */
+ public static final byte SYSTEM_OUTPUT = 0x01;
+ /**
+ * SYSTEM_ERROR indicates that the log is going to be done to System.err.
+ */
+ public static final byte SYSTEM_ERROR = 0x02;
+ /**
+ * RECORD indicates that the log is going to be stored in an internal
+ * RecordStore.
+ */
+ public static final byte RECORD = 0x10;
+ /**
+ * DISABLED indicates that the loggin is disabled.
+ */
+ public static final byte DISABLED = 0x00;
+ /**
+ * REMOTE indicates that the log is going to be casted to a remote logging
+ * facility.
+ */
+ public static final byte REMOTE = 0x20;
+
+ private static final Level DEFAULT_LEVEL = Level.ALL;
+ private static final byte DEFAULT_DESTINATION = SYSTEM_OUTPUT;
+ private static final String DEFAULT_RECORD_NAME = "spotlog";
+ private static final String DEFAULT_DEBUG_RECORD_NAME = "debuglog";
+
+ private static final String DELIMITER = ": ";
+ private static final boolean CREATE_RECORD_IF_NECESSARY = true;
+
+ private byte destination;
+ private String name;
+ private Level level;
+
+ private TimeZone timeZone;
+
+ private int numberOfRecords;
+
+ private SystemContext context;
+
+ /**
+ * Public constructor with a default configuration.
+ *
+ * The logger will be initially configured for ALL messages done to
+ * System.out.
+ */
+ public Logger() {
+ this.destination = DEFAULT_DESTINATION;
+ this.name = DEFAULT_RECORD_NAME;
+ this.level = DEFAULT_LEVEL;
+ this.timeZone = TimeZone.getTimeZone("GMT+1");
+ this.numberOfRecords = 0;
+ }
+
+ /**
+ * Public constructor with default configuration using {@code name} as the
+ * name for the internal record storage.
+ *
+ * The logger will be initially configured for ALL messages done to
+ * System.out.
+ *
+ * @param name The name of the record store.
+ */
+ public Logger(String name) {
+ this();
+ this.name = name;
+ }
+
+ /**
+ * Public constructor with default configuration using {@code destination}
+ * as the destination for the logs.
+ *
+ * @param destination The destination for the logs.
+ */
+ public Logger(byte destination) {
+ this();
+ this.destination = destination;
+ }
+
+ /**
+ * Public constructor with default configuration using {@code name} as the
+ * name for the record store, and {@code destination} for the destination of
+ * the logs.
+ *
+ * @param name The name of the record store.
+ * @param destination The destination for the logs.
+ */
+ public Logger(String name, byte destination) {
+ this();
+ this.destination = destination;
+ this.name = name;
+ }
+
+ /**
+ * Public constructor with default configuration using {@code name} as the
+ * name for the record store, {@code destination} as the destination for the
+ * logs, and {@code level} as the minimum level of the logs to be recorded.
+ *
+ * @param name The name of the record store.
+ * @param destination The destination for the logs.
+ * @param level The minimum level of the logs to be recorded.
+ */
+ public Logger(String name, byte destination, Level level) {
+ this();
+ this.destination = destination;
+ this.name = name;
+ this.level = level;
+ }
+
+ /**
+ * Set the name of the record store.
+ *
+ * @param name The name of the record store.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the name of the record store.
+ *
+ * @return The name of the record store.
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Set the destination of the log messages.
+ *
+ * @param destination The destination of the log messages.
+ */
+ public void setDestination(byte destination) {
+ this.destination = destination;
+ }
+
+ /**
+ * Get the destination of the log messages.
+ *
+ * @return The detination of the log messages.
+ */
+ public byte getDestination() {
+ return this.destination;
+ }
+
+ /**
+ * Set the logging level.
+ *
+ * @param level The logging level.
+ */
+ public void setLevel(Level level) {
+ this.level = level;
+ }
+
+ /**
+ * Get the logging level.
+ *
+ * @return The logging level.
+ */
+ public Level getLevel() {
+ return this.level;
+ }
+
+ /**
+ * Set the level to logging all.
+ */
+ public void setAll() {
+ this.level = Level.ALL;
+ }
+
+ /**
+ * Set off the logging.
+ */
+ public void setOff() {
+ this.level = Level.OFF;
+ }
+
+ /**
+ * Log a message of level {@code FINEST}.
+ *
+ * @param msg The message.
+ */
+ public void finest(String msg) {
+ this.log(Level.FINEST, msg);
+ }
+
+ /**
+ * Log a message of level {@code FINER}.
+ *
+ * @param msg The message.
+ */
+ public void finer(String msg) {
+ this.log(Level.FINER, msg);
+ }
+
+ /**
+ * Log a message of level {@code FINE}.
+ *
+ * @param msg The message.
+ */
+ public void fine(String msg) {
+ this.log(Level.FINE, msg);
+ }
+
+ /**
+ * Log a message of level {@code DEBUG}.
+ *
+ * @param msg The message.
+ */
+ public void debug(String msg) {
+ this.log(Level.DEBUG, msg);
+ }
+
+ /**
+ * Log a message of level {@code CONFIG}.
+ *
+ * @param msg The message.
+ */
+ public void config(String msg) {
+ this.log(Level.CONFIG, msg);
+ }
+
+ /**
+ * Log a message of level {@code INFO}.
+ *
+ * @param msg The message.
+ */
+ public void info(String msg) {
+ this.log(Level.INFO, msg);
+ }
+
+ /**
+ * Log a message of level {@code WARNING}.
+ *
+ * @param msg The message.
+ */
+ public void warning(String msg) {
+ this.log(Level.WARNING, msg);
+ }
+
+ /**
+ * Log a message of level {@code SEVERE}.
+ *
+ * @param msg The message.
+ */
+ public void severe(String msg) {
+ this.log(Level.SEVERE, msg);
+ }
+
+ /**
+ * Log a message of level {@code level}.
+ *
+ * @param level The level.
+ * @param msg The message.
+ */
+ public void log(Level level, String msg) {
+
+ if (level.intValue() >= this.level.intValue()) {
+ Date timestamp = Calendar.getInstance().getTime();
+ StringBuffer logBuffer = new StringBuffer();
+ logBuffer.append(timestamp.toString());
+ logBuffer.append(DELIMITER);
+ logBuffer.append(level.getName());
+ logBuffer.append(DELIMITER);
+ logBuffer.append(msg);
+
+ String logMessage = logBuffer.toString();
+ switch (this.destination) {
+ case SYSTEM_OUTPUT:
+ System.out.println(logMessage);
+ break;
+ case SYSTEM_ERROR:
+ System.err.println(logMessage);
+ break;
+ case RECORD:
+ RecordStore recordStore;
+ try {
+ recordStore = RecordStore.openRecordStore(name, CREATE_RECORD_IF_NECESSARY);
+ System.out.println("Trying to record a message with size " + logMessage.length());
+ recordStore.addRecord(logMessage.getBytes(), 0, logMessage.length());
+ numberOfRecords++;
+ System.out.println("Updated number of records is " + numberOfRecords);
+ recordStore.closeRecordStore();
+ } catch (RecordStoreFullException exception) {
+ System.err.println("WARNING. Record store is full");
+ } catch (RecordStoreException ex) {
+ if (this.level.intValue() <= Level.DEBUG.intValue()) {
+ System.out.println("An error has ocurred trying to store a log in the record store named \"" + name + "\"");
+ ex.printStackTrace();
+ } else {
+ System.out.println("You shoulden't be reading this... contact with yourself and try to solve this mesh!!!");
+ }
+ }
+ break;
+ case REMOTE:
+ // Not implemented
+ break;
+ case DISABLED:
+ // Do nothing
+ break;
+ default:
+ System.out.println(logMessage);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Log a byte array of level {@code level}.
+ *
+ * @param level The level.
+ * @param baos The byte array message.
+ */
+ public void log(Level level, ByteArrayOutputStream baos) {
+
+ if (level.intValue() >= this.level.intValue()) {
+ Date timestamp = Calendar.getInstance().getTime();
+
+ switch (this.destination) {
+ case SYSTEM_OUTPUT:
+ PrettyPrint.prettyPrint(baos.toByteArray());
+ break;
+ case SYSTEM_ERROR:
+ PrettyPrint.prettyPrint(baos.toByteArray());
+ break;
+ case RECORD:
+ RecordStore recordStore;
+ try {
+ recordStore = RecordStore.openRecordStore(name, CREATE_RECORD_IF_NECESSARY);
+ System.out.println("Trying to record a message with size " + baos.size());
+ recordStore.addRecord(baos.toByteArray(), 0, baos.size());
+ numberOfRecords++;
+ System.out.println("Updated number of records is " + numberOfRecords);
+ recordStore.closeRecordStore();
+ } catch (RecordStoreFullException exception) {
+ System.err.println("WARNING. Record store is full");
+ } catch (RecordStoreException ex) {
+ if (this.level.intValue() <= Level.DEBUG.intValue()) {
+ System.out.println("An error has ocurred trying to store a log in the record store named \"" + name + "\"");
+ ex.printStackTrace();
+ } else {
+ System.out.println("You shoulden't be reading this... contact with yourself and try to solve this mesh!!!");
+ }
+ }
+ break;
+ case REMOTE:
+ // Not implemented
+ break;
+ case DISABLED:
+ // Do nothing
+ break;
+ default:
+ System.out.println("DESTINATION NOT IMPLEMENTED. DEFAULT TO STDOUT");
+ PrettyPrint.prettyPrint(baos.toByteArray());
+ break;
+ }
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NDPFactory.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NDPFactory.java
new file mode 100644
index 0000000..519ce88
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NDPFactory.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery;
+
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.ondemand.OnDemandNeighborDiscovery;
+
+/**
+ *
A NDPFactory is a factory method to provide a Neighbor Discovery Protocol
+ * manager selected accordingly to the instance requested. See
+ * {@link NeighborDiscoveryType} for further information regarding the current
+ * available managers.
+ *
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ * @since 20140923
+ *
+ */
+public class NDPFactory {
+ /**
+ * A factory to create instances of requested neighbor discovery protocols.
+ *
+ * @param neighborDiscoveryType The type of neighbor discovery required.
+ * @return The instantiated neighbor discovery protocol.
+ * @throws NeighborDiscoveryFactoryException when the requested typr is not implemented.
+ */
+ public static NeighborDiscoveryProtocol getInstance(NeighborDiscoveryType neighborDiscoveryType) throws NeighborDiscoveryFactoryException {
+ switch (neighborDiscoveryType.hashCode()) {
+ case NeighborDiscoveryType.NODE_DEGREE_MANAGER_V1_CODE:
+ return new NodeDegreeManagerV1();
+ case NeighborDiscoveryType.ON_DEMAND_NODE_DEGREE_CODE:
+ return new OnDemandNeighborDiscovery();
+ default:
+ throw new NeighborDiscoveryFactoryException(neighborDiscoveryType.toString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryException.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryException.java
new file mode 100644
index 0000000..4b63dec
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryException.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery;
+
+/**
+ * Thrown when an error occurs in the neighbor discovery protocol.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class NeighborDiscoveryException extends Exception {
+
+ /**
+ * Constructs a {@code NeighborDiscoveryException} with the specified
+ * detail message.
+ *
+ * @param s The detail message.
+ */
+ public NeighborDiscoveryException(String s) {
+ super(s);
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryFactoryException.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryFactoryException.java
new file mode 100644
index 0000000..d673315
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryFactoryException.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery;
+
+/**
+ * Thrown when the neighbor discovery protocol factory is requested to create
+ * an instance of an non implemented neighbor discovery protocol.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class NeighborDiscoveryFactoryException extends Exception {
+
+ /**
+ * Constructs a {@code NeighborDiscoveryFactoryException} with the specified
+ * detail message.
+ *
+ * @param neighborDiscoveryType The detail message.
+ */
+ public NeighborDiscoveryFactoryException(String neighborDiscoveryType) {
+ super("Unknown " + neighborDiscoveryType + " requested.");
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryProtocol.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryProtocol.java
new file mode 100644
index 0000000..a229b06
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryProtocol.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery;
+
+import java.util.Vector;
+
+/**
+ * Defines the public methods for any neighbor discovery protocol used in the
+ * slef-adaptive power controller.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public interface NeighborDiscoveryProtocol {
+ /**
+ * Gets the number of active neighbors (Node Degree).
+ *
+ * @return The number of active neighbors.
+ */
+ public long getNodeDegree();
+
+ /**
+ * Gets the list of active neighbors.
+ *
+ * @return The list of active neighbors.
+ */
+ public Vector getNeighborList();
+
+ /**
+ * Performs a neighbor discovery request.
+ */
+ public void doNeighborDiscovery();
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryType.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryType.java
new file mode 100644
index 0000000..a2ac5ac
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NeighborDiscoveryType.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery;
+
+/**
+ * Represents the type of neighbor discovery protocol.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class NeighborDiscoveryType {
+
+ /** String description for the Node Degree Manager V1. */
+ public static final String NODE_DEGREE_MANAGER_V1_STRING = "Node Degree Manager V1 (Guard Interval)";
+ /** String description for the Node Degree Manager V2. */
+ public static final String NODE_DEGREE_MANAGER_V2_STRING = "Node Degree Manager V2 (Incremental Management)";
+ /** String description for the outdated Basic Neighbor Discovery. */
+ public static final String BASIC_NEIGHBOR_DISCOVERY_STRING = "Basic Neighbor Discovery Manager V1";
+ /** String description for the On Demand Node Degree. */
+ public static final String ON_DEMAND_NODE_DEGREE_STRING = "On Demand Node Degree Manager V1";
+
+ /** Code for the Node Degree Manager V1. */
+ public static final int NODE_DEGREE_MANAGER_V1_CODE = 0x01;
+ /** Code for the Node Degree Manager V2. */
+ public static final int NODE_DEGREE_MANAGER_V2_CODE = 0x02;
+ /** Code for the outdated Basic Neighbor Discovery. */
+ public static final int BASIC_NEIGHBOR_DISCOVERY_CODE = 0x03;
+ /** Code for the On Demand Node Degree. */
+ public static final int ON_DEMAND_NODE_DEGREE_CODE = 0x04;
+
+ /** Neighbor Discovery Type for the Node Degree Manager V1. */
+ public static final NeighborDiscoveryType NODE_DEGREE_MANAGER_V1 = new NeighborDiscoveryType(NODE_DEGREE_MANAGER_V1_STRING, NODE_DEGREE_MANAGER_V1_CODE);
+ /** Neighbor Discovery Type for the Node Degree Manager Vw. */
+ public static final NeighborDiscoveryType NODE_DEGREE_MANAGER_V2 = new NeighborDiscoveryType(NODE_DEGREE_MANAGER_V2_STRING, NODE_DEGREE_MANAGER_V2_CODE);
+ /** Neighbor Discovery Type for the outdated Basic Neighbor Discovery. */
+ public static final NeighborDiscoveryType BASIC_NEIGHBOR_DISCOVERY = new NeighborDiscoveryType(BASIC_NEIGHBOR_DISCOVERY_STRING, BASIC_NEIGHBOR_DISCOVERY_CODE);
+ /** Neighbor Discovery Type for the On Demand Node Degree. */
+ public static final NeighborDiscoveryType ON_DEMAND_NODE_DEGREE = new NeighborDiscoveryType(ON_DEMAND_NODE_DEGREE_STRING, ON_DEMAND_NODE_DEGREE_CODE);
+
+ private final String name;
+ private int code;
+
+ /**
+ * Creates a new Neighbor Discovery Type.
+ *
+ * @param name Name descriptor for the Neighbor Discovery Type.
+ * @param code Unique code number used to identify the Neighbor Discovery Type.
+ */
+ protected NeighborDiscoveryType(String name, int code) {
+ this.name = name;
+ this.code = code;
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param obj The reference object with which to compare.
+ * @return True if this object is the same as the obj argument, false otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final NeighborDiscoveryType other = (NeighborDiscoveryType) obj;
+ if (this.code != other.code) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a hash code value for the object.
+ *
+ * @return A hash code value for this object.
+ */
+ public int hashCode() {
+ return this.code;
+ }
+
+ /**
+ * Returns a string representation of the object.
+ *
+ * @return A string representation of the object.
+ */
+ public String toString() {
+ return this.name;
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1.java
new file mode 100644
index 0000000..b374299
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV1.java
@@ -0,0 +1,348 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery;
+
+import com.sun.spot.multihop.io.j2me.radiogram.RadiogramConnection;
+import com.sun.squawk.util.NotImplementedYetException;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Random;
+import java.util.Vector;
+import javax.microedition.io.Connector;
+import javax.microedition.io.Datagram;
+
+/**
+ *
+ * @author Vicente Hern´ndez Díaz
+ * @version 1.0.0
+ *
+ * Modified by Néstor Lucas Martínez for communication
+ * pervasiveness.
+ */
+public class NodeDegreeManagerV1 implements NeighborDiscoveryProtocol {
+
+ public Vector getNeighborList() {
+ Vector sources = this.neighboursInfo.sources;
+
+ return sources;
+ }
+
+ public void doNeighborDiscovery() {
+ throw new NotImplementedYetException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ public void setContext(SystemContext context) {
+ //throw new java.lang.UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ private class NeighborsDiscoveryMgr implements Runnable {
+
+ /**
+ * Message of type Neighbor Discovery Request.
+ */
+ private final byte ND_REQUEST = 0;
+ /**
+ * Message of type Neighbor Discovery Response.
+ */
+ private final byte ND_RESPONSE = 1;
+ /**
+ * Message of type Neighbor Discovery Response Acknowledge.
+ */
+ private final byte ND_RESPONSE_ACK = 2;
+
+ /**
+ * Port used for this particular Neighbor Discovery Protocol.
+ */
+ private final int NEIGHBORS_DISCOVERY_PORT = 200;
+
+ /**
+ * Information regarding the Node Degree (the number of available
+ * neighbors at any given moment).
+ */
+ private final NDInformation nodeDegreeInformation;
+
+ /**
+ * Random number generator.
+ */
+ private final Random randomGenerator;
+
+ public NeighborsDiscoveryMgr(NDInformation nodeDegreeInformation) {
+ this.nodeDegreeInformation = nodeDegreeInformation;
+ randomGenerator = new Random();
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager: A new NeighboursDiscoveryMgr instantiated.");
+ new Thread(this).start();
+ }
+
+ public void requestForNeighbors() {
+ try {
+ long requestID;
+ do {
+ requestID = randomGenerator.nextLong();
+ } while (requestID < 0);
+
+ nodeDegreeInformation.changeReqID(requestID);
+ RadiogramConnection con = (RadiogramConnection) Connector.open("radiogram://broadcast:" + NEIGHBORS_DISCOVERY_PORT);
+ con.setMaxBroadcastHops(1);
+ Datagram datagram = con.newDatagram(con.getMaximumLength());
+ datagram.writeByte(ND_REQUEST);
+ datagram.writeLong(requestID);
+ con.send(datagram);
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.requestForNeighbours: Requesting neighbours reponses.");
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ private synchronized void sendMessage(String to, int type, long reqID) {
+ RadiogramConnection connection = null;
+
+ try {
+
+ if (connection == null) {
+ connection = (RadiogramConnection) Connector.open("radiogram://" + to + ":" + NEIGHBORS_DISCOVERY_PORT);
+ }
+
+ Datagram datagram = connection.newDatagram(connection.getMaximumLength());
+ datagram.writeByte(type);
+ datagram.writeLong(reqID);
+ connection.send(datagram);
+ connection.close();
+ logger.log(Level.DEBUG, "NeighborDiscoveryManager.sendMessage: A message (" + ((type == this.ND_RESPONSE) ? "RESPONSE" : ((type == this.ND_RESPONSE_ACK) ? "RESPONSE_ACK" : "UNKNOWN")) + ") sent to: " + to + " with reqID " + reqID + ".");
+ } catch (IOException ex) {
+ logger.log(Level.DEBUG, "NeighborDiscoveryManager.sendMessage: Exception trying to send a message (" + ((type == this.ND_RESPONSE) ? "RESPONSE" : ((type == this.ND_RESPONSE_ACK) ? "RESPONSE_ACK" : "UNKNOWN")) + ") to: " + to + " with reqID " + reqID + ".");
+ ex.printStackTrace();
+ } finally {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (IOException ex) {
+ logger.log(Level.DEBUG, "NeighborDiscoveryManager.sendMessage: ERROR trying to close the connection");
+ }
+ }
+ }
+ }
+
+ public void run() {
+ Hashtable requests = new Hashtable();
+ RadiogramConnection connection = null;
+
+ boolean exit = false;
+
+ do {
+ try {
+ if (connection == null) {
+ connection = (RadiogramConnection) Connector.open("radiogram://:" + this.NEIGHBORS_DISCOVERY_PORT);
+ connection.setTimeout(-1);
+ }
+ Datagram datagram = connection.newDatagram(connection.getMaximumLength());
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: Waiting for messages from neighbours.");
+
+ connection.receive(datagram);
+ byte op = datagram.readByte();
+ long reqID = datagram.readLong();
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: Message from neighbours: From: " + datagram.getAddress() + ", Op: " + op + ", ReqID: " + reqID);
+ switch (op) {
+ case ND_REQUEST:
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: A neighbour request received: " + datagram.getAddress() + ", " + reqID + ".");
+ requests.put(datagram.getAddress(), new Long(reqID));
+ sendMessage(datagram.getAddress(), this.ND_RESPONSE, reqID);
+ break;
+ case ND_RESPONSE:
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: A neighbour response received: " + datagram.getAddress() + ", " + reqID + ".");
+ nodeDegreeInformation.addNeighbour(datagram.getAddress(), reqID);
+ sendMessage(datagram.getAddress(), this.ND_RESPONSE_ACK, reqID);
+ break;
+ case ND_RESPONSE_ACK:
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: A neighbour response ack received: " + datagram.getAddress() + ", " + reqID + ".");
+ Object aux = requests.get(datagram.getAddress());
+ if (aux != null) {
+ long valor = ((Long) aux).longValue();
+ if (valor == reqID) {
+ nodeDegreeInformation.addNeighbour(datagram.getAddress());
+ }
+ } else {
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: A neighbour response ack received but there is no previous request.");
+ }
+ break;
+ }
+ } catch (IOException exception) {
+ logger.log(Level.WARNING, "NeighboursDiscoveryManager.run: Exception. Activate DEBUG Level for printing the stack trace.");
+ if (logger.getLevel().equals(Level.DEBUG)) {
+ exception.printStackTrace();
+ }
+ }
+ } while (!exit);
+ }
+ }
+
+ private class NDInformation {
+
+ private long requestID;
+ private long nodeDegreeOld;
+ private boolean flag;
+ private long nodeDegree;
+ private final Vector sources;
+ private final Object lock;
+
+ public NDInformation() {
+ flag = false;
+ nodeDegreeOld = 0;
+ requestID = -1;
+ nodeDegree = 0;
+ sources = new Vector();
+ lock = new Object();
+ logger.log(Level.DEBUG, "NDInformation: A new NDInformation object instantiated.");
+ }
+
+ public void addNeighbour(String who, long reqID) {
+ synchronized (lock) {
+ if (requestID == -1) {
+ logger.log(Level.DEBUG, "NDInformation.addNeighbour: Response from " + who + " rejected as no previous request was sent.");
+ return;
+ }
+
+ if (requestID != reqID) {
+ logger.log(Level.DEBUG, "NDInformation.addNeighbour: Response from " + who + " rejected reqIDs don't match.");
+ return;
+ }
+
+ this.addNeighbour(who);
+// if (!sources.contains(who)) {
+// nodeDegree++;
+// sources.addElement(who);
+// logger.log(Level.DEBUG, "NDInformation.addNeighbour: New neighbour (" + who + ") added. There are " + nodeDegree + " neighbours.");
+// } else {
+// logger.log(Level.DEBUG, "NDInformation.addNeighbour: " + who + " has sent more than one response.");
+// }
+ }
+ }
+
+ public void addNeighbour(String who) {
+ synchronized (lock) {
+ if (!sources.contains(who)) {
+ nodeDegree++;
+ // -- BEGIN clean this up later
+ // if property.log.level <= FINE *** CHANGE LOG LEVELS POLICY
+ long nd = flag ? nodeDegreeOld : nodeDegree;
+ logger.setDestination(Logger.RECORD);
+ logger.debug("Adding " + who + " to neighbour list.");
+ logger.setDestination(Logger.SYSTEM_OUTPUT);
+
+ // -- END clean this up later
+ sources.addElement(who);
+ logger.log(Level.DEBUG, "NDInformation.addNeighbour: Request from (" + who + ") accepted. There are " + nodeDegree + " neighbours.");
+ } else {
+ logger.log(Level.DEBUG, "NDInformation.addNeighbour: " + who + " has sent more than one response.");
+ }
+ }
+ }
+
+ public long getNodeDegree() {
+ synchronized (lock) {
+ long res;
+ if (flag) {
+ res = this.nodeDegreeOld;
+ } else {
+ res = this.nodeDegree;
+ }
+ logger.log(Level.DEBUG, "NDInforamtion.getNodeDegree: Number of neighbours: " + res + ".");
+ return res;
+ }
+ }
+
+ public void changeReqID(long reqID) {
+ synchronized (lock) {
+ nodeDegreeOld = nodeDegree;
+ new Thread(
+ new Runnable() {
+ public void run() {
+ flag = true;
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException ex) {
+ }
+ flag = false;
+ }
+ }
+ ) {
+ }.start();
+ if (reqID >= 0) {
+ requestID = reqID;
+ nodeDegree = 0;
+ sources.removeAllElements();
+ logger.log(Level.DEBUG, "NDInformation.changeReqID: New request with ID " + reqID + " registered.");
+ } else {
+ logger.log(Level.DEBUG, "NDInformation.changeReqID: New request with ID " + reqID + " rejected.");
+ }
+ }
+ }
+ }
+
+ private class NDTimer implements Runnable {
+
+ private final long REQUEST_PERIOD = 5000;
+
+ private final NeighborsDiscoveryMgr neighboursDiscoveryMgr;
+
+ public NDTimer(NeighborsDiscoveryMgr neighboursDiscoveryMgr) {
+ if (neighboursDiscoveryMgr == null) {
+ logger.log(Level.DEBUG, "NDTimer: no manager for discovering neighbours has been provided.");
+ throw new IllegalArgumentException("NDTimer: no manager for discovering neighbours has been provided.");
+ }
+ this.neighboursDiscoveryMgr = neighboursDiscoveryMgr;
+ logger.log(Level.DEBUG, "NDTimer: a new timer for updating the node degree has been started.");
+ }
+
+ public void run() {
+ boolean exit = false;
+ logger.log(Level.DEBUG, "NDTimer: Timer started.");
+ do {
+ this.neighboursDiscoveryMgr.requestForNeighbors();
+ logger.log(Level.DEBUG, "NDTimer: a new request for neighbours has been invoked.");
+ try {
+ Thread.sleep(REQUEST_PERIOD);
+ } catch (InterruptedException ex) {
+ exit = true;
+ }
+ } while (!exit);
+ logger.log(Level.DEBUG, "NDTimer: the timer for updating the node degree is stopped.");
+ }
+ }
+
+ private final Logger logger = new Logger();
+ private final NDInformation neighboursInfo;
+
+ public NodeDegreeManagerV1() {
+ neighboursInfo = new NDInformation();
+ NeighborsDiscoveryMgr discoveryMgr = new NeighborsDiscoveryMgr(neighboursInfo);
+ new Thread(new NDTimer(discoveryMgr)).start();
+
+ }
+
+ public long getNodeDegree() {
+ return this.neighboursInfo.getNodeDegree();
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2.java
new file mode 100644
index 0000000..09c050f
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/NodeDegreeManagerV2.java
@@ -0,0 +1,355 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery;
+
+import com.sun.spot.core.util.Utils;
+import com.sun.spot.multihop.io.j2me.radiogram.RadiogramConnection;
+import com.sun.squawk.util.NotImplementedYetException;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Random;
+import java.util.Vector;
+import javax.microedition.io.Connector;
+import javax.microedition.io.Datagram;
+
+/**
+ *
+ * @author Vicente Hern´ndez Díaz
+ * @version 1.0.0
+ *
+ * Modified by Néstor Lucas Martínez for communication
+ * pervasiveness.
+ */
+public class NodeDegreeManagerV2 implements NeighborDiscoveryProtocol {
+
+ public void doNeighborDiscovery() {
+ throw new NotImplementedYetException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ public void setContext(SystemContext context) {
+ //throw new java.lang.UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ private class NeighborsDiscoveryMgr implements Runnable {
+
+ /**
+ * Message of type Neighbor Discovery Request.
+ */
+ private final byte ND_REQUEST = 0;
+ /**
+ * Message of type Neighbor Discovery Response.
+ */
+ private final byte ND_RESPONSE = 1;
+ /**
+ * Message of type Neighbor Discovery Response Acknowledge.
+ */
+ private final byte ND_RESPONSE_ACK = 2;
+
+ /**
+ * Port used for this particular Neighbor Discovery Protocol.
+ */
+ private final int NEIGHBORS_DISCOVERY_PORT = 200;
+
+ /**
+ * Information regarding the Node Degree (the number of available
+ * neighbors at any given moment).
+ */
+ private final NDInformation nodeDegreeInformation;
+
+ /**
+ * Random number generator.
+ */
+ private final Random randomGenerator;
+
+ public NeighborsDiscoveryMgr(NDInformation nodeDegreeInformation) {
+ this.nodeDegreeInformation = nodeDegreeInformation;
+ randomGenerator = new Random();
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager: A new NeighboursDiscoveryMgr instantiated.");
+ new Thread(this).start();
+ }
+
+ public void requestForNeighbors() {
+ try {
+ long requestID;
+ requestID = randomGenerator.nextLong();
+
+ if (requestID < 0) {
+ requestID *= -1;
+ }
+
+ nodeDegreeInformation.changeReqID(requestID);
+ RadiogramConnection con = (RadiogramConnection) Connector.open("radiogram://broadcast:" + NEIGHBORS_DISCOVERY_PORT);
+ con.setMaxBroadcastHops(1);
+ Datagram datagram = con.newDatagram(con.getMaximumLength());
+ datagram.writeByte(ND_REQUEST);
+ datagram.writeLong(requestID);
+ con.send(datagram);
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.requestForNeighbours: Requesting neighbours reponses.");
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ private synchronized void sendMessage(String to, int type, long reqID) {
+ RadiogramConnection connection = null;
+
+ try {
+ if (connection == null) {
+ connection = (RadiogramConnection) Connector.open("radiogram://" + to + ":" + NEIGHBORS_DISCOVERY_PORT);
+ }
+
+ Datagram datagram = connection.newDatagram(connection.getMaximumLength());
+ datagram.writeByte(type);
+ datagram.writeLong(reqID);
+ connection.send(datagram);
+ connection.close();
+ logger.log(Level.DEBUG, "NeighborDiscoveryManager.sendMessage: A message (" + ((type == this.ND_RESPONSE) ? "RESPONSE" : ((type == this.ND_RESPONSE_ACK) ? "RESPONSE_ACK" : "UNKNOWN")) + ") sent to: " + to + " with reqID " + reqID + ".");
+ } catch (IOException ex) {
+ logger.log(Level.DEBUG, "NeighborDiscoveryManager.sendMessage: Exception trying to send a message (" + ((type == this.ND_RESPONSE) ? "RESPONSE" : ((type == this.ND_RESPONSE_ACK) ? "RESPONSE_ACK" : "UNKNOWN")) + ") to: " + to + " with reqID " + reqID + ".");
+ ex.printStackTrace();
+ } finally {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (IOException ex) {
+ logger.log(Level.DEBUG, "NeighborDiscoveryManager.sendMessage: ERROR trying to close the connection");
+ }
+ }
+ }
+ }
+
+ public void run() {
+ Hashtable requests = new Hashtable();
+ RadiogramConnection connection = null;
+
+ boolean exit = false;
+
+ do {
+ try {
+ if (connection == null) {
+ connection = (RadiogramConnection) Connector.open("radiogram://:" + this.NEIGHBORS_DISCOVERY_PORT);
+ connection.setTimeout(-1);
+ }
+ Datagram datagram = connection.newDatagram(connection.getMaximumLength());
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: Waiting for messages from neighbours.");
+
+ connection.receive(datagram);
+ byte op = datagram.readByte();
+ long reqID = datagram.readLong();
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: Message from neighbours: From: " + datagram.getAddress() + ", Op: " + op + ", ReqID: " + reqID);
+ switch (op) {
+ case ND_REQUEST:
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: A neighbour request received: " + datagram.getAddress() + ", " + reqID + ".");
+ requests.put(datagram.getAddress(), new Long(reqID));
+ sendMessage(datagram.getAddress(), this.ND_RESPONSE, reqID);
+ break;
+ case ND_RESPONSE:
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: A neighbour response received: " + datagram.getAddress() + ", " + reqID + ".");
+ nodeDegreeInformation.addNeighbour(datagram.getAddress(), reqID);
+ sendMessage(datagram.getAddress(), this.ND_RESPONSE_ACK, reqID);
+ break;
+ case ND_RESPONSE_ACK:
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: A neighbour response ack received: " + datagram.getAddress() + ", " + reqID + ".");
+ Object aux = requests.get(datagram.getAddress());
+ if (aux != null) {
+ long valor = ((Long) aux).longValue();
+ if (valor == reqID) {
+ nodeDegreeInformation.addNeighbour(datagram.getAddress());
+ }
+ } else {
+ logger.log(Level.DEBUG, "NeighboursDiscoveryManager.run: A neighbour response ack received but there is no previous request.");
+ }
+ break;
+ }
+ } catch (IOException exception) {
+ logger.log(Level.WARNING, "NeighboursDiscoveryManager.run: Exception. Activate DEBUG Level for printing the stack trace.");
+ if (logger.getLevel().equals(Level.DEBUG)) {
+ exception.printStackTrace();
+ }
+ }
+ } while (!exit);
+ }
+ }
+
+ private class NDInformation {
+
+ private static final long EXPIRY_TIME = 10000;
+
+ private long requestID;
+ private final Hashtable neighborTable;
+ private final Object lock;
+
+ public NDInformation() {
+ requestID = -1;
+ neighborTable = new Hashtable();
+ lock = new Object();
+ logger.log(Level.DEBUG, "NDInformation: A new NDInformation object instantiated.");
+ }
+
+ public void addNeighbour(String who, long reqID) {
+ synchronized (lock) {
+ if (requestID == -1) {
+ logger.log(Level.DEBUG, "NDInformation.addNeighbour: Response from " + who + " rejected as no previous request was sent.");
+ return;
+ }
+
+ if (requestID != reqID) {
+ logger.log(Level.DEBUG, "NDInformation.addNeighbour: Response from " + who + " rejected reqIDs don't match.");
+ return;
+ }
+
+ this.addNeighbour(who);
+ }
+ }
+
+ public void addNeighbour(String who) {
+ synchronized (lock) {
+ long timestamp = System.currentTimeMillis();
+ if (neighborTable.containsKey(who)) {
+ logger.log(Level.DEBUG, "NDInformation.addNeighbour: Request from (" + who + ") accepted. There are " + neighborTable.size() + " neighbours.");
+ } else {
+ logger.log(Level.DEBUG, "NDInformation.addNeighbour: " + who + " has sent more than one response.");
+ }
+
+ neighborTable.put(who, Long.valueOf(timestamp));
+ displayInformation();
+ }
+ }
+
+ public void displayInformation() {
+ long nd = neighborTable.size();
+
+ StringBuffer neighborsCSV = new StringBuffer();
+ Enumeration neighbors = neighborTable.keys();
+
+ while (neighbors.hasMoreElements()) {
+ neighborsCSV.append(neighbors.nextElement());
+ if (neighbors.hasMoreElements()) {
+ neighborsCSV.append(",");
+ }
+ }
+ logger.setDestination(Logger.RECORD);
+ logger.debug(neighborsCSV.toString());
+ logger.setDestination(Logger.SYSTEM_OUTPUT);
+ }
+
+ public long getNodeDegree() {
+ synchronized (lock) {
+ long nodeDegree = (long) neighborTable.size();
+ logger.log(Level.DEBUG, "NDInforamtion.getNodeDegree: Number of neighbours: " + nodeDegree + ".");
+ return nodeDegree;
+ }
+ }
+
+ public Vector getNeighborList() {
+ synchronized (lock) {
+ Vector neighborList = new Vector();
+
+ Enumeration neighbors = neighborTable.keys();
+
+ while (neighbors.hasMoreElements()) {
+ neighborList.addElement(neighbors.nextElement());
+ }
+
+ return neighborList;
+ }
+ }
+
+ public void changeReqID(long reqID) {
+ synchronized (lock) {
+ if (reqID >= 0) {
+ requestID = reqID;
+ logger.log(Level.DEBUG, "NDInformation.changeReqID: New request with ID " + reqID + " registered.");
+ } else {
+ logger.log(Level.DEBUG, "NDInformation.changeReqID: New request with ID " + reqID + " rejected.");
+ }
+
+ // Update neighbor table
+ long timestamp = System.currentTimeMillis();
+ Enumeration neighbors = neighborTable.keys();
+
+ logger.debug("NDInformation.changeReqID: updating neighborTable");
+ while (neighbors.hasMoreElements()) {
+ Object key = neighbors.nextElement();
+ long lastTimestamp = ((Long) neighborTable.get(key)).longValue();
+ if ((timestamp - lastTimestamp) > EXPIRY_TIME) {
+ logger.debug("NDInformation.changeReqID: neighbor " + key + " has been in the table since " + lastTimestamp + " and is now EXPIRED (" + timestamp + ")");
+ neighborTable.remove(key);
+ } else {
+ logger.debug("NDInformation.changeReqID: neighbor " + key + " has been in the table since " + lastTimestamp + " and is now ALIVE (" + timestamp + ")");
+
+ }
+ }
+ }
+ }
+ }
+
+ private class NDTimer implements Runnable {
+
+ private final long REQUEST_PERIOD = 10000;
+
+ private final NeighborsDiscoveryMgr neighboursDiscoveryMgr;
+
+ public NDTimer(NeighborsDiscoveryMgr neighboursDiscoveryMgr) {
+ if (neighboursDiscoveryMgr == null) {
+ logger.log(Level.DEBUG, "NDTimer: no manager for discovering neighbours has been provided.");
+ throw new IllegalArgumentException("NDTimer: no manager for discovering neighbours has been provided.");
+ }
+ this.neighboursDiscoveryMgr = neighboursDiscoveryMgr;
+ logger.log(Level.DEBUG, "NDTimer: a new timer for updating the node degree has been started.");
+ }
+
+ public void run() {
+ boolean exit = false;
+ logger.log(Level.DEBUG, "NDTimer: Timer started.");
+ do {
+ this.neighboursDiscoveryMgr.requestForNeighbors();
+ logger.log(Level.DEBUG, "NDTimer: a new request for neighbours has been invoked.");
+ Utils.sleep(REQUEST_PERIOD);
+ } while (!exit);
+ logger.log(Level.DEBUG, "NDTimer: the timer for updating the node degree is stopped.");
+ }
+ }
+
+ private final Logger logger = new Logger();
+ private final NDInformation neighborsInfo;
+
+ public NodeDegreeManagerV2() {
+ neighborsInfo = new NDInformation();
+ NeighborsDiscoveryMgr discoveryMgr = new NeighborsDiscoveryMgr(neighborsInfo);
+ new Thread(new NDTimer(discoveryMgr)).start();
+
+ }
+
+ public long getNodeDegree() {
+ return this.neighborsInfo.getNodeDegree();
+ }
+
+ public Vector getNeighborList() {
+ return this.neighborsInfo.getNeighborList();
+ }
+
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery.java
new file mode 100644
index 0000000..0d31963
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscovery.java
@@ -0,0 +1,251 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.ondemand;
+
+import com.sun.spot.core.util.Queue;
+import com.sun.spot.core.util.Utils;
+import com.sun.spot.multihop.io.j2me.radiogram.Radiogram;
+import com.sun.spot.multihop.io.j2me.radiogram.RadiogramConnection;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.NeighborDiscoveryException;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.NeighborDiscoveryProtocol;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.pdu.NeighborDiscoveryPDU;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.pdu.NeighborDiscoveryPDUException;
+import java.io.IOException;
+import java.util.Vector;
+import javax.microedition.io.Connector;
+
+/**
+ * OnDemandNeighborDiscovery implements a basic three-tiered protocol for doing
+ * an on demand neighbor discovery.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class OnDemandNeighborDiscovery implements NeighborDiscoveryProtocol, OnDemandNeighborDiscoveryListener {
+
+ /**
+ * Default port for neighbor discovery communications.
+ */
+ public static final int DEFAULT_PORT = 200;
+ /**
+ * Default interval for the internal incoming message handler.
+ */
+ public static final long DEFAULT_HANDLER_INTERVAL = 100;
+
+ private OnDemandNeighborTableManager neighborTableManager;
+ private OnDemandNeighborDiscoveryRequester ndRequester;
+ private OnDemandNeighborDiscoveryCommunicationsListener ndCommunicationsListener;
+ private Thread ndCommunicationsListenerThread;
+ private Vector incomingDataQueue;
+ private boolean running;
+ private Logger logger;
+
+ private Queue NDRadiogramsQueue;
+ private NDEngine ndMessageProcessor;
+ private Thread ndMessageProcessorThread;
+ private SystemContext context;
+
+ /**
+ * The main constructor for this class provides the basic functionality of
+ * the three-tiered DEMANES/UPM Neighbor Discovery Protocol.
+ */
+ public OnDemandNeighborDiscovery() {
+ this.neighborTableManager = new OnDemandNeighborTableManager();
+ this.ndRequester = new OnDemandNeighborDiscoveryRequester(DEFAULT_PORT);
+
+ this.logger = SystemContext.getLogger();
+
+ this.NDRadiogramsQueue = new Queue();
+ }
+
+ /**
+ * Starts the neighbor discovery daemon.
+ */
+ public void start() {
+ this.running = true;
+
+ this.ndCommunicationsListener = new OnDemandNeighborDiscoveryCommunicationsListener(DEFAULT_PORT);
+ this.ndCommunicationsListener.addListener(this);
+ this.ndMessageProcessor = new NDEngine();
+
+ this.ndCommunicationsListenerThread = new Thread(this.ndCommunicationsListener);
+ this.ndMessageProcessorThread = new Thread(this.ndMessageProcessor);
+
+ this.ndCommunicationsListenerThread.start();
+ this.ndMessageProcessorThread.start();
+ }
+
+ /**
+ * Stops the neighbor discovery daemon.
+ */
+ public void stop() {
+ this.running = false;
+ this.ndCommunicationsListener.setActive(false);
+ try {
+ this.ndCommunicationsListenerThread.join();
+ this.ndMessageProcessorThread.join();
+ } catch (InterruptedException ex) {
+ if (SystemContext.isDebugActive() & SystemContext.isUSBConnected()) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Indicate whether the neighbor discovery is running or not.
+ *
+ * @return True if the neighbor discovery is active, false otherwise.
+ */
+ public boolean isRunning() {
+ return running;
+ }
+
+ /**
+ * Sets the neighbor discovery running state.
+ *
+ * @param handlerAlive True if active, false otherwise.
+ */
+ public void setRunning(boolean handlerAlive) {
+ this.running = handlerAlive;
+ }
+
+ /**
+ * Get the actual number of active neighbors (node degree).
+ *
+ * @return The number of current active neighbors.
+ */
+ public long getNodeDegree() {
+ return this.neighborTableManager.getNeighborCount();
+ }
+
+ /**
+ * Get the list if active neighbors.
+ *
+ * @return The list of current active neighbors.
+ */
+ public Vector getNeighborList() {
+ return this.neighborTableManager.getNeighborList();
+ }
+
+ /**
+ * Notifies the parsing method that a new neighbor discovery message has
+ * been received.
+ *
+ * @param incomingData The unprocessed neighbor discovery message.
+ */
+ public void notify(Radiogram incomingData) {
+ NDRadiogramsQueue.put(incomingData);
+ logger.debug("OnDemandNeighborDiscovery.notify: added incoming datagram from " + incomingData.getAddress() + " to the queue");
+ }
+
+ /**
+ * Performs a new neighbor discovery requests.
+ */
+ public void doNeighborDiscovery() {
+ neighborTableManager.clearTable();
+ ndRequester.doRequest();
+ }
+
+ /**
+ * Private class that implements the neighbor discovery protocol.
+ */
+ private class NDEngine implements Runnable {
+
+ public void run() {
+ Radiogram message;
+ while (running) {
+ try {
+ if (!NDRadiogramsQueue.isEmpty()) {
+ logger.debug("OnDemandNeighborDiscoveryIncomingMessages.run: Processing queue...");
+ Radiogram incomingRadiogram = (Radiogram) NDRadiogramsQueue.get();
+
+ String address = incomingRadiogram.getAddress();
+
+ logger.debug("OnDemandNeighborDiscoveryIncomingMessages.run: Queue datagram from " + address);
+
+ try {
+ NeighborDiscoveryPDU ndPDU = NeighborDiscoveryPDU.parsePDU(incomingRadiogram.getData());
+ logger.debug("OnDemandNeighborDiscoveryIncomingMessages.run: Processing PDU of type " + ndPDU.getTypeOfPDU() + " from " + address);
+
+ switch (ndPDU.getTypeOfPDU()) {
+ case NeighborDiscoveryPDU.NDPDU_REQUEST:
+ long incomingRequestID;
+ incomingRequestID = ndPDU.getRequestID();
+ logger.debug("OnDemandNeighborDiscoveryIncomingMessages.run: Recevied a REQUEST message from " + incomingRadiogram.getAddress() + " with requestID " + incomingRequestID);
+ sendMessage(address, NeighborDiscoveryPDU.toByteArray(NeighborDiscoveryPDU.NDPDU_RESPONSE, incomingRequestID));
+ break;
+ case NeighborDiscoveryPDU.NDPDU_RESPONSE:
+ if (ndRequester.checkRequestID(ndPDU.getRequestID())) {
+ logger.debug("OnDemandNeighborDiscoveryIncomingMessages.run: Received a RESPONSE message with VALID requestID " + ndPDU.getRequestID());
+ } else {
+ logger.debug("OnDemandNeighborDiscoveryIncomingMessages.run: Received a RESPONSE message with INVALID requestID " + ndPDU.getRequestID());
+ }
+ neighborTableManager.addNeighbor(address);
+ break;
+ case NeighborDiscoveryPDU.NDPDU_RESPONSE_ACK:
+ break;
+ default:
+ throw new NeighborDiscoveryException("OnDemandNeighborDiscoveryIncomingMessages.run: Unrecognized PDU type.");
+ }
+ } catch (NeighborDiscoveryPDUException ex) {
+ logger.debug("OnDemandNeighborDiscoveryIncomingMessages.run: Processing PDU exception...");
+ } catch (NeighborDiscoveryException ex) {
+ logger.debug("OnDemandNeighborDiscoveryIncomingMessages.run: Unexpected exception...");
+ }
+ }
+ Utils.sleep(DEFAULT_HANDLER_INTERVAL);
+ } catch (Exception ex) {
+ if (SystemContext.isDebugActive() & SystemContext.isUSBConnected()) {
+ ex.printStackTrace();
+ }
+ Utils.sleep(DEFAULT_HANDLER_INTERVAL);
+ }
+ }
+ }
+
+ private void sendMessage(String address, byte[] generatePDU) {
+ RadiogramConnection connection = null;
+
+ try {
+ connection = (RadiogramConnection) Connector.open("radiogram://" + address + ":" + DEFAULT_PORT);
+ Radiogram responseDatagram = (Radiogram) connection.newDatagram(connection.getMaximumLength());
+
+ responseDatagram.write(generatePDU);
+
+ connection.send(responseDatagram);
+ } catch (IOException ex) {
+ logger.debug("OnDemandNeighborDiscovery.sendMessage: Unexpected error trying to send datagram to " + address);
+ } finally {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (IOException ex) {
+ logger.debug("OnDemandNeighborDiscovery.sendMessage: Error closing connection after send.");
+ }
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryCommunicationsListener.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryCommunicationsListener.java
new file mode 100644
index 0000000..77055cf
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryCommunicationsListener.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.ondemand;
+
+import com.sun.spot.core.peripheral.TimeoutException;
+import com.sun.spot.core.util.PrettyPrint;
+import com.sun.spot.multihop.io.j2me.radiogram.Radiogram;
+import com.sun.spot.multihop.io.j2me.radiogram.RadiogramConnection;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+import javax.microedition.io.Connector;
+
+/**
+ * OnDemandNeighborDiscoveryCommunicationsListener executes a thread for
+ * listening neighbor discovery requests from other neighbors.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class OnDemandNeighborDiscoveryCommunicationsListener implements Runnable {
+
+ private Vector listeners;
+ private int port;
+
+ private boolean active;
+ private Logger logger;
+
+ /**
+ * Creates a new OnDemandNeighborDiscoveryCommunicationsListener on port
+ * port
+ *
+ * @param port Port used for listening neighbor discovery protocol messages.
+ */
+ public OnDemandNeighborDiscoveryCommunicationsListener(int port) {
+ this.listeners = new Vector();
+ this.port = port;
+ this.active = true;
+ this.logger = SystemContext.getLogger();
+ }
+
+ /**
+ * Gets the port used in this listener.
+ *
+ * @return The port used in this listener.
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Sets a new port for listening to neighbor requests.
+ *
+ * @param port The new port.
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ * Indicate whether this listener is active or not.
+ *
+ * @return True if the listener is active, false otherwise.
+ */
+ public boolean isActive() {
+ return active;
+ }
+
+ /**
+ * Set the active status for this listener.
+ *
+ * @param active Sets the status for this listener, true for active, false
+ * otherwise.
+ */
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+ /**
+ * Adds a listener for parsing new neigbor discovery messages.
+ *
+ * @param listener The listener for new messages.
+ */
+ public void addListener(OnDemandNeighborDiscoveryListener listener) {
+ listeners.addElement(listener);
+ }
+
+ /**
+ * Removes a listener
+ *
+ * @param listener The listener to be removed.
+ */
+ public void removeListener(OnDemandNeighborDiscoveryListener listener) {
+ listeners.removeElement(listener);
+ }
+
+ /**
+ * The run method is used to be executed as a separate thread, providing a
+ * loop for listening for new neighbor discovery messages and parsing them.
+ */
+ public void run() {
+ RadiogramConnection connection = null;
+ Radiogram incomingDatagram;
+
+ while (active) {
+ try {
+ if (connection == null) {
+ connection = (RadiogramConnection) Connector.open("radiogram://:" + this.port);
+ }
+ incomingDatagram = (Radiogram) connection.newDatagram(connection.getMaximumLength());
+
+ connection.receive(incomingDatagram);
+ Radiogram receivedDatagram = incomingDatagram;
+ logger.debug("NeighboursDiscoveryCommunicationsListener.run: Received incoming datagram from " + incomingDatagram.getAddress());
+ logger.debug(PrettyPrint.prettyPrint(receivedDatagram.getData()));
+
+ Enumeration listenerList = listeners.elements();
+ while (listenerList.hasMoreElements()) {
+ ((OnDemandNeighborDiscoveryListener) listenerList.nextElement()).notify(receivedDatagram);
+ }
+
+ } catch (TimeoutException exception) {
+ // Do nothing
+ } catch (IOException exception) {
+ logger.warning("NeighboursDiscoveryCommunicationsListener.run: Exception. Activate DEBUG Level for printing the stack trace.");
+ if (SystemContext.isDebugActive() & SystemContext.isUSBConnected()) {
+ exception.printStackTrace();
+ }
+ }
+ }
+
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (IOException ex) {
+ if (SystemContext.isDebugActive() & SystemContext.isUSBConnected()) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryListener.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryListener.java
new file mode 100644
index 0000000..dee620c
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryListener.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.ondemand;
+
+import com.sun.spot.multihop.io.j2me.radiogram.Radiogram;
+
+/**
+ * OnDemandNeighborDiscoveryListener defines the interface used by the
+ * listener of neighbor discovery requests issued by other motes.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public interface OnDemandNeighborDiscoveryListener {
+ public void notify(Radiogram incomingData);
+
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryRequester.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryRequester.java
new file mode 100644
index 0000000..2e8fa59
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborDiscoveryRequester.java
@@ -0,0 +1,169 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.ondemand;
+
+import com.sun.spot.core.util.Utils;
+import com.sun.spot.multihop.io.j2me.radiogram.Radiogram;
+import com.sun.spot.multihop.io.j2me.radiogram.RadiogramConnection;
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.pdu.NeighborDiscoveryPDU;
+import eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.pdu.NeighborDiscoveryPDUException;
+import java.io.IOException;
+import java.util.Random;
+import java.util.Vector;
+import javax.microedition.io.Connector;
+
+/**
+ * OnDemandNeighborDiscoveryRequester is used to manage the issue of a
+ * neighbor discovery request.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class OnDemandNeighborDiscoveryRequester implements Runnable {
+ private static final long DEFAULT_INTERVAL = 500;
+ private static final int MAXIMUM_VALID_REQUEST_ID = 10;
+
+ private long interval;
+ private long requestID;
+ private final int port;
+
+ private Vector validRequestIDs;
+
+ private Object lock;
+ private Logger logger;
+ private boolean active;
+
+ private Random randomGenerator;
+
+ /**
+ * Creates a new Neighbor Discovery Requester on port port.
+ *
+ * @param port Port for use in the Neighbor Discovery Protocol
+ */
+ public OnDemandNeighborDiscoveryRequester(int port) {
+ this.interval = DEFAULT_INTERVAL;
+ this.port = port;
+
+ this.validRequestIDs = new Vector();
+
+ this.lock = new Object();
+ this.logger = SystemContext.getLogger();
+ this.active = true;
+
+ this.randomGenerator = new Random();
+ }
+
+ /**
+ * Checks if the Neighbor Discovery Requester is alive.
+ *
+ * @return true if the Requester is alive. false otherwise.
+ */
+ public boolean isActive() {
+ return active;
+ }
+
+ /**
+ * Sets the active status of the Neighbor Discovery Requester.
+ *
+ * @param active
+ */
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+ /**
+ * Run method for being run as a thread.
+ */
+ public void run() {
+ while (active) {
+ doRequest();
+ Utils.sleep(interval);
+ }
+ }
+
+ /**
+ * Generates a new request identifier on demand. The request identifier is
+ * always a positive long number.
+ *
+ * @return a new request identifier
+ */
+ private long generateRequestID() {
+ long generatedRequestID;
+
+ generatedRequestID = this.randomGenerator.nextLong();
+ generatedRequestID = generatedRequestID >= 0 ? generatedRequestID : (-1 * generatedRequestID);
+
+ synchronized (lock) {
+ if (this.validRequestIDs.size() >= MAXIMUM_VALID_REQUEST_ID) {
+ this.validRequestIDs.removeElement(this.validRequestIDs.firstElement());
+ this.validRequestIDs.trimToSize();
+ }
+ }
+
+ this.validRequestIDs.addElement(Long.valueOf(generatedRequestID));
+
+ return generatedRequestID;
+ }
+
+ /**
+ * Checks the validity of a passed by request ID.
+ *
+ * @param requestID The request ID to be checked up.
+ * @return True if the request ID is valid. False otherwise.
+ */
+ public boolean checkRequestID(long requestID) {
+ synchronized (lock) {
+ return this.validRequestIDs.contains(Long.valueOf(requestID));
+ }
+ }
+
+ /**
+ * Performs a neighbor request.
+ */
+ public void doRequest() {
+ RadiogramConnection connection = null;
+ Radiogram requestDatagram;
+ byte[] pduRequest;
+
+ requestID = generateRequestID();
+ try {
+ pduRequest = NeighborDiscoveryPDU.toByteArray(NeighborDiscoveryPDU.NDPDU_REQUEST, requestID);
+
+ if (connection == null) {
+ connection = (RadiogramConnection) Connector.open("radiogram://broadcast:" + this.port);
+ }
+
+ requestDatagram = (Radiogram) connection.newDatagram(connection.getMaximumLength());
+ requestDatagram.reset();
+ requestDatagram.write(pduRequest);
+
+ connection.send(requestDatagram);
+ logger.debug("NeighborDiscoveryRequester.doRequest: Sent datagram of type REQUEST and requestID " + requestID);
+ } catch (NeighborDiscoveryPDUException ex) {
+ logger.warning("NeighborDiscoveryRequester.doRequest: A problem occurred while trying to parse a NDP PDU.");
+ } catch (IOException ex) {
+ logger.warning("NeighborDiscoveryRequester.doRequest: A problem occurred while trying to send a REQUEST.");
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborTableManager.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborTableManager.java
new file mode 100644
index 0000000..265da16
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/ondemand/OnDemandNeighborTableManager.java
@@ -0,0 +1,197 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.ondemand;
+
+import eu.artemis.demanes.impl.SunSPOT.common.SystemContext;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Level;
+import eu.artemis.demanes.impl.SunSPOT.utils.logging.Logger;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * OnDemandNeighborTableMAnager implements the table used to store the active
+ * neighbors detected by the Neighbor Discovery Protocol.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class OnDemandNeighborTableManager {
+
+ private static final long DEFAULT_EXPIRY_TIME = 5000;
+
+ private Hashtable neighborTable;
+ private Vector neighborList;
+ private long expiryTime;
+ private StringBuffer neighborsCSV;
+
+ private final Logger logger;
+ private final Object lock;
+
+ /**
+ * Creates a new instance of the neighbor table manager using the default
+ * expiry time for new entries.
+ */
+ public OnDemandNeighborTableManager() {
+ this.neighborTable = new Hashtable();
+ this.neighborList = new Vector();
+ this.expiryTime = DEFAULT_EXPIRY_TIME;
+ this.neighborsCSV = new StringBuffer();
+ this.lock = new Object();
+ this.logger = SystemContext.getLogger();
+ }
+
+ /**
+ * Creates a new instance of the neighbor table manager using the expiry
+ * time especified by expiryTime.
+ *
+ * @param expiryTime The expiry time for new entries in the table.
+ */
+ public OnDemandNeighborTableManager(long expiryTime) {
+ this();
+ this.expiryTime = expiryTime;
+ }
+
+ /**
+ * Sets a new expiry time.
+ *
+ * @param expiryTime The new expiry time.
+ */
+ public void setExpiryTime(long expiryTime) {
+ this.expiryTime = expiryTime;
+ }
+
+ /**
+ * Gets the current expiry time.
+ *
+ * @return The current expiry time.
+ */
+ public long getExpiryTime() {
+ return this.expiryTime;
+ }
+
+ /**
+ * Gets the number of acive neighbors registered in the table.
+ *
+ * @return The number of active neighbors.
+ */
+ public int getNeighborCount() {
+ synchronized (lock) {
+ logNeighborInformation();
+
+ return this.neighborTable.size();
+ }
+ }
+
+ /**
+ * Retrives the list of active neighbors.
+ *
+ * @return The list of active neighbors.
+ */
+ public Vector getNeighborList() {
+ synchronized (lock) {
+ this.neighborList.removeAllElements();
+ Enumeration neighbors = this.neighborTable.keys();
+
+ while (neighbors.hasMoreElements()) {
+ neighborList.addElement(neighbors.nextElement());
+ }
+
+ return neighborList;
+ }
+ }
+
+ /**
+ * Adds a neighbor to the table.
+ *
+ * @param neighborAddress The address of the neighbor
+ */
+ public void addNeighbor(String neighborAddress) {
+ synchronized (lock) {
+ long timestamp = System.currentTimeMillis();
+ if (neighborTable.containsKey(neighborAddress)) {
+ logger.log(Level.DEBUG, "OnDemandNeighborTableManager.addNeighbour: Request from (" + neighborAddress + ") accepted. There are " + neighborTable.size() + " neighbours.");
+ } else {
+ logger.log(Level.DEBUG, "OnDemandNeighborTableManager.addNeighbour: " + neighborAddress + " has sent more than one response.");
+ }
+
+ neighborTable.put(neighborAddress, Long.valueOf(timestamp));
+ }
+ }
+
+ /**
+ * Performs a maintenance check of the neighbor table, removing those
+ * neighbors which their last alive update is greater than the expiry time.
+ */
+ public void maintainNeighborTable() {
+ synchronized (lock) {
+ long actualTimestamp = System.currentTimeMillis();
+ Enumeration neighbors = neighborTable.keys();
+
+ while (neighbors.hasMoreElements()) {
+ Object key = neighbors.nextElement();
+ long recordedTimestamp = ((Long) neighborTable.get(key)).longValue();
+ long timeAlive = actualTimestamp - recordedTimestamp;
+
+ if (timeAlive > this.expiryTime) {
+ logger.debug("OnDemandNeighborTableManager.maintainNeighborTable: Time for neighbor " + key + " has expired (" + timeAlive + "). REMOVING");
+ neighborTable.remove(key);
+ }
+ }
+ }
+ }
+
+ /**
+ * Logs neighbor information. For debug purposes only.
+ */
+ public void logNeighborInformation() {
+ long nd = neighborTable.size();
+
+ neighborsCSV.setLength(0);
+ Enumeration neighbors = neighborTable.keys();
+
+ while (neighbors.hasMoreElements()) {
+ neighborsCSV.append((String) neighbors.nextElement());
+ if (neighbors.hasMoreElements()) {
+ neighborsCSV.append(",");
+ }
+ }
+
+ if (nd > 0) {
+ if (SystemContext.isDebugActive()) {
+ byte originalDestination = logger.getDestination();
+ logger.setDestination(Logger.RECORD);
+ logger.debug(neighborsCSV.toString());
+ logger.setDestination(originalDestination);
+ }
+ }
+ }
+
+ /**
+ * Clears the neighbor table.
+ */
+ public void clearTable() {
+ synchronized (lock) {
+ this.neighborTable.clear();
+ }
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDU.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDU.java
new file mode 100644
index 0000000..2dd10ac
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDU.java
@@ -0,0 +1,191 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.pdu;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * Neighbor Discovery PDU is a representation of a PDU for the Neighbor Discovery
+ * Protocol.
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class NeighborDiscoveryPDU {
+
+ private static final String PROTOCOL_ID = "NDP";
+
+ private static final byte VERSION = 0x02;
+
+ public static final byte NDPDU_REQUEST = 0x01;
+ public static final byte NDPDU_RESPONSE = 0x02;
+ public static final byte NDPDU_RESPONSE_ACK = 0x03;
+
+ private byte typeOfPDU;
+ private long requestID;
+
+ /**
+ * Public constructor. Creates a new PDU of type typeOfPDU with a
+ * request ID requestID.
+ *
+ * @param typeOfPDU Type of the Neighbor Discovery PDU
+ * @param requestID Request ID
+ */
+ public NeighborDiscoveryPDU(byte typeOfPDU, long requestID) {
+ this.typeOfPDU = typeOfPDU;
+ this.requestID = requestID;
+ }
+
+ /**
+ * Creates a newly allocated byte array for a Neighbor Discovery PDU of type
+ * typeOfPDU and request ID requestID.
+ *
+ * @param typeOfPDU Type of PDU
+ * @param requestID Request ID
+ * @return The newly allocated byte array representing the PDU
+ * @throws NeighborDiscoveryPDUException
+ */
+ public static byte[] toByteArray(byte typeOfPDU, long requestID) throws NeighborDiscoveryPDUException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(baos);
+
+ try {
+ dos.write(PROTOCOL_ID.getBytes());
+ dos.writeByte(VERSION);
+ dos.writeByte(typeOfPDU);
+ dos.writeLong(requestID);
+ } catch (IOException exception) {
+ throw new NeighborDiscoveryPDUException("generatePDU", "Error trying to write the PDU to a byte array");
+ }
+
+ return baos.toByteArray();
+ }
+
+ /**
+ * Get the type of instanced PDU
+ *
+ * @return The type of PDU
+ */
+ public byte getTypeOfPDU() {
+ return typeOfPDU;
+ }
+
+ /**
+ * Set the type of the instanced PDU
+ *
+ * @param typeOfPDU the type of PDU
+ */
+ public void setTypeOfPDU(byte typeOfPDU) {
+ this.typeOfPDU = typeOfPDU;
+ }
+
+ /**
+ * Get the request ID of the instanced PDU
+ *
+ * @return the request ID
+ */
+ public long getRequestID() {
+ return requestID;
+ }
+
+ /**
+ * Set the request ID of the instanced PDU
+ *
+ * @param requestID the request ID
+ */
+ public void setRequestID(long requestID) {
+ this.requestID = requestID;
+ }
+
+ /**
+ * Parse a byte array containing a Neighbor Discovery PDU.
+ *
+ * @param pdu the byte array containing the Neighbor Discovery PDU
+ * @return the instanced NeighborDiscoveryPDU
+ * @throws NeighborDiscoveryPDUException if the byte array does not comply with the Neighbor Discovery PDU
+ */
+ public static NeighborDiscoveryPDU parsePDU(byte[] pdu) throws NeighborDiscoveryPDUException {
+ final String methodName = "parsePDU";
+
+ String protocolID;
+ byte version;
+ byte typeOfPDU;
+ long requestID;
+
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(pdu));
+
+ byte[] pidArray = new byte[NeighborDiscoveryPDU.PROTOCOL_ID.length()];
+
+ try {
+ dis.read(pidArray, 0, NeighborDiscoveryPDU.PROTOCOL_ID.length());
+ } catch (IOException ex) {
+ throw new NeighborDiscoveryPDUException(methodName, "Unable to read the protocol ID.");
+ }
+
+ protocolID = new String(pidArray);
+
+ if (!protocolID.equalsIgnoreCase(NeighborDiscoveryPDU.PROTOCOL_ID)) {
+ throw new NeighborDiscoveryPDUException(methodName, "Protocol ID mismatch. Expected \"" + NeighborDiscoveryPDU.PROTOCOL_ID + "\" and found " + protocolID);
+ }
+
+ try {
+ version = dis.readByte();
+ } catch (IOException ex) {
+ throw new NeighborDiscoveryPDUException(methodName, "Unable to read the protocol version.");
+ }
+
+ if (version != NeighborDiscoveryPDU.VERSION) {
+ throw new NeighborDiscoveryPDUException(methodName, "Protocol version mismatch.");
+ }
+
+ try {
+ typeOfPDU = dis.readByte();
+ } catch (IOException ex) {
+ throw new NeighborDiscoveryPDUException(methodName, "Unable to read the type of PDU.");
+ }
+
+ if (typeOfPDU != NeighborDiscoveryPDU.NDPDU_REQUEST) {
+ if (typeOfPDU != NeighborDiscoveryPDU.NDPDU_RESPONSE) {
+ if (typeOfPDU != NeighborDiscoveryPDU.NDPDU_RESPONSE_ACK) {
+ throw new NeighborDiscoveryPDUException(methodName, "Unrecognized PDU type.");
+ }
+ }
+ }
+
+ try {
+ requestID = dis.readLong();
+ } catch (IOException ex) {
+ throw new NeighborDiscoveryPDUException(methodName, "Unable to read the request ID.");
+ }
+
+ if (requestID < 0) {
+ throw new NeighborDiscoveryPDUException(methodName, "Invalid request ID.");
+ }
+
+ return new NeighborDiscoveryPDU(typeOfPDU, requestID);
+ }
+}
diff --git a/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDUException.java b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDUException.java
new file mode 100644
index 0000000..a7cbb8a
--- /dev/null
+++ b/src/eu/artemis/demanes/impl/SunSPOT/utils/neighbordiscovery/pdu/NeighborDiscoveryPDUException.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright 2014-2015 Universidad Politécnica de Madrid (UPM).
+ *
+ * Authors:
+ * José-Fernan Martínez Ortega
+ * Vicente Hernández Díaz
+ * Néstor Lucas Martínez
+ * Yuanjiang Huang
+ * Raúl del Toro Matamoros
+ *
+ * This software is distributed under a dual-license scheme:
+ *
+ * - For academic uses: Licensed under GNU Affero General Public License as
+ * published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * - For any other use: Licensed under the Apache License, Version 2.0.
+ *
+ * You can get a copy of the license terms in licences/LICENSE.
+ */
+package eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.pdu;
+
+/**
+ * An NeighborDiscoveryPDUException is thrown to indicate that an error occurred
+ * during the generation or parsing of a {@linkplain NeighborDiscoveryPDU}. The
+ * original exception is added as a cause.
+ *
+ * @see eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.pdu.NeighborDiscoveryPDU#toByteArray
+ * @see eu.artemis.demanes.impl.SunSPOT.utils.neighbordiscovery.pdu.NeighborDiscoveryPDU#parsePDU
+ *
+ * @author Néstor Lucas Martínez
+ * @version 1.0.0
+ */
+public class NeighborDiscoveryPDUException extends Exception {
+
+ public NeighborDiscoveryPDUException(String method, String reason) {
+ super("NeighborDiscoveryPDU." + method + ": " + reason);
+ }
+
+}
diff --git a/src/eu/artemis/demanes/reconfiguration/Action.java b/src/eu/artemis/demanes/reconfiguration/Action.java
new file mode 100644
index 0000000..a7ff466
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/Action.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+import eu.artemis.demanes.datatypes.ANES_BUNDLE;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.exceptions.ActionInvocationException;
+
+/**
+ *
+ * An action is the unit of reconfiguration actuation. The user must use Actions
+ * to modify the system in any way the Actions allow it to. If there is no
+ * Action object that enables the modification of the system, then it cannot be
+ * modified.
+ *
+ *
+ *
+ * Every Action has a unique identifier that denotes the type of action that it
+ * performs. This identifier must be specific not only for the type of Action
+ * that it performs, but also on what specific part of the system it will
+ * perform this Action.
+ *
+ *
+ *
+ * Once an Action exists, and has been made available to modify the system, the
+ * user may call the {@link #invoke(ANES_BUNDLE)} method. This will do the
+ * actual modification, possibly influenced by a set of arguments.
+ *
+ * Returns the unique identifier of this Action.
+ *
+ *
+ *
+ * Every Action is uniquely identifiable via a ANES_URN identifier. By
+ * obtaining this identifier, the user should be able to know what the
+ * Action will do if invoked, an what (sub)component of the system is
+ * influenced by it.
+ *
+ *
+ * @return An ANES_URN uniquely identifying the action
+ */
+ public ANES_URN getActionID();
+
+ /**
+ *
+ * Invokes the action
+ *
+ *
+ *
+ * As a generic way to have Actions modify the system, this method must
+ * always be called in order to have the Action perform it's modification on
+ * the system as it is intended to do. Any other functions of the Action may
+ * exist but will not modify the rest of the system.
+ *
+ *
+ * @param arguments
+ * The arguments may indicate a specification of how the action
+ * should be invoked. For instance in order to modify a parameter
+ * of a component, the new parameter value can be one of the
+ * elements in the argument list.
+ * @throws ActionInvocationException
+ * If at some point in the invocation of the Action an error
+ * occurs which disallows the proper modification of the system,
+ * an ActionInvocationException is thrown indicating that the
+ * invocation failed.
+ */
+ public void invoke(ANES_BUNDLE arguments) throws ActionInvocationException;
+
+}
+
+/**
+ *
Assumptions:
+ *
+ *
+ * Because the Reasoner will never get the actual Action, but will only invoke
+ * actions via the ActionProvider interface, there is no use implementing other
+ * functions that would provide information to the Reasoner.
+ *
+ */
diff --git a/src/eu/artemis/demanes/reconfiguration/ActionProvider.java b/src/eu/artemis/demanes/reconfiguration/ActionProvider.java
new file mode 100644
index 0000000..e3e7464
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/ActionProvider.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+import eu.artemis.demanes.datatypes.ANES_BUNDLE;
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.exceptions.ActionInvocationException;
+import eu.artemis.demanes.exceptions.InexistentActionID;
+import java.util.Vector;
+
+/**
+ *
+ * The ActionProvider is the interface through which an object can obtain the
+ * available actions to reconfigure the system. The purpose of it is to provide
+ * a generic interface from which the reconfiguration process can be controlled.
+ *
+ *
+ *
+ * If an object is an ActionProvider, this means that it is responsible for
+ * invoking the correct {@linkplain Action} object, identified by it's
+ * {@linkplain ANES_URN}.
+ *
+ * Query the Actions that can be invoked using this ActionProvider
+ *
+ *
+ *
+ * The {@linkplain #invoke(ANES_URN, ANES_BUNDLE)} function requires a
+ * ANES_URN argument which identifies which action to invoke. By using this
+ * function the user gets an array which indicate what the relevant
+ * ANES_URNs can be used as a valid argument.
+ *
+ *
+ *
+ * If there are no possible actions that can be invokes, this function will
+ * return null.
+ *
+ *
+ * @return an Array of ANES_URNs that can be invoked using this
+ * ActionProvider.
+ */
+ Vector getActions();
+
+ /**
+ *
+ * Invokes a specific {@linkplain Action} in order to modify the system
+ *
+ *
+ *
+ * By calling this function, the user can specify that an Action with a
+ * specific identifier should be invoked. This results internally in
+ * invoking the corresponding Action.
+ *
+ *
+ * @param id
+ * In order to resolve which Action to invoke, the identity of
+ * the corresponding Action should be provided. To obtain a list
+ * of available actions from this ActionProvider, use the
+ * {@linkplain #getActions()} function.
+ * @param arguments
+ * The arguments may indicate a specification of how the action
+ * should be invoked. For instance in order to modify a parameter
+ * of a component, the new parameter value can be one of the
+ * elements in the argument list.
+ * @throws InexistentActionID
+ * If the provided id can not be resolved by the ActionProvider,
+ * an exception is thrown, indicating that the this identifier
+ * does not exist. (As far as this ActionProvider concerns)
+ * @throws ActionInvocationException
+ * Is thrown if the invoked action cannot successfully complete.
+ *
+ * @see Action#invoke(ANES_BUNDLE)
+ */
+ void invoke(ANES_URN id, ANES_BUNDLE arguments) throws InexistentActionID,
+ ActionInvocationException;
+
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/reconfiguration/Actuator.java b/src/eu/artemis/demanes/reconfiguration/Actuator.java
new file mode 100644
index 0000000..68f45e3
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/Actuator.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+import java.util.Vector;
+
+/**
+ *
+ * An object implementing the Actuator interface (so it is an actuator) is the
+ * interface to obtain {@linkplain Action}s. Every system component which is
+ * reconfigurable should come with at least one actuator.
+ *
+ *
+ *
+ * Actuators are made by the designers of system component, and can provide one
+ * or more {@linkplain Action}s by which the components can be changed. The
+ * actuator is merely the interface to actions that correspond to a component,
+ * and should not contain the functionality to change the component itself.
+ *
+ * In order for the user to obtain all {@linkplain Action}s by which a
+ * system component may be changed, this function returns an array of
+ * actions which are available.
+ *
+ *
+ *
+ * If there are no actions available this function returns null
+ *
+ *
+ * @return an Array or Actions that may be invoked to reconfigure the system
+ */
+ public Vector getActions();
+
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/reconfiguration/ActuatorRegistry.java b/src/eu/artemis/demanes/reconfiguration/ActuatorRegistry.java
new file mode 100644
index 0000000..06e912e
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/ActuatorRegistry.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+/**
+ *
+ * An ActuatorRegistry is used to combine all actuators that control the
+ * behavior of the reconfiguration. By adding {@linkplain Actuators} the user
+ * can provide the means by which the system can be modified.
+ *
+ * Add a {@linkplain Actuator} object to the collection of actuators by
+ * which the ReasoningEngine can modify the system. If the actuator has
+ * already been registered before, nothing changes.
+ *
+ *
+ * @param a
+ * the Actuator to register.
+ */
+ public void registerActuator(Actuator a);
+
+ /**
+ *
+ * Remove a {@linkplain Actuator} object from the collection of actuators.
+ * This function should be called before the actuator is destroyed. If the
+ * object was not registered before, nothing happens.
+ *
+ *
+ * @param a
+ * the object that no longer can be used.
+ */
+ public void unregisterActuator(Actuator a);
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/reconfiguration/ORAMediator.java b/src/eu/artemis/demanes/reconfiguration/ORAMediator.java
new file mode 100644
index 0000000..6a67cca
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/ORAMediator.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+/**
+ *
+ * The ORAMediator defines the interface trough which Observers, Reasoners,
+ * Actuators and TriggerPolicies come together. This is the main component in
+ * which the mediates these different reconfiguration modules.
+ *
+ *
+ *
+ * ORAMediator stands for Observe - Reason - Act Mediator. It is the object in
+ * which the cycle (similar to the MAPE cycle) is bound together. Hence it uses
+ * the Mediator design pattern to combine the three modules. The TriggerPolicy
+ * is not part of the acronym as it is not considered as a primary function of
+ * the of the mediator, instead it is just a utility.
+ *
+ *
+ *
+ * A ORAMediator is used to combine all interfaces that define the behavior of
+ * the reconfiguration. By adding {@linkplain Observers} and
+ * {@linkplain Actuators} the user can provide the means by which the system can
+ * be observed and modified. The {@linkplain Reasoner} can be set to define how
+ * the system can make a decision to take an action. And finally the
+ * {@linkplain TriggeringPolicy} can be set to determine when the Reasoner
+ * should make these decisions.
+ *
+ * Set an object with the {@linkplain Reasoner} as the current reasoner.
+ * This reasoner object defines the behavior of the reconfiguration.
+ *
+ *
+ *
+ * There can only be one reasoner at a time, so if this function is called
+ * when another reasoner is set, this function overwrites it.
+ *
+ *
+ * @param r
+ * an Object with the Reasoner specifying how the decisions
+ * should be made to reconfigure the system.
+ */
+ public void setReasoner(Reasoner r);
+
+ /**
+ *
+ * Set an object with the {@linkplain TriggerPolicy} as the current
+ * triggering policy. This policy object defines the when the
+ * reconfiguration reasoner should be triggered. For example if the reasoner
+ * should be triggered periodically or if a threshold is reached.
+ *
+ *
+ *
+ * There can only be one triggering policy at a time, so if this function is
+ * called when another triggering policy is set, this function overwrites
+ * it.
+ *
+ *
+ * @param r
+ * an Object with the TriggerPolicy specifying when the reasoner
+ * should be activated to reconfigure the system.
+ */
+ public void setTriggeringPolicy(TriggerPolicy t);
+
+}
+
+/**
+ *
Assumptions
+ *
+ *
+ * AFTER the setReasoner function is called or AFTER the setTriggeringPolicy is
+ * called, the registerTriggerable() function is called on the TriggeringPolicy
+ * with the Reasoner.
+ *
+ *
+ *
+ * This makes sure that at all times, the Reasoner is registered as Triggerable
+ * in the TriggeringPolicy.
+ *
+ */
diff --git a/src/eu/artemis/demanes/reconfiguration/Observation.java b/src/eu/artemis/demanes/reconfiguration/Observation.java
new file mode 100644
index 0000000..4cb7455
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/Observation.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.exceptions.ObservationInvocationException;
+
+/**
+ *
+ * An Observation is the unit of monitoring the system for reconfiguration. The
+ * user must use Observations to monitor the system in any way the Observation
+ * allow it to. If there is no Observation object that enables the monitoring of
+ * the system, then it cannot be monitored.
+ *
+ *
+ *
+ * Every Observation has a unique identifier that denotes the type of
+ * observation that it provides. This identifier must be specific not only for
+ * the type of observation, but also what specific component of the system it
+ * will observe.
+ *
+ *
+ *
+ * Once an Observation exists, and has been made available to the system, the
+ * user may call the {@link #getValue()} method. This will do the actual
+ * observation and provide the value that represents the status.
+ *
+ * Returns the unique identifier of this Observation.
+ *
+ *
+ *
+ * Every Observation is uniquely identifiable via a {@linkplain ANES_URN}
+ * identifier. By obtaining this identifier, the user should be able to know
+ * what property the Observation will observe, an what (sub)component of the
+ * system it is observing.
+ *
+ *
+ * @return An ANES_URN uniquely identifying the observation
+ */
+ public ANES_URN getObservationID();
+
+ /**
+ *
+ * Get the value of the observation
+ *
+ *
+ *
+ * As a generic way to have Observations monitor the system, this method
+ * must always be called in order to have the Observation get the
+ * information from the system as it is intended to do. Any other functions
+ * of the Action may exist but will get information from the system
+ * component.
+ *
+ *
+ * @return an Object which represents the value of the observation. An
+ * Observation may specify what type of Object is returned, but any
+ * type of return value is possible.
+ * @throws ObservationInvocationException
+ * If at some point in obtaining the information from the system
+ * an error occurs, an ObservationInvocationException is thrown
+ * indicating that the observation failed.
+ */
+ public Object getValue() throws ObservationInvocationException;
+
+}
+
+/**
+ *
Assumptions
+ *
+ *
+ * It is possible that the results of the observation are a buffered version of
+ * the information. This means that calling {@link #getValue()} will not do the
+ * observation itself, but the information is gathered at some intermediate
+ * moment. This is a choice of the designer of the Observation, but will have to
+ * be stated explicitly to the user.
+ *
+ */
diff --git a/src/eu/artemis/demanes/reconfiguration/ObservationProvider.java b/src/eu/artemis/demanes/reconfiguration/ObservationProvider.java
new file mode 100644
index 0000000..cf23115
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/ObservationProvider.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+import eu.artemis.demanes.datatypes.ANES_URN;
+import eu.artemis.demanes.exceptions.InexistentObservationID;
+import eu.artemis.demanes.exceptions.ObservationInvocationException;
+import java.util.Vector;
+
+/**
+ *
+ * The ObservationProvider is the interface through which an object can obtain
+ * the available observations to monitor the system. The purpose of it is to
+ * provide a generic interface from which the reconfiguration process can obtain
+ * information from the system.
+ *
+ *
+ *
+ * If an object is an ObservationProvider, this means that it is responsible for
+ * providing the correct {@linkplain Observation} value, identified by it's
+ * {@linkplain ANES_URN}.
+ *
+ * Query the Observations that can be obtained from this ObservationProvider
+ *
+ *
+ *
+ * The {@linkplain #getValue(ANES_URN)} function requires a ANES_URN
+ * argument which identifies which observation to obtain. By using this
+ * function the user gets an array which indicate what the relevant
+ * ANES_URNs can be used as a valid argument.
+ *
+ *
+ *
+ * If there are no possible observations that can be obtained, this function
+ * will return null.
+ *
+ *
+ * @return an Array of ANES_URNs that can be observed using this
+ * ActionProvider.
+ */
+ Vector getObservations();
+
+ /**
+ *
+ * Get the value of a specific {@linkplain Observation} in order to monitor
+ * the system
+ *
+ *
+ *
+ * By calling this function, the user can specify that an Observation with a
+ * specific identifier should be invoked. This results internally in
+ * invoking the corresponding Observation.
+ *
+ *
+ * @param id In order to resolve which Observation to invoke, the identity
+ * of the corresponding Observation should be provided. To obtain a list of
+ * available observations from this ObservationProvider, use the
+ * {@linkplain #getObservations()} function.
+ * @throws InexistentObservationID If the provided id can not be resolved by
+ * the ObservationProvider, an exception is thrown, indicating that the this
+ * identifier does not exist. (As far as this ObservationProvider concerns)
+ * @throws ObservationInvocationException Is thrown if the observation
+ * cannot successfully obtain it's information.
+ *
+ * @see Observation#getValue()
+ */
+ public Object getValue(ANES_URN id) throws InexistentObservationID,
+ ObservationInvocationException;
+
+}
diff --git a/src/eu/artemis/demanes/reconfiguration/Observer.java b/src/eu/artemis/demanes/reconfiguration/Observer.java
new file mode 100644
index 0000000..4020140
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/Observer.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+import java.util.Vector;
+
+
+/**
+ *
+ * An object having the the Observer interface (so it is an observer) is the
+ * interface to obtain {@linkplain Observations}s. Every system component which
+ * provides information as input for reconfiguration should come with at least
+ * one observer.
+ *
+ *
+ *
+ * Observers are made by the designers of the corresponding system component,
+ * and can provide one or more {@linkplain Observations}s which indicate what
+ * the status is of the component. The observer is merely the interface to
+ * observations that correspond to a component, and should not contain the
+ * functionality to monitor the component itself.
+ *
+ * In order for the user to obtain all {@linkplain Observations}s which
+ * provide information about the system component, this function returns an
+ * array of observations which are available.
+ *
+ *
+ *
+ * If there are no observations available this function returns null
+ *
+ *
+ * @return an Array or Observations that may be used to obtain information
+ * about the system
+ */
+ public Vector getObservations();
+
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/reconfiguration/ObserverRegistry.java b/src/eu/artemis/demanes/reconfiguration/ObserverRegistry.java
new file mode 100644
index 0000000..4c267a1
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/ObserverRegistry.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+/**
+ *
+ * A ObserverRegistry is used on the side of the ORAMediator to combine all
+ * Observers that provide input for the reconfiguration. By adding
+ * {@linkplain Observers} the user can provide the means by which the system can
+ * be observed.
+ *
+ * Add a {@linkplain Observer} object to the collection of observers by
+ * which the ReasoningEngine can monitor the system. If the observer has
+ * already been registered before, nothing changes.
+ *
+ *
+ * @param a
+ * the Observer to register.
+ */
+ public void registerObserver(Observer o);
+
+ /**
+ *
+ * Remove a {@linkplain Observer} object from the collection of observers.
+ * This function should be called before the observer is destroyed. If the
+ * object was not registered before, nothing happens.
+ *
+ *
+ * @param a
+ * the observer that should be unregistered.
+ */
+ public void unregisterObserver(Observer o);
+
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/reconfiguration/Reasoner.java b/src/eu/artemis/demanes/reconfiguration/Reasoner.java
new file mode 100644
index 0000000..2b55051
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/Reasoner.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+/**
+ *
+ * The Reasoner specifies the input and the output of the reasoner. It allows
+ * for generalized methods for providing the information needed for the reasoner
+ * (e.g. KPIs) and methods for providing it's output possibilities.
+ *
+ *
+ *
+ * The input of the reasoner is via an object that provides the reasoner with
+ * {@linkplain Observation}s. The output of a reasoner is via an object that
+ * provides it with a set of {@linkplain Action}s.
+ *
+ * Sets the object that will provide this Reasoner with it's actuators.
+ *
+ *
+ *
+ * This function specifies that an {@linkplain ActionProvider} should be
+ * used as the object to get it's {@linkplain Action}s from. The actions can
+ * be obtained by the Reasoner using the ActionProvider's interface, and the
+ * obtained actions can be subsequently used to change anything in the
+ * system.
+ *
+ *
+ *
+ * If there was previously another object set as it's action provider, this
+ * new object will overwrite it. There can only be one at a time.
+ *
+ *
+ * @param ap
+ * The object to be used from now on in order to get actions from
+ *
+ */
+ public void setActuationProvider(ActionProvider ap);
+
+ /**
+ *
+ * Sets the object that will provide this Reasoner with it's observations.
+ *
+ *
+ *
+ * By specifying that an {@linkplain ObservationProvider} should be used as
+ * the object to get it's {@linkplain Observation}s from, means that all the
+ * input of the Reasoner will have to come from this object. These
+ * observations can then be obtained by the Reasoner via the appropriate
+ * functions from the ObservationProvider interface.
+ *
+ *
+ *
+ * If there was already another observation provider set, this new object
+ * will overwrite it. There can always only be one at a time.
+ *
+ *
+ * @param op
+ * The object to be used from now on in order to get input from
+ *
+ */
+ public void setObservationProvider(ObservationProvider op);
+
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/reconfiguration/TriggerPolicy.java b/src/eu/artemis/demanes/reconfiguration/TriggerPolicy.java
new file mode 100644
index 0000000..afd5b1a
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/TriggerPolicy.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+/**
+ *
+ * A TriggerPolicy defines the temporal behavior of any {@linkplain Triggerable}
+ * object. When the policy is started it will trigger it's registerd objects at
+ * a specific time, defined by the implementation.
+ *
+ *
+ *
+ * A TriggerPolicy can be started and stopped, and it can be suspended and
+ * resumed. The specific behavior of these actions may be implementation
+ * specific, but should adhere to the interface's definitions.
+ *
+ * Add a {@linkplain Triggerable} object to the collection of objects to
+ * trigger whenever the policy intends to do so. If the object has already
+ * been registered before, nothing changes.
+ *
+ *
+ * @param t
+ * the object to trigger
+ */
+ public void registerTriggerable(Triggerable t);
+
+ /**
+ *
+ * Resumes the trigger policy activity if it is suspended. Calling this
+ * function when the trigger policy is stopped, or started has no effect.
+ * Resuming may cause immediate firing of the triggerable object.
+ *
+ */
+ public void resume();
+
+ /**
+ *
+ * Runs the trigger policy. After this call, the trigger policy will
+ * determine the conditions and regularity in which the triggerable object
+ * will be fired. Starting may cause the immediate firing of the triggerable
+ * object.
+ *
+ *
+ *
+ * If start is invoked and the trigger policy is not in stopped state, it
+ * will have no effect.
+ *
+ */
+ public void start();
+
+ /**
+ *
+ * Stops the functioning of the trigger policy. After this method is invoked
+ * there will be no firing of the triggerable object which was registered.
+ * Additionally the internal state of the Triggerpolicy (if any) is cleared.
+ *
+ */
+ public void stop();
+
+ /**
+ *
+ * Temporarily suspends the firing of the triggerable object. The normal
+ * functioning of the trigger policy must be resumed by using the resume()
+ * method.
+ *
+ */
+ public void suspend();
+
+ /**
+ *
+ * Remove a {@linkplain Triggerable} object from the collection of objects
+ * to trigger whenever the policy intends to do so. If the object was not
+ * registered before, nothing changes
+ *
+ *
+ * @param t
+ * the object that no longer needs to be triggered
+ */
+ public void unregisterTriggerable(Triggerable t);
+
+}
\ No newline at end of file
diff --git a/src/eu/artemis/demanes/reconfiguration/Triggerable.java b/src/eu/artemis/demanes/reconfiguration/Triggerable.java
new file mode 100644
index 0000000..8fdb163
--- /dev/null
+++ b/src/eu/artemis/demanes/reconfiguration/Triggerable.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2013-2015 DEMANES.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the LicenseLicensed under the Apache License, Version 2.0.
+ */
+package eu.artemis.demanes.reconfiguration;
+
+import eu.artemis.demanes.datatypes.ANES_URN;
+
+/**
+ *
+ * An object implementing the Triggerable interface can be triggered in order to
+ * perform it's actions. It allows for it's accessors to have a method that will
+ * start the object's main functionality
+ *
+ * The trigger function triggers the object to do it's main purpose. The
+ * trigger function is merely a generic get an object started. It receives
+ * no arguments, it can be seen merely as a button that activates the
+ * Triggerable object.
+ *