?? session.java
字號:
private void safeGenericNack(int commandStatus, int sequenceNumber) throws IOException {
try {
genericNack(commandStatus, sequenceNumber);
} catch (SmppException e) {
debug.write("Ignoring unexpected SmppException caught sending generic nack.");
event.write(e, "Ignoring unexpected exception caught sending generic nack.");
}
}
/**
* Sets the state of the session.
* It's private as it's only for use by the methods of the session.
* @param state the new state of the session
* @see #checkState(int)
* @see #checkState(PDU)
* @see WrongSessionStateException
*/
private void setState(int state) {
this.state = state;
}
/**
* Returns the current state of the session.
* It's public to allow the user to check the state of the session if necessary.
* @return the current state of the session
* @see #checkState(int)
* @see #checkState(PDU)
* @see WrongSessionStateException
*/
public int getState() {
return state;
}
/**
* Enables checking if the session allows certain operation in the current state.
*/
public void enableStateChecking() {
this.stateChecking = true;
}
/**
* Disables checking if the session allows certain operation in the current state.
*/
public void disableStateChecking() {
this.stateChecking = false;
}
/**
* Checks if the session is in the state which is required by the parameter.
* If not, then exception <code>WrongSessionStateException</code> is thrown.
* Note that the states are bit values in integer, so there can be a "set"
* of states required, the session must be in one of the states required.
* The checking can be turned off, see
* <a href="#disableStateChecking()">disableStateChecking</a>.
* @param requestedState the state(s) in which the session is expected to be; if it
* is not, then exception is thrown
* @throws WrongSessionStateException if the session is not in the state
* required
* @see WrongSessionStateException
*/
public void checkState(int requestedState) throws WrongSessionStateException {
if (stateChecking) {
debug.write(
DSESS,
"checking state current=0x"
+ Integer.toHexString(state)
+ " requested esme=0x"
+ Integer.toHexString(requestedState));
if ((state & requestedState) == 0) {
throw new WrongSessionStateException(type, requestedState, state);
}
}
}
/**
* Checks if the session's state allows sending the PDU provided.
* If not, then exception <code>WrongSessionStateException</code> is thrown.
* For each state there is only a subset of PDUs which can be sent over the
* session. For example, if the session is bound as a receiver, it cannot
* submit messages, but it can send enquire link, generic nack etc.
* This method checks the PDU type (command id) aganst matrix of allowed states.
* The checking can be turned off, see
* <a href="#disableStateChecking()">disableStateChecking</a>.
* @param pdu the pdu which has to be checked if it's allowed in the current
* state
* @throws WrongSessionStateException if the session is not in the state
* required
* @see #checkState(int)
* @see WrongSessionStateException
*/
public void checkState(PDU pdu) throws WrongSessionStateException {
if (stateChecking) {
Hashtable pduMatrix = getStateMatrix(type);
Integer commandIdInteger = new Integer(pdu.getCommandId());
Integer requestedStateInteger = pduMatrix == null ? null : (Integer) pduMatrix.get(commandIdInteger);
if (requestedStateInteger != null) {
checkState(requestedStateInteger.intValue());
} else {
if (disallowUnknownPDU) {
throw new WrongSessionStateException();
}
}
}
}
/**
* Checks if the session is in the state which is required by the parameter.
* Note that this method doesn't throw an exception rather it returns false
* if the session is not in one of the provided states.
* @param requestedState the state(s) which have to be checked
* @return if the session is in on of the provided states
* @see #checkState(int)
*/
public boolean isStateAllowed(int requestedState) {
boolean stateAllowed = true;
try {
checkState(requestedState);
} catch (WrongSessionStateException e) {
stateAllowed = false;
}
return stateAllowed;
}
/**
* Checks if the pdu provided is allowed in the current session state.
* Note that this method doesn't throw an exception rather it returns false
* if the pdu is not alloewd in the current session state.
* @param pdu the pdu which has to be checked if it's allowed in the current
* state
* @return if the pdu is allowed to be sent in the current session state
* @see #checkState(PDU)
*/
public boolean isPDUAllowed(PDU pdu) {
boolean pduAllowed = true;
try {
checkState(pdu);
} catch (WrongSessionStateException e) {
pduAllowed = false;
}
return pduAllowed;
}
/**
* Initialises state matrices for checking if PDU is allowed in a certain session
* state.
*/
static {
initialiseStateMatrix();
}
/**
* Initialise list containing which operations (PDUs) valid in which state.
* @see #checkState(PDU)
* @see #type
*/
private static void initialiseStateMatrix() {
esmeStateMatrix = new Hashtable();
addValidState(esmeStateMatrix, Data.BIND_TRANSMITTER, STATE_CLOSED);
addValidState(esmeStateMatrix, Data.BIND_TRANSMITTER_RESP, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.BIND_RECEIVER, STATE_CLOSED);
addValidState(esmeStateMatrix, Data.BIND_RECEIVER_RESP, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.BIND_TRANSCEIVER, STATE_CLOSED);
addValidState(esmeStateMatrix, Data.BIND_TRANSCEIVER_RESP, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.OUTBIND, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.UNBIND, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.UNBIND_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.SUBMIT_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.SUBMIT_SM_RESP, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.SUBMIT_MULTI, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.SUBMIT_MULTI_RESP, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.DATA_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.DATA_SM_RESP, STATE_RECEIVER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.DELIVER_SM, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.DELIVER_SM_RESP, STATE_RECEIVER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.QUERY_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.QUERY_SM_RESP, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.CANCEL_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.CANCEL_SM_RESP, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.REPLACE_SM, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(esmeStateMatrix, Data.REPLACE_SM_RESP, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.ENQUIRE_LINK, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_ALWAYS);
addValidState(esmeStateMatrix, Data.ENQUIRE_LINK_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_ALWAYS);
addValidState(esmeStateMatrix, Data.ALERT_NOTIFICATION, STATE_NOT_ALLOWED);
addValidState(esmeStateMatrix, Data.GENERIC_NACK, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_ALWAYS);
mcStateMatrix = new Hashtable();
addValidState(mcStateMatrix, Data.BIND_TRANSMITTER, STATE_NOT_ALLOWED);
addValidState(
mcStateMatrix,
Data.BIND_TRANSMITTER_RESP,
STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_OPENED);
addValidState(mcStateMatrix, Data.BIND_RECEIVER, STATE_NOT_ALLOWED);
addValidState(mcStateMatrix, Data.BIND_RECEIVER_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_OPENED);
addValidState(mcStateMatrix, Data.BIND_TRANSCEIVER, STATE_NOT_ALLOWED);
addValidState(
mcStateMatrix,
Data.BIND_TRANSCEIVER_RESP,
STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_OPENED);
addValidState(mcStateMatrix, Data.OUTBIND, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_OPENED);
addValidState(mcStateMatrix, Data.UNBIND, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.UNBIND_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.SUBMIT_SM, STATE_NOT_ALLOWED);
addValidState(mcStateMatrix, Data.SUBMIT_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.SUBMIT_MULTI, STATE_NOT_ALLOWED);
addValidState(mcStateMatrix, Data.SUBMIT_MULTI_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.DATA_SM, STATE_RECEIVER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.DATA_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.DELIVER_SM, STATE_RECEIVER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.DELIVER_SM_RESP, STATE_NOT_ALLOWED);
addValidState(mcStateMatrix, Data.QUERY_SM, STATE_NOT_ALLOWED);
addValidState(mcStateMatrix, Data.QUERY_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.CANCEL_SM, STATE_NOT_ALLOWED);
addValidState(mcStateMatrix, Data.CANCEL_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.REPLACE_SM, STATE_NOT_ALLOWED);
addValidState(mcStateMatrix, Data.REPLACE_SM_RESP, STATE_TRANSMITTER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.ENQUIRE_LINK, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_ALWAYS);
addValidState(mcStateMatrix, Data.ENQUIRE_LINK_RESP, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_ALWAYS);
addValidState(mcStateMatrix, Data.ALERT_NOTIFICATION, STATE_RECEIVER | STATE_TRANSCEIVER);
addValidState(mcStateMatrix, Data.GENERIC_NACK, STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER);
// STATE_ALWAYS);
}
/**
* Adds to the matrix a set of states in which can be sent a PDU with the
* provided command id.
* @param matrix the matrix to add the mapping to
* @param commandId the commandId of the PDU the mapping is created for
* @param state the state(s) in which is the PDU valid
* @see #checkState(PDU)
* @see #isStateAllowed(int)
*/
private static void addValidState(Hashtable matrix, int commandId, int state) {
matrix.put(new Integer(commandId), new Integer(state));
}
/**
* Returns the state matrix for the requested session type.
* @see #type
* @see #TYPE_ESME
* @see #TYPE_MC
* @see #initialiseStateMatrix()
*/
private static Hashtable getStateMatrix(int type) {
switch (type) {
case TYPE_ESME :
return esmeStateMatrix;
case TYPE_MC :
return mcStateMatrix;
default :
return null;
}
}
/**
* God, I would never think that to keep unbind synchronous in
* an asynchronous enviroment would be so funny. Here is the replacement
* listener which encapsulates the original listener and hunts for the
* unbind pdu. Good luck, you source code reader!<br>
* The problem is that we want to return a response from session's unbind()
* even if the session is asynchronous, i.e. all pdus from the smsc
* are passed to an implementation of <code>ServerPDUEventListener</code>
* event responses. We can't simply stop the asynchronicity
* as there can still be some responses expected, so we need a bridge
* which allows us to wait for the unbind response and still serve
* the other pdus from the smsc in asynchronous manner. Thus this
* encapsulating listener, which exactly does the thing.
*/
private class UnbindServerPDUEventListener extends SmppObject implements ServerPDUEventListener {
Session session;
ServerPDUEventListener origListener;
Unbind unbindReq;
UnbindResp expectedResp;
UnbindResp unbindResp = null;
public UnbindServerPDUEventListener(Session session, ServerPDUEventListener origListener, Unbind unbindReq) {
this.session = session;
this.origListener = origListener;
this.unbindReq = unbindReq;
expectedResp = (UnbindResp) unbindReq.getResponse();
}
public void handleEvent(ServerPDUEvent event) {
PDU pdu = event.getPDU();
if (pdu.getSequenceNumber() == unbindReq.getSequenceNumber()) {
synchronized (this) {
try {
unbindResp = (UnbindResp) (session.checkResponse(pdu, expectedResp));
} catch (Exception e) {
debug.write(DSESS, "exception handling unbind " + e);
SmppObject.event.write(e, "exception handling unbind");
}
// notify as session waits for the notification
this.notify();
}
} else {
// all other pdus are processed by the original handler,
// if any
if (origListener != null) {
origListener.handleEvent(event);
}
}
}
public UnbindResp getUnbindResp() {
return unbindResp;
}
}
}
/*
* $Log: Session.java,v $
* Revision 1.4 2006/03/09 16:24:14 sverkera
* Removed compiler and javadoc warnings
*
* Revision 1.3 2006/02/22 16:45:01 paoloc
* UnbindServerPDUEventListener: if (pdu.equals(unbindReq)): as reported by users, this is incompatible with the new improved PDU.equals(); fixed.
*
* Revision 1.2 2004/09/10 23:03:44 sverkera
* Added isOpened method
*
* Revision 1.1 2003/07/23 00:28:39 sverkera
* Imported
*
*
* Old changelog:
* 08-08-01 ticp@logica.com added asynchronous processing capability
* 02-10-01 ticp@logica.com tracing now belongs to DSESS group
* 20-11-01 ticp@logica.com the receiver thread is now started even for
* the transmitter session - before transmitter
* sessions couldn't receive anything
* 20-11-01 ticp@logica.com receiver thread is started after the bind request
* is sent to the MC, before it was started before the bind
* req was sent to MC, therefore the response could be processed
* by the listener
* 22-11-01 ticp@logica.com implemented session states with checking if certain
* operation is allowed in the current session state
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -