session.java
来自「Logica lastest SMPP API」· Java 代码 · 共 1,451 行 · 第 1/4 页
JAVA
1,451 行
/* * Copyright (c) 1996-2001 * Logica Mobile Networks Limited * All rights reserved. * * This software is distributed under Logica Open Source License Version 1.0 * ("Licence Agreement"). You shall use it and distribute only in accordance * with the terms of the License Agreement. * */package com.logica.smpp;import java.io.IOException;import java.util.Hashtable;import com.logica.smpp.pdu.AlertNotification;import com.logica.smpp.pdu.BindReceiver;import com.logica.smpp.pdu.BindRequest;import com.logica.smpp.pdu.BindResponse;import com.logica.smpp.pdu.BindTransciever;import com.logica.smpp.pdu.BindTransmitter;import com.logica.smpp.pdu.CancelSM;import com.logica.smpp.pdu.CancelSMResp;import com.logica.smpp.pdu.DataSM;import com.logica.smpp.pdu.DataSMResp;import com.logica.smpp.pdu.DeliverSM;import com.logica.smpp.pdu.DeliverSMResp;import com.logica.smpp.pdu.EnquireLink;import com.logica.smpp.pdu.EnquireLinkResp;import com.logica.smpp.pdu.GenericNack;import com.logica.smpp.pdu.InvalidPDUException;import com.logica.smpp.pdu.Outbind;import com.logica.smpp.pdu.PDU;import com.logica.smpp.pdu.PDUException;import com.logica.smpp.pdu.QuerySM;import com.logica.smpp.pdu.QuerySMResp;import com.logica.smpp.pdu.ReplaceSM;import com.logica.smpp.pdu.ReplaceSMResp;import com.logica.smpp.pdu.Request;import com.logica.smpp.pdu.Response;import com.logica.smpp.pdu.SubmitMultiSM;import com.logica.smpp.pdu.SubmitMultiSMResp;import com.logica.smpp.pdu.SubmitSM;import com.logica.smpp.pdu.SubmitSMResp;import com.logica.smpp.pdu.Unbind;import com.logica.smpp.pdu.UnbindResp;import com.logica.smpp.pdu.UnknownCommandIdException;import com.logica.smpp.pdu.ValueNotSetException;import com.logica.smpp.util.NotEnoughDataInByteBufferException;import com.logica.smpp.util.TerminatingZeroNotFoundException;/** * Class <code>Session</code> provides all methods necessary for communication * with SMSC using SMPP protocol, i.e. methods for sending PDUs as defined * in SMPP specification as well as receiving responses for sent PDUs * and waiting for PDUs whose sending was initiated by SMSC.<br> * Instance of <code>Session</code> represents one connection of ESME * to a SMSC. Multiple connections can be established using * multiple <code>Sessions</code>. * <p> * <code>Session</code> uses <code>Connection</code> object which is * instantiated outside of the <code>Session</code>. This way is * the <code>Session</code> made independent on the communication protocol * and <code>Session</code>'s code isn't populated by protocol dependent * initialisation. * <p> * Code example of binding, sending one message and unbinding: * <br><blockquote><pre> * Connection conn = new TCPIPConnection("123.123.123.123", 6543); * Session session = new Session(conn); * BindRequest breq = new BindTransmitter(); * breq.setSystemId("MYNAME"); * breq.setPassword("my_pswdx"); * Response resp = session.bind(breq); * if (resp.getCommandStatus() == Data.ESME_ROK) { * SubmitSM msg = new SubmitSM(); * msg.setSourceAddr("3538998765432"); * msg.setDestAddr("3538619283746"); * msg.setShortMessage("Hello, world!"); * resp = session.submit(msg); * if (resp.getCommandStatus() == Data.ESME_ROK) { * System.out.println("Message submitted. Status=" + resp.getCommandStatus()); * } else { * System.out.println("Message submission failed. Status=" + resp.getCommandStatus()); * } * session.unbind(); * } else { * System.out.println("Couldn't bind. Status=" + resp.getCommandStatus()); * } * </pre></blockquote> * Note that the cycle bind - send PDU's - unbind can be called * several times for once created session. * <p> * Particular methods for sending PDUs to SMSC return responses to the sent * PDUs. They return null if no response is received in time specified * by the receive timeout in receiver. This means that the methods wait * for response corresponding to the request. * The corresponding response is recognized using sequence number of the sent * PDU and a corresponding response command id.<br> * The session can work in assynchronous manner, i.e. it doesn't wait * for response for the sent request, instead all responses are handled * by instance of callback class <code>ServerPDUEventListener</code> * whenever they are received.<br> * The <code>Session</code> class checks if operations invoked are valid in * the current state of the session. If not, then such operation throws * <code>WrongSessionStateException</code> expcetion. For example it's incorrect * to try to submit a message if the session is bound as receiver. The checking * if the operation is valid in the current state of session is turned off * by default. * * @author Logica Mobile Networks SMPP Open Source Team * @version 1.2, 20 Nov 2001 * @see Connection * @see Transmitter * @see Receiver * @see ServerPDUEventListener */ /* 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*/public class Session extends SmppObject{ /** * Status of the connection. It's set by <code>open</code> method, * which is called from <code>bind</code> method. * @see #open() * @see #bind(BindRequest) */ private boolean opened = false; /** * Status of bounding. It's set by <code>bind</code> methdod if * the binding is successfull. * @see #bind(BindRequest) */ private boolean bound = false; /** Special state for actions which are never allowed for the session. */ public static final int STATE_NOT_ALLOWED = 0x00; // 00000b /** The connection is closed (or not opened yet) and session isn't bound. */ public static final int STATE_CLOSED = 0x01; // 00001b /** The connection is opened, but the session isn't bound. */ public static final int STATE_OPENED = 0x02; // 00010b /** The session is bound as transmitter. */ public static final int STATE_TRANSMITTER = 0x04; // 00100b /** The session is bound as receiver. */ public static final int STATE_RECEIVER = 0x08; // 01000b /** The session is bound as transceiver. */ public static final int STATE_TRANSCEIVER = 0x10; // 10000b /** Special state for actions which are always allowed (e.g. generic_nack.) */ public static final int STATE_ALWAYS = // 11111b STATE_OPENED | STATE_TRANSMITTER | STATE_RECEIVER | STATE_TRANSCEIVER; /** * Table with command id's and session states in which they can be used. * For session on ESME side. * @see #initialiseStateMatrix() */ private static Hashtable esmeStateMatrix; /** * Table with command id's and session states in which they can be used. * For session on MC side. Note that even if this is from the MC side * the bind states are still entered from the EMSE point of veiw. * E.g. for deliver_sm this table contains states receiver and transceiver, * which means that MC can send PDU with deliver_sm command id only in case * the ESME is bound as receiver or transceiver.<br> * <emp>Note:</emp> The MC state matrix is not completly supported by * the current implementation of session, so it's currently altered * to reflect the impplementation. * @see #initialiseStateMatrix() */ private static Hashtable mcStateMatrix; /** * If PDU with unknown command id is probed this says if this PDU is * allowed or not. Generaly it's not good idea to allow unknown PDUs, but * for backward compatiblity we leave it set to false. */ private boolean disallowUnknownPDU = false; /** * The current state of this Session. * @see #esmeStateMatrix * @see #mcStateMatrix * @see #setState(int) * @see #getState() */ private int state = STATE_CLOSED; /** * If the checking of states is active. It's generaly good idea to leave it * set to true, it'll save you communication bandwidth (MC should reject your * PDU if you are in wrong state) and it'll discover bad logic in your application. * For backward compatibility we set that the state is NOT checked. * @see #enableStateChecking() * @see #disableStateChecking() */ private boolean stateChecking = false; /** * Indicates that the session is session for ESME 'point of view.' * @see #type */ public static final int TYPE_ESME = 1; /** * Indicates that the session is session for MC 'point of view.' * MC is Message Center and it is a term for generic Message Centre such as SMSC. * @see #type */ public static final int TYPE_MC = 2; /** * If this session is ESME session or if it is used in MC (or simulator * or routing entity, simply the other side of normal ESME). * Normally this would be equal to TYPE_ESME as mostly this library will be used * for developing ESME applications and not MCs. If you don't understand * what is this variable for, just leave it as it is. * @see #setType(int) * @see #getType() */ private int type = TYPE_ESME; /** * The connection object. It's created outside of the <code>Session</code> * class and passed as a parameter during the <code>Session</code> * creation. It's then passed to <code>Transmitter</code> and * <code>Receiver</code>. * @see Connection * @see TCPIPConnection * @see Transmitter * @see Receiver */ private Connection connection; /** * Object used for transmitting of PDUs over connection. * @see Transmitter */ private Transmitter transmitter; /** * Object used for receiving of PDU from connection. * @see Receiver */ private Receiver receiver; /** * If the receiving is asynchronous, <code>pduListener</code> must * contain the callback object used for processing of PDUs received * from the SMSC. <code>Receiver</code> after receiving a PDU passes * the received PDU to apropriate member function of the processor. * @see #asynchronous * @see #setServerPDUEventListener(ServerPDUEventListener) * @see #bind(BindRequest) * @see Receiver */ private ServerPDUEventListener pduListener = null; /** * Indicates that the sending of PDUs to the SMSC is asynchronous, i.e. * the session doesn't wait for a response to the sent request as well as * the <code>receive</code> functions will return null as all received * PDUs are passed to the <code>pduListener</code> object in * the <code>receiver</code>. * @see #pduListener * @see #setServerPDUEventListener(ServerPDUEventListener) * @see #bind(BindRequest) * @see Receiver */ private boolean asynchronous = false; /** * Default constructor made protected as it's not desirable to * allow creation of <code>Session</code> without providing * <code>Connection</code>. */ protected Session() { } /** * Creates <code>Session</code> which uses provided <code>Connection</code>. * In most cases the <code>connection</code> parameter will be an instance * of <code>TCPIPConnection</code> class. * * @param connection connection used for transmitting and receiving * the data */ public Session(Connection connection) { this.connection = connection; } /** * Opens the connection for communication. * Sets indication that the connection is opened. * * @exception IOException exception during communication */ public void open() throws IOException,WrongSessionStateException { checkState(STATE_CLOSED); if (!opened) { connection.open(); opened = true; setState(STATE_OPENED); } } /** * Closes the connection for communication. * Sets indication that the connection is not opened. * * @exception IOException exception during communication */ public void close() throws IOException,WrongSessionStateException { checkState(STATE_OPENED); if (opened) { connection.close(); opened = false; setState(STATE_CLOSED); } } /** * Returns of the connection is opened. * @return current status of connection */ public boolean isOpened() { return opened; } /** * Returns if the session is bound to SMSC. * @return current status of bound */ public boolean isBound() { return bound; } /** * Sets the listener which is passed all PDUs received by the
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?