You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
3.3 KiB
Java

// 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
<br/> 1.4 (9th March 2006, KJT): updated for JDK 1.5
<br/> 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<ProtocolEvent> entityEvents; // events from entity
public ABPSender(Medium m, String name) {
this.name = name;
medium = m;
initialise();
}
public String getName() {
return(name);
}
public Vector<String> getServices() {
Vector<String> list = new Vector<String>();
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<ProtocolEvent>(); // empty medium events
}
public Vector<ProtocolEvent> performService(String s) {
Vector<ProtocolEvent> events = new Vector<ProtocolEvent>();
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<ProtocolEvent> receivePDU(PDU pdu) {
pduReceived = pdu;
return(new Vector<ProtocolEvent>());
}
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;
}
}