📄 pdu.java
字号:
/* * 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.pdu;import java.util.Dictionary;import java.util.Enumeration;import java.util.Vector;import com.logica.smpp.Data;import com.logica.smpp.pdu.tlv.TLV;import com.logica.smpp.pdu.tlv.TLVException;import com.logica.smpp.pdu.tlv.TLVOctets;import com.logica.smpp.util.ByteBuffer;import com.logica.smpp.util.NotEnoughDataInByteBufferException;import com.logica.smpp.util.TerminatingZeroNotFoundException;/** * Class <code>PDU</code> is abstract base class for all classes which * represent a PDU. It contains methods for manipulating PDU header, * checking validity of PDU, automatic parsing and generation of optional * part of PDU, methods for creating instance of proper class representing * certain PDU based only in command id, methods for detection if the * PDU is request or response PDU, automatic sequence number * assignment, etc. It also implements <code>setData</code> and * <code>getData</code> methods as the header and optional params * parsing and composition is the same for all PDUs. The derived * classes on turn implement functions <code>setBody</code> and * <code>getBody</code>. * <p> * The <code>PDU</code> has two descendants, <code>Request</code> and * <code>Response</code>, which serve as a base classes for concrete * PDU classes like SubmitSM, SubmitSMResp etc. * * @author Logica Mobile Networks SMPP Open Source Team * @version 1.4, 20 Oct 2001 *//* 13-07-01 ticp@logica.com added assignSequenceNumber(boolean) to allow assigning seq nr even if the seq nr has been already changed 13-07-01 ticp@logica.com debug of buffer in hex is now printed in setData and getData methods 23-08-01 ticp@logica.com in setData() added test if the data following mandatory params can be optional params, i.e. if command length indicates that there are more data after parsing mandatory params. before if the buffer contained more data (e.g. more than 1 pdu) the additional data were parsed as opt params even if they were beyond the command length 23-08-01 ticp@logica.com cosmetic change: tabs replaced by spaces 26-09-01 ticp@logica.com method resetSequenceNumber() added which causes that the PDU 'forgets' that it's sequence number was already set, so if submitted again it'll get new one 02-10-01 ticp@logica.com comments added 02-10-01 ticp@logica.com debug now belongs to DPDU and DPDUD groups 02-10-01 ticp@logica.com fixed bug in setData which could cause the optional params to be read beyond the indicated length of PDU 02-10-01 ticp@logica.com equals now checks if the object to be compared to is instance of PDU 09-10-01 ticp@logica.com added possibility to attach to PDU some application specific data 16-10-01 ticp@logica.com added checking if debug's group is active when logging the buffer's hex dump in setData and getData 16-10-01 ticp@logica.com improved parsing of the pdu for the sake of debug debug speed improvement (in setData()) 20-11-01 ticp@logica.com added support for additional (extra) optional parameters which aren't defined in the specs*/public abstract class PDU extends ByteData{ /** * This constant indicates that parsing of the buffer failed * parsing of the header of PDU. * * @see #setData(ByteBuffer) * @see #valid */ public static final byte VALID_NONE = 0; /** * This constant indicates that parsing of the buffer passed * parsing of the header of PDU but failed parsing of mandatory * part of body. * * @see #setData(ByteBuffer) * @see #valid */ public static final byte VALID_HEADER = 1; /** * This constant indicates that parsing of the buffer passed * parsing of the mandatory part of body of PDU but failed parsing * of optional parameters. * * @see #setData(ByteBuffer) * @see #valid */ public static final byte VALID_BODY = 2; /** * This constant indicates that parsing of the buffer passed * all parts of the PDU, i.e. headet, mandator and optional * parameters. * * @see #setData(ByteBuffer) * @see #valid */ public static final byte VALID_ALL = 3; /** * This vector contains instances of all possible PDUs whic can be * received and sent. It is used to create new instance of * class based only on command id. * * @see #createPDU(int) * @see #createPDU(ByteBuffer) */ private static Vector pduList = null; /** * This is counter of sequence numbers. Each time the method * <code>assignSequenceNumber</code> is called, this counter * is increased and the it's value is assigned as a sequence number * of th PDU. * * @see #assignSequenceNumber() */ private static int sequenceNumber = 500; /** * Indicates that the sequence number has been changed either by setting * by method <code>setSequenceNumber(int) or by reading from buffer by * method <code>setHeader</code>. * * @see #setSequenceNumber(int) * @see #assignSequenceNumber() */ private boolean sequenceNumberChanged = false; /** * This is the header of the PDU. It's only created when necessary. * <code>PDU</code> class implements accessor methdos for setting * and getting parameters of header like comand id, sequence * number etc. * * @see #checkHeader() * @see #setHeader(ByteBuffer) * @see #getHeader() */ private PDUHeader header = null; /** * This contains all optional parameters defined for particular * concrete PDU. E.g. for submit_sm class <code>SubmitSM</code> * puts here all it's possible optional parameters. It is used * to build a byte buffer from optional parameters as well as * fill them from a buffer. * * @see #registerOptional(TLV) * @see TLV */ private Vector optionalParameters = new Vector(10,2); /** * Contains optional parameters which aren't defined in the SMPP spec. * * @see #setExtraOptional(TLV) * @see #setExtraOptional(short,ByteBuffer) * @see #getExtraOptional(short) * @see #registerExtraOptional(TLV) */ private Vector extraOptionalParameters = new Vector(1,1); /** * This indicates what stage was reached when parsing byte buffer * in <code>setData</code> method. * * @see #VALID_NONE * @see #VALID_HEADER * @see #VALID_BODY * @see #VALID_ALL * @see #setData(ByteBuffer) */ private byte valid = VALID_ALL; /** * Application developers can attach application specific data to an instance * of PDU or derived class. This facility can be used to carry data * over different components of the application in the PDU without explicit * development of PDU to data mapping functionality. * Typical use would be attaching an information about data from which a * Request was created and after receiving a Response to that Request * these data can be used for controling the proper reaction to the Response. * If you use string gey, be carefull and choose a key which would be expected * to be unique, fo example your class name qualified with full package name * and with additional key description name appended. * @see #setApplicationSpecificInfo(Object,Object) * @see #getApplicationSpecificInfo(Object) * @see #removeApplicationSpecificInfo(Object) */ private Dictionary applicationSpecificInfo = null; /** * Default constructor, what else. */ public PDU() { super(); } /** * Initialises PDU with given command id. Derived classes should * provide correct command id for their type, e.g. SubmitSM should * provide <code>Data.SUBMIT_SM</code>, which is equal to 4 (as defined * in SMPP 3.4 spec.) * * @param commandId the numerical id of the PDU as specified in SMPP * specification */ public PDU(int commandId) { super(); checkHeader(); setCommandId(commandId); } /** * Default method for seting mandatory parameters of the PDU. * Derived classes should overwrite this method if they want * to fill their member variables with data from the binary * data buffer. * * @param buffer the buffer with the PDU's data as received from SMSC * @see #setData(ByteBuffer) */ public void setBody(ByteBuffer buffer) throws NotEnoughDataInByteBufferException, TerminatingZeroNotFoundException, PDUException { } /** * Default method for composing binary representation of * the mandatory part of the PDU. Derived classes should overwrite this * method with composition of buffer from their member variables. * * @see #getData() */ public ByteBuffer getBody() throws ValueNotSetException { return null; } /** * This method indicates that the object represents PDU which can * and should be responded to. For example for <code>SubmitSM</code> * class this should return <code>true</code>, while for * <code>SubmitSMResp</code> or <code>AlertNotification</code> classes * this should return <code>false</code>. This method is overwritten in * class <code>Request</code> as most "request" PDUs have response * counterparts. (Exception to this rule is above mentioned * <code>AlertNotification</code> which doesn't have response.) * @return if the PDU can have a response * @see Request#canResponse() * @see Response#canResponse() * @see AlertNotification#canResponse() */ public boolean canResponse() { return false; } /** * Returns if the object represents PDU which is a request. * E.g. classes derived from <code>Request</code> class return * <code>true</code>. * @return if the PDU represents request */ public abstract boolean isRequest(); /** * Returns if the object represents PDU which is response. * E.g. classes derived from <code>Response</code> class return * <code>true</code>. * @return if the PDU represents response */ public abstract boolean isResponse(); /** * Assigns newly generated sequence number if the sequence number * hasn't been assigned yet. Doesn't have any effect if the sequence * number was already assigned. * * @see #assignSequenceNumber(boolean) * @see #setSequenceNumber(int) * @see #setHeader(ByteBuffer) */ public void assignSequenceNumber() { assignSequenceNumber(false); } /** * Assigns newly generated sequence number. If the sequence * number was previously set by <code>setSequenceNumber</code> method or * from byte buffer in <code>setHeader</code>, this method only assigns the * number if the parameter <code>always</code> is true. * * @param always if the number has to be assigned even if it was already assigned * @see #setSequenceNumber(int) * @see #setHeader(ByteBuffer) */ public void assignSequenceNumber(boolean always) { if ((!sequenceNumberChanged) || always) { setSequenceNumber(++sequenceNumber); } } /** * If the sequence number was previously set to a value, this function * resets that fact. I.e. if the PDU is re-used for another say submit, * then after calling of this function a new sequence number will * assigned to it the PDU despite of the fact that there was another one * assigned to it before. */ public void resetSequenceNumber() { setSequenceNumber(0); sequenceNumberChanged = false; } /** * Parses the binary buffer to get the PDUs header, fields from mandatory * part and fields from the optional part.<br> * The header and optional part are parsed common way for all PDUs * using functions <code>setHeader</code> and <code>setOptionalBody</code> * the mandatory body is parsed by the derived classes in * <code>setBody</code> function. If parsing throws an exception, the PDU's * <code>getValid</code> function returns the phase which was correct * last.<br> * The buffer can contain more than one PDU, then only one PDU is taken * from the buffer and the rest remains unaltered. * @param buffer the buffer containg the PDU binary data which are source * for the content of the fields of this PDU * @see #setHeader(ByteBuffer) * @see #setBody(ByteBuffer) * @see #setOptionalBody(ByteBuffer) * @see #getValid() * @see #getData() */ public void setData(ByteBuffer buffer)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -