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.

172 lines
5.0 KiB
Java

// ABRAService.java (C) I. A. Robin, K. J. Turner 08/03/06
package protocol;
import java.util.*;
import support.*;
public class ABRAService implements ProtocolEntity {
// Service state constants
private static final int DISCONNECTED = 0; // no connection in progress
// or active
private static final int CALLING = 1; // connection initiated by local
// user is being established
private static final int CALLED = 2; // connection initiated by remote
// user is being established
private static final int CONNECTED = 3; // data transfer is possible
// Service primitives
public static final String CON_REQ = "Connection Request";
public static final String CON_IND = "Connection Indication";
public static final String CON_RESP = "Connection Response";
public static final String CON_CONF = "Connection Confirmation";
public static final String DAT_REQ = "Data Request";
public static final String DAT_IND = "Data Indication";
public static final String DIS_REQ = "Disconnection Request";
public static final String DIS_IND = "Disconnection Indication";
private ProtocolEntity provider; // protocol providing service
private Vector providerEvents;
private PDU pduSent;
private String name;
private int state;
private int block; // sequence number of data block
private boolean okToSend; // OK to send DatReq to provider
public ABRAService(String name) {
this.name = name;
initialise();
}
public String getName() {
return(name);
}
public Vector<String> getServices() {
Vector<String> list = new Vector<String>();
switch (state) {
case DISCONNECTED:
list.addElement("Send " + CON_REQ);
break;
case CALLING:
list.addElement("Send " + DIS_REQ);
break;
case CALLED:
list.addElement("Send " + CON_RESP);
list.addElement("Send " + DIS_REQ);
break;
case CONNECTED:
if (okToSend)
list.addElement("Send " + DAT_REQ + "(D" + block + ")");
list.addElement("Send " + DIS_REQ);
break;
}
return(list);
}
public void initialise() {
block = 0;
okToSend = true;
providerEvents = new Vector();
state = DISCONNECTED;
}
public Vector<ProtocolEvent> performService(String s) {
Vector<ProtocolEvent> events = new Vector<ProtocolEvent>();
switch (state) {
case DISCONNECTED:
if (s.equals("Send " + CON_REQ)) {
transmitPDU(new PDU("ConReq"), provider);
events.addElement(
new ProtocolEvent(ProtocolEvent.SEND, pduSent));
state = CALLING;
}
case CALLING:
if (s.equals("Send " + DIS_REQ)) {
transmitPDU(new PDU("DisReq"), provider);
events.addElement(
new ProtocolEvent(ProtocolEvent.SEND, pduSent));
state = DISCONNECTED;
}
break;
case CALLED:
if (s.equals("Send " + CON_RESP)) {
transmitPDU(new PDU("ConResp"), provider);
events.addElement(
new ProtocolEvent(ProtocolEvent.SEND, pduSent));
state = CONNECTED;
}
if (s.equals("Send " + DIS_REQ)) {
transmitPDU(new PDU("DisReq"), provider);
events.addElement(
new ProtocolEvent(ProtocolEvent.SEND, pduSent));
state = DISCONNECTED;
}
break;
case CONNECTED:
if (s.startsWith("Send " + DAT_REQ)) {
String sdu = "D" + block;
transmitPDU(new PDU("DatReq", sdu), provider);
block++;
events.addElement(
new ProtocolEvent(ProtocolEvent.SEND, pduSent));
// No state transition
}
if (s.equals("Send " + DIS_REQ)) {
transmitPDU(new PDU("DisReq"), provider);
events.addElement(
new ProtocolEvent(ProtocolEvent.SEND, pduSent));
state = DISCONNECTED;
}
}
for (Enumeration e = providerEvents.elements(); e.hasMoreElements(); )
events.addElement((ProtocolEvent) e.nextElement());
return(events);
}
/** Respond to PDU received from underlying protocol */
public Vector<ProtocolEvent> receivePDU(PDU pdu) {
Vector<ProtocolEvent> events = new Vector<ProtocolEvent>();
String pduType = pdu.type;
switch (state) {
case DISCONNECTED:
if (pduType.equals("ConInd")) state = CALLED;
break;
case CALLING:
// Is the ConInd possibility below needed?
if (pduType.equals("ConConf")
|| pduType.equals("ConInd")) state = CONNECTED;
if (pduType.equals("DisInd")) state = DISCONNECTED;
break;
case CALLED:
if (pduType.equals("DisInd")) state = DISCONNECTED;
break;
case CONNECTED:
if (pduType.equals("DisInd")) state = DISCONNECTED;
break;
}
return(events);
}
/** Implements flow control by back-pressure. DatReq allowed only when
okToSend is true */
public void setOKToSend(boolean ok) {
okToSend = ok;
}
public void setProvider(ProtocolEntity provider) {
this.provider = provider;
}
public void transmitPDU(PDU pdu, ProtocolEntity dest) {
pdu.setSource(this);
pdu.setDestination(dest);
providerEvents = dest.receivePDU(pdu);
pduSent = pdu;
}
}