// ABPSender.java package protocol; // protocol package import java.util.Enumeration; // enumeration import java.util.Vector; // vector (list) import support.*; // protocol entity support /** This is the class for the alternating bit protocol sender. @author Iain A. Robin, Kenneth J. Turner @version 1.0 (1st September 1999, IAR): initial version
1.4 (9th March 2006, KJT): updated for JDK 1.5
1.5 (27th July 2010, KJT): minor tidying */ public class ABPSender implements ProtocolEntity, Timeouts { private PDU pduBeingSent; private PDU pduReceived; private ProtocolEntity peer; private Medium medium; private String name; private boolean timerEnabled; private Vector entityEvents; // events from entity public ABPSender(Medium m, String name) { this.name = name; medium = m; initialise(); } public String getName() { return(name); } public Vector getServices() { Vector list = new Vector(); if (pduReceived != null && pduReceived.type.equals("ACK")) { list.addElement("Send DATA(" + pduReceived.seq + ")"); timerEnabled = false; } if (timerEnabled) list.addElement("Timeout - presume loss of message and resend"); return(list); } public boolean hasTimer(String type) { return(true); } /** Increment PDU sequence number (0 or 1 only in ABP protocol) */ private int inc(int seq) { return(1 - seq); } public void initialise() { // dummy initial data PDU pduBeingSent = new PDU("DATA", 1); pduBeingSent.setSource(this); // dummy initial ack PDU pduReceived = new PDU("ACK", 0); timerEnabled = false; entityEvents = new Vector(); // empty medium events } public Vector performService(String s) { Vector events = new Vector(); if (s.startsWith("Send DATA")) { // PDU seq number delimited by brackets: int startIndex = s.indexOf( '(' ) + 1; int endIndex = s.indexOf( ')' ); int seq = Integer.parseInt(s.substring(startIndex, endIndex)); transmitPDU(new PDU("DATA", seq), peer); events.addElement( new ProtocolEvent(ProtocolEvent.TRANSMIT, pduBeingSent)); } if (s.startsWith("Timeout")) { transmitPDU(pduBeingSent, peer); events.addElement( new ProtocolEvent(ProtocolEvent.TIMEOUT, pduBeingSent)); } for (Enumeration e = entityEvents.elements(); // get medium events e.hasMoreElements(); ) events.addElement( // add medium event (ProtocolEvent) e.nextElement()); return(events); } public Vector receivePDU(PDU pdu) { pduReceived = pdu; return(new Vector()); } public void setPeer(ProtocolEntity peer) { this.peer = peer; } /** Set the timer for a specified PDU. @param pdu PDU @param enabled whether the timer is enabled */ public void setTimer(PDU pdu, boolean enabled) { timerEnabled = enabled; } public void transmitPDU(PDU pdu, ProtocolEntity dest) { pdu.setSource(this); pdu.setDestination(dest); pduBeingSent = pdu; entityEvents = medium.receivePDU(pdu); // medium receives PDU pduReceived = null; timerEnabled = false; } }