Merge branch 'master' of ssh://contiki.git.sourceforge.net/gitroot/contiki/contiki
This commit is contained in:
commit
66f0a1bc95
21 changed files with 1135 additions and 997 deletions
|
@ -56,7 +56,7 @@ uart0_init()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
U0CSR = UCSR_MODE; /* UART mode */
|
U0CSR = UCSR_MODE; /* UART mode */
|
||||||
U0UCR = 0x80; /* Flush */
|
U0UCR |= 0x80; /* Flush */
|
||||||
UART0_RX_EN();
|
UART0_RX_EN();
|
||||||
|
|
||||||
UART0_RX_INT(1);
|
UART0_RX_INT(1);
|
||||||
|
|
|
@ -201,7 +201,7 @@ clock_delay(unsigned int i)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
void
|
void
|
||||||
__delay_cycles(int c)
|
__delay_cycles(unsigned long c)
|
||||||
{
|
{
|
||||||
c /= 4;
|
c /= 4;
|
||||||
asm("add #-1, r15");
|
asm("add #-1, r15");
|
||||||
|
|
|
@ -381,7 +381,12 @@ void halLcdActive(void)
|
||||||
|
|
||||||
// Wait a minimum of 25ms after issuing "start oscillation"
|
// Wait a minimum of 25ms after issuing "start oscillation"
|
||||||
// command (to accomodate for MCLK up to 25MHz)
|
// command (to accomodate for MCLK up to 25MHz)
|
||||||
__delay_cycles(250000);
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < 5; ++i) {
|
||||||
|
__delay_cycles(50000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LcdInitMacro[3 * 6 + 5] |= BIT3;
|
LcdInitMacro[3 * 6 + 5] |= BIT3;
|
||||||
LcdInitMacro[3 * 6 + 5] &= ~BIT0;
|
LcdInitMacro[3 * 6 + 5] &= ~BIT0;
|
||||||
|
|
|
@ -214,10 +214,9 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
|
||||||
this.myCpu.setMonitorExec(true);
|
this.myCpu.setMonitorExec(true);
|
||||||
this.myCpu.setTrace(0); /* TODO Enable */
|
this.myCpu.setTrace(0); /* TODO Enable */
|
||||||
|
|
||||||
int[] memory = myCpu.memory;
|
|
||||||
logger.info("Loading firmware from: " + fileELF.getAbsolutePath());
|
logger.info("Loading firmware from: " + fileELF.getAbsolutePath());
|
||||||
GUI.setProgressMessage("Loading " + fileELF.getName());
|
GUI.setProgressMessage("Loading " + fileELF.getName());
|
||||||
node.loadFirmware(((MspMoteType)getType()).getELF(), memory);
|
node.loadFirmware(((MspMoteType)getType()).getELF());
|
||||||
|
|
||||||
/* Throw exceptions at bad memory access */
|
/* Throw exceptions at bad memory access */
|
||||||
/*myCpu.setThrowIfWarning(true);*/
|
/*myCpu.setThrowIfWarning(true);*/
|
||||||
|
@ -417,6 +416,10 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
|
||||||
}
|
}
|
||||||
|
|
||||||
MoteInterface moteInterface = getInterfaces().getInterfaceOfType(moteInterfaceClass);
|
MoteInterface moteInterface = getInterfaces().getInterfaceOfType(moteInterfaceClass);
|
||||||
|
if (moteInterface == null) {
|
||||||
|
logger.fatal("Could not find mote interface of class: " + moteInterfaceClass);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
moteInterface.setConfigXML(element.getChildren(), visAvailable);
|
moteInterface.setConfigXML(element.getChildren(), visAvailable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,18 +69,21 @@ import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.GUI;
|
import se.sics.cooja.GUI;
|
||||||
|
import se.sics.cooja.GUI.RunnableInEDT;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MotePlugin;
|
import se.sics.cooja.MotePlugin;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
import se.sics.cooja.Simulation;
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.SupportedArguments;
|
||||||
import se.sics.cooja.VisPlugin;
|
import se.sics.cooja.VisPlugin;
|
||||||
import se.sics.cooja.GUI.RunnableInEDT;
|
|
||||||
import se.sics.cooja.dialogs.CompileContiki;
|
import se.sics.cooja.dialogs.CompileContiki;
|
||||||
import se.sics.cooja.dialogs.MessageList;
|
import se.sics.cooja.dialogs.MessageList;
|
||||||
|
import se.sics.cooja.interfaces.IPAddress;
|
||||||
import se.sics.cooja.interfaces.SerialPort;
|
import se.sics.cooja.interfaces.SerialPort;
|
||||||
|
|
||||||
@ClassDescription("Open Native IP Gateway")
|
@ClassDescription("Open Native IP Gateway")
|
||||||
@PluginType(PluginType.MOTE_PLUGIN)
|
@PluginType(PluginType.MOTE_PLUGIN)
|
||||||
|
@SupportedArguments(moteInterfaces = {IPAddress.class})
|
||||||
public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(NativeIPGateway.class);
|
private static Logger logger = Logger.getLogger(NativeIPGateway.class);
|
||||||
|
@ -238,7 +241,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detect selected network interface */
|
/* Detect selected network interface */
|
||||||
NetworkInterfaceW intf =
|
NetworkInterfaceW intf =
|
||||||
(NetworkInterfaceW) ((JComboBox)e.getSource()).getSelectedItem();
|
(NetworkInterfaceW) ((JComboBox)e.getSource()).getSelectedItem();
|
||||||
if (networkInterface == intf) {
|
if (networkInterface == intf) {
|
||||||
/* Already selected */
|
/* Already selected */
|
||||||
|
@ -546,7 +549,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
||||||
final JDialog progressDialog;
|
final JDialog progressDialog;
|
||||||
if (GUI.isVisualized()) {
|
if (GUI.isVisualized()) {
|
||||||
progressDialog = new JDialog(
|
progressDialog = new JDialog(
|
||||||
(Window)GUI.getTopParentContainer(),
|
(Window)GUI.getTopParentContainer(),
|
||||||
"Starting Native IP Gateway plugin"
|
"Starting Native IP Gateway plugin"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -564,7 +567,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
||||||
progressDialog.getContentPane().add(BorderLayout.NORTH, progressBar);
|
progressDialog.getContentPane().add(BorderLayout.NORTH, progressBar);
|
||||||
progressDialog.getContentPane().add(BorderLayout.CENTER, new JScrollPane(output));
|
progressDialog.getContentPane().add(BorderLayout.CENTER, new JScrollPane(output));
|
||||||
progressDialog.setSize(350, 150);
|
progressDialog.setSize(350, 150);
|
||||||
progressDialog.setLocationRelativeTo((Window)GUI.getTopParentContainer());
|
progressDialog.setLocationRelativeTo(GUI.getTopParentContainer());
|
||||||
progressDialog.setVisible(true);
|
progressDialog.setVisible(true);
|
||||||
GUI.setProgressMessage("Compiling hello-world.minimal-net (Native IP Gateway)");
|
GUI.setProgressMessage("Compiling hello-world.minimal-net (Native IP Gateway)");
|
||||||
return true;
|
return true;
|
||||||
|
@ -613,7 +616,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||||
|
|
||||||
/* Waiting some time - otherwise pcap may not discover the new interface */
|
/* Waiting some time - otherwise pcap may not discover the new interface */
|
||||||
Thread.sleep(250);
|
Thread.sleep(250);
|
||||||
|
|
||||||
|
@ -622,7 +625,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
||||||
logger.fatal("Error when creating tap0: " + e.getMessage());
|
logger.fatal("Error when creating tap0: " + e.getMessage());
|
||||||
logger.fatal("Try using an already existing network interface");
|
logger.fatal("Try using an already existing network interface");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide progress bar */
|
/* Hide progress bar */
|
||||||
if (GUI.isVisualized()) {
|
if (GUI.isVisualized()) {
|
||||||
new RunnableInEDT<Boolean>() {
|
new RunnableInEDT<Boolean>() {
|
||||||
|
@ -1007,7 +1010,7 @@ public class NativeIPGateway extends VisPlugin implements MotePlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteTunInterface();
|
deleteTunInterface();
|
||||||
|
|
||||||
if (shutdownHook != null) {
|
if (shutdownHook != null) {
|
||||||
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
||||||
shutdownHook = null;
|
shutdownHook = null;
|
||||||
|
|
|
@ -4,7 +4,6 @@ KEYBOARD_SHORTCUTS = \
|
||||||
<br><i>Ctrl+S:</i> Start/pause simulation\
|
<br><i>Ctrl+S:</i> Start/pause simulation\
|
||||||
<br><i>Ctrl+R:</i> Reload current simulation. If no simulation exists, the last used simulation config is loaded\
|
<br><i>Ctrl+R:</i> Reload current simulation. If no simulation exists, the last used simulation config is loaded\
|
||||||
<br><i>Ctrl+Shift+R:</i> Reload current simulation with another random seed\
|
<br><i>Ctrl+Shift+R:</i> Reload current simulation with another random seed\
|
||||||
<br><i>Ctrl+X:</i> Quit COOJA\
|
|
||||||
<br>\
|
<br>\
|
||||||
<br><i>F1:</i> Toggle quick help
|
<br><i>F1:</i> Toggle quick help
|
||||||
|
|
||||||
|
|
|
@ -1,113 +1,100 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<simconf>
|
<simconf>
|
||||||
<project>../apps/mrm</project>
|
<simulation>
|
||||||
<project>../apps/mspsim</project>
|
<title>Hello World test (Cooja motes)</title>
|
||||||
<project>../apps/avrora</project>
|
<randomseed>generated</randomseed>
|
||||||
<project>../apps/native_gateway</project>
|
<motedelay_us>1000000</motedelay_us>
|
||||||
<simulation>
|
<radiomedium>
|
||||||
<title>My simulation</title>
|
se.sics.cooja.radiomediums.UDGM
|
||||||
<delaytime>0</delaytime>
|
<transmitting_range>50.0</transmitting_range>
|
||||||
<randomseed>generated</randomseed>
|
<interference_range>100.0</interference_range>
|
||||||
<motedelay_us>1000000</motedelay_us>
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
<radiomedium>
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
se.sics.cooja.radiomediums.UDGM
|
</radiomedium>
|
||||||
<transmitting_range>50.0</transmitting_range>
|
<events>
|
||||||
<interference_range>100.0</interference_range>
|
<logoutput>40000</logoutput>
|
||||||
<success_ratio_tx>1.0</success_ratio_tx>
|
</events>
|
||||||
<success_ratio_rx>1.0</success_ratio_rx>
|
<motetype>
|
||||||
</radiomedium>
|
se.sics.cooja.contikimote.ContikiMoteType
|
||||||
<motetype>
|
<identifier>mtype725</identifier>
|
||||||
se.sics.cooja.contikimote.ContikiMoteType
|
<description>Contiki Mote Type #1</description>
|
||||||
<identifier>mtype82</identifier>
|
<source>[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||||
<description>Contiki Mote Type #1</description>
|
<commands>make hello-world.cooja TARGET=cooja</commands>
|
||||||
<contikiapp>../../../examples/hello-world/hello-world.c</contikiapp>
|
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||||
<commands>make hello-world.cooja TARGET=cooja</commands>
|
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
<symbols>false</symbols>
|
||||||
<symbols>false</symbols>
|
</motetype>
|
||||||
<commstack>Rime</commstack>
|
<mote>
|
||||||
</motetype>
|
<interface_config>
|
||||||
<mote>
|
se.sics.cooja.interfaces.Position
|
||||||
se.sics.cooja.contikimote.ContikiMote
|
<x>69.64867743029201</x>
|
||||||
<motetype_identifier>mtype82</motetype_identifier>
|
<y>69.2570131081022</y>
|
||||||
<interface_config>
|
<z>0.0</z>
|
||||||
se.sics.cooja.interfaces.Position
|
</interface_config>
|
||||||
<x>69.64867743029201</x>
|
<interface_config>
|
||||||
<y>69.2570131081022</y>
|
se.sics.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
<z>0.0</z>
|
<id>1</id>
|
||||||
</interface_config>
|
</interface_config>
|
||||||
<interface_config>
|
<motetype_identifier>mtype725</motetype_identifier>
|
||||||
se.sics.cooja.interfaces.Battery
|
</mote>
|
||||||
<infinite>false</infinite>
|
</simulation>
|
||||||
</interface_config>
|
<plugin>
|
||||||
<interface_config>
|
se.sics.cooja.plugins.Visualizer
|
||||||
se.sics.cooja.contikimote.interfaces.ContikiMoteID
|
<plugin_config>
|
||||||
<id>1</id>
|
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||||
</interface_config>
|
<skin>se.sics.cooja.plugins.skins.LogVisualizerSkin</skin>
|
||||||
</mote>
|
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 59.68302051791636 6.039078992634368</viewport>
|
||||||
</simulation>
|
</plugin_config>
|
||||||
<plugin>
|
<width>259</width>
|
||||||
se.sics.cooja.plugins.Visualizer
|
<z>1</z>
|
||||||
<plugin_config>
|
<height>198</height>
|
||||||
<skin>Mote IDs</skin>
|
<location_x>2</location_x>
|
||||||
<skin>Log output: printf()'s</skin>
|
<location_y>203</location_y>
|
||||||
</plugin_config>
|
</plugin>
|
||||||
<width>259</width>
|
<plugin>
|
||||||
<z>1</z>
|
se.sics.cooja.plugins.LogListener
|
||||||
<height>198</height>
|
<plugin_config>
|
||||||
<location_x>2</location_x>
|
<filter />
|
||||||
<location_y>203</location_y>
|
</plugin_config>
|
||||||
<minimized>false</minimized>
|
<width>259</width>
|
||||||
</plugin>
|
<z>2</z>
|
||||||
<plugin>
|
<height>217</height>
|
||||||
se.sics.cooja.plugins.LogListener
|
<location_x>2</location_x>
|
||||||
<plugin_config>
|
<location_y>403</location_y>
|
||||||
<filter />
|
</plugin>
|
||||||
</plugin_config>
|
<plugin>
|
||||||
<width>259</width>
|
se.sics.cooja.plugins.SimControl
|
||||||
<z>2</z>
|
<width>259</width>
|
||||||
<height>217</height>
|
<z>3</z>
|
||||||
<location_x>2</location_x>
|
<height>200</height>
|
||||||
<location_y>403</location_y>
|
<location_x>2</location_x>
|
||||||
<minimized>false</minimized>
|
<location_y>3</location_y>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
se.sics.cooja.plugins.SimControl
|
se.sics.cooja.plugins.ScriptRunner
|
||||||
<width>259</width>
|
<plugin_config>
|
||||||
<z>3</z>
|
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||||
<height>200</height>
|
<active>true</active>
|
||||||
<location_x>2</location_x>
|
</plugin_config>
|
||||||
<location_y>3</location_y>
|
<width>592</width>
|
||||||
<minimized>false</minimized>
|
<z>0</z>
|
||||||
</plugin>
|
<height>618</height>
|
||||||
<plugin>
|
<location_x>318</location_x>
|
||||||
se.sics.cooja.plugins.ScriptRunner
|
<location_y>61</location_y>
|
||||||
<plugin_config>
|
</plugin>
|
||||||
<script>TIMEOUT(2000, log.log("last message: " + msg + "\n"));
|
</simconf>
|
||||||
|
|
||||||
WAIT_UNTIL(msg.equals('Hello, world'));
|
|
||||||
log.testOK();</script>
|
|
||||||
<active>true</active>
|
|
||||||
</plugin_config>
|
|
||||||
<width>592</width>
|
|
||||||
<z>0</z>
|
|
||||||
<height>618</height>
|
|
||||||
<location_x>264</location_x>
|
|
||||||
<location_y>3</location_y>
|
|
||||||
<minimized>false</minimized>
|
|
||||||
</plugin>
|
|
||||||
</simconf>
|
|
||||||
|
|
||||||
|
|
|
@ -1,125 +1,83 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<simconf>
|
<simconf>
|
||||||
<project>[CONTIKI_DIR]/tools/cooja/apps/mrm</project>
|
<simulation>
|
||||||
<project>[CONTIKI_DIR]/tools/cooja/apps/mspsim</project>
|
<title>Hello World (ESB)</title>
|
||||||
<project>[CONTIKI_DIR]/tools/cooja/apps/avrora</project>
|
<randomseed>generated</randomseed>
|
||||||
<simulation>
|
<motedelay_us>1000000</motedelay_us>
|
||||||
<title>My simulation</title>
|
<radiomedium>
|
||||||
<delaytime>0</delaytime>
|
se.sics.cooja.radiomediums.UDGM
|
||||||
<randomseed>generated</randomseed>
|
<transmitting_range>50.0</transmitting_range>
|
||||||
<motedelay_us>1000000</motedelay_us>
|
<interference_range>100.0</interference_range>
|
||||||
<radiomedium>
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
se.sics.cooja.radiomediums.UDGM
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
<transmitting_range>50.0</transmitting_range>
|
</radiomedium>
|
||||||
<interference_range>100.0</interference_range>
|
<events>
|
||||||
<success_ratio_tx>1.0</success_ratio_tx>
|
<logoutput>40000</logoutput>
|
||||||
<success_ratio_rx>1.0</success_ratio_rx>
|
</events>
|
||||||
</radiomedium>
|
<motetype>
|
||||||
<events>
|
se.sics.cooja.mspmote.ESBMoteType
|
||||||
<logoutput>40000</logoutput>
|
<identifier>esb1</identifier>
|
||||||
</events>
|
<description>ESB Mote Type #esb1</description>
|
||||||
<motetype>
|
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||||
se.sics.cooja.mspmote.ESBMoteType
|
<commands EXPORT="discard">make hello-world.esb TARGET=esb</commands>
|
||||||
<identifier>esb1</identifier>
|
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.esb</firmware>
|
||||||
<description>ESB Mote Type #esb1</description>
|
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||||
<source>[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
<commands>make clean TARGET=esb
|
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||||
make hello-world.esb TARGET=esb</commands>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||||
<firmware>[CONTIKI_DIR]/examples/hello-world/hello-world.esb</firmware>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.ESBLED</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.ESBButton</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.TR1001Radio</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.ESBLED</moteinterface>
|
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.ESBButton</moteinterface>
|
</motetype>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
<mote>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.TR1001Radio</moteinterface>
|
<breakpoints />
|
||||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
<interface_config>
|
||||||
</motetype>
|
se.sics.cooja.interfaces.Position
|
||||||
<mote>
|
<x>57.296459690977144</x>
|
||||||
se.sics.cooja.mspmote.ESBMote
|
<y>73.20759478605089</y>
|
||||||
<breakpoints />
|
<z>0.0</z>
|
||||||
<interface_config>
|
</interface_config>
|
||||||
se.sics.cooja.interfaces.Position
|
<interface_config>
|
||||||
<x>57.296459690977144</x>
|
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||||
<y>73.20759478605089</y>
|
<id>1</id>
|
||||||
<z>0.0</z>
|
</interface_config>
|
||||||
</interface_config>
|
<motetype_identifier>esb1</motetype_identifier>
|
||||||
<interface_config>
|
</mote>
|
||||||
se.sics.cooja.mspmote.interfaces.MspMoteID
|
</simulation>
|
||||||
<id>1</id>
|
<plugin>
|
||||||
</interface_config>
|
se.sics.cooja.plugins.LogListener
|
||||||
<motetype_identifier>esb1</motetype_identifier>
|
<plugin_config>
|
||||||
</mote>
|
<filter />
|
||||||
</simulation>
|
</plugin_config>
|
||||||
<plugin>
|
<width>623</width>
|
||||||
se.sics.cooja.plugins.SimControl
|
<z>1</z>
|
||||||
<width>259</width>
|
<height>270</height>
|
||||||
<z>6</z>
|
<location_x>29</location_x>
|
||||||
<height>184</height>
|
<location_y>256</location_y>
|
||||||
<location_x>60</location_x>
|
</plugin>
|
||||||
<location_y>60</location_y>
|
<plugin>
|
||||||
<minimized>false</minimized>
|
se.sics.cooja.plugins.ScriptRunner
|
||||||
</plugin>
|
<plugin_config>
|
||||||
<plugin>
|
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||||
se.sics.cooja.plugins.Visualizer
|
<active>true</active>
|
||||||
<plugin_config>
|
</plugin_config>
|
||||||
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
|
<width>600</width>
|
||||||
<skin>se.sics.cooja.plugins.skins.LogVisualizerSkin</skin>
|
<z>0</z>
|
||||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 91.91230937183896 53.4476411035901</viewport>
|
<height>453</height>
|
||||||
</plugin_config>
|
<location_x>337</location_x>
|
||||||
<width>300</width>
|
<location_y>25</location_y>
|
||||||
<z>3</z>
|
</plugin>
|
||||||
<height>300</height>
|
<plugin>
|
||||||
<location_x>945</location_x>
|
se.sics.cooja.plugins.SimControl
|
||||||
<location_y>0</location_y>
|
<width>280</width>
|
||||||
<minimized>false</minimized>
|
<z>2</z>
|
||||||
</plugin>
|
<height>160</height>
|
||||||
<plugin>
|
<location_x>20</location_x>
|
||||||
se.sics.cooja.plugins.LogListener
|
<location_y>23</location_y>
|
||||||
<plugin_config>
|
</plugin>
|
||||||
<filter />
|
</simconf>
|
||||||
</plugin_config>
|
|
||||||
<width>1245</width>
|
|
||||||
<z>5</z>
|
|
||||||
<height>150</height>
|
|
||||||
<location_x>0</location_x>
|
|
||||||
<location_y>530</location_y>
|
|
||||||
<minimized>false</minimized>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
se.sics.cooja.plugins.TimeLine
|
|
||||||
<plugin_config>
|
|
||||||
<mote>0</mote>
|
|
||||||
<showRadioRXTX />
|
|
||||||
<showRadioHW />
|
|
||||||
<showLEDs />
|
|
||||||
<split>109</split>
|
|
||||||
<zoom>9</zoom>
|
|
||||||
</plugin_config>
|
|
||||||
<width>1245</width>
|
|
||||||
<z>1</z>
|
|
||||||
<height>150</height>
|
|
||||||
<location_x>0</location_x>
|
|
||||||
<location_y>680</location_y>
|
|
||||||
<minimized>false</minimized>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
se.sics.cooja.plugins.ScriptRunner
|
|
||||||
<plugin_config>
|
|
||||||
<script>TIMEOUT(5000, log.log("last message: " + msg + "\n"));
|
|
||||||
|
|
||||||
WAIT_UNTIL(msg.equals('Hello, world'));
|
|
||||||
log.testOK();</script>
|
|
||||||
<active>true</active>
|
|
||||||
</plugin_config>
|
|
||||||
<width>600</width>
|
|
||||||
<z>0</z>
|
|
||||||
<height>453</height>
|
|
||||||
<location_x>337</location_x>
|
|
||||||
<location_y>25</location_y>
|
|
||||||
<minimized>false</minimized>
|
|
||||||
</plugin>
|
|
||||||
</simconf>
|
|
||||||
|
|
||||||
|
|
83
tools/cooja/contiki_tests/exp5438_helloworld.csc
Normal file
83
tools/cooja/contiki_tests/exp5438_helloworld.csc
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<simconf>
|
||||||
|
<simulation>
|
||||||
|
<title>Hello World (Exp5438)</title>
|
||||||
|
<randomseed>generated</randomseed>
|
||||||
|
<motedelay_us>1000000</motedelay_us>
|
||||||
|
<radiomedium>
|
||||||
|
se.sics.cooja.radiomediums.UDGM
|
||||||
|
<transmitting_range>50.0</transmitting_range>
|
||||||
|
<interference_range>100.0</interference_range>
|
||||||
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
|
</radiomedium>
|
||||||
|
<events>
|
||||||
|
<logoutput>40000</logoutput>
|
||||||
|
</events>
|
||||||
|
<motetype>
|
||||||
|
se.sics.cooja.mspmote.Exp5438MoteType
|
||||||
|
<identifier>exp5438#1</identifier>
|
||||||
|
<description>Exp5438 Mote Type exp5438#1</description>
|
||||||
|
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||||
|
<commands EXPORT="discard">make hello-world.exp5438 TARGET=exp5438</commands>
|
||||||
|
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.exp5438</firmware>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.UsciA1Serial</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.Exp5438LED</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||||
|
</motetype>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
se.sics.cooja.interfaces.Position
|
||||||
|
<x>26.321738050614275</x>
|
||||||
|
<y>34.93092009073432</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>1</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>exp5438#1</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
</simulation>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.SimControl
|
||||||
|
<width>280</width>
|
||||||
|
<z>2</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>38</location_x>
|
||||||
|
<location_y>49</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.LogListener
|
||||||
|
<plugin_config>
|
||||||
|
<filter />
|
||||||
|
</plugin_config>
|
||||||
|
<width>680</width>
|
||||||
|
<z>1</z>
|
||||||
|
<height>240</height>
|
||||||
|
<location_x>86</location_x>
|
||||||
|
<location_y>384</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.ScriptRunner
|
||||||
|
<plugin_config>
|
||||||
|
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||||
|
<active>true</active>
|
||||||
|
</plugin_config>
|
||||||
|
<width>600</width>
|
||||||
|
<z>0</z>
|
||||||
|
<height>700</height>
|
||||||
|
<location_x>347</location_x>
|
||||||
|
<location_y>21</location_y>
|
||||||
|
</plugin>
|
||||||
|
</simconf>
|
||||||
|
|
9
tools/cooja/contiki_tests/hello-world.js
Normal file
9
tools/cooja/contiki_tests/hello-world.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
TIMEOUT(5000);
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
log.log("> " + msg + "\n");
|
||||||
|
if (msg.equals('Hello, world')) {
|
||||||
|
log.testOK();
|
||||||
|
}
|
||||||
|
YIELD();
|
||||||
|
}
|
|
@ -1,120 +1,79 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<simconf>
|
<simconf>
|
||||||
<project>../apps/mrm</project>
|
<simulation>
|
||||||
<project>../apps/mspsim</project>
|
<title>Hello World (MicaZ)</title>
|
||||||
<project>../apps/avrora</project>
|
<randomseed>generated</randomseed>
|
||||||
<simulation>
|
<motedelay_us>1000000</motedelay_us>
|
||||||
<title>My simulation</title>
|
<radiomedium>
|
||||||
<delaytime>0</delaytime>
|
se.sics.cooja.radiomediums.UDGM
|
||||||
<randomseed>generated</randomseed>
|
<transmitting_range>50.0</transmitting_range>
|
||||||
<motedelay_us>1000000</motedelay_us>
|
<interference_range>100.0</interference_range>
|
||||||
<radiomedium>
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
se.sics.cooja.radiomediums.UDGM
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
<transmitting_range>50.0</transmitting_range>
|
</radiomedium>
|
||||||
<interference_range>100.0</interference_range>
|
<events>
|
||||||
<success_ratio_tx>1.0</success_ratio_tx>
|
<logoutput>40000</logoutput>
|
||||||
<success_ratio_rx>1.0</success_ratio_rx>
|
</events>
|
||||||
</radiomedium>
|
<motetype>
|
||||||
<events>
|
se.sics.cooja.avrmote.MicaZMoteType
|
||||||
<logoutput>40000</logoutput>
|
<identifier>micaz1</identifier>
|
||||||
</events>
|
<description>MicaZ Mote Type #micaz1</description>
|
||||||
<motetype>
|
<source>[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||||
se.sics.cooja.avrmote.MicaZMoteType
|
<commands>make hello-world.elf TARGET=micaz</commands>
|
||||||
<identifier>micaz1</identifier>
|
<firmware>[CONTIKI_DIR]/examples/hello-world/hello-world.elf</firmware>
|
||||||
<description>MicaZ Mote Type #micaz1</description>
|
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||||
<source>../../../examples/hello-world/hello-world.c</source>
|
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaZID</moteinterface>
|
||||||
<commands>make clean TARGET=micaz
|
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaZLED</moteinterface>
|
||||||
make hello-world.elf TARGET=micaz</commands>
|
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaZRadio</moteinterface>
|
||||||
<firmware>../../../examples/hello-world/hello-world.elf</firmware>
|
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaClock</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaSerial</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaZID</moteinterface>
|
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaZLED</moteinterface>
|
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaZRadio</moteinterface>
|
</motetype>
|
||||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaClock</moteinterface>
|
<mote>
|
||||||
<moteinterface>se.sics.cooja.avrmote.interfaces.MicaSerial</moteinterface>
|
<interface_config>
|
||||||
</motetype>
|
se.sics.cooja.interfaces.Position
|
||||||
<mote>
|
<x>36.478849033811386</x>
|
||||||
se.sics.cooja.avrmote.MicaZMote
|
<y>97.17795415366507</y>
|
||||||
<motetype_identifier>micaz1</motetype_identifier>
|
<z>0.0</z>
|
||||||
<interface_config>
|
</interface_config>
|
||||||
se.sics.cooja.interfaces.Position
|
<interface_config>
|
||||||
<x>68.44103812985554</x>
|
se.sics.cooja.avrmote.interfaces.MicaZID
|
||||||
<y>35.6791174319418</y>
|
<id>1</id>
|
||||||
<z>0.0</z>
|
</interface_config>
|
||||||
</interface_config>
|
<motetype_identifier>micaz1</motetype_identifier>
|
||||||
<interface_config>
|
</mote>
|
||||||
se.sics.cooja.avrmote.interfaces.MicaZID
|
</simulation>
|
||||||
<id>1</id>
|
<plugin>
|
||||||
</interface_config>
|
se.sics.cooja.plugins.SimControl
|
||||||
</mote>
|
<width>280</width>
|
||||||
</simulation>
|
<z>2</z>
|
||||||
<plugin>
|
<height>160</height>
|
||||||
se.sics.cooja.plugins.SimControl
|
<location_x>17</location_x>
|
||||||
<width>259</width>
|
<location_y>16</location_y>
|
||||||
<z>4</z>
|
</plugin>
|
||||||
<height>184</height>
|
<plugin>
|
||||||
<location_x>0</location_x>
|
se.sics.cooja.plugins.LogListener
|
||||||
<location_y>0</location_y>
|
<plugin_config>
|
||||||
<minimized>false</minimized>
|
<filter />
|
||||||
</plugin>
|
</plugin_config>
|
||||||
<plugin>
|
<width>680</width>
|
||||||
se.sics.cooja.plugins.Visualizer
|
<z>1</z>
|
||||||
<plugin_config>
|
<height>240</height>
|
||||||
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
|
<location_x>20</location_x>
|
||||||
<skin>se.sics.cooja.plugins.skins.LogVisualizerSkin</skin>
|
<location_y>285</location_y>
|
||||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 81.78087442740406 87.56443869823474</viewport>
|
</plugin>
|
||||||
</plugin_config>
|
<plugin>
|
||||||
<width>300</width>
|
se.sics.cooja.plugins.ScriptRunner
|
||||||
<z>1</z>
|
<plugin_config>
|
||||||
<height>300</height>
|
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||||
<location_x>456</location_x>
|
<active>true</active>
|
||||||
<location_y>0</location_y>
|
</plugin_config>
|
||||||
<minimized>false</minimized>
|
<width>600</width>
|
||||||
</plugin>
|
<z>0</z>
|
||||||
<plugin>
|
<height>535</height>
|
||||||
se.sics.cooja.plugins.LogListener
|
<location_x>403</location_x>
|
||||||
<plugin_config>
|
<location_y>23</location_y>
|
||||||
<filter />
|
</plugin>
|
||||||
</plugin_config>
|
</simconf>
|
||||||
<width>756</width>
|
|
||||||
<z>2</z>
|
|
||||||
<height>150</height>
|
|
||||||
<location_x>0</location_x>
|
|
||||||
<location_y>286</location_y>
|
|
||||||
<minimized>false</minimized>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
se.sics.cooja.plugins.TimeLine
|
|
||||||
<plugin_config>
|
|
||||||
<mote>0</mote>
|
|
||||||
<showRadioRXTX />
|
|
||||||
<showRadioHW />
|
|
||||||
<showLEDs />
|
|
||||||
<split>109</split>
|
|
||||||
<zoom>9</zoom>
|
|
||||||
</plugin_config>
|
|
||||||
<width>756</width>
|
|
||||||
<z>3</z>
|
|
||||||
<height>150</height>
|
|
||||||
<location_x>0</location_x>
|
|
||||||
<location_y>436</location_y>
|
|
||||||
<minimized>false</minimized>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
se.sics.cooja.plugins.ScriptRunner
|
|
||||||
<plugin_config>
|
|
||||||
<script>TIMEOUT(2000, log.log("last message: " + msg + "\n"));
|
|
||||||
|
|
||||||
WAIT_UNTIL(msg.startsWith('Hello, world'));
|
|
||||||
log.testOK();</script>
|
|
||||||
<active>true</active>
|
|
||||||
</plugin_config>
|
|
||||||
<width>600</width>
|
|
||||||
<z>0</z>
|
|
||||||
<height>305</height>
|
|
||||||
<location_x>89</location_x>
|
|
||||||
<location_y>211</location_y>
|
|
||||||
<minimized>false</minimized>
|
|
||||||
</plugin>
|
|
||||||
</simconf>
|
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ msg = "";
|
||||||
GENERATE_MSG(5000, "continue");
|
GENERATE_MSG(5000, "continue");
|
||||||
WAIT_UNTIL(msg.equals("continue"));
|
WAIT_UNTIL(msg.equals("continue"));
|
||||||
|
|
||||||
/* override simulation delay to realtime */
|
/* override simulation speed limit to realtime */
|
||||||
sim.setDelayTime(java.lang.Integer.MIN_VALUE);
|
sim.setSpeedLimit(1.0);
|
||||||
|
|
||||||
/* create tunnel interface */
|
/* create tunnel interface */
|
||||||
log.log("create tunnel interface\n");
|
log.log("create tunnel interface\n");
|
||||||
|
|
|
@ -1,80 +1,82 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<simconf>
|
<simconf>
|
||||||
<project>../apps/mrm</project>
|
<simulation>
|
||||||
<project>../apps/mspsim</project>
|
<title>Hello World test (Sky)</title>
|
||||||
<project>../apps/avrora</project>
|
<randomseed>generated</randomseed>
|
||||||
<project>../apps/native_gateway</project>
|
<motedelay_us>1000000</motedelay_us>
|
||||||
<simulation>
|
<radiomedium>
|
||||||
<title>Hello World (Sky)</title>
|
se.sics.cooja.radiomediums.UDGM
|
||||||
<delaytime>0</delaytime>
|
<transmitting_range>50.0</transmitting_range>
|
||||||
<randomseed>generated</randomseed>
|
<interference_range>100.0</interference_range>
|
||||||
<motedelay_us>1000000</motedelay_us>
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
<radiomedium>
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
se.sics.cooja.radiomediums.UDGM
|
</radiomedium>
|
||||||
<transmitting_range>50.0</transmitting_range>
|
<events>
|
||||||
<interference_range>100.0</interference_range>
|
<logoutput>40000</logoutput>
|
||||||
<success_ratio_tx>1.0</success_ratio_tx>
|
</events>
|
||||||
<success_ratio_rx>1.0</success_ratio_rx>
|
<motetype>
|
||||||
</radiomedium>
|
se.sics.cooja.mspmote.SkyMoteType
|
||||||
<motetype>
|
<identifier>sky1</identifier>
|
||||||
se.sics.cooja.mspmote.SkyMoteType
|
<description>Sky Mote Type #1</description>
|
||||||
<identifier>sky1</identifier>
|
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||||
<description>Sky Mote Type #1</description>
|
<commands EXPORT="discard">make hello-world.sky TARGET=sky</commands>
|
||||||
<source>../../../examples/hello-world/hello-world.c</source>
|
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.sky</firmware>
|
||||||
<commands>make clean TARGET=sky
|
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||||
make hello-world.sky TARGET=sky</commands>
|
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||||
<firmware>../../../examples/hello-world/hello-world.sky</firmware>
|
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
|
</motetype>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkySerial</moteinterface>
|
<mote>
|
||||||
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
<breakpoints />
|
||||||
</motetype>
|
<interface_config>
|
||||||
<mote>
|
se.sics.cooja.interfaces.Position
|
||||||
se.sics.cooja.mspmote.SkyMote
|
<x>64.11203103628397</x>
|
||||||
<motetype_identifier>sky1</motetype_identifier>
|
<y>93.06735634828134</y>
|
||||||
<breakpoints />
|
<z>0.0</z>
|
||||||
<interface_config>
|
</interface_config>
|
||||||
se.sics.cooja.interfaces.Position
|
<interface_config>
|
||||||
<x>64.11203103628397</x>
|
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||||
<y>93.06735634828134</y>
|
<id>1</id>
|
||||||
<z>0.0</z>
|
</interface_config>
|
||||||
</interface_config>
|
<motetype_identifier>sky1</motetype_identifier>
|
||||||
<interface_config>
|
</mote>
|
||||||
se.sics.cooja.mspmote.interfaces.MspMoteID
|
</simulation>
|
||||||
<id>1</id>
|
<plugin>
|
||||||
</interface_config>
|
se.sics.cooja.plugins.ScriptRunner
|
||||||
</mote>
|
<plugin_config>
|
||||||
</simulation>
|
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||||
<plugin>
|
<active>true</active>
|
||||||
se.sics.cooja.plugins.SimControl
|
</plugin_config>
|
||||||
<width>248</width>
|
<width>541</width>
|
||||||
<z>1</z>
|
<z>0</z>
|
||||||
<height>200</height>
|
<height>448</height>
|
||||||
<location_x>0</location_x>
|
<location_x>299</location_x>
|
||||||
<location_y>0</location_y>
|
<location_y>7</location_y>
|
||||||
<minimized>false</minimized>
|
</plugin>
|
||||||
</plugin>
|
<plugin>
|
||||||
<plugin>
|
se.sics.cooja.plugins.SimControl
|
||||||
se.sics.cooja.plugins.ScriptRunner
|
<width>280</width>
|
||||||
<plugin_config>
|
<z>2</z>
|
||||||
<script>TIMEOUT(2000, log.log("last message: " + msg + "\n"));
|
<height>160</height>
|
||||||
|
<location_x>7</location_x>
|
||||||
WAIT_UNTIL(msg.equals('Hello, world'));
|
<location_y>10</location_y>
|
||||||
log.testOK();</script>
|
</plugin>
|
||||||
<active>true</active>
|
<plugin>
|
||||||
</plugin_config>
|
se.sics.cooja.plugins.LogListener
|
||||||
<width>541</width>
|
<plugin_config>
|
||||||
<z>0</z>
|
<filter />
|
||||||
<height>448</height>
|
</plugin_config>
|
||||||
<location_x>248</location_x>
|
<width>680</width>
|
||||||
<location_y>-1</location_y>
|
<z>1</z>
|
||||||
<minimized>false</minimized>
|
<height>240</height>
|
||||||
</plugin>
|
<location_x>51</location_x>
|
||||||
</simconf>
|
<location_y>288</location_y>
|
||||||
|
</plugin>
|
||||||
|
</simconf>
|
||||||
|
|
||||||
|
|
84
tools/cooja/contiki_tests/wismote_helloworld.csc
Normal file
84
tools/cooja/contiki_tests/wismote_helloworld.csc
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<simconf>
|
||||||
|
<simulation>
|
||||||
|
<title>Hello World (Wismote)</title>
|
||||||
|
<randomseed>generated</randomseed>
|
||||||
|
<motedelay_us>1000000</motedelay_us>
|
||||||
|
<radiomedium>
|
||||||
|
se.sics.cooja.radiomediums.UDGM
|
||||||
|
<transmitting_range>50.0</transmitting_range>
|
||||||
|
<interference_range>100.0</interference_range>
|
||||||
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
|
</radiomedium>
|
||||||
|
<events>
|
||||||
|
<logoutput>40000</logoutput>
|
||||||
|
</events>
|
||||||
|
<motetype>
|
||||||
|
se.sics.cooja.mspmote.WismoteMoteType
|
||||||
|
<identifier>wismote1</identifier>
|
||||||
|
<description>Wismote Mote Type #wismote1</description>
|
||||||
|
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||||
|
<commands EXPORT="discard">make hello-world.wismote TARGET=wismote</commands>
|
||||||
|
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.wismote</firmware>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspButton</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspLED</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||||
|
</motetype>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
se.sics.cooja.interfaces.Position
|
||||||
|
<x>36.76551518369201</x>
|
||||||
|
<y>29.330591009779383</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>1</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>wismote1</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
</simulation>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.SimControl
|
||||||
|
<width>280</width>
|
||||||
|
<z>2</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>22</location_x>
|
||||||
|
<location_y>14</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.LogListener
|
||||||
|
<plugin_config>
|
||||||
|
<filter />
|
||||||
|
</plugin_config>
|
||||||
|
<width>680</width>
|
||||||
|
<z>1</z>
|
||||||
|
<height>240</height>
|
||||||
|
<location_x>84</location_x>
|
||||||
|
<location_y>408</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.ScriptRunner
|
||||||
|
<plugin_config>
|
||||||
|
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||||
|
<active>true</active>
|
||||||
|
</plugin_config>
|
||||||
|
<width>600</width>
|
||||||
|
<z>0</z>
|
||||||
|
<height>548</height>
|
||||||
|
<location_x>335</location_x>
|
||||||
|
<location_y>22</location_y>
|
||||||
|
</plugin>
|
||||||
|
</simconf>
|
||||||
|
|
83
tools/cooja/contiki_tests/z1_helloworld.csc
Normal file
83
tools/cooja/contiki_tests/z1_helloworld.csc
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<simconf>
|
||||||
|
<simulation>
|
||||||
|
<title>Hello World (Z1)</title>
|
||||||
|
<randomseed>generated</randomseed>
|
||||||
|
<motedelay_us>1000000</motedelay_us>
|
||||||
|
<radiomedium>
|
||||||
|
se.sics.cooja.radiomediums.UDGM
|
||||||
|
<transmitting_range>50.0</transmitting_range>
|
||||||
|
<interference_range>100.0</interference_range>
|
||||||
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
|
</radiomedium>
|
||||||
|
<events>
|
||||||
|
<logoutput>40000</logoutput>
|
||||||
|
</events>
|
||||||
|
<motetype>
|
||||||
|
se.sics.cooja.mspmote.Z1MoteType
|
||||||
|
<identifier>z11</identifier>
|
||||||
|
<description>Z1 Mote Type #z11</description>
|
||||||
|
<source EXPORT="discard">[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
|
||||||
|
<commands EXPORT="discard">make hello-world.z1 TARGET=z1</commands>
|
||||||
|
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/hello-world/hello-world.z1</firmware>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspLED</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||||
|
</motetype>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
se.sics.cooja.interfaces.Position
|
||||||
|
<x>94.96401380574989</x>
|
||||||
|
<y>21.247662337471553</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>1</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>z11</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
</simulation>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.SimControl
|
||||||
|
<width>280</width>
|
||||||
|
<z>2</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>38</location_x>
|
||||||
|
<location_y>13</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.LogListener
|
||||||
|
<plugin_config>
|
||||||
|
<filter />
|
||||||
|
</plugin_config>
|
||||||
|
<width>680</width>
|
||||||
|
<z>1</z>
|
||||||
|
<height>240</height>
|
||||||
|
<location_x>109</location_x>
|
||||||
|
<location_y>377</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.ScriptRunner
|
||||||
|
<plugin_config>
|
||||||
|
<scriptfile>[CONFIG_DIR]/hello-world.js</scriptfile>
|
||||||
|
<active>true</active>
|
||||||
|
</plugin_config>
|
||||||
|
<width>600</width>
|
||||||
|
<z>0</z>
|
||||||
|
<height>700</height>
|
||||||
|
<location_x>330</location_x>
|
||||||
|
<location_y>24</location_y>
|
||||||
|
</plugin>
|
||||||
|
</simconf>
|
||||||
|
|
|
@ -39,6 +39,7 @@ import java.awt.Dimension;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.GraphicsDevice;
|
import java.awt.GraphicsDevice;
|
||||||
import java.awt.GraphicsEnvironment;
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.GridLayout;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
|
@ -296,12 +297,12 @@ public class GUI extends Observable {
|
||||||
|
|
||||||
protected GUIEventHandler guiEventHandler = new GUIEventHandler();
|
protected GUIEventHandler guiEventHandler = new GUIEventHandler();
|
||||||
|
|
||||||
private JMenu toolsMenu, menuMoteTypeClasses, menuMoteTypes;
|
private JMenu menuMoteTypeClasses, menuMoteTypes;
|
||||||
|
|
||||||
private JMenu menuOpenSimulation;
|
private JMenu menuOpenSimulation;
|
||||||
private boolean hasFileHistoryChanged;
|
private boolean hasFileHistoryChanged;
|
||||||
|
|
||||||
private Vector<Class<? extends Plugin>> menuMotePluginClasses;
|
private Vector<Class<? extends Plugin>> menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
|
||||||
|
|
||||||
private JDesktopPane myDesktopPane;
|
private JDesktopPane myDesktopPane;
|
||||||
|
|
||||||
|
@ -369,17 +370,6 @@ public class GUI extends Observable {
|
||||||
myGUI = this;
|
myGUI = this;
|
||||||
mySimulation = null;
|
mySimulation = null;
|
||||||
myDesktopPane = desktop;
|
myDesktopPane = desktop;
|
||||||
if (toolsMenu == null) {
|
|
||||||
toolsMenu = new JMenu("Tools");
|
|
||||||
toolsMenu.removeAll();
|
|
||||||
|
|
||||||
/* COOJA/GUI plugins at top, simulation plugins in middle, mote plugins at bottom */
|
|
||||||
/*toolsMenu.addSeparator();
|
|
||||||
toolsMenu.addSeparator();*/
|
|
||||||
}
|
|
||||||
if (menuMotePluginClasses == null) {
|
|
||||||
menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Help panel */
|
/* Help panel */
|
||||||
quickHelpTextPane = new JTextPane();
|
quickHelpTextPane = new JTextPane();
|
||||||
|
@ -703,7 +693,7 @@ public class GUI extends Observable {
|
||||||
JMenu fileMenu = new JMenu("File");
|
JMenu fileMenu = new JMenu("File");
|
||||||
JMenu simulationMenu = new JMenu("Simulation");
|
JMenu simulationMenu = new JMenu("Simulation");
|
||||||
JMenu motesMenu = new JMenu("Motes");
|
JMenu motesMenu = new JMenu("Motes");
|
||||||
/* toolsMenu = new JMenu("Tools"); */
|
final JMenu toolsMenu = new JMenu("Tools");
|
||||||
JMenu settingsMenu = new JMenu("Settings");
|
JMenu settingsMenu = new JMenu("Settings");
|
||||||
JMenu helpMenu = new JMenu("Help");
|
JMenu helpMenu = new JMenu("Help");
|
||||||
|
|
||||||
|
@ -931,56 +921,118 @@ public class GUI extends Observable {
|
||||||
|
|
||||||
motesMenu.add(new JMenuItem(removeAllMotesAction));
|
motesMenu.add(new JMenuItem(removeAllMotesAction));
|
||||||
|
|
||||||
// Tools menu
|
/* Tools menu */
|
||||||
toolsMenu.addMenuListener(new MenuListener() {
|
toolsMenu.addMenuListener(new MenuListener() {
|
||||||
public void menuSelected(MenuEvent e) {
|
private ActionListener menuItemListener = new ActionListener() {
|
||||||
for (Component menuComponent: toolsMenu.getMenuComponents()) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
if (!(menuComponent instanceof JMenuItem)) {
|
Object pluginClass = ((JMenuItem)e.getSource()).getClientProperty("class");
|
||||||
continue;
|
Object mote = ((JMenuItem)e.getSource()).getClientProperty("mote");
|
||||||
}
|
tryStartPlugin((Class<? extends Plugin>) pluginClass, myGUI, getSimulation(), (Mote)mote);
|
||||||
JMenuItem menuItem = (JMenuItem) menuComponent;
|
}
|
||||||
Class<? extends Plugin> pluginClass = (Class<? extends Plugin>) menuItem.getClientProperty("class");
|
};
|
||||||
int pluginType;
|
private JMenuItem createMenuItem(Class<? extends Plugin> newPluginClass, int pluginType) {
|
||||||
if (pluginClass.isAnnotationPresent(PluginType.class)) {
|
String description = getDescriptionOf(newPluginClass);
|
||||||
pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
JMenuItem menuItem = new JMenuItem(description + "...");
|
||||||
} else {
|
menuItem.putClientProperty("class", newPluginClass);
|
||||||
pluginType = PluginType.UNDEFINED_PLUGIN;
|
menuItem.addActionListener(menuItemListener);
|
||||||
}
|
|
||||||
|
|
||||||
/* No simulation -> deactivate non-GUI plugins */
|
String tooltip = "<html><pre>";
|
||||||
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
||||||
menuItem.setEnabled(true);
|
tooltip += "Cooja plugin: ";
|
||||||
continue;
|
} else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||||
}
|
tooltip += "Simulation plugin: ";
|
||||||
/* Mote plugin -> not accessed from this menu */
|
|
||||||
if (pluginType == PluginType.MOTE_PLUGIN) {
|
|
||||||
menuItem.setEnabled(false);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (pluginType != PluginType.SIM_PLUGIN && pluginType != PluginType.SIM_STANDARD_PLUGIN) {
|
|
||||||
/* Unknown */
|
|
||||||
menuItem.setEnabled(false);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (getSimulation() == null) {
|
if (getSimulation() == null) {
|
||||||
menuItem.setEnabled(false);
|
menuItem.setEnabled(false);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
} else if (pluginType == PluginType.MOTE_PLUGIN) {
|
||||||
|
tooltip += "Mote plugin: ";
|
||||||
|
}
|
||||||
|
tooltip += description + " (" + newPluginClass.getName() + ")";
|
||||||
|
|
||||||
/* Check if simulation plugin depends on any particular radio medium */
|
/* Check if simulation plugin depends on any particular radio medium */
|
||||||
if (pluginClass.getAnnotation(SupportedArguments.class) != null) {
|
if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||||
menuItem.setEnabled(false);
|
if (newPluginClass.getAnnotation(SupportedArguments.class) != null) {
|
||||||
Class<? extends RadioMedium>[] radioMediums = pluginClass.getAnnotation(SupportedArguments.class).radioMediums();
|
boolean active = false;
|
||||||
|
Class<? extends RadioMedium>[] radioMediums = newPluginClass.getAnnotation(SupportedArguments.class).radioMediums();
|
||||||
for (Class<? extends Object> o: radioMediums) {
|
for (Class<? extends Object> o: radioMediums) {
|
||||||
if (o.isAssignableFrom(getSimulation().getRadioMedium().getClass())) {
|
if (o.isAssignableFrom(getSimulation().getRadioMedium().getClass())) {
|
||||||
menuItem.setEnabled(true);
|
active = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if (!active) {
|
||||||
menuItem.setEnabled(true);
|
menuItem.setVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if plugin was imported by a extension directory */
|
||||||
|
File project =
|
||||||
|
getProjectConfig().getUserProjectDefining(GUI.class, "PLUGINS", newPluginClass.getName());
|
||||||
|
if (project != null) {
|
||||||
|
tooltip += "\nLoaded by extension: " + project.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip += "</html>";
|
||||||
|
/*menuItem.setToolTipText(tooltip);*/
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void menuSelected(MenuEvent e) {
|
||||||
|
/* Populate tools menu */
|
||||||
|
toolsMenu.removeAll();
|
||||||
|
|
||||||
|
/* Cooja plugins */
|
||||||
|
boolean hasCoojaPlugins = false;
|
||||||
|
for (Class<? extends Plugin> pluginClass: pluginClasses) {
|
||||||
|
int pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||||
|
if (pluginType != PluginType.COOJA_PLUGIN && pluginType != PluginType.COOJA_STANDARD_PLUGIN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
toolsMenu.add(createMenuItem(pluginClass, pluginType));
|
||||||
|
hasCoojaPlugins = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simulation plugins */
|
||||||
|
boolean hasSimPlugins = false;
|
||||||
|
for (Class<? extends Plugin> pluginClass: pluginClasses) {
|
||||||
|
if (pluginClass.equals(SimControl.class)) {
|
||||||
|
continue; /* ignore */
|
||||||
|
}
|
||||||
|
if (pluginClass.equals(SimInformation.class)) {
|
||||||
|
continue; /* ignore */
|
||||||
|
}
|
||||||
|
if (pluginClass.equals(MoteTypeInformation.class)) {
|
||||||
|
continue; /* ignore */
|
||||||
|
}
|
||||||
|
|
||||||
|
int pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||||
|
if (pluginType != PluginType.SIM_PLUGIN && pluginType != PluginType.SIM_STANDARD_PLUGIN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCoojaPlugins) {
|
||||||
|
hasCoojaPlugins = false;
|
||||||
|
toolsMenu.addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
toolsMenu.add(createMenuItem(pluginClass, pluginType));
|
||||||
|
hasSimPlugins = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Class<? extends Plugin> pluginClass: pluginClasses) {
|
||||||
|
int pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||||
|
if (pluginType != PluginType.MOTE_PLUGIN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasSimPlugins) {
|
||||||
|
hasSimPlugins = false;
|
||||||
|
toolsMenu.addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
toolsMenu.add(createMotePluginsSubmenu(pluginClass));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public void menuDeselected(MenuEvent e) {
|
public void menuDeselected(MenuEvent e) {
|
||||||
}
|
}
|
||||||
|
@ -1051,10 +1103,6 @@ public class GUI extends Observable {
|
||||||
menuItem.setEnabled(false);
|
menuItem.setEnabled(false);
|
||||||
helpMenu.add(menuItem);
|
helpMenu.add(menuItem);
|
||||||
|
|
||||||
// Mote plugins popup menu (not available via menu bar)
|
|
||||||
if (menuMotePluginClasses == null) {
|
|
||||||
menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
|
|
||||||
}
|
|
||||||
return menuBar;
|
return menuBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,9 +1552,9 @@ public class GUI extends Observable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register plugins
|
// Register plugins
|
||||||
registerPlugin(SimControl.class, false); // Not in menu
|
registerPlugin(SimControl.class);
|
||||||
registerPlugin(SimInformation.class, false); // Not in menu
|
registerPlugin(SimInformation.class);
|
||||||
registerPlugin(MoteTypeInformation.class, false); // Not in menu
|
registerPlugin(MoteTypeInformation.class);
|
||||||
String[] pluginClassNames = projectConfig.getStringArrayValue(GUI.class,
|
String[] pluginClassNames = projectConfig.getStringArrayValue(GUI.class,
|
||||||
"PLUGINS");
|
"PLUGINS");
|
||||||
if (pluginClassNames != null) {
|
if (pluginClassNames != null) {
|
||||||
|
@ -1816,155 +1864,54 @@ public class GUI extends Observable {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a plugin to be included in the GUI. The plugin will be visible in
|
|
||||||
* the menubar.
|
|
||||||
*
|
|
||||||
* @param newPluginClass
|
|
||||||
* New plugin to register
|
|
||||||
* @return True if this plugin was registered ok, false otherwise
|
|
||||||
*/
|
|
||||||
public boolean registerPlugin(Class<? extends Plugin> newPluginClass) {
|
|
||||||
return registerPlugin(newPluginClass, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregister a plugin class. Removes any plugin menu items links as well.
|
* Unregister a plugin class. Removes any plugin menu items links as well.
|
||||||
*
|
*
|
||||||
* @param pluginClass Plugin class
|
* @param pluginClass Plugin class
|
||||||
*/
|
*/
|
||||||
public void unregisterPlugin(Class<? extends Plugin> pluginClass) {
|
public void unregisterPlugin(Class<? extends Plugin> pluginClass) {
|
||||||
/* Remove from menu */
|
|
||||||
for (Component menuComponent : toolsMenu.getMenuComponents()) {
|
|
||||||
if (!(menuComponent instanceof JMenuItem)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
JMenuItem menuItem = (JMenuItem) menuComponent;
|
|
||||||
if (menuItem.getClientProperty("class").equals(pluginClass)) {
|
|
||||||
toolsMenu.remove(menuItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menuMotePluginClasses.remove(pluginClass);
|
|
||||||
pluginClasses.remove(pluginClass);
|
pluginClasses.remove(pluginClass);
|
||||||
|
menuMotePluginClasses.remove(pluginClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a plugin to be included in the GUI.
|
* Register a plugin to be included in the GUI.
|
||||||
*
|
*
|
||||||
* @param newPluginClass
|
* @param pluginClass New plugin to register
|
||||||
* New plugin to register
|
|
||||||
* @param addToMenu
|
|
||||||
* Should this plugin be added to the dedicated plugins menubar?
|
|
||||||
* @return True if this plugin was registered ok, false otherwise
|
* @return True if this plugin was registered ok, false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean registerPlugin(final Class<? extends Plugin> newPluginClass,
|
public boolean registerPlugin(final Class<? extends Plugin> pluginClass) {
|
||||||
boolean addToMenu) {
|
|
||||||
|
|
||||||
// Get description annotation (if any)
|
/* Check plugin type */
|
||||||
final String description = getDescriptionOf(newPluginClass);
|
|
||||||
|
|
||||||
// Get plugin type annotation (required)
|
|
||||||
final int pluginType;
|
final int pluginType;
|
||||||
if (newPluginClass.isAnnotationPresent(PluginType.class)) {
|
if (pluginClass.isAnnotationPresent(PluginType.class)) {
|
||||||
pluginType = newPluginClass.getAnnotation(PluginType.class).value();
|
pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||||
} else {
|
} else {
|
||||||
pluginType = PluginType.UNDEFINED_PLUGIN;
|
logger.fatal("Could not register plugin, no plugin type found: " + pluginClass);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that plugin type is valid and constructor exists
|
/* Check plugin constructor */
|
||||||
try {
|
try {
|
||||||
if (pluginType == PluginType.MOTE_PLUGIN) {
|
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
||||||
newPluginClass.getConstructor(new Class[] { Mote.class,
|
pluginClass.getConstructor(new Class[] { GUI.class });
|
||||||
Simulation.class, GUI.class });
|
} else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||||
} else if (pluginType == PluginType.SIM_PLUGIN
|
pluginClass.getConstructor(new Class[] { Simulation.class, GUI.class });
|
||||||
|| pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
} else if (pluginType == PluginType.MOTE_PLUGIN) {
|
||||||
newPluginClass.getConstructor(new Class[] { Simulation.class, GUI.class });
|
pluginClass.getConstructor(new Class[] { Mote.class, Simulation.class, GUI.class });
|
||||||
} else if (pluginType == PluginType.COOJA_PLUGIN
|
menuMotePluginClasses.add(pluginClass);
|
||||||
|| pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
|
||||||
newPluginClass.getConstructor(new Class[] { GUI.class });
|
|
||||||
} else {
|
} else {
|
||||||
logger.fatal("Could not find valid plugin type annotation in class " + newPluginClass);
|
logger.fatal("Could not register plugin, bad plugin type: " + pluginType);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
pluginClasses.add(pluginClass);
|
||||||
} catch (NoClassDefFoundError e) {
|
} catch (NoClassDefFoundError e) {
|
||||||
logger.fatal("No plugin class: " + newPluginClass + ": " + e.getMessage());
|
logger.fatal("No plugin class: " + pluginClass + ": " + e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
logger.fatal("No plugin class constructor: " + newPluginClass + ": " + e.getMessage());
|
logger.fatal("No plugin class constructor: " + pluginClass + ": " + e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addToMenu && toolsMenu != null) {
|
|
||||||
new RunnableInEDT<Boolean>() {
|
|
||||||
public Boolean work() {
|
|
||||||
// Create 'start plugin'-menu item
|
|
||||||
JMenuItem menuItem;
|
|
||||||
String tooltip = "<html><pre>";
|
|
||||||
|
|
||||||
/* Sort menu according to plugin type */
|
|
||||||
int itemIndex=0;
|
|
||||||
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
|
||||||
for (; itemIndex < toolsMenu.getItemCount(); itemIndex++) {
|
|
||||||
if (toolsMenu.getItem(itemIndex) == null /* separator */) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tooltip += "Cooja plugin: " + newPluginClass.getName();
|
|
||||||
menuItem = new JMenuItem(description);
|
|
||||||
menuItem.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
tryStartPlugin(newPluginClass, myGUI, null, null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
|
||||||
for (; itemIndex < toolsMenu.getItemCount(); itemIndex++) {
|
|
||||||
if (toolsMenu.getItem(itemIndex) == null /* separator */) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
itemIndex++;
|
|
||||||
for (; itemIndex < toolsMenu.getItemCount(); itemIndex++) {
|
|
||||||
if (toolsMenu.getItem(itemIndex) == null /* separator */) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tooltip += "Simulation plugin: " + newPluginClass.getName();
|
|
||||||
GUIAction guiAction = new StartPluginGUIAction(description);
|
|
||||||
menuItem = new JMenuItem(guiAction);
|
|
||||||
guiActions.add(guiAction);
|
|
||||||
} else if (pluginType == PluginType.MOTE_PLUGIN) {
|
|
||||||
// Disable previous menu item and add new item to mote plugins menu
|
|
||||||
menuItem = new JMenuItem(description);
|
|
||||||
menuItem.setEnabled(false);
|
|
||||||
tooltip += "Mote plugin: " + newPluginClass.getName();
|
|
||||||
tooltip += "\nStart mote plugins by right-clicking a mote in the simulation visualizer";
|
|
||||||
menuMotePluginClasses.add(newPluginClass);
|
|
||||||
itemIndex = toolsMenu.getItemCount();
|
|
||||||
} else {
|
|
||||||
logger.warn("Unknown plugin type: " + pluginType);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if plugin was imported by a extension directory */
|
|
||||||
File project =
|
|
||||||
getProjectConfig().getUserProjectDefining(GUI.class, "PLUGINS", newPluginClass.getName());
|
|
||||||
if (project != null) {
|
|
||||||
tooltip += "\nLoaded by extension: " + project.getPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltip += "</html>";
|
|
||||||
/*menuItem.setToolTipText(tooltip); */
|
|
||||||
menuItem.putClientProperty("class", newPluginClass);
|
|
||||||
|
|
||||||
toolsMenu.add(menuItem, itemIndex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}.invokeAndWait();
|
|
||||||
}
|
|
||||||
|
|
||||||
pluginClasses.add(newPluginClass);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1972,16 +1919,7 @@ public class GUI extends Observable {
|
||||||
* Unregister all plugin classes
|
* Unregister all plugin classes
|
||||||
*/
|
*/
|
||||||
public void unregisterPlugins() {
|
public void unregisterPlugins() {
|
||||||
if (toolsMenu != null) {
|
menuMotePluginClasses.clear();
|
||||||
toolsMenu.removeAll();
|
|
||||||
|
|
||||||
/* COOJA/GUI plugins at top, simulation plugins in middle, mote plugins at bottom */
|
|
||||||
toolsMenu.addSeparator();
|
|
||||||
toolsMenu.addSeparator();
|
|
||||||
}
|
|
||||||
if (menuMotePluginClasses != null) {
|
|
||||||
menuMotePluginClasses.clear();
|
|
||||||
}
|
|
||||||
pluginClasses.clear();
|
pluginClasses.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2016,6 +1954,107 @@ public class GUI extends Observable {
|
||||||
return startedPlugins.toArray(new Plugin[0]);
|
return startedPlugins.toArray(new Plugin[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isMotePluginCompatible(Class<? extends Plugin> motePluginClass, Mote mote) {
|
||||||
|
if (motePluginClass.getAnnotation(SupportedArguments.class) == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check mote interfaces */
|
||||||
|
boolean moteInterfacesOK = true;
|
||||||
|
Class<? extends MoteInterface>[] moteInterfaces =
|
||||||
|
motePluginClass.getAnnotation(SupportedArguments.class).moteInterfaces();
|
||||||
|
StringBuilder moteTypeInterfacesError = new StringBuilder();
|
||||||
|
moteTypeInterfacesError.append(
|
||||||
|
"The plugin:\n" +
|
||||||
|
getDescriptionOf(motePluginClass) +
|
||||||
|
"\nrequires the following mote interfaces:\n"
|
||||||
|
);
|
||||||
|
for (Class<? extends MoteInterface> requiredMoteInterface: moteInterfaces) {
|
||||||
|
moteTypeInterfacesError.append(getDescriptionOf(requiredMoteInterface) + "\n");
|
||||||
|
if (mote.getInterfaces().getInterfaceOfType(requiredMoteInterface) == null) {
|
||||||
|
moteInterfacesOK = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check mote type */
|
||||||
|
boolean moteTypeOK = false;
|
||||||
|
Class<? extends Mote>[] motes =
|
||||||
|
motePluginClass.getAnnotation(SupportedArguments.class).motes();
|
||||||
|
StringBuilder moteTypeError = new StringBuilder();
|
||||||
|
moteTypeError.append(
|
||||||
|
"The plugin:\n" +
|
||||||
|
getDescriptionOf(motePluginClass) +
|
||||||
|
"\ndoes not support motes of type:\n" +
|
||||||
|
getDescriptionOf(mote) +
|
||||||
|
"\n\nIt only supports motes of types:\n"
|
||||||
|
);
|
||||||
|
for (Class<? extends Mote> supportedMote: motes) {
|
||||||
|
moteTypeError.append(getDescriptionOf(supportedMote) + "\n");
|
||||||
|
if (supportedMote.isAssignableFrom(mote.getClass())) {
|
||||||
|
moteTypeOK = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (!moteInterfacesOK) {
|
||||||
|
menuItem.setToolTipText(
|
||||||
|
"<html><pre>" + moteTypeInterfacesError + "</html>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!moteTypeOK) {
|
||||||
|
menuItem.setToolTipText(
|
||||||
|
"<html><pre>" + moteTypeError + "</html>"
|
||||||
|
);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return moteInterfacesOK && moteTypeOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JMenu createMotePluginsSubmenu(Class<? extends Plugin> pluginClass) {
|
||||||
|
JMenu menu = new JMenu(getDescriptionOf(pluginClass));
|
||||||
|
if (getSimulation() == null || getSimulation().getMotesCount() == 0) {
|
||||||
|
menu.setEnabled(false);
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionListener menuItemListener = new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
Object pluginClass = ((JMenuItem)e.getSource()).getClientProperty("class");
|
||||||
|
Object mote = ((JMenuItem)e.getSource()).getClientProperty("mote");
|
||||||
|
tryStartPlugin((Class<? extends Plugin>) pluginClass, myGUI, getSimulation(), (Mote)mote);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final int MAX_PER_ROW = 30;
|
||||||
|
final int MAX_COLUMNS = 5;
|
||||||
|
|
||||||
|
int added = 0;
|
||||||
|
for (Mote mote: getSimulation().getMotes()) {
|
||||||
|
if (!isMotePluginCompatible(pluginClass, mote)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
JMenuItem menuItem = new JMenuItem(mote.toString() + "...");
|
||||||
|
menuItem.putClientProperty("class", pluginClass);
|
||||||
|
menuItem.putClientProperty("mote", mote);
|
||||||
|
menuItem.addActionListener(menuItemListener);
|
||||||
|
|
||||||
|
menu.add(menuItem);
|
||||||
|
added++;
|
||||||
|
|
||||||
|
if (added == MAX_PER_ROW) {
|
||||||
|
menu.getPopupMenu().setLayout(new GridLayout(MAX_PER_ROW, MAX_COLUMNS));
|
||||||
|
}
|
||||||
|
if (added >= MAX_PER_ROW*MAX_COLUMNS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (added == 0) {
|
||||||
|
menu.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a mote plugins submenu for given mote.
|
* Return a mote plugins submenu for given mote.
|
||||||
*
|
*
|
||||||
|
@ -2026,38 +2065,15 @@ public class GUI extends Observable {
|
||||||
JMenu menuMotePlugins = new JMenu("Mote tools for " + mote);
|
JMenu menuMotePlugins = new JMenu("Mote tools for " + mote);
|
||||||
|
|
||||||
for (Class<? extends Plugin> motePluginClass: menuMotePluginClasses) {
|
for (Class<? extends Plugin> motePluginClass: menuMotePluginClasses) {
|
||||||
GUIAction guiAction = new StartPluginGUIAction(getDescriptionOf(motePluginClass));
|
if (!isMotePluginCompatible(motePluginClass, mote)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUIAction guiAction = new StartPluginGUIAction(getDescriptionOf(motePluginClass) + "...");
|
||||||
JMenuItem menuItem = new JMenuItem(guiAction);
|
JMenuItem menuItem = new JMenuItem(guiAction);
|
||||||
menuItem.putClientProperty("class", motePluginClass);
|
menuItem.putClientProperty("class", motePluginClass);
|
||||||
menuItem.putClientProperty("mote", mote);
|
menuItem.putClientProperty("mote", mote);
|
||||||
|
|
||||||
/* Check if mote plugin depends on any particular type of mote */
|
|
||||||
boolean enableMenuItem = true;
|
|
||||||
if (motePluginClass.getAnnotation(SupportedArguments.class) != null) {
|
|
||||||
enableMenuItem = false;
|
|
||||||
Class<? extends Mote>[] motes = motePluginClass.getAnnotation(SupportedArguments.class).motes();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(
|
|
||||||
"<html><pre>This plugin:\n" +
|
|
||||||
motePluginClass.getName() +
|
|
||||||
"\ndoes not support motes of type:\n" +
|
|
||||||
mote.getClass().getName() +
|
|
||||||
"\n\nIt only supports motes of types:\n"
|
|
||||||
);
|
|
||||||
for (Class<? extends Object> o: motes) {
|
|
||||||
sb.append(o.getName() + "\n");
|
|
||||||
if (o.isAssignableFrom(mote.getClass())) {
|
|
||||||
enableMenuItem = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.append("</html>");
|
|
||||||
if (!enableMenuItem) {
|
|
||||||
menuItem.setToolTipText(sb.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menuItem.setEnabled(enableMenuItem);
|
|
||||||
menuMotePlugins.add(menuItem);
|
menuMotePlugins.add(menuItem);
|
||||||
}
|
}
|
||||||
return menuMotePlugins;
|
return menuMotePlugins;
|
||||||
|
@ -2607,6 +2623,7 @@ public class GUI extends Observable {
|
||||||
mySimulation.addMote(newMote);
|
mySimulation.addMote(newMote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateGUIComponentState();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logger.warn("No simulation active");
|
logger.warn("No simulation active");
|
||||||
|
@ -4503,8 +4520,8 @@ public class GUI extends Observable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class StartPluginGUIAction extends GUIAction {
|
class StartPluginGUIAction extends GUIAction {
|
||||||
private static final long serialVersionUID = 7368495576372376196L;
|
private static final long serialVersionUID = 7368495576372376196L;
|
||||||
public StartPluginGUIAction(String name) {
|
public StartPluginGUIAction(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
public void actionPerformed(final ActionEvent e) {
|
public void actionPerformed(final ActionEvent e) {
|
||||||
|
@ -4521,6 +4538,7 @@ public class GUI extends Observable {
|
||||||
return getSimulation() != null;
|
return getSimulation() != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIAction removeAllMotesAction = new GUIAction("Remove all motes") {
|
GUIAction removeAllMotesAction = new GUIAction("Remove all motes") {
|
||||||
private static final long serialVersionUID = 4709776747913364419L;
|
private static final long serialVersionUID = 4709776747913364419L;
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
|
@ -61,4 +61,9 @@ public @interface SupportedArguments {
|
||||||
* @return List of accepted radio medium classes.
|
* @return List of accepted radio medium classes.
|
||||||
*/
|
*/
|
||||||
Class<? extends RadioMedium>[] radioMediums() default { RadioMedium.class };
|
Class<? extends RadioMedium>[] radioMediums() default { RadioMedium.class };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return List of required mote interfaces.
|
||||||
|
*/
|
||||||
|
Class<? extends MoteInterface>[] moteInterfaces() default { MoteInterface.class };
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,19 +25,20 @@
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
|
||||||
* $Id: ContikiClock.java,v 1.13 2010/02/05 08:49:18 fros4943 Exp $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.contikimote.interfaces;
|
package se.sics.cooja.contikimote.interfaces;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
import se.sics.cooja.Mote;
|
||||||
|
import se.sics.cooja.SectionMoteMemory;
|
||||||
|
import se.sics.cooja.Simulation;
|
||||||
import se.sics.cooja.contikimote.ContikiMote;
|
import se.sics.cooja.contikimote.ContikiMote;
|
||||||
import se.sics.cooja.contikimote.ContikiMoteInterface;
|
import se.sics.cooja.contikimote.ContikiMoteInterface;
|
||||||
import se.sics.cooja.interfaces.Clock;
|
import se.sics.cooja.interfaces.Clock;
|
||||||
|
@ -74,7 +75,7 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB
|
||||||
|
|
||||||
private long moteTime; /* Microseconds */
|
private long moteTime; /* Microseconds */
|
||||||
private long timeDrift; /* Microseconds */
|
private long timeDrift; /* Microseconds */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mote Mote
|
* @param mote Mote
|
||||||
*
|
*
|
||||||
|
@ -117,9 +118,9 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB
|
||||||
/* Update time */
|
/* Update time */
|
||||||
setTime(mote.getSimulation().getSimulationTime() + timeDrift);
|
setTime(mote.getSimulation().getSimulationTime() + timeDrift);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doActionsAfterTick() {
|
public void doActionsAfterTick() {
|
||||||
|
|
||||||
/* Request next tick for remaining events / timers */
|
/* Request next tick for remaining events / timers */
|
||||||
int processRunValue = moteMem.getIntValueOf("simProcessRunValue");
|
int processRunValue = moteMem.getIntValueOf("simProcessRunValue");
|
||||||
if (processRunValue != 0) {
|
if (processRunValue != 0) {
|
||||||
|
@ -137,12 +138,12 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB
|
||||||
/* Request tick next wakeup time */
|
/* Request tick next wakeup time */
|
||||||
int nextExpirationTime = moteMem.getIntValueOf("simNextExpirationTime");
|
int nextExpirationTime = moteMem.getIntValueOf("simNextExpirationTime");
|
||||||
if (nextExpirationTime <= 0) {
|
if (nextExpirationTime <= 0) {
|
||||||
logger.warn("Event timer already expired, but has been delayed: " + nextExpirationTime);
|
/*logger.warn("Event timer already expired, but has been delayed: " + nextExpirationTime);*/
|
||||||
mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND);
|
mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND*(long)nextExpirationTime);
|
mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND*nextExpirationTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
|
||||||
* $Id: ScriptRunner.java,v 1.28 2010/08/17 15:03:52 fros4943 Exp $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins;
|
package se.sics.cooja.plugins;
|
||||||
|
@ -71,6 +69,8 @@ import javax.swing.JPopupMenu;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JSplitPane;
|
import javax.swing.JSplitPane;
|
||||||
import javax.swing.JTextArea;
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.event.MenuEvent;
|
||||||
|
import javax.swing.event.MenuListener;
|
||||||
import javax.swing.filechooser.FileFilter;
|
import javax.swing.filechooser.FileFilter;
|
||||||
|
|
||||||
import jsyntaxpane.DefaultSyntaxKit;
|
import jsyntaxpane.DefaultSyntaxKit;
|
||||||
|
@ -110,15 +110,13 @@ public class ScriptRunner extends VisPlugin {
|
||||||
};
|
};
|
||||||
|
|
||||||
private Simulation simulation;
|
private Simulation simulation;
|
||||||
|
private LogScriptEngine engine;
|
||||||
private LogScriptEngine engine = null;
|
|
||||||
|
|
||||||
private static BufferedWriter logWriter = null; /* For non-GUI tests */
|
private static BufferedWriter logWriter = null; /* For non-GUI tests */
|
||||||
|
|
||||||
private JEditorPane codeEditor = null;
|
private JEditorPane codeEditor;
|
||||||
|
private JTextArea logTextArea;
|
||||||
private JTextArea logTextArea = null;
|
private JSplitPane centerPanel;
|
||||||
/*private JButton toggleButton = null;*/
|
|
||||||
|
|
||||||
private JSyntaxLinkFile actionLinkFile = null;
|
private JSyntaxLinkFile actionLinkFile = null;
|
||||||
private File linkedFile = null;
|
private File linkedFile = null;
|
||||||
|
@ -126,6 +124,7 @@ public class ScriptRunner extends VisPlugin {
|
||||||
public ScriptRunner(Simulation simulation, GUI gui) {
|
public ScriptRunner(Simulation simulation, GUI gui) {
|
||||||
super("Simulation script editor", gui, false);
|
super("Simulation script editor", gui, false);
|
||||||
this.simulation = simulation;
|
this.simulation = simulation;
|
||||||
|
this.engine = null;
|
||||||
|
|
||||||
/* Menus */
|
/* Menus */
|
||||||
JMenuBar menuBar = new JMenuBar();
|
JMenuBar menuBar = new JMenuBar();
|
||||||
|
@ -139,9 +138,8 @@ public class ScriptRunner extends VisPlugin {
|
||||||
|
|
||||||
this.setJMenuBar(menuBar);
|
this.setJMenuBar(menuBar);
|
||||||
|
|
||||||
/* Examples popup menu */
|
/* Example scripts */
|
||||||
JMenu examplesMenu = new JMenu("Load example script");
|
final JMenu examplesMenu = new JMenu("Load example script");
|
||||||
|
|
||||||
for (int i=0; i < EXAMPLE_SCRIPTS.length; i += 2) {
|
for (int i=0; i < EXAMPLE_SCRIPTS.length; i += 2) {
|
||||||
final String file = EXAMPLE_SCRIPTS[i];
|
final String file = EXAMPLE_SCRIPTS[i];
|
||||||
JMenuItem exampleItem = new JMenuItem(EXAMPLE_SCRIPTS[i+1]);
|
JMenuItem exampleItem = new JMenuItem(EXAMPLE_SCRIPTS[i+1]);
|
||||||
|
@ -159,11 +157,10 @@ public class ScriptRunner extends VisPlugin {
|
||||||
});
|
});
|
||||||
examplesMenu.add(exampleItem);
|
examplesMenu.add(exampleItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
fileMenu.add(examplesMenu);
|
fileMenu.add(examplesMenu);
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Workaround to configure jsyntaxpane */
|
/* XXX Workaround to configure jsyntaxpane */
|
||||||
JEditorPane e = new JEditorPane();
|
JEditorPane e = new JEditorPane();
|
||||||
new JScrollPane(e);
|
new JScrollPane(e);
|
||||||
e.setContentType("text/javascript");
|
e.setContentType("text/javascript");
|
||||||
|
@ -171,6 +168,7 @@ public class ScriptRunner extends VisPlugin {
|
||||||
DefaultSyntaxKit kit = (DefaultSyntaxKit) e.getEditorKit();
|
DefaultSyntaxKit kit = (DefaultSyntaxKit) e.getEditorKit();
|
||||||
kit.setProperty("PopupMenu", "copy-to-clipboard,-,find,find-next,goto-line,-,linkfile");
|
kit.setProperty("PopupMenu", "copy-to-clipboard,-,find,find-next,goto-line,-,linkfile");
|
||||||
kit.setProperty("Action.linkfile", JSyntaxLinkFile.class.getName());
|
kit.setProperty("Action.linkfile", JSyntaxLinkFile.class.getName());
|
||||||
|
kit.setProperty("Action.execute-script", "jsyntaxpane.actions.ScriptRunnerAction");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,16 +181,11 @@ public class ScriptRunner extends VisPlugin {
|
||||||
logTextArea.setEditable(true);
|
logTextArea.setEditable(true);
|
||||||
logTextArea.setCursor(null);
|
logTextArea.setCursor(null);
|
||||||
|
|
||||||
/*toggleButton = new JButton("Activate");*/
|
final JCheckBoxMenuItem activateMenuItem = new JCheckBoxMenuItem("Activate");
|
||||||
JCheckBoxMenuItem activateMenuItem = new JCheckBoxMenuItem("Activate");
|
|
||||||
activateMenuItem.addActionListener(new ActionListener() {
|
activateMenuItem.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent ev) {
|
public void actionPerformed(ActionEvent ev) {
|
||||||
try {
|
try {
|
||||||
if (!isActive()) {
|
setScriptActive(!isActive());
|
||||||
setScriptActive(true);
|
|
||||||
} else {
|
|
||||||
setScriptActive(false);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.fatal("Error: " + e.getMessage(), e);
|
logger.fatal("Error: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@ -200,8 +193,7 @@ public class ScriptRunner extends VisPlugin {
|
||||||
});
|
});
|
||||||
runMenu.add(activateMenuItem);
|
runMenu.add(activateMenuItem);
|
||||||
|
|
||||||
/*JButton runTestButton = new JButton("Run without GUI");*/
|
final JMenuItem runTestMenuItem = new JMenuItem("Save simulation and run with script");
|
||||||
JMenuItem runTestMenuItem = new JMenuItem("Save simulation and run with script");
|
|
||||||
runMenu.add(runTestMenuItem);
|
runMenu.add(runTestMenuItem);
|
||||||
runTestMenuItem.addActionListener(new ActionListener() {
|
runTestMenuItem.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
@ -210,29 +202,50 @@ public class ScriptRunner extends VisPlugin {
|
||||||
});
|
});
|
||||||
|
|
||||||
doLayout();
|
doLayout();
|
||||||
JSplitPane centerPanel = new JSplitPane(
|
centerPanel = new JSplitPane(
|
||||||
JSplitPane.VERTICAL_SPLIT,
|
JSplitPane.VERTICAL_SPLIT,
|
||||||
new JScrollPane(codeEditor),
|
new JScrollPane(codeEditor),
|
||||||
new JScrollPane(logTextArea)
|
new JScrollPane(logTextArea)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
MenuListener toggleMenuItems = new MenuListener() {
|
||||||
|
public void menuSelected(MenuEvent e) {
|
||||||
|
activateMenuItem.setSelected(isActive());
|
||||||
|
runTestMenuItem.setEnabled(!isActive());
|
||||||
|
examplesMenu.setEnabled(!isActive());
|
||||||
|
}
|
||||||
|
public void menuDeselected(MenuEvent e) {
|
||||||
|
}
|
||||||
|
public void menuCanceled(MenuEvent e) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fileMenu.addMenuListener(toggleMenuItems);
|
||||||
|
editMenu.addMenuListener(toggleMenuItems);
|
||||||
|
runMenu.addMenuListener(toggleMenuItems);
|
||||||
|
|
||||||
|
|
||||||
codeEditor.setContentType("text/javascript");
|
codeEditor.setContentType("text/javascript");
|
||||||
if (codeEditor.getEditorKit() instanceof DefaultSyntaxKit) {
|
if (codeEditor.getEditorKit() instanceof DefaultSyntaxKit) {
|
||||||
DefaultSyntaxKit kit = (DefaultSyntaxKit) codeEditor.getEditorKit();
|
DefaultSyntaxKit kit = (DefaultSyntaxKit) codeEditor.getEditorKit();
|
||||||
kit.setProperty("PopupMenu", "copy-to-clipboard,-,find,find-next,goto-line,-,linkfile");
|
kit.setProperty("PopupMenu", "copy-to-clipboard,-,find,find-next,goto-line,-,linkfile");
|
||||||
kit.setProperty("Action.linkfile", JSyntaxLinkFile.class.getName());
|
kit.setProperty("Action.linkfile", JSyntaxLinkFile.class.getName());
|
||||||
|
kit.setProperty("Action.execute-script", "jsyntaxpane.actions.ScriptRunnerAction");
|
||||||
}
|
}
|
||||||
|
|
||||||
JPopupMenu p = codeEditor.getComponentPopupMenu();
|
JPopupMenu p = codeEditor.getComponentPopupMenu();
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
for (Component c: p.getComponents()) {
|
for (Component c: p.getComponents()) {
|
||||||
if (c instanceof JMenuItem) {
|
if (!(c instanceof JMenuItem)) {
|
||||||
if (((JMenuItem) c).getAction() != null &&
|
continue;
|
||||||
((JMenuItem) c).getAction() instanceof JSyntaxLinkFile) {
|
}
|
||||||
actionLinkFile = (JSyntaxLinkFile)(((JMenuItem) c).getAction());
|
if (((JMenuItem) c).getAction() == null) {
|
||||||
actionLinkFile.setMenuText("Link script to disk file");
|
continue;
|
||||||
actionLinkFile.putValue("ScriptRunner", this);
|
}
|
||||||
}
|
Action a = ((JMenuItem) c).getAction();
|
||||||
|
if (a instanceof JSyntaxLinkFile) {
|
||||||
|
actionLinkFile = (JSyntaxLinkFile) a;
|
||||||
|
actionLinkFile.setMenuText("Link script to disk file");
|
||||||
|
actionLinkFile.putValue("ScriptRunner", this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,10 +254,6 @@ public class ScriptRunner extends VisPlugin {
|
||||||
centerPanel.setResizeWeight(0.5);
|
centerPanel.setResizeWeight(0.5);
|
||||||
|
|
||||||
JPanel buttonPanel = new JPanel(new BorderLayout());
|
JPanel buttonPanel = new JPanel(new BorderLayout());
|
||||||
/*buttonPanel.add(BorderLayout.CENTER, toggleButton);*/
|
|
||||||
|
|
||||||
/* buttonPanel.add(BorderLayout.EAST, runTestButton);*/
|
|
||||||
|
|
||||||
JPanel southPanel = new JPanel(new BorderLayout());
|
JPanel southPanel = new JPanel(new BorderLayout());
|
||||||
southPanel.add(BorderLayout.EAST, buttonPanel);
|
southPanel.add(BorderLayout.EAST, buttonPanel);
|
||||||
|
|
||||||
|
@ -280,6 +289,7 @@ public class ScriptRunner extends VisPlugin {
|
||||||
codeEditor.setEditable(true);
|
codeEditor.setEditable(true);
|
||||||
} else {
|
} else {
|
||||||
updateScript(linkedFile);
|
updateScript(linkedFile);
|
||||||
|
GUI.setExternalToolsSetting("SCRIPTRUNNER_LAST_SCRIPTFILE", source.getAbsolutePath());
|
||||||
|
|
||||||
if (actionLinkFile != null) {
|
if (actionLinkFile != null) {
|
||||||
actionLinkFile.setMenuText("Unlink script: " + source.getName());
|
actionLinkFile.setMenuText("Unlink script: " + source.getName());
|
||||||
|
@ -357,9 +367,9 @@ public class ScriptRunner extends VisPlugin {
|
||||||
engine.activateScript(codeEditor.getText());
|
engine.activateScript(codeEditor.getText());
|
||||||
|
|
||||||
if (!headless) {
|
if (!headless) {
|
||||||
actionLinkFile.setEnabled(false);
|
if (actionLinkFile != null) {
|
||||||
/* toggleButton.setText("Deactivate");*/
|
actionLinkFile.setEnabled(false);
|
||||||
/*examplesButton.setEnabled(false);*/
|
}
|
||||||
logTextArea.setText("");
|
logTextArea.setText("");
|
||||||
codeEditor.setEnabled(false);
|
codeEditor.setEnabled(false);
|
||||||
updateTitle();
|
updateTitle();
|
||||||
|
@ -402,9 +412,9 @@ public class ScriptRunner extends VisPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!headless) {
|
if (!headless) {
|
||||||
actionLinkFile.setEnabled(true);
|
if (actionLinkFile != null) {
|
||||||
/*toggleButton.setText("Activate")*/;
|
actionLinkFile.setEnabled(true);
|
||||||
/*examplesButton.setEnabled(linkedFile==null?true:false);*/
|
}
|
||||||
codeEditor.setEnabled(true);
|
codeEditor.setEnabled(true);
|
||||||
updateTitle();
|
updateTitle();
|
||||||
}
|
}
|
||||||
|
@ -413,14 +423,14 @@ public class ScriptRunner extends VisPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTitle() {
|
private void updateTitle() {
|
||||||
/*String title = "Contiki Test Editor ";
|
String title = "Simulation script editor ";
|
||||||
if (linkedFile != null) {
|
if (linkedFile != null) {
|
||||||
title += ": " + linkedFile.getName() + " ";
|
title += "(" + linkedFile.getName() + ") ";
|
||||||
}
|
}
|
||||||
if (isActive()) {
|
if (isActive()) {
|
||||||
title += "(ACTIVE) ";
|
title += "*active*";
|
||||||
}
|
}
|
||||||
setTitle(title);*/
|
setTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportAndRun() {
|
private void exportAndRun() {
|
||||||
|
@ -609,7 +619,6 @@ public class ScriptRunner extends VisPlugin {
|
||||||
element = new Element("scriptfile");
|
element = new Element("scriptfile");
|
||||||
element.setText(simulation.getGUI().createPortablePath(linkedFile).getPath().replace('\\', '/'));
|
element.setText(simulation.getGUI().createPortablePath(linkedFile).getPath().replace('\\', '/'));
|
||||||
config.add(element);
|
config.add(element);
|
||||||
/*StringUtils.saveToFile(scriptFile, scriptTextArea.getText());*/
|
|
||||||
} else {
|
} else {
|
||||||
element = new Element("script");
|
element = new Element("script");
|
||||||
element.setText(codeEditor.getText());
|
element.setText(codeEditor.getText());
|
||||||
|
@ -692,7 +701,12 @@ public class ScriptRunner extends VisPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
JFileChooser fileChooser = new JFileChooser();
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
fileChooser.setCurrentDirectory(new java.io.File("."));
|
String suggest = GUI.getExternalToolsSetting("SCRIPTRUNNER_LAST_SCRIPTFILE", null);
|
||||||
|
if (suggest != null) {
|
||||||
|
fileChooser.setSelectedFile(new File(suggest));
|
||||||
|
} else {
|
||||||
|
fileChooser.setCurrentDirectory(new java.io.File("."));
|
||||||
|
}
|
||||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||||
fileChooser.setDialogTitle("Select script file");
|
fileChooser.setDialogTitle("Select script file");
|
||||||
fileChooser.setFileFilter(new FileFilter() {
|
fileChooser.setFileFilter(new FileFilter() {
|
||||||
|
|
|
@ -37,7 +37,6 @@ import java.awt.Cursor;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.MouseInfo;
|
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Polygon;
|
import java.awt.Polygon;
|
||||||
import java.awt.RenderingHints;
|
import java.awt.RenderingHints;
|
||||||
|
@ -54,6 +53,7 @@ import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.ItemEvent;
|
import java.awt.event.ItemEvent;
|
||||||
import java.awt.event.ItemListener;
|
import java.awt.event.ItemListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseMotionListener;
|
import java.awt.event.MouseMotionListener;
|
||||||
|
@ -68,7 +68,7 @@ import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JButton;
|
import javax.swing.Action;
|
||||||
import javax.swing.JCheckBoxMenuItem;
|
import javax.swing.JCheckBoxMenuItem;
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
|
@ -77,9 +77,12 @@ import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.JSeparator;
|
import javax.swing.JSeparator;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.MenuElement;
|
import javax.swing.MenuElement;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
|
import javax.swing.event.MenuEvent;
|
||||||
|
import javax.swing.event.MenuListener;
|
||||||
import javax.swing.plaf.basic.BasicInternalFrameUI;
|
import javax.swing.plaf.basic.BasicInternalFrameUI;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
@ -87,16 +90,16 @@ import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.GUI;
|
import se.sics.cooja.GUI;
|
||||||
|
import se.sics.cooja.GUI.MoteRelation;
|
||||||
import se.sics.cooja.HasQuickHelp;
|
import se.sics.cooja.HasQuickHelp;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MoteInterface;
|
import se.sics.cooja.MoteInterface;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
import se.sics.cooja.RadioMedium;
|
import se.sics.cooja.RadioMedium;
|
||||||
|
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
||||||
import se.sics.cooja.Simulation;
|
import se.sics.cooja.Simulation;
|
||||||
import se.sics.cooja.SupportedArguments;
|
import se.sics.cooja.SupportedArguments;
|
||||||
import se.sics.cooja.VisPlugin;
|
import se.sics.cooja.VisPlugin;
|
||||||
import se.sics.cooja.GUI.MoteRelation;
|
|
||||||
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
|
||||||
import se.sics.cooja.interfaces.LED;
|
import se.sics.cooja.interfaces.LED;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.Position;
|
||||||
import se.sics.cooja.interfaces.SerialPort;
|
import se.sics.cooja.interfaces.SerialPort;
|
||||||
|
@ -160,7 +163,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
private Cursor moveCursor = new Cursor(Cursor.MOVE_CURSOR);
|
private Cursor moveCursor = new Cursor(Cursor.MOVE_CURSOR);
|
||||||
|
|
||||||
/* Visualizers */
|
/* Visualizers */
|
||||||
private final JButton skinButton = new JButton("Select visualizer skins");
|
|
||||||
private static ArrayList<Class<? extends VisualizerSkin>> visualizerSkins =
|
private static ArrayList<Class<? extends VisualizerSkin>> visualizerSkins =
|
||||||
new ArrayList<Class<? extends VisualizerSkin>>();
|
new ArrayList<Class<? extends VisualizerSkin>>();
|
||||||
static {
|
static {
|
||||||
|
@ -222,29 +224,47 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
|
|
||||||
/* Menus */
|
/* Menus */
|
||||||
JMenuBar menuBar = new JMenuBar();
|
JMenuBar menuBar = new JMenuBar();
|
||||||
|
|
||||||
viewMenu = new JMenu("View");
|
viewMenu = new JMenu("View");
|
||||||
|
viewMenu.addMenuListener(new MenuListener() {
|
||||||
|
public void menuSelected(MenuEvent e) {
|
||||||
|
viewMenu.removeAll();
|
||||||
|
populateSkinMenu(viewMenu);
|
||||||
|
}
|
||||||
|
public void menuDeselected(MenuEvent e) {
|
||||||
|
}
|
||||||
|
public void menuCanceled(MenuEvent e) {
|
||||||
|
}
|
||||||
|
});
|
||||||
JMenu zoomMenu = new JMenu("Zoom");
|
JMenu zoomMenu = new JMenu("Zoom");
|
||||||
|
|
||||||
menuBar.add(viewMenu);
|
menuBar.add(viewMenu);
|
||||||
menuBar.add(zoomMenu);
|
menuBar.add(zoomMenu);
|
||||||
|
|
||||||
this.setJMenuBar(menuBar);
|
this.setJMenuBar(menuBar);
|
||||||
|
|
||||||
JMenuItem zoomInItem = new JMenuItem("Zoom in");
|
Action zoomInAction = new AbstractAction("Zoom in") {
|
||||||
zoomInItem.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
zoomToFactor(zoomFactor() * 1.2);
|
zoomToFactor(zoomFactor() * 1.2);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
zoomInAction.putValue(
|
||||||
|
Action.ACCELERATOR_KEY,
|
||||||
|
KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, ActionEvent.CTRL_MASK)
|
||||||
|
);
|
||||||
|
JMenuItem zoomInItem = new JMenuItem(zoomInAction);
|
||||||
zoomMenu.add(zoomInItem);
|
zoomMenu.add(zoomInItem);
|
||||||
|
|
||||||
JMenuItem zoomOutItem = new JMenuItem("Zoom out");
|
Action zoomOutAction = new AbstractAction("Zoom out") {
|
||||||
zoomOutItem.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
zoomToFactor(zoomFactor() / 1.2);
|
zoomToFactor(zoomFactor() / 1.2);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
zoomOutAction.putValue(
|
||||||
|
Action.ACCELERATOR_KEY,
|
||||||
|
KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, ActionEvent.CTRL_MASK)
|
||||||
|
);
|
||||||
|
JMenuItem zoomOutItem = new JMenuItem(zoomOutAction);
|
||||||
zoomMenu.add(zoomOutItem);
|
zoomMenu.add(zoomOutItem);
|
||||||
|
|
||||||
JMenuItem resetViewportItem = new JMenuItem("Reset viewport");
|
JMenuItem resetViewportItem = new JMenuItem("Reset viewport");
|
||||||
|
@ -280,20 +300,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
canvas.setBackground(Color.WHITE);
|
canvas.setBackground(Color.WHITE);
|
||||||
viewportTransform = new AffineTransform();
|
viewportTransform = new AffineTransform();
|
||||||
|
|
||||||
/* Skin selector */
|
|
||||||
skinButton.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
Point mouse = MouseInfo.getPointerInfo().getLocation();
|
|
||||||
JPopupMenu skinPopupMenu = new JPopupMenu();
|
|
||||||
|
|
||||||
populateSkinMenu(skinPopupMenu);
|
|
||||||
|
|
||||||
skinPopupMenu.setLocation(mouse);
|
|
||||||
skinPopupMenu.setInvoker(skinButton);
|
|
||||||
skinPopupMenu.setVisible(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
/*this.add(BorderLayout.NORTH, skinButton);*/
|
|
||||||
this.add(BorderLayout.CENTER, canvas);
|
this.add(BorderLayout.CENTER, canvas);
|
||||||
|
|
||||||
/* Observe simulation and mote positions */
|
/* Observe simulation and mote positions */
|
||||||
|
@ -524,7 +530,7 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
|
|
||||||
/* XXX HACK: here we set the position and size of the window when it appears on a blank simulation screen. */
|
/* XXX HACK: here we set the position and size of the window when it appears on a blank simulation screen. */
|
||||||
this.setLocation(1, 1);
|
this.setLocation(1, 1);
|
||||||
this.setSize(400, 400);
|
this.setSize(400, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateAndActivateSkin(Class<? extends VisualizerSkin> skinClass) {
|
private void generateAndActivateSkin(Class<? extends VisualizerSkin> skinClass) {
|
||||||
|
@ -550,9 +556,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
} catch (IllegalAccessException e1) {
|
} catch (IllegalAccessException e1) {
|
||||||
e1.printStackTrace();
|
e1.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
skinButton.setText("Select visualizer " +
|
|
||||||
"(" + currentSkins.size() + "/" + visualizerSkins.size() + ")");
|
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,7 +575,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
simulation.getGUI().tryLoadClass(this, VisualizerSkin.class, skin);
|
simulation.getGUI().tryLoadClass(this, VisualizerSkin.class, skin);
|
||||||
generateAndActivateSkin(skinClass);
|
generateAndActivateSkin(skinClass);
|
||||||
}
|
}
|
||||||
populateSkinMenu(viewMenu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VisualizerSkin[] getCurrentSkins() {
|
public VisualizerSkin[] getCurrentSkins() {
|
||||||
|
@ -698,11 +700,15 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
menu.setVisible(true);
|
menu.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateSkinMenu(MenuElement skinMenu) {
|
private void populateSkinMenu(MenuElement menu) {
|
||||||
JCheckBoxMenuItem item;
|
|
||||||
for (Class<? extends VisualizerSkin> skinClass: visualizerSkins) {
|
for (Class<? extends VisualizerSkin> skinClass: visualizerSkins) {
|
||||||
|
/* Should skin be enabled in this simulation? */
|
||||||
|
if (!isSkinCompatible(skinClass)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String description = GUI.getDescriptionOf(skinClass);
|
String description = GUI.getDescriptionOf(skinClass);
|
||||||
item = new JCheckBoxMenuItem(description, false);
|
JCheckBoxMenuItem item = new JCheckBoxMenuItem(description, false);
|
||||||
item.putClientProperty("skinclass", skinClass);
|
item.putClientProperty("skinclass", skinClass);
|
||||||
|
|
||||||
/* Select skin if active */
|
/* Select skin if active */
|
||||||
|
@ -747,23 +753,15 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
skinToDeactivate.setInactive();
|
skinToDeactivate.setInactive();
|
||||||
repaint();
|
repaint();
|
||||||
currentSkins.remove(skinToDeactivate);
|
currentSkins.remove(skinToDeactivate);
|
||||||
skinButton.setText("Select visualizers " +
|
|
||||||
"(" + currentSkins.size() + "/" + visualizerSkins.size() + ")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (menu instanceof JMenu) {
|
||||||
/* Should skin be enabled in this simulation? */
|
((JMenu)menu).add(item);
|
||||||
if (!isSkinCompatible(skinClass)) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
if (menu instanceof JPopupMenu) {
|
||||||
if (skinMenu instanceof JMenu) {
|
((JPopupMenu)menu).add(item);
|
||||||
((JMenu)skinMenu).add(item);
|
|
||||||
}
|
|
||||||
if (skinMenu instanceof JPopupMenu) {
|
|
||||||
((JPopupMenu)skinMenu).add(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -833,24 +831,26 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private double zoomFactor()
|
private double zoomFactor() {
|
||||||
{
|
|
||||||
return viewportTransform.getScaleX();
|
return viewportTransform.getScaleX();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void zoomToFactor(double newZoom) {
|
private void zoomToFactor(double newZoom) {
|
||||||
|
Position center = transformPixelToPosition(
|
||||||
|
new Point(canvas.getWidth()/2, canvas.getHeight()/2)
|
||||||
|
);
|
||||||
viewportTransform.setToScale(
|
viewportTransform.setToScale(
|
||||||
newZoom,
|
newZoom,
|
||||||
newZoom
|
newZoom
|
||||||
);
|
);
|
||||||
|
Position newCenter = transformPixelToPosition(
|
||||||
/*Position moved = transformPixelToPosition(zoomingPixel);
|
new Point(canvas.getWidth()/2, canvas.getHeight()/2)
|
||||||
viewportTransform.translate(
|
);
|
||||||
moved.getXCoordinate() - zoomingPosition.getXCoordinate(),
|
viewportTransform.translate(
|
||||||
moved.getYCoordinate() - zoomingPosition.getYCoordinate()
|
newCenter.getXCoordinate() - center.getXCoordinate(),
|
||||||
);*/
|
newCenter.getYCoordinate() - center.getYCoordinate()
|
||||||
|
);
|
||||||
repaint();
|
repaint();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMouseMove(MouseEvent e, boolean stop) {
|
private void handleMouseMove(MouseEvent e, boolean stop) {
|
||||||
|
@ -917,7 +917,7 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
}
|
}
|
||||||
/* Restore cursor */
|
/* Restore cursor */
|
||||||
canvas.setCursor(Cursor.getDefaultCursor());
|
canvas.setCursor(Cursor.getDefaultCursor());
|
||||||
|
|
||||||
|
|
||||||
/* Move mote */
|
/* Move mote */
|
||||||
if (moveStartTime < 0 || System.currentTimeMillis() - moveStartTime > 300) {
|
if (moveStartTime < 0 || System.currentTimeMillis() - moveStartTime > 300) {
|
||||||
|
@ -1294,7 +1294,7 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
||||||
loadedConfig = true;
|
loadedConfig = true;
|
||||||
|
|
||||||
for (Element element : configXML) {
|
for (Element element : configXML) {
|
||||||
if (element.getName().equals("skin")) {
|
if (element.getName().equals("skin")) {
|
||||||
|
@ -1335,7 +1335,6 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
} else if (element.getName().equals("hidden")) {
|
} else if (element.getName().equals("hidden")) {
|
||||||
BasicInternalFrameUI ui = (BasicInternalFrameUI) getUI();
|
BasicInternalFrameUI ui = (BasicInternalFrameUI) getUI();
|
||||||
ui.getNorthPane().setPreferredSize(new Dimension(0,0));
|
ui.getNorthPane().setPreferredSize(new Dimension(0,0));
|
||||||
skinButton.setVisible(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1489,11 +1488,9 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
ui.getNorthPane().getPreferredSize().height == 0) {
|
ui.getNorthPane().getPreferredSize().height == 0) {
|
||||||
/* Restore window decorations */
|
/* Restore window decorations */
|
||||||
ui.getNorthPane().setPreferredSize(null);
|
ui.getNorthPane().setPreferredSize(null);
|
||||||
visualizer.skinButton.setVisible(true);
|
|
||||||
} else {
|
} else {
|
||||||
/* Hide window decorations */
|
/* Hide window decorations */
|
||||||
ui.getNorthPane().setPreferredSize(new Dimension(0,0));
|
ui.getNorthPane().setPreferredSize(new Dimension(0,0));
|
||||||
visualizer.skinButton.setVisible(false);
|
|
||||||
}
|
}
|
||||||
visualizer.revalidate();
|
visualizer.revalidate();
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@ -1525,10 +1522,10 @@ public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
public String getQuickHelp() {
|
public String getQuickHelp() {
|
||||||
return
|
return
|
||||||
"<b>Network</b> " +
|
"<b>Network</b> " +
|
||||||
"<p>The network windo shows the positions of simulated motes. " +
|
"<p>The network window shows the positions of simulated motes. " +
|
||||||
"It is possible to zoom (CRTL+Mouse drag) and pan (Shift+Mouse drag) the current view. Motes can be moved by dragging them. " +
|
"It is possible to zoom (CRTL+Mouse drag) and pan (Shift+Mouse drag) the current view. Motes can be moved by dragging them. " +
|
||||||
"Mouse right-click motes for options. " +
|
"Mouse right-click motes for options. " +
|
||||||
"<p>The network window suppors different views. " +
|
"<p>The network window supports different views. " +
|
||||||
"Each view provides some specific information, such as the IP addresses of motes. " +
|
"Each view provides some specific information, such as the IP addresses of motes. " +
|
||||||
"Multiple views can be active at the same time. " +
|
"Multiple views can be active at the same time. " +
|
||||||
"Use the View menu to select views. ";
|
"Use the View menu to select views. ";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, Swedish Institute of Computer Science.
|
* Copyright (c) 2012, Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,8 +25,6 @@
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
|
||||||
* $Id: TrafficVisualizerSkin.java,v 1.5 2010/02/26 07:46:26 nifi Exp $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins.skins;
|
package se.sics.cooja.plugins.skins;
|
||||||
|
@ -34,273 +32,203 @@ package se.sics.cooja.plugins.skins;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.util.ArrayDeque;
|
import java.awt.Polygon;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
|
||||||
import javax.swing.Box;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.RadioConnection;
|
import se.sics.cooja.RadioConnection;
|
||||||
import se.sics.cooja.Simulation;
|
import se.sics.cooja.Simulation;
|
||||||
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
import se.sics.cooja.SupportedArguments;
|
||||||
|
import se.sics.cooja.TimeEvent;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.Position;
|
||||||
import se.sics.cooja.interfaces.Radio;
|
import se.sics.cooja.interfaces.Radio;
|
||||||
import se.sics.cooja.plugins.Visualizer;
|
import se.sics.cooja.plugins.Visualizer;
|
||||||
import se.sics.cooja.plugins.VisualizerSkin;
|
import se.sics.cooja.plugins.VisualizerSkin;
|
||||||
import se.sics.cooja.plugins.Visualizer.SimulationMenuAction;
|
|
||||||
import se.sics.cooja.radiomediums.AbstractRadioMedium;
|
import se.sics.cooja.radiomediums.AbstractRadioMedium;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Radio traffic visualizer skin.
|
* Radio traffic history visualizer skin.
|
||||||
*
|
*
|
||||||
* Transmitting motes are painted blue. Receiving motes are painted green.
|
|
||||||
* Interfered motes are painted red. Motes without radios are painted gray. All
|
|
||||||
* other motes are painted white.
|
|
||||||
*
|
|
||||||
* In contrast to the {@link UDGMVisualizerSkin}, this skin listens to all mote
|
|
||||||
* radios, not to the radio medium. The radio traffic skin also displays a
|
|
||||||
* history.
|
|
||||||
*
|
|
||||||
* @see UDGMVisualizerSkin
|
* @see UDGMVisualizerSkin
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
@ClassDescription("Radio traffic")
|
@ClassDescription("Radio traffic")
|
||||||
|
@SupportedArguments(radioMediums = {AbstractRadioMedium.class})
|
||||||
public class TrafficVisualizerSkin implements VisualizerSkin {
|
public class TrafficVisualizerSkin implements VisualizerSkin {
|
||||||
private static Logger logger = Logger.getLogger(TrafficVisualizerSkin.class);
|
private static Logger logger = Logger.getLogger(TrafficVisualizerSkin.class);
|
||||||
|
|
||||||
private static final boolean DRAW_ARROWS = true;
|
private final int MAX_HISTORY_SIZE = 200;
|
||||||
private static final Color COLOR_HISTORY = new Color(100, 100, 100, 100);
|
|
||||||
|
|
||||||
|
private boolean active = false;
|
||||||
private Simulation simulation = null;
|
private Simulation simulation = null;
|
||||||
private Visualizer visualizer = null;
|
private Visualizer visualizer = null;
|
||||||
|
private AbstractRadioMedium radioMedium = null;
|
||||||
|
|
||||||
private Box counters;
|
private ArrayList<RadioConnectionArrow> historyList = new ArrayList<RadioConnectionArrow>();
|
||||||
|
private RadioConnectionArrow[] history = null;
|
||||||
|
|
||||||
private final static int HISTORY_SIZE = 16;
|
private Observer radioMediumObserver = new Observer() {
|
||||||
private boolean showHistory = false;
|
public void update(Observable obs, Object obj) {
|
||||||
private ArrayDeque<RadioConnection> history = new ArrayDeque<RadioConnection>();
|
RadioConnection last = radioMedium.getLastConnection();
|
||||||
|
if (last != null && historyList.size() < MAX_HISTORY_SIZE) {
|
||||||
private AbstractRadioMedium radioMedium;
|
historyList.add(new RadioConnectionArrow(last));
|
||||||
private Observer radioObserver, radioMediumObserver;
|
history = historyList.toArray(new RadioConnectionArrow[0]);
|
||||||
|
visualizer.repaint(500);
|
||||||
public void setActive(Simulation simulation, Visualizer vis) {
|
}
|
||||||
if (!(simulation.getRadioMedium() instanceof AbstractRadioMedium)) {
|
|
||||||
logger.fatal("Radio medium type not supported: " + simulation.getRadioMedium());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
private TimeEvent ageArrowsTimeEvent = new TimeEvent(0) {
|
||||||
|
public void execute(long t) {
|
||||||
|
if (!active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (historyList.size() > 0) {
|
||||||
|
boolean hasOld = false;
|
||||||
|
|
||||||
|
/* Increase age */
|
||||||
|
for (RadioConnectionArrow connArrow : historyList) {
|
||||||
|
connArrow.increaseAge();
|
||||||
|
if(connArrow.getAge() >= connArrow.getMaxAge()) {
|
||||||
|
hasOld = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove too old arrows */
|
||||||
|
if (hasOld) {
|
||||||
|
RadioConnectionArrow[] historyArr = historyList.toArray(new RadioConnectionArrow[0]);
|
||||||
|
for (RadioConnectionArrow connArrow : historyArr) {
|
||||||
|
if(connArrow.getAge() >= connArrow.getMaxAge()) {
|
||||||
|
historyList.remove(connArrow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
historyArr = historyList.toArray(new RadioConnectionArrow[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
visualizer.repaint(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reschedule myself */
|
||||||
|
simulation.scheduleEvent(this, t + 100*Simulation.MILLISECOND);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void setActive(final Simulation simulation, Visualizer vis) {
|
||||||
this.radioMedium = (AbstractRadioMedium) simulation.getRadioMedium();
|
this.radioMedium = (AbstractRadioMedium) simulation.getRadioMedium();
|
||||||
this.simulation = simulation;
|
this.simulation = simulation;
|
||||||
this.visualizer = vis;
|
this.visualizer = vis;
|
||||||
|
this.active = true;
|
||||||
|
|
||||||
final JLabel txCounter = new JLabel("TX: " + radioMedium.COUNTER_TX);
|
simulation.invokeSimulationThread(new Runnable() {
|
||||||
final JLabel rxCounter = new JLabel("RX: " + radioMedium.COUNTER_RX);
|
public void run() {
|
||||||
final JLabel interferedCounter = new JLabel("INT: " + radioMedium.COUNTER_INTERFERED);
|
historyList.clear();
|
||||||
|
history = null;
|
||||||
|
|
||||||
counters = Box.createHorizontalBox();
|
/* Start observing radio medium for transmissions */
|
||||||
counters.add(txCounter);
|
radioMedium.addRadioMediumObserver(radioMediumObserver);
|
||||||
counters.add(Box.createHorizontalStrut(10));
|
|
||||||
counters.add(rxCounter);
|
|
||||||
counters.add(Box.createHorizontalStrut(10));
|
|
||||||
counters.add(interferedCounter);
|
|
||||||
|
|
||||||
/* visualizer.getCurrentCanvas().add(counters);*/
|
/* Fade away arrows */
|
||||||
|
simulation.scheduleEvent(ageArrowsTimeEvent, simulation.getSimulationTime() + 100*Simulation.MILLISECOND);
|
||||||
/* Start observing radio medium and radios */
|
|
||||||
radioMedium.addRadioMediumObserver(radioMediumObserver = new Observer() {
|
|
||||||
public void update(Observable obs, Object obj) {
|
|
||||||
txCounter.setText("TX: " + radioMedium.COUNTER_TX);
|
|
||||||
rxCounter.setText("RX: " + radioMedium.COUNTER_RX);
|
|
||||||
interferedCounter.setText("INT: " + + radioMedium.COUNTER_INTERFERED);
|
|
||||||
|
|
||||||
if (showHistory) {
|
|
||||||
RadioConnection last = radioMedium.getLastConnection();
|
|
||||||
if (last != null) {
|
|
||||||
history.add(last);
|
|
||||||
while (history.size() > HISTORY_SIZE) {
|
|
||||||
history.removeFirst();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
visualizer.repaint();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
radioObserver = new Observer() {
|
|
||||||
public void update(Observable o, Object arg) {
|
|
||||||
visualizer.repaint();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
simulation.getEventCentral().addMoteCountListener(new MoteCountListener() {
|
|
||||||
public void moteWasAdded(Mote mote) {
|
|
||||||
Radio r = mote.getInterfaces().getRadio();
|
|
||||||
if (r != null) {
|
|
||||||
r.addObserver(radioObserver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void moteWasRemoved(Mote mote) {
|
|
||||||
Radio r = mote.getInterfaces().getRadio();
|
|
||||||
if (r != null) {
|
|
||||||
r.deleteObserver(radioObserver);
|
|
||||||
}
|
|
||||||
history.clear();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
for (Mote mote: simulation.getMotes()) {
|
|
||||||
Radio r = mote.getInterfaces().getRadio();
|
|
||||||
if (r != null) {
|
|
||||||
r.addObserver(radioObserver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Register menu actions */
|
|
||||||
visualizer.registerSimulationMenuAction(ToggleHistoryAction.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInactive() {
|
public void setInactive() {
|
||||||
|
this.active = false;
|
||||||
if (simulation == null) {
|
if (simulation == null) {
|
||||||
/* Skin was never activated */
|
/* Skin was never activated */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
visualizer.getCurrentCanvas().remove(counters);
|
/* Stop observing radio medium */
|
||||||
|
|
||||||
/* Stop observing radio medium and radios */
|
|
||||||
radioMedium.deleteRadioMediumObserver(radioMediumObserver);
|
radioMedium.deleteRadioMediumObserver(radioMediumObserver);
|
||||||
for (Mote mote: simulation.getMotes()) {
|
|
||||||
Radio r = mote.getInterfaces().getRadio();
|
|
||||||
if (r != null) {
|
|
||||||
r.addObserver(radioObserver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unregister menu actions */
|
|
||||||
visualizer.unregisterSimulationMenuAction(ToggleHistoryAction.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color[] getColorOf(Mote mote) {
|
public Color[] getColorOf(Mote mote) {
|
||||||
if (simulation == null) {
|
|
||||||
/* Skin was never activated */
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Radio moteRadio = mote.getInterfaces().getRadio();
|
|
||||||
if (moteRadio == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moteRadio.isRadioOn()) {
|
|
||||||
return new Color[] { Color.GRAY };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moteRadio.isTransmitting()) {
|
|
||||||
return new Color[] { Color.BLUE };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moteRadio.isInterfered()) {
|
|
||||||
return new Color[] { Color.RED };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moteRadio.isReceiving()) {
|
|
||||||
return new Color[] { Color.GREEN };
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Polygon arrowPoly = new Polygon();
|
||||||
|
private void drawArrow(Graphics g, int xSource, int ySource, int xDest, int yDest, int delta) {
|
||||||
|
double dx = xSource - xDest;
|
||||||
|
double dy = ySource - yDest;
|
||||||
|
double dir = Math.atan2(dx, dy);
|
||||||
|
double len = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
dx /= len;
|
||||||
|
dy /= len;
|
||||||
|
len -= delta;
|
||||||
|
xDest = xSource - (int) (dx * len);
|
||||||
|
yDest = ySource - (int) (dy * len);
|
||||||
|
g.drawLine(xDest, yDest, xSource, ySource);
|
||||||
|
|
||||||
|
final int size = 8;
|
||||||
|
arrowPoly.reset();
|
||||||
|
arrowPoly.addPoint(xDest, yDest);
|
||||||
|
arrowPoly.addPoint(xDest + xCor(size, dir + 0.5), yDest + yCor(size, dir + 0.5));
|
||||||
|
arrowPoly.addPoint(xDest + xCor(size, dir - 0.5), yDest + yCor(size, dir - 0.5));
|
||||||
|
arrowPoly.addPoint(xDest, yDest);
|
||||||
|
g.fillPolygon(arrowPoly);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int yCor(int len, double dir) {
|
||||||
|
return (int)(0.5 + len * Math.cos(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int xCor(int len, double dir) {
|
||||||
|
return (int)(0.5 + len * Math.sin(dir));
|
||||||
|
}
|
||||||
|
|
||||||
public void paintBeforeMotes(Graphics g) {
|
public void paintBeforeMotes(Graphics g) {
|
||||||
if (simulation == null) {
|
RadioConnectionArrow[] historyCopy = history;
|
||||||
/* Skin was never activated */
|
if (historyCopy == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (RadioConnectionArrow connArrow : historyCopy) {
|
||||||
if (showHistory) {
|
float colorHistoryIndex = (float)connArrow.getAge() / (float)connArrow.getMaxAge();
|
||||||
/* Paint history in gray */
|
g.setColor(new Color(colorHistoryIndex, colorHistoryIndex, 1.0f));
|
||||||
RadioConnection[] historyArr = history.toArray(new RadioConnection[0]);
|
Radio source = connArrow.getConnection().getSource();
|
||||||
for (RadioConnection conn : historyArr) {
|
Point sourcePoint = visualizer.transformPositionToPixel(source.getPosition());
|
||||||
if (conn == null) {
|
for (Radio destRadio : connArrow.getConnection().getDestinations()) {
|
||||||
continue;
|
Position destPos = destRadio.getPosition();
|
||||||
}
|
Point destPoint = visualizer.transformPositionToPixel(destPos);
|
||||||
g.setColor(COLOR_HISTORY);
|
drawArrow(g, sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y, 8);
|
||||||
Radio source = conn.getSource();
|
|
||||||
Point sourcePoint = visualizer.transformPositionToPixel(source.getPosition());
|
|
||||||
for (Radio destRadio : conn.getDestinations()) {
|
|
||||||
Position destPos = destRadio.getPosition();
|
|
||||||
Point destPoint = visualizer.transformPositionToPixel(destPos);
|
|
||||||
g.drawLine(sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Paint active connections in black */
|
|
||||||
RadioConnection[] conns = radioMedium.getActiveConnections();
|
|
||||||
if (conns != null) {
|
|
||||||
g.setColor(Color.BLACK);
|
|
||||||
for (RadioConnection conn : conns) {
|
|
||||||
if (conn == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Radio source = conn.getSource();
|
|
||||||
Point sourcePoint = visualizer.transformPositionToPixel(source.getPosition());
|
|
||||||
for (Radio destRadio : conn.getDestinations()) {
|
|
||||||
if (destRadio == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Position destPos = destRadio.getPosition();
|
|
||||||
Point destPoint = visualizer.transformPositionToPixel(destPos);
|
|
||||||
g.drawLine(sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y);
|
|
||||||
|
|
||||||
/* Draw arrows */
|
|
||||||
if (DRAW_ARROWS) {
|
|
||||||
Point centerPoint = new Point(
|
|
||||||
destPoint.x/2 + sourcePoint.x/2,
|
|
||||||
destPoint.y/2 + sourcePoint.y/2
|
|
||||||
);
|
|
||||||
int startAngle = (int) (-180 * Math.atan2(destPoint.y - sourcePoint.y, destPoint.x - sourcePoint.x)/Math.PI - 90);
|
|
||||||
g.drawArc(centerPoint.x-5, centerPoint.y-5, 10, 10, startAngle, 180);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paintAfterMotes(Graphics g) {
|
public void paintAfterMotes(Graphics g) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ToggleHistoryAction implements SimulationMenuAction {
|
|
||||||
public boolean isEnabled(Visualizer visualizer, Simulation simulation) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription(Visualizer visualizer, Simulation simulation) {
|
|
||||||
VisualizerSkin[] skins = visualizer.getCurrentSkins();
|
|
||||||
boolean showing = false;
|
|
||||||
for (VisualizerSkin skin: skins) {
|
|
||||||
if (skin instanceof TrafficVisualizerSkin) {
|
|
||||||
showing = ((TrafficVisualizerSkin)skin).showHistory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (showing) {
|
|
||||||
return "Hide traffic history";
|
|
||||||
}
|
|
||||||
return "Show traffic history";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doAction(Visualizer visualizer, Simulation simulation) {
|
|
||||||
VisualizerSkin[] skins = visualizer.getCurrentSkins();
|
|
||||||
for (VisualizerSkin skin: skins) {
|
|
||||||
if (skin instanceof TrafficVisualizerSkin) {
|
|
||||||
((TrafficVisualizerSkin)skin).showHistory = !((TrafficVisualizerSkin)skin).showHistory;
|
|
||||||
visualizer.repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public Visualizer getVisualizer() {
|
public Visualizer getVisualizer() {
|
||||||
return visualizer;
|
return visualizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class RadioConnectionArrow {
|
||||||
|
private RadioConnection conn;
|
||||||
|
private int age;
|
||||||
|
private static final int MAX_AGE = 10;
|
||||||
|
RadioConnectionArrow(RadioConnection conn) {
|
||||||
|
this.conn = conn;
|
||||||
|
this.age = 0;
|
||||||
|
}
|
||||||
|
public void increaseAge() {
|
||||||
|
if (age < MAX_AGE) {
|
||||||
|
age++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
public RadioConnection getConnection() {
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
public int getMaxAge() {
|
||||||
|
return MAX_AGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue