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
172 lines
5.0 KiB
Java
4 years ago
|
// 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;
|
||
|
}
|
||
|
|
||
|
}
|