package device; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Collections; import java.util.LinkedList; import java.util.List; import map.MapLayer; import map.NetworkParameters; import radio_module.ErrorBits; import radio_module.RadioPacketGenerator; import radio_module.RadioStandard; import utilities.MapCalc; import wisen_simulation.SimLog; import wisen_simulation.SimulationInputs; public class Channels { public static int numberOfSentMessages = 0; public static int numberOfReceivedMessages = 0; public static int numberOfAckMessages = 0; public static int numberOfLostMessages = 0; protected List<List<PacketEvent>> channelEventList = Collections.synchronizedList(new LinkedList<List<PacketEvent>>()); //protected LinkedList<List<PacketEvent>> channelEventList = new LinkedList<List<PacketEvent>>(); public Channels(int std) { super(); init(std); } public void init(int std) { channelEventList = new LinkedList<List<PacketEvent>>(); int channelNumber = 0; if(std == RadioStandard.ZIGBEE_802_15_4) channelNumber = 16; if(std == RadioStandard.LORA) channelNumber = 1; if(std == RadioStandard.WIFI_802_11) channelNumber = 14; for(int i=0; i < channelNumber; i++) { channelEventList.add(new LinkedList<PacketEvent>()); } } public void addPacketEvent(int type, String message, SensorNode tSensor, SensorNode rSensor) { // type=0 : Direct sending // type=1 : ACK sending // type=2 : Broadcast sending if((!rSensor.isReceiving() || !SimulationInputs.ack) || type==1) { if(type == 1) numberOfAckMessages++; SimLog.add("S" + rSensor.getId() +" (radio: " + rSensor.getCurrentRadioModule().getName() + ") is receiving the message : \"" + message + "\" in its buffer."); double ratio1 = 1.0/tSensor.getCurrentRadioModule().getRadioDataRate(); double ratio2 = 1.0/rSensor.getUartDataRate(); double durationOfSending = ratio1*(RadioPacketGenerator.packetLengthInBits(type, tSensor.getStandard())) ; double durationOfUARTReceiving = 0; if(type==1) durationOfUARTReceiving = 0 ; else durationOfUARTReceiving = ratio2*(message.length()*8) ; double duration = durationOfSending + durationOfUARTReceiving ; double lastTime = 0; tSensor.setSending(true); rSensor.setReceiving(true); PacketEvent packetEvent = new PacketEvent(type, tSensor, rSensor, message, lastTime+duration); channelEventList.get(tSensor.getCurrentRadioModule().getCh()).add(packetEvent); //Collections.sort(channelEventList.get(sSensor.getCurrentRadioModule().getCh())); //System.out.println(WisenSimulation.time+ " " + channelEventList); } } public void receivedMessages() { for (List<PacketEvent> packetEventList : channelEventList) { while(packetEventList.size()>0 && packetEventList.get(0).getTime()==0) { int type = packetEventList.get(0).getType(); String message = packetEventList.get(0).getMessage(); SensorNode tSensor = packetEventList.get(0).getSSensor(); SensorNode rSensor = packetEventList.get(0).getRSensor(); rSensor.setDrssi(tSensor.distance(rSensor)); numberOfReceivedMessages++; rSensor.consumeRx(RadioPacketGenerator.packetLengthInBits(type, tSensor.getStandard())); boolean errorBitsOk = ErrorBits.errorBitsOk(message, tSensor, rSensor); tSensor.setSending(false); rSensor.setReceiving(false); // type=0 : Direct sending // type=1 : ACK sending // type=2 : Broadcast sending if ((type == 0) || (type == 2)) { if (errorBitsOk || (type == 2)) { rSensor.addMessageToBuffer(packetEventList.get(0).getMessage()); if(rSensor.getScript().getCurrent().isWait()) { rSensor.setEvent(0); } if((type == 0) && (SimulationInputs.ack)) { addPacketEvent(1, "", rSensor, tSensor); } } } if (type == 1) { tSensor.setAckWaiting(false); rSensor.setAckReceived(true); rSensor.setAckWaiting(false); rSensor.setEvent(0); } packetEventList.remove(0); } } } public void goToTheNextTime(double min) { for (List<PacketEvent> packetEvent : channelEventList) { for (PacketEvent packet : packetEvent) { packet.setTime(packet.getTime()-min); } } } public double getMin() { double min = Double.MAX_VALUE; for (List<PacketEvent> PacketEventList : channelEventList) { if(PacketEventList.size()>0) { if (PacketEventList.get(0).getTime() < min) min = PacketEventList.get(0).getTime(); } } return min; } public void drawChannelLinks(Graphics g) { for(List<PacketEvent> packetEventList : channelEventList) { if(packetEventList.size()>0) { Graphics2D g2 = (Graphics2D) g; g2.setStroke(new BasicStroke(2f)); if(MapLayer.mapViewer.getZoom() > 3) { g2.setStroke(new BasicStroke(1f)); } if(MapLayer.mapViewer.getZoom() < 2) { g2.setStroke(new BasicStroke(3)); } int [] coord ; int lx1 ; int ly1 ; int lx2 ; int ly2 ; double dx = 0; double dy = 0; double alpha = 0; for(int idx=0; idx<packetEventList.size(); idx++) { //for(PacketEvent packetEvent : packetEventList) { try { PacketEvent packetEvent = packetEventList.get(idx); if(packetEvent.getSSensor().isSending() && packetEvent.getRSensor().isReceiving()) { if(packetEvent.getType()==0 || packetEvent.getType()==2 || ((packetEvent.getType()==1) && SimulationInputs.showAckLinks)) { g.setColor(packetEvent.getSSensor().getRadioLinkColor()); if((packetEvent.getType()==1) && SimulationInputs.showAckLinks) { g.setColor(Color.BLACK); if(MapLayer.dark) g.setColor(Color.ORANGE); } coord = MapCalc.geoToPixelMapA(packetEvent.getSSensor().getLatitude(), packetEvent.getSSensor().getLongitude()); lx1 = coord[0]; ly1 = coord[1]; coord = MapCalc.geoToPixelMapA(packetEvent.getRSensor().getLatitude(), packetEvent.getRSensor().getLongitude()); lx2 = coord[0]; ly2 = coord[1]; dx = lx2 - lx1; dy = ly2 - ly1; g.drawLine(lx1, ly1, lx2, ly2); alpha = Math.atan(dy / dx); alpha = 180 * alpha / Math.PI; int as = 14; if(MapLayer.mapViewer.getZoom() < 2) { as = 21; } if(MapLayer.mapViewer.getZoom() > 3) { as = 10; } if (dx >= 0) g.fillArc((int) lx2 - as, (int) ly2 - as, as*2, as*2,180 - (int) alpha - as, as*2); else g.fillArc((int) lx2 - as, (int) ly2 - as, as*2, as*2, -(int) alpha - as, as*2); if(NetworkParameters.displayRadioMessages) { if(packetEvent.getType()!=1) { MapLayer.drawMessage(lx1, lx2, ly1, ly2, packetEvent.getMessage(), g2); MapLayer.drawMessageAttempts(lx1, lx2, ly1, ly2, ""+(packetEvent.getSSensor().getAttempts()+1), g2); } } } } } catch (Exception e) {} } } } } public void display() { String s=""; for (List<PacketEvent> PacketEventList : channelEventList) { s += "[" ; for (PacketEvent p : PacketEventList) { s += p.toString() + " | "; } s += "]\n"; } System.out.println(s); } }