/* * Copyright (c) 2009, 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.emulatedmote; import java.util.*; import org.apache.log4j.Logger; import org.jdom.Element; import org.contikios.cooja.*; import org.contikios.cooja.interfaces.CustomDataRadio; import org.contikios.cooja.interfaces.Position; import org.contikios.cooja.interfaces.Radio; /** * 802.15.4 radio class for COOJA. * * @author Joakim Eriksson */ public abstract class Radio802154 extends Radio implements CustomDataRadio { private final static boolean DEBUG = false; private static final Logger logger = Logger.getLogger(Radio802154.class); protected long lastEventTime = 0; protected RadioEvent lastEvent = RadioEvent.UNKNOWN; protected boolean isInterfered = false; private boolean isTransmitting = false; protected boolean isReceiving = false; // private boolean hasFailedReception = false; private boolean radioOn = true; private RadioByte lastOutgoingByte = null; private RadioByte lastIncomingByte = null; private RadioPacket lastOutgoingPacket = null; private RadioPacket lastIncomingPacket = null; // private int mode; protected Mote mote; public Radio802154(Mote mote) { this.mote = mote; } int len = 0; int expLen = 0; byte[] buffer = new byte[127 + 15]; protected void handleTransmit(byte val) { if (len == 0) { lastEventTime = mote.getSimulation().getSimulationTime(); lastEvent = RadioEvent.TRANSMISSION_STARTED; if (DEBUG) logger.debug("----- 802.15.4 TRANSMISSION STARTED -----"); setChanged(); notifyObservers(); } /* send this byte to all nodes */ lastOutgoingByte = new RadioByte(val); lastEventTime = mote.getSimulation().getSimulationTime(); lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED; setChanged(); notifyObservers(); buffer[len++] = val; logger.debug("802.15.4: " + (val & 0xff) + " transmitted..."); if (len == 6) { expLen = val + 6; } if (len == expLen) { if (DEBUG) logger.debug("----- 802.15.4 CUSTOM DATA TRANSMITTED -----"); lastOutgoingPacket = Radio802154PacketConverter.fromCC2420ToCooja(buffer); lastEventTime = mote.getSimulation().getSimulationTime(); lastEvent = RadioEvent.PACKET_TRANSMITTED; if (DEBUG) logger.debug("----- 802.15.4 PACKET TRANSMITTED -----"); setChanged(); notifyObservers(); lastEventTime = mote.getSimulation().getSimulationTime(); logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----"); lastEvent = RadioEvent.TRANSMISSION_FINISHED; setChanged(); notifyObservers(); len = 0; } } /* Packet radio support */ @Override public RadioPacket getLastPacketTransmitted() { return lastOutgoingPacket; } @Override public RadioPacket getLastPacketReceived() { return lastIncomingPacket; } @Override public void setReceivedPacket(RadioPacket packet) { } /* Custom data radio support */ @Override public Object getLastCustomDataTransmitted() { return lastOutgoingByte; } @Override public Object getLastCustomDataReceived() { return lastIncomingByte; } @Override public void receiveCustomData(Object data) { if (data instanceof RadioByte) { lastIncomingByte = (RadioByte) data; handleReceive(lastIncomingByte.getPacketData()[0]); } } /* General radio support */ @Override public boolean isTransmitting() { return isTransmitting; } @Override public boolean isReceiving() { return isReceiving; } @Override public boolean isInterfered() { return isInterfered; } protected abstract void handleReceive(byte b); protected abstract void handleEndOfReception(); @Override public abstract int getChannel(); public abstract int getFrequency(); @Override public abstract boolean isRadioOn(); @Override public abstract double getCurrentOutputPower(); @Override public abstract int getCurrentOutputPowerIndicator(); @Override public abstract int getOutputPowerIndicatorMax(); @Override public abstract double getCurrentSignalStrength(); @Override public abstract void setCurrentSignalStrength(double signalStrength); /* need to add a few more methods later??? */ @Override public void signalReceptionStart() { isReceiving = true; // cc2420.setCCA(true); // hasFailedReception = mode == CC2420.MODE_TXRX_OFF; /* TODO cc2420.setSFD(true); */ lastEventTime = mote.getSimulation().getSimulationTime(); lastEvent = RadioEvent.RECEPTION_STARTED; if (DEBUG) logger.debug("----- 802.15.4 RECEPTION STARTED -----"); setChanged(); notifyObservers(); } @Override public void signalReceptionEnd() { /* Deliver packet data */ isReceiving = false; // hasFailedReception = false; isInterfered = false; // cc2420.setCCA(false); /* tell the receiver that the packet is ended */ handleEndOfReception(); lastEventTime = mote.getSimulation().getSimulationTime(); lastEvent = RadioEvent.RECEPTION_FINISHED; if (DEBUG) logger.debug("----- 802.15.4 RECEPTION FINISHED -----"); // Exception e = new IllegalStateException("Why finished?"); // e.printStackTrace(); setChanged(); notifyObservers(); } @Override public RadioEvent getLastEvent() { return lastEvent; } @Override public void interfereAnyReception() { isInterfered = true; isReceiving = false; // hasFailedReception = false; lastIncomingPacket = null; //cc2420.setCCA(true); /* is this ok ?? */ handleEndOfReception(); //recv.nextByte(false, (byte)0); lastEventTime = mote.getSimulation().getSimulationTime(); lastEvent = RadioEvent.RECEPTION_INTERFERED; /*logger.debug("----- SKY RECEPTION INTERFERED -----");*/ setChanged(); notifyObservers(); } @Override public Mote getMote() { return mote; } @Override public Position getPosition() { return mote.getInterfaces().getPosition(); } @Override public Collection getConfigXML() { return null; } @Override public void setConfigXML(Collection configXML, boolean visAvailable) { } }