diff --git a/.travis.yml b/.travis.yml index 003ccedb8..7994153e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_script: ## Install toolchain for mc1233x, cc2538 and mbxxx in care-free way - "[ ${BUILD_ARCH:-0} = arm ] && curl -s \ - https://raw.github.com/wiki/malvira/libmc1322x/files/arm-2008q3-66-arm-none-eabi-i686-pc-linux-gnu.tar.bz2 \ + https://raw.githubusercontent.com/wiki/malvira/libmc1322x/files/arm-2008q3-66-arm-none-eabi-i686-pc-linux-gnu.tar.bz2 \ | tar xjf - -C /tmp/ && sudo cp -f -r /tmp/arm-2008q3/* /usr/ && rm -rf /tmp/arm-2008q3 && arm-none-eabi-gcc --version || true" ## Install RL78 GCC chain (following the instructions in platform/eval-adf7xxxmb4z/README.md) @@ -23,7 +23,7 @@ before_script: ## Install SDCC from a purpose-built bundle - "[ ${BUILD_ARCH:-0} = 8051 ] && curl -s \ - https://raw.github.com/wiki/g-oikonomou/contiki-sensinode/files/sdcc.tar.gz \ + https://raw.githubusercontent.com/wiki/g-oikonomou/contiki-sensinode/files/sdcc.tar.gz \ | tar xzf - -C /tmp/ && sudo cp -f -r /tmp/sdcc/* /usr/local/ && rm -rf /tmp/sdcc && sdcc --version || true" - "[ ${BUILD_ARCH:-0} = 8051 ] && sudo apt-get -qq install srecord || true" diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index ad3cb1861..0512591f5 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -186,4 +186,13 @@ #define RPL_DEFAULT_LIFETIME RPL_CONF_DEFAULT_LIFETIME #endif +/* + * DAG preference field + */ +#ifdef RPL_CONF_PREFERENCE +#define RPL_PREFERENCE RPL_CONF_PREFERENCE +#else +#define RPL_PREFERENCE 0 +#endif + #endif /* RPL_CONF_H */ diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 08178d5ad..fad1c2a0e 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -270,6 +270,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) dag->version = version; dag->joined = 1; dag->grounded = RPL_GROUNDED; + dag->preference = RPL_PREFERENCE; instance->mop = RPL_MOP_DEFAULT; instance->of = &RPL_OF; rpl_set_preferred_parent(dag, NULL); @@ -712,7 +713,7 @@ best_parent(rpl_dag_t *dag) p = nbr_table_head(rpl_parents); while(p != NULL) { - if(p->rank == INFINITE_RANK) { + if(p->dag != dag || p->rank == INFINITE_RANK) { /* ignore this neighbor */ } else if(best == NULL) { best = p; diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 8f2455b29..7b26c3730 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -134,29 +134,6 @@ #define INFINITE_RANK 0xffff -/* Represents 2^n ms. */ -/* Default value according to the specification is 3 which - means 8 milliseconds, but that is an unreasonable value if - using power-saving / duty-cycling */ -#ifdef RPL_CONF_DIO_INTERVAL_MIN -#define RPL_DIO_INTERVAL_MIN RPL_CONF_DIO_INTERVAL_MIN -#else -#define RPL_DIO_INTERVAL_MIN 12 -#endif - -/* Maximum amount of timer doublings. */ -#ifdef RPL_CONF_DIO_INTERVAL_DOUBLINGS -#define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS -#else -#define RPL_DIO_INTERVAL_DOUBLINGS 8 -#endif - -/* Default DIO redundancy. */ -#ifdef RPL_CONF_DIO_REDUNDANCY -#define RPL_DIO_REDUNDANCY RPL_CONF_DIO_REDUNDANCY -#else -#define RPL_DIO_REDUNDANCY 10 -#endif /* Expire DAOs from neighbors that do not respond in this time. (seconds) */ #define DAO_EXPIRATION_TIMEOUT 60 diff --git a/cpu/6502/net/cs8900a.S b/cpu/6502/net/cs8900a.S index fc4d5d1ca..8cf3bea23 100644 --- a/cpu/6502/net/cs8900a.S +++ b/cpu/6502/net/cs8900a.S @@ -32,7 +32,7 @@ ; ;--------------------------------------------------------------------- - .segment "JUMPTABLE" + .segment "HEADER" ; Driver signature .byte $65, $74, $68 ; "eth" diff --git a/cpu/6502/net/lan91c96.S b/cpu/6502/net/lan91c96.S index d034b9788..e3f92b75a 100644 --- a/cpu/6502/net/lan91c96.S +++ b/cpu/6502/net/lan91c96.S @@ -33,7 +33,7 @@ ; ;--------------------------------------------------------------------- - .segment "JUMPTABLE" + .segment "HEADER" ; Driver signature .byte $65, $74, $68 ; "eth" diff --git a/cpu/6502/net/w5100.S b/cpu/6502/net/w5100.S index 3952c1121..ca0878bf3 100644 --- a/cpu/6502/net/w5100.S +++ b/cpu/6502/net/w5100.S @@ -32,7 +32,7 @@ ; ;--------------------------------------------------------------------- - .segment "JUMPTABLE" + .segment "HEADER" ; Driver signature .byte $65, $74, $68 ; "eth" diff --git a/cpu/cc2538/dev/random.c b/cpu/cc2538/dev/random.c index a4ef7c03a..8c955aa8a 100644 --- a/cpu/cc2538/dev/random.c +++ b/cpu/cc2538/dev/random.c @@ -92,6 +92,9 @@ random_init(unsigned short seed) /* Enable clock for the RF Core */ REG(SYS_CTRL_RCGCRFC) = 1; + /* Wait for the clock ungating to take effect */ + while(REG(SYS_CTRL_RCGCRFC) != 1); + /* Infinite RX - FRMCTRL0[3:2] = 10 * This will mess with radio operation - see note above */ REG(RFCORE_XREG_FRMCTRL0) = 0x00000008; diff --git a/cpu/stm32w108/Makefile.stm32w108 b/cpu/stm32w108/Makefile.stm32w108 index 29e2f9c72..dce0b1383 100644 --- a/cpu/stm32w108/Makefile.stm32w108 +++ b/cpu/stm32w108/Makefile.stm32w108 @@ -100,9 +100,13 @@ endif ifeq ($(STM32W_CPUREV), CC) LD-EXT=-stm32w108CC + RAM_SIZE = 2*8192 + FLASH_SIZE = 2*128*1024 ${warning "using stm32w108CC specific ld file"} else ifeq ($(STM32W_CPUREV), xB) LD-EXT=-stm32w108xB + RAM_SIZE = 8192 + FLASH_SIZE = 128*1024 ${warning "using stm32w108xB specific ld file"} else ${error "Bad STM32W_CPUREV value or no STM32W_CPUREV value specified. Cpu revision should be specified. Please read cpu/stm32w108/README.txt for more details."} @@ -207,8 +211,6 @@ endif ### Custom rules -OBJECTDIR = obj_$(TARGET) - ssubst = ${patsubst %.s,%.o,${patsubst %.s79,%.o,$(1)}} CONTIKI_OBJECTFILES += ${addprefix $(OBJECTDIR)/,${call ssubst, $(STM32W_S)}} @@ -229,18 +231,21 @@ endif CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 $(OBJECTDIR)/%.o: %.c | $(OBJECTDIR) - $(CC) $(CFLAGS) $< --dependencies=m $(@:.o=.P) -o $@ + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) $< --dependencies=m $(@:.o=.P) -o $@ @$(SEDCOMMAND); rm -f $(@:.o=.P) @$(FINALIZE_DEPENDENCY) CUSTOM_RULE_C_TO_CO = 1 %.co: %.c - $(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@ + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@ else #IAR CUSTOM_RULE_C_TO_CE = 1 %.ce: %.c - $(CC) $(CFLAGS) -fno-merge-constants -fno-function-sections -DAUTOSTART_ENABLE -c $< -o $@ + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) -fno-merge-constants -fno-function-sections -DAUTOSTART_ENABLE -c $< -o $@ $(STRIP) --strip-unneeded -g -x $@ CUSTOM_RULE_LINK = 1 @@ -259,12 +264,14 @@ symbols.c symbols.h: endif %.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(OBJECTDIR)/symbols.o - $(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} -Wl,-\( ${filter %.a,$^} $(TARGET_LIBFILES) -Wl,-\) -o $@ + $(TRACE_LD) + $(Q)$(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} -Wl,-\( ${filter %.a,$^} $(TARGET_LIBFILES) -Wl,-\) -o $@ @echo >> contiki-$(TARGET).map @$(SIZE) $(SIZEFLAGS) $@ >> contiki-$(TARGET).map #%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) $(CONTIKI_OBJECTFILES) -# $(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ +# $(TRACE_LD) +# $(Q)$(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ # @echo "\n" >> contiki-$(TARGET).map # @$(SIZE) $(SIZEFLAGS) $@ >> contiki-$(TARGET).map @@ -283,10 +290,12 @@ stm-motes: @echo $(MOTES) $(OBJECTDIR)/%.o: %.s79 | $(OBJECTDIR) - $(AS) $(ASFLAGS) -o $@ $< + $(TRACE_AS) + $(Q)$(AS) $(ASFLAGS) -o $@ $< $(OBJECTDIR)/%.o: %.s | $(OBJECTDIR) - $(AS) $(ASFLAGS) -o $@ $< + $(TRACE_AS) + $(Q)$(AS) $(ASFLAGS) -o $@ $< %.bin: %.$(TARGET) $(OBJCOPY) $(OBJOPTS) $< $@ @@ -314,9 +323,13 @@ endif # a target that gives a user-friendly memory profile, taking into account the RAM # that is statically occupied by the stack as defined in cpu/stm32w108/gnu.ld -RAM_SIZE = 2*8192 -FLASH_SIZE = 2*128*1024 STACK_SIZE = 1280 +ifndef RAM_SIZE + ${error no ram size configured} +endif +ifndef FLASH_SIZE + ${error no flash size configured} +endif %.size: %.$(TARGET) @size -A $< | egrep "data|bss" | awk '{s+=$$2} END {s=s+$(STACK_SIZE); f=$(RAM_SIZE)-s; printf "[RAM] used %6d, free %6d\n",s,f;}' @size -A $< | egrep "text|isr_vector" | awk '{s+=$$2} END {f=$(FLASH_SIZE)-s; printf "[Flash] used %6d, free %6d\n",s,f;}' diff --git a/tools/cooja/config/cooja_default.config b/tools/cooja/config/cooja_default.config index b28337631..a48c89e2d 100644 --- a/tools/cooja/config/cooja_default.config +++ b/tools/cooja/config/cooja_default.config @@ -3,8 +3,7 @@ org.contikios.cooja.contikimote.interfaces.ContikiRadio.RADIO_TRANSMISSION_RATE_ org.contikios.cooja.contikimote.ContikiMoteType.MOTE_INTERFACES = org.contikios.cooja.interfaces.Position org.contikios.cooja.interfaces.Battery org.contikios.cooja.contikimote.interfaces.ContikiVib org.contikios.cooja.contikimote.interfaces.ContikiMoteID org.contikios.cooja.contikimote.interfaces.ContikiRS232 org.contikios.cooja.contikimote.interfaces.ContikiBeeper org.contikios.cooja.interfaces.RimeAddress org.contikios.cooja.contikimote.interfaces.ContikiIPAddress org.contikios.cooja.contikimote.interfaces.ContikiRadio org.contikios.cooja.contikimote.interfaces.ContikiButton org.contikios.cooja.contikimote.interfaces.ContikiPIR org.contikios.cooja.contikimote.interfaces.ContikiClock org.contikios.cooja.contikimote.interfaces.ContikiLED org.contikios.cooja.contikimote.interfaces.ContikiCFS org.contikios.cooja.interfaces.Mote2MoteRelations org.contikios.cooja.interfaces.MoteAttributes org.contikios.cooja.contikimote.ContikiMoteType.C_SOURCES = org.contikios.cooja.Cooja.MOTETYPES = org.contikios.cooja.motes.ImportAppMoteType org.contikios.cooja.motes.DisturberMoteType org.contikios.cooja.contikimote.ContikiMoteType -org.contikios.cooja.Cooja.PLUGINS = org.contikios.cooja.plugins.Visualizer org.contikios.cooja.plugins.LogListener org.contikios.cooja.plugins.TimeLine org.contikios.cooja.plugins.MoteInformation org.contikios.cooja.plugins.MoteInterfaceViewer org.contikios.cooja.plugins.VariableWatcher org.contikios.cooja.plugins.EventListener org.contikios.cooja.plugins.RadioLogger org.contikios.cooja.plugins.ScriptRunner org.contikios.cooja.plugins.Notes org.contikios.cooja.plugins.BufferListener org.contikios.cooja.plugins.DGRMConfigurator +org.contikios.cooja.Cooja.PLUGINS = org.contikios.cooja.plugins.Visualizer org.contikios.cooja.plugins.LogListener org.contikios.cooja.plugins.TimeLine org.contikios.cooja.plugins.MoteInformation org.contikios.cooja.plugins.MoteInterfaceViewer org.contikios.cooja.plugins.VariableWatcher org.contikios.cooja.plugins.EventListener org.contikios.cooja.plugins.RadioLogger org.contikios.cooja.plugins.ScriptRunner org.contikios.cooja.plugins.Notes org.contikios.cooja.plugins.BufferListener org.contikios.cooja.plugins.DGRMConfigurator org.contikios.cooja.plugins.BaseRSSIconf org.contikios.cooja.Cooja.POSITIONERS = org.contikios.cooja.positioners.RandomPositioner org.contikios.cooja.positioners.LinearPositioner org.contikios.cooja.positioners.EllipsePositioner org.contikios.cooja.positioners.ManualPositioner org.contikios.cooja.Cooja.RADIOMEDIUMS = org.contikios.cooja.radiomediums.UDGM org.contikios.cooja.radiomediums.UDGMConstantLoss org.contikios.cooja.radiomediums.DirectedGraphMedium org.contikios.cooja.radiomediums.SilentRadioMedium org.contikios.cooja.plugins.Visualizer.SKINS = org.contikios.cooja.plugins.skins.DGRMVisualizerSkin - diff --git a/tools/cooja/java/org/contikios/cooja/plugins/BaseRSSIconf.java b/tools/cooja/java/org/contikios/cooja/plugins/BaseRSSIconf.java new file mode 100644 index 000000000..bf0982902 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/plugins/BaseRSSIconf.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * 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 + * SUCH DAMAGE. + * + */ + +package org.contikios.cooja.plugins; + +import java.awt.BorderLayout; +import java.util.Observable; +import java.util.Observer; + +import javax.swing.DefaultCellEditor; +import javax.swing.JComboBox; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellEditor; + +import org.apache.log4j.Logger; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Cooja; +import org.contikios.cooja.PluginType; +import org.contikios.cooja.Simulation; +import org.contikios.cooja.SupportedArguments; +import org.contikios.cooja.VisPlugin; +import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.radiomediums.AbstractRadioMedium; +import org.contikios.cooja.radiomediums.DirectedGraphMedium; + + +/** + * Simple user interface for configuring BaseRSSI of Motes + * + * @see DirectedGraphMedium + * @author Sebastian Schinabeck + */ +@ClassDescription("Base RSSI") +@PluginType(PluginType.SIM_PLUGIN) +@SupportedArguments(radioMediums = { AbstractRadioMedium.class }) + +public class BaseRSSIconf extends VisPlugin { + private static final long serialVersionUID = 8955776548892545638L; + private static Logger logger = Logger.getLogger(BaseRSSIconf.class); + + private final static int IDX_Mote = 0; + private final static int IDX_BaseRSSI = 1; + + private final static String[] COLUMN_NAMES = new String[] { "Mote", + "BaseRSSI (-45!)" }; // TODO maybe include offset of -45 directly + + private Cooja gui = null; + private AbstractRadioMedium radioMedium = null; + private Observer changeObserver; + private JTable motesTable = null; + private JComboBox combo = new JComboBox(); + private Simulation sim = null; + + + + public BaseRSSIconf(Simulation sim, Cooja gui) { + super("Base RSSI Configurator", gui); + this.gui = gui; + this.sim = sim; + radioMedium = (AbstractRadioMedium) sim.getRadioMedium(); + + changeObserver = new Observer() { + public void update(Observable obs, Object obj) { + logger.debug("Changed"); + model.fireTableDataChanged(); + + } + }; + + radioMedium.addRadioMediumObserver(changeObserver); + + sim.addObserver(changeObserver); + + /* Represent motes and RSSI by table */ + motesTable = new JTable(model) { + private static final long serialVersionUID = -4680013510092815210L; + + public TableCellEditor getCellEditor(int row, int column) { + combo.removeAllItems(); + if (column == IDX_Mote) { + for (double d = 1.0; d <= radioMedium.getRegisteredRadios().length; d += 1.0) { + combo.addItem(d); + } + } else if (column == IDX_BaseRSSI) { + for (double d = AbstractRadioMedium.SS_STRONG; d >= AbstractRadioMedium.SS_NOTHING; d -= 1) { + combo.addItem((int) d); + } + } + + return super.getCellEditor(row, column); + } + }; + motesTable.setFillsViewportHeight(true); + combo.setEditable(true); + + motesTable.getColumnModel().getColumn(IDX_Mote) + .setCellRenderer(new DefaultTableCellRenderer() { // TODO ???? + private static final long serialVersionUID = 4470088575039698508L; + + public void setValue(Object value) { + if (!(value instanceof Double)) { + setText(value.toString()); + return; + } + double v = ((Double) value).doubleValue(); + setText(String.format("%1.1f", v)); + } + }); + motesTable.getColumnModel().getColumn(IDX_BaseRSSI) + .setCellRenderer(new DefaultTableCellRenderer() { + private static final long serialVersionUID = -7170745293267593460L; + + public void setValue(Object value) { + if (!(value instanceof Double)) { + setText(value.toString()); + return; + } + double v = ((Double) value).doubleValue(); + setText(String.format("%1.1f dBm", v)); + } + }); + motesTable.getColumnModel().getColumn(IDX_Mote) + .setCellEditor(new DefaultCellEditor(combo)); + motesTable.getColumnModel().getColumn(IDX_BaseRSSI) + .setCellEditor(new DefaultCellEditor(combo)); + + motesTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); + motesTable.getSelectionModel().setSelectionMode( + ListSelectionModel.SINGLE_SELECTION); + + + add(BorderLayout.CENTER, new JScrollPane(motesTable)); + + model.fireTableDataChanged(); + setSize(400, 300); + } + + + final AbstractTableModel model = new AbstractTableModel() { + private static final long serialVersionUID = 9101118401527171218L; + + public String getColumnName(int column) { + if (column < 0 || column >= COLUMN_NAMES.length) { + return ""; + } + return COLUMN_NAMES[column]; + } + + public int getRowCount() { + return radioMedium.getRegisteredRadios().length; + } + + public int getColumnCount() { + return COLUMN_NAMES.length; + } + + public Object getValueAt(int row, int column) { + if (row < 0 || row >= radioMedium.getRegisteredRadios().length) { + return ""; + } + if (column < 0 || column >= COLUMN_NAMES.length) { + return ""; + } + Radio radio = radioMedium.getRegisteredRadios()[row]; // sim.getMotes()... + if (column == IDX_Mote) { + return radio.getMote(); + } + if (column == IDX_BaseRSSI) { + return radioMedium.getBaseRssi(radio); + } + return ""; + } + + public void setValueAt(Object value, int row, int column) { + if (row < 0 || row >= radioMedium.getRegisteredRadios().length) { + return; + } + if (column < 0 || column >= COLUMN_NAMES.length) { + return; + } + + Radio radio = radioMedium.getRegisteredRadios()[row]; + try { + if (column == IDX_BaseRSSI) { + radioMedium.setBaseRssi(radio, + ((Number) value).doubleValue()); + } else { + super.setValueAt(value, row, column); + } + + } catch (ClassCastException e) { + } + } + + public boolean isCellEditable(int row, int column) { + if (row < 0 || row >= radioMedium.getRegisteredRadios().length) { + return false; + } + + if (column == IDX_Mote) { + gui.signalMoteHighlight(radioMedium.getRegisteredRadios()[row] + .getMote()); + return false; + } + if (column == IDX_BaseRSSI) { + gui.signalMoteHighlight(radioMedium.getRegisteredRadios()[row] + .getMote()); + return true; + } + return false; + } + + public Class getColumnClass(int c) { + return getValueAt(0, c).getClass(); + } + }; + + public void closePlugin() { + radioMedium.deleteRadioMediumObserver(changeObserver); + sim.deleteObserver(changeObserver); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java index 742dbeaf3..0aed97d52 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java @@ -31,8 +31,13 @@ package org.contikios.cooja.radiomediums; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import java.util.Observable; import java.util.Observer; +import java.util.WeakHashMap; import org.apache.log4j.Logger; @@ -44,6 +49,7 @@ import org.contikios.cooja.Simulation; import org.contikios.cooja.TimeEvent; import org.contikios.cooja.interfaces.CustomDataRadio; import org.contikios.cooja.interfaces.Radio; +import org.jdom.Element; /** * Abstract radio medium provides basic functionality for implementing radio @@ -68,6 +74,8 @@ public abstract class AbstractRadioMedium extends RadioMedium { public static final double SS_NOTHING = -100; public static final double SS_STRONG = -10; public static final double SS_WEAK = -95; + protected Map baseRssi = java.util.Collections.synchronizedMap(new HashMap()); + protected Map sendRssi = java.util.Collections.synchronizedMap(new HashMap()); private ArrayList registeredRadios = new ArrayList(); @@ -136,7 +144,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { /* Reset signal strengths */ for (Radio radio : getRegisteredRadios()) { - radio.setCurrentSignalStrength(SS_NOTHING); + radio.setCurrentSignalStrength(getBaseRssi(radio)); } /* Set signal strength to strong on destinations */ @@ -454,6 +462,68 @@ public abstract class AbstractRadioMedium extends RadioMedium { updateSignalStrengths(); } + /** + * Get the RSSI value that is set when there is "silence" + * + * @param radio + * The radio to get the base RSSI for + * @return The base RSSI value; Default: SS_NOTHING + */ + public double getBaseRssi(Radio radio) { + Double rssi = baseRssi.get(radio); + if (rssi == null) { + rssi = SS_NOTHING; + } + return rssi; + } + + /** + * Set the base RSSI for a radio. This value is set when there is "silence" + * + * @param radio + * The radio to set the RSSI value for + * @param rssi + * The RSSI value to set during silence + */ + public void setBaseRssi(Radio radio, double rssi) { + baseRssi.put(radio, rssi); + simulation.invokeSimulationThread(new Runnable() { + @Override + public void run() { + updateSignalStrengths(); + } + }); + } + + + /** + * Get the minimum RSSI value that is set when the radio is sending + * + * @param radio + * The radio to get the send RSSI for + * @return The send RSSI value; Default: SS_STRONG + */ + public double getSendRssi(Radio radio) { + Double rssi = sendRssi.get(radio); + if (rssi == null) { + rssi = SS_STRONG; + } + return rssi; + } + + /** + * Set the send RSSI for a radio. This is the minimum value when the radio is + * sending + * + * @param radio + * The radio to set the RSSI value for + * @param rssi + * The minimum RSSI value to set when sending + */ + public void setSendRssi(Radio radio, double rssi) { + sendRssi.put(radio, rssi); + } + public void addRadioMediumObserver(Observer observer) { radioMediumObservable.addObserver(observer); } @@ -469,5 +539,46 @@ public abstract class AbstractRadioMedium extends RadioMedium { public RadioConnection getLastConnection() { return lastConnection; } + public Collection getConfigXML() { + Collection config = new ArrayList(); + for(Entry ent: baseRssi.entrySet()){ + Element element = new Element("BaseRSSIConfig"); + element.setAttribute("Mote", "" + ent.getKey().getMote().getID()); + element.addContent("" + ent.getValue()); + config.add(element); + } + + for(Entry ent: sendRssi.entrySet()){ + Element element = new Element("SendRSSIConfig"); + element.setAttribute("Mote", "" + ent.getKey().getMote().getID()); + element.addContent("" + ent.getValue()); + config.add(element); + } + + return config; + } + + private Collection delayedConfiguration = null; + + public boolean setConfigXML(final Collection configXML, boolean visAvailable) { + delayedConfiguration = configXML; + return true; + } + + public void simulationFinishedLoading() { + if (delayedConfiguration == null) { + return; + } + + for (Element element : delayedConfiguration) { + if (element.getName().equals("BaseRSSIConfig")) { + Radio r = simulation.getMoteWithID(Integer.parseInt(element.getAttribute("Mote").getValue())).getInterfaces().getRadio(); + setBaseRssi(r, Double.parseDouble(element.getText())); + } else if (element.getName().equals("SendRSSIConfig")) { + Radio r = simulation.getMoteWithID(Integer.parseInt(element.getAttribute("Mote").getValue())).getInterfaces().getRadio(); + setSendRssi(r, Double.parseDouble(element.getText())); + } + } + } } diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java index 48d90a0f8..23db83c3c 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java @@ -144,21 +144,23 @@ public class DirectedGraphMedium extends AbstractRadioMedium { } } + + public void updateSignalStrengths() { - /* Reset signal strengths */ + /* Reset signal strengths (Default: SS_NOTHING) */ for (Radio radio : getRegisteredRadios()) { - radio.setCurrentSignalStrength(SS_NOTHING); + radio.setCurrentSignalStrength(getBaseRssi(radio)); } /* Set signal strengths */ RadioConnection[] conns = getActiveConnections(); for (RadioConnection conn : conns) { - /* When sending RSSI is Strong! - * TODO: is this reasonable + /* + * Set sending RSSI. (Default: SS_STRONG) */ - if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) { - conn.getSource().setCurrentSignalStrength(SS_STRONG); + if (conn.getSource().getCurrentSignalStrength() < getSendRssi(conn.getSource())) { + conn.getSource().setCurrentSignalStrength(getSendRssi(conn.getSource())); } //Maximum reception signal of all possible radios received DGRMDestinationRadio dstRadios[] = getPotentialDestinations(conn.getSource()); @@ -311,10 +313,10 @@ public class DirectedGraphMedium extends AbstractRadioMedium { } public Collection getConfigXML() { - ArrayList config = new ArrayList(); - Element element; + Collection config = super.getConfigXML(); for (Edge edge: getEdges()) { + Element element; element = new Element("edge"); element.addContent(edge.getConfigXML()); config.add(element); @@ -325,6 +327,8 @@ public class DirectedGraphMedium extends AbstractRadioMedium { private Collection delayedConfiguration = null; public boolean setConfigXML(Collection configXML, boolean visAvailable) { + super.setConfigXML(configXML, visAvailable); + random = simulation.getRandomGenerator(); /* Wait until simulation has been loaded */ @@ -337,6 +341,8 @@ public void simulationFinishedLoading() { return; } + super.simulationFinishedLoading(); + boolean oldConfig = false; for (Element element : delayedConfiguration) { if (element.getName().equals("edge")) { diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java b/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java index c469bb32e..e0ff8af38 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java @@ -276,7 +276,7 @@ public class UDGM extends AbstractRadioMedium { /* Reset signal strengths */ for (Radio radio : getRegisteredRadios()) { - radio.setCurrentSignalStrength(SS_NOTHING); + radio.setCurrentSignalStrength(getBaseRssi(radio)); } /* Set signal strength to below strong on destinations */ @@ -341,7 +341,7 @@ public class UDGM extends AbstractRadioMedium { } public Collection getConfigXML() { - ArrayList config = new ArrayList(); + Collection config = super.getConfigXML(); Element element; /* Transmitting range */ @@ -368,6 +368,7 @@ public class UDGM extends AbstractRadioMedium { } public boolean setConfigXML(Collection configXML, boolean visAvailable) { + super.setConfigXML(configXML, visAvailable); for (Element element : configXML) { if (element.getName().equals("transmitting_range")) { TRANSMITTING_RANGE = Double.parseDouble(element.getText()); diff --git a/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java b/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java index 46dabf38d..9ba6bd01a 100644 --- a/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java +++ b/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java @@ -187,7 +187,15 @@ public class ExecuteJAR { logger.info("Starting simulation"); Cooja.setLookAndFeel(); - Cooja.quickStartSimulationConfig(new File(executeDir, SIMCONFIG_FILENAME), false, null); + Simulation sim = Cooja.quickStartSimulationConfig(new File(executeDir, SIMCONFIG_FILENAME), false, null); + if (sim != null){ + /* Set simulation speed to maximum and start simulation */ + sim.setSpeedLimit(null); + sim.startSimulation(); + } else { + logger.fatal("Cannot load simulation, aborting"); + System.exit(1); + } } /** @@ -284,7 +292,8 @@ public class ExecuteJAR { /* Unpacking COOJA core JARs */ String[] coreJARs = new String[] { - "tools/cooja/lib/jdom.jar", "tools/cooja/lib/log4j.jar", "tools/cooja/dist/cooja.jar" + "tools/cooja/lib/jdom.jar", "tools/cooja/lib/log4j.jar", + "tools/cooja/dist/cooja.jar", "tools/cooja/lib/jsyntaxpane.jar" }; for (String jar: coreJARs) { File jarFile = new File(Cooja.getExternalToolsSetting("PATH_CONTIKI"), jar); diff --git a/tools/z1/z1-bsl-nopic b/tools/z1/z1-bsl-nopic index 9cbe4c827..db2435b92 100755 --- a/tools/z1/z1-bsl-nopic +++ b/tools/z1/z1-bsl-nopic @@ -234,6 +234,7 @@ class LowLevel: BSL_ERASE = 0x16 #Erase one segment BSL_MERAS = 0x18 #Erase complete FLASH memory BSL_CHANGEBAUD = 0x20 #Change baudrate + BSL_SETMEMOFFSET = 0x21 #Set memory offset BSL_LOADPC = 0x1A #Load PC and start execution BSL_TXVERSION = 0x1E #Get BSL version @@ -806,6 +807,7 @@ class Memory: segmentdata = [] currentAddr = 0 startAddr = 0 + offsetAddr = 0 lines = file.readlines() for l in lines: if l[0] != ':': raise BSLException("File Format Error\n") @@ -815,21 +817,32 @@ class Memory: type = int(l[7:9],16) check = int(l[-2:],16) if type == 0x00: - if currentAddr != address: + if currentAddr != offsetAddr + address: if segmentdata: self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) - startAddr = currentAddr = address + startAddr = currentAddr = offsetAddr + address segmentdata = [] for i in range(length): segmentdata.append( chr(int(l[9+2*i:11+2*i],16)) ) currentAddr = length + currentAddr - elif type in (0x01, 0x02, 0x03, 0x04, 0x05): + elif type == 0x02: + if segmentdata: + self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) + offsetAddr = int(l[9:13],16)*16 + startAddr = currentAddr = offsetAddr + segmentdata = [] + elif type in (0x01, 0x03, 0x04, 0x05): pass else: sys.stderr.write("Ignored unknown field (type 0x%02x) in ihex file.\n" % type) if segmentdata: self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) + if DEBUG: + sys.stderr.write("loadIHex\n") + for segment in self.segments: + sys.stderr.write(" Segment(startadress = 0x%04x, len = %i)\n" % (segment.startaddress, len(segment))) + def loadTIText(self, file): """load data from a (opened) file in TI-Text format""" next = 1 @@ -1012,6 +1025,11 @@ class BootStrapLoader(LowLevel): if DEBUG > 1: sys.stderr.write("* programData()\n") for seg in segments: currentAddr = seg.startaddress + offsetAddr = 0 + if (seg.startaddress > 0xFFFF): + offsetAddr = seg.startaddress >> 16 + self.bslTxRx(self.BSL_SETMEMOFFSET, 0, offsetAddr) + currentAddr = currentAddr - (offsetAddr << 16) pstart = 0 while pstart