From e4858a2ade13704b10e9b490186600bd8ed60a3e Mon Sep 17 00:00:00 2001 From: fros4943 Date: Wed, 1 Apr 2009 17:43:17 +0000 Subject: [PATCH] update ip interface to supports ipv6 addresses. also disabled writing IP addresses from inside COOJA, since the these should rather be determined by Contiki --- .../mspmote/interfaces/MspIPAddress.java | 117 +-------- .../interfaces/ContikiIPAddress.java | 117 +-------- .../se/sics/cooja/interfaces/IPAddress.java | 225 ++++++++++++++++-- 3 files changed, 224 insertions(+), 235 deletions(-) diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspIPAddress.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspIPAddress.java index 0075b5a31..14004a186 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspIPAddress.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspIPAddress.java @@ -26,136 +26,23 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: MspIPAddress.java,v 1.3 2009/03/21 15:49:29 fros4943 Exp $ + * $Id: MspIPAddress.java,v 1.4 2009/04/01 17:43:18 fros4943 Exp $ */ package se.sics.cooja.mspmote.interfaces; -import java.util.Collection; -import java.util.Observable; -import java.util.Observer; -import javax.swing.JLabel; -import javax.swing.JPanel; import org.apache.log4j.Logger; -import org.jdom.Element; - import se.sics.cooja.Mote; -import se.sics.cooja.TimeEvent; -import se.sics.cooja.AddressMemory.UnknownVariableException; import se.sics.cooja.interfaces.IPAddress; -import se.sics.cooja.mspmote.MspMote; -import se.sics.cooja.mspmote.MspMoteMemory; public class MspIPAddress extends IPAddress { private static Logger logger = Logger.getLogger(MspIPAddress.class); - private MspMote mote; - private MspMoteMemory moteMem = null; - public MspIPAddress(Mote mote) { - this.mote = (MspMote) mote; - this.moteMem = (MspMoteMemory) mote.getMemory(); - - TimeEvent updateWhenAddressReady = new TimeEvent(0) { - public void execute(long t) { - if (getIPString().equals("0.0.0.0")) { - MspIPAddress.this.mote.getSimulation().scheduleEvent( - this, - MspIPAddress.this.mote.getSimulation().getSimulationTime() + 10); - return; - } - setChanged(); - notifyObservers(); - } - }; - mote.getSimulation().scheduleEvent( - updateWhenAddressReady, - mote.getSimulation().getSimulationTime() + 10 - ); - } - - public String getIPString() { - try { - byte[] addr = moteMem.getByteArray("uip_hostaddr", 4); - return - (addr[0]&0xFF) + "." + - (addr[1]&0xFF) + "." + - (addr[2]&0xFF) + "." + - (addr[3]&0xFF); - } catch (UnknownVariableException e) { - /*logger.warn("IP Address not available on mote: " + e.getMessage());*/ - } - return "?.?.?.?"; - } - - public void setIPString(String ipAddress) { - String[] ipArray = ipAddress.split("\\."); - if (ipArray.length < 4) { - logger.warn("Could not set ip address (" + ipAddress + ")"); - } else { - setIPNumber((char) Integer.parseInt(ipArray[0]), (char) Integer - .parseInt(ipArray[1]), (char) Integer.parseInt(ipArray[2]), - (char) Integer.parseInt(ipArray[3])); - } - } - - public void setIPNumber(char a, char b, char c, char d) { - try { - byte[] addr = new byte[4]; - - addr[0] = (byte) a; - addr[1] = (byte) b; - addr[2] = (byte) c; - addr[3] = (byte) d; - moteMem.setByteArray("uip_hostaddr", addr); - } catch (UnknownVariableException e) { - logger.fatal("IP Address not available on mote: " + e.getMessage()); - } - - setChanged(); - notifyObservers(); - } - - public JPanel getInterfaceVisualizer() { - JPanel panel = new JPanel(); - final JLabel ipLabel = new JLabel(); - - ipLabel.setText("IPv4 address: " + getIPString()); - - panel.add(ipLabel); - - Observer observer; - this.addObserver(observer = new Observer() { - public void update(Observable obs, Object obj) { - ipLabel.setText("IPv4 address: " + getIPString()); - } - }); - - // Saving observer reference for releaseInterfaceVisualizer - panel.putClientProperty("intf_obs", observer); - - return panel; - } - - public void releaseInterfaceVisualizer(JPanel panel) { - Observer observer = (Observer) panel.getClientProperty("intf_obs"); - if (observer == null) { - logger.fatal("Error when releasing panel, observer is null"); - return; - } - - this.deleteObserver(observer); + super(mote); } public double energyConsumption() { return 0; } - - public Collection getConfigXML() { - return null; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { - } - } diff --git a/tools/cooja/java/se/sics/cooja/contikimote/interfaces/ContikiIPAddress.java b/tools/cooja/java/se/sics/cooja/contikimote/interfaces/ContikiIPAddress.java index 606e70f68..892f3eef3 100644 --- a/tools/cooja/java/se/sics/cooja/contikimote/interfaces/ContikiIPAddress.java +++ b/tools/cooja/java/se/sics/cooja/contikimote/interfaces/ContikiIPAddress.java @@ -26,16 +26,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ContikiIPAddress.java,v 1.5 2009/02/25 14:46:24 fros4943 Exp $ + * $Id: ContikiIPAddress.java,v 1.6 2009/04/01 17:43:18 fros4943 Exp $ */ package se.sics.cooja.contikimote.interfaces; -import java.util.*; -import javax.swing.*; import org.apache.log4j.Logger; -import org.jdom.Element; - import se.sics.cooja.*; import se.sics.cooja.contikimote.ContikiMoteInterface; import se.sics.cooja.interfaces.IPAddress; @@ -43,135 +39,46 @@ import se.sics.cooja.interfaces.IPAddress; /** * uIP IP address. * - * Contiki variables: + * Contiki variables (currently not activated): *
    - *
  • char simIPa - *
  • char simIPb - *
  • char simIPc - *
  • char simIPd + *
  • char simIP[4], or char simIP[16] + *
  • int simIPv4 + *
  • int simIPv6 *
  • char simIPChanged (1 if new IP should be set) *
*

* - * The new IP will be "simIPa.simIPb.simIPc.simIPd". - * Note that this mote interface does not detect if Contiki changes IP address. - * * Core interface: *

    *
  • ip_interface *
* - * This observable notifies when the IP address is set or altered. + * This observable notifies when the IP address is set. + * Note that this mote interface does not detect if Contiki changes IP address at run-time. * * @author Fredrik Osterlind */ public class ContikiIPAddress extends IPAddress implements ContikiMoteInterface { - private SectionMoteMemory moteMem = null; private static Logger logger = Logger.getLogger(ContikiIPAddress.class); /** * Creates an interface to the IP address at mote. * - * @param mote - * IP address' mote. + * @param mote IP address' mote. * @see Mote * @see se.sics.cooja.MoteInterfaceHandler */ - public ContikiIPAddress(Mote mote) { - this.moteMem = (SectionMoteMemory) mote.getMemory(); + public ContikiIPAddress(final Mote mote) { + super(mote); } public static String[] getCoreInterfaceDependencies() { - return new String[]{"ip_interface"}; - } - - public String getIPString() { - return - (int) moteMem.getByteValueOf("simIPa") - + "." + - (int) moteMem.getByteValueOf("simIPb") - + "." + - (int) moteMem.getByteValueOf("simIPc") - + "." + - (int) moteMem.getByteValueOf("simIPd"); - } - - public void setIPString(String ipAddress) { - String[] ipArray = ipAddress.split("\\."); - if (ipArray.length < 4) { - logger.warn("Could not set ip address (" + ipAddress + ")"); - } else { - setIPNumber((char) Integer.parseInt(ipArray[0]), (char) Integer - .parseInt(ipArray[1]), (char) Integer.parseInt(ipArray[2]), - (char) Integer.parseInt(ipArray[3])); - } - } - - public void setIPNumber(char a, char b, char c, char d) { - moteMem.setByteValueOf("simIPa", (byte) a); - moteMem.setByteValueOf("simIPb", (byte) b); - moteMem.setByteValueOf("simIPc", (byte) c); - moteMem.setByteValueOf("simIPd", (byte) d); - moteMem.setByteValueOf("simIPChanged", (byte) 1); - - setChanged(); - notifyObservers(); - } - - public JPanel getInterfaceVisualizer() { - JPanel panel = new JPanel(); - final JLabel ipLabel = new JLabel(); - - ipLabel.setText("IPv4 address: " + getIPString()); - - panel.add(ipLabel); - - Observer observer; - this.addObserver(observer = new Observer() { - public void update(Observable obs, Object obj) { - ipLabel.setText("IPv4 address: " + getIPString()); - } - }); - - // Saving observer reference for releaseInterfaceVisualizer - panel.putClientProperty("intf_obs", observer); - - return panel; - } - - public void releaseInterfaceVisualizer(JPanel panel) { - Observer observer = (Observer) panel.getClientProperty("intf_obs"); - if (observer == null) { - logger.fatal("Error when releasing panel, observer is null"); - return; - } - - this.deleteObserver(observer); + /*return new String[]{"ip_interface"};*/ + return null; } public double energyConsumption() { // Virtual interface, does not require any energy return 0.0; } - - public Collection getConfigXML() { - Vector config = new Vector(); - Element element; - - // Infinite boolean - element = new Element("ipv4address"); - element.setText(getIPString()); - config.add(element); - - return config; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { - for (Element element : configXML) { - if (element.getName().equals("ipv4address")) { - setIPString(element.getText()); - } - } - } - } diff --git a/tools/cooja/java/se/sics/cooja/interfaces/IPAddress.java b/tools/cooja/java/se/sics/cooja/interfaces/IPAddress.java index 4e5964801..564068aff 100644 --- a/tools/cooja/java/se/sics/cooja/interfaces/IPAddress.java +++ b/tools/cooja/java/se/sics/cooja/interfaces/IPAddress.java @@ -26,41 +26,236 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: IPAddress.java,v 1.2 2008/10/28 12:30:48 fros4943 Exp $ + * $Id: IPAddress.java,v 1.3 2009/04/01 17:43:17 fros4943 Exp $ */ package se.sics.cooja.interfaces; +import java.util.Collection; +import java.util.Observable; +import java.util.Observer; +import java.util.Vector; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +import org.apache.log4j.Logger; +import org.jdom.Element; + import se.sics.cooja.*; /** - * IP Address represents a mote Internet address. An implementation should notify all - * observers if the address is set or changed. + * IPv4 or IPv6 address. * * @author Fredrik Osterlind */ -@ClassDescription("IPv4 Address") +@ClassDescription("IP Address") public abstract class IPAddress extends MoteInterface { + private static Logger logger = Logger.getLogger(IPAddress.class); + private AddressMemory moteMem; + private static boolean warnedNotImplemented = false; + + public IPAddress(final Mote mote) { + moteMem = (AddressMemory) mote.getMemory(); + + /* Detect startup IP (only zeroes) */ + TimeEvent updateWhenAddressReady = new TimeEvent(0) { + public void execute(long t) { + if (!isVersion4() && !isVersion6()) { + return; + } + + String ipString = getIPString(); + ipString = ipString.replace(".", ""); + ipString = ipString.replace("0", ""); + if (!ipString.isEmpty()) { + setChanged(); + notifyObservers(); + return; + } + + /* Postpone until IP has been set */ + mote.getSimulation().scheduleEvent( + this, + mote.getSimulation().getSimulationTime() + 1); + return; + } + }; + updateWhenAddressReady.execute(0); + } /** - * Get current IP address on the form a.b.c.d. + * Returns IP address string. + * Supports both IPv4 and IPv6 addresses. + * + * @see #setIPString(String) * @return IP address string */ - public abstract String getIPString(); + public String getIPString() { + if (isVersion4()) { + String ipString = ""; + byte[] ip = moteMem.getByteArray("uip_hostaddr", 4); + for (int i=0; i < 3; i++) { + ipString += (0xFF & ip[i]) + "."; + } + ipString += ip[3]; + return ipString; + } else if (isVersion6()) { + String ipString = ""; + + /* XXX Assuming fixed offset in struct uip_netif (uip-netif.h) */ + int offset = + 4*4 /* 4 uint32_t */ + 2*moteMem.getIntegerLength() /* 2 uint8_t */; + byte[] tmp = moteMem.getByteArray( + "uip_netif_physical_if", + offset + 16); + byte[] ip = new byte[16]; + System.arraycopy(tmp, offset, ip, 0, 16); + + int i=0; + while (i < 14) { + int val = (0xFF&ip[i+1]) + ((0xFF&ip[i])<<8); + ipString += hex16ToString(val) + "."; + i+=2; + } + int val = (0xFF&ip[15]) + ((0xFF&ip[14])<<8); + ipString += hex16ToString(val); + + return ipString; + } + return null; + } /** - * Change/Set IP address. - * @param ipAddress IP string on the form a.b.c.d + * @return True if mote has an IPv4 address */ - public abstract void setIPString(String ipAddress); + public boolean isVersion4() { + return moteMem.variableExists("uip_hostaddr"); + } /** - * Change/Set IP address. - * @param a First byte of IP address - * @param b Second byte of IP address - * @param c Third byte of IP address - * @param d Fourth byte of IP address + * @return True if mote has an IPv6 address */ - public abstract void setIPNumber(char a, char b, char c, char d); + public boolean isVersion6() { + return moteMem.variableExists("uip_netif_physical_if"); + } + /** + * Set IPv4 address: a.b.c.d. + * + * @param a First byte + * @param b Second byte + * @param c Third byte + * @param d Fourth byte + */ + public void setIPv4Address(int a, int b, int c, int d) { + /* TODO Implement */ + if (!warnedNotImplemented) { + warnedNotImplemented = true; + logger.warn("Changing IP addresses is no longer supported."); + logger.warn("The IP address is instead determined by Contiki, for example based on the MAC/Rime address, or the node ID."); + } + } + + /** + * Set IPv6 address. + * + * @param address 16 element IP address array + */ + public void setIPv6Address(int[] address) { + /* TODO Implement */ + if (!warnedNotImplemented) { + warnedNotImplemented = true; + logger.warn("Changing IP addresses is no longer supported."); + logger.warn("The IP address is instead determined by Contiki, for example based on the MAC/Rime address, or the node ID."); + } + } + + /** + * Set IP address. + * Supports both IPv4 and IPv6 addresses. + * + * @see #getIPString() + * @param ipString IP address string + */ + public void setIPString(String ipString) { + /* TODO Implement */ + if (!warnedNotImplemented) { + warnedNotImplemented = true; + logger.warn("Changing IP addresses is no longer supported."); + logger.warn("The IP address is instead determined by Contiki, for example based on the MAC/Rime address, or the node ID."); + } + } + + public JPanel getInterfaceVisualizer() { + JPanel panel = new JPanel(); + final JLabel ipLabel = new JLabel(); + + if (isVersion4()) { + ipLabel.setText("IPv4 address: " + getIPString()); + } else if (isVersion6()) { + ipLabel.setText("IPv6 address: " + getIPString()); + } else { + ipLabel.setText("Unknown IP"); + } + + panel.add(ipLabel); + + Observer observer; + this.addObserver(observer = new Observer() { + public void update(Observable obs, Object obj) { + if (isVersion4()) { + ipLabel.setText("IPv4 address: " + getIPString()); + } else if (isVersion6()) { + ipLabel.setText("IPv6 address: " + getIPString()); + } else { + ipLabel.setText("Unknown IP"); + } + } + }); + + panel.putClientProperty("intf_obs", observer); + + return panel; + } + + public void releaseInterfaceVisualizer(JPanel panel) { + Observer observer = (Observer) panel.getClientProperty("intf_obs"); + if (observer == null) { + logger.fatal("Error when releasing panel, observer is null"); + return; + } + + this.deleteObserver(observer); + } + + + public Collection getConfigXML() { + Vector config = new Vector(); + Element element; + + // Infinite boolean + element = new Element("ip"); + element.setText(getIPString()); + config.add(element); + + return config; + } + + public void setConfigXML(Collection configXML, boolean visAvailable) { + for (Element element : configXML) { + if (element.getName().equals("ip")) { + setIPString(element.getText()); + } + } + } + + private static String hex16ToString(int data) { + String str16 = "0000000000000000"; + String s = Integer.toString(data & 0xffff, 16); + if (s.length() < 4) { + s = str16.substring(0, 4 - s.length()) + s; + } + return s; + } }