⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdu.java

📁 Short Message Peer to Peer
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			throw new InvalidPDUException(this, e);
		} catch (TerminatingZeroNotFoundException e) {
			throw new InvalidPDUException(this, e);
		} catch (PDUException e) {
			e.setPDU(this);
			throw e;
		} catch (Exception e) {
			// transform generic exception into InvalidPDUException
			throw new InvalidPDUException(this, e);
		}
		if (buffer.length() != (initialBufLen - getCommandLength())) {
			// i.e. we've parsed out different number of bytes
			// than is specified by command length in the pdu's header
			throw new InvalidPDUException(this, "The parsed size of the message is not equal to command_length.");
		}
	}

	/**
	 * Construct the binary PDU for sending to SMSC.
	 * First creates the mandatory part using <code>getBody</code> method,
	 * which has to be implemented in the derived classes (if they 
	 * represent PDU with body), then creates the optional part of the PDU
	 * using <code>getOptionalBody</code>, which is common for all PDUs.
	 * Calculates the size of the PDU and then creates the header using
	 * <code>getHeader</code> and returns the full binary PDU.
	 * @see #getBody()
	 * @see #getOptionalBody(Vector)
	 * @see #getHeader()
	 * @see #setData(ByteBuffer)
	 */
	public ByteBuffer getData() throws ValueNotSetException {
		// prepare all body
		ByteBuffer bodyBuf = new ByteBuffer();
		bodyBuf.appendBuffer(getBody());
		bodyBuf.appendBuffer(getOptionalBody());
		// get its size and add size of the header; set the result as length
		setCommandLength(bodyBuf.length() + Data.PDU_HEADER_SIZE);
		ByteBuffer pduBuf = getHeader();
		pduBuf.appendBuffer(bodyBuf);
		if (debug.active(DPDU)) {
			debug.write(DPDU, "PDU.getData() build up data " + pduBuf.getHexDump());
		}
		return pduBuf;
	}

	/** Sets if the PDU contains correctly formated data.  */
	public void setValid(byte valid) {
		this.valid = valid;
	}

	/** Returns if the PDU contains correctly formated data. */
	public byte getValid() {
		return valid;
	}

	/**
	 * Returns if the parsing of the binary PDU data successfully parsed
	 * complete PDU.
	 */
	public boolean isValid() {
		return getValid() == VALID_ALL;
	}

	/**
	 * Returns if the parsing of the binary PDU data ended before parsing
	 * of the header.
	 */
	public boolean isInvalid() {
		return getValid() == VALID_NONE;
	}

	/** Returns if at least the header of the binary PDU data was correct. */
	public boolean isHeaderValid() {
		return getValid() >= VALID_HEADER;
	}

	/**
	 * Parses the header from the buffer.
	 * Also sets the flag that the sequence number was changed as it was read
	 * from the binary buffer.
	 * @param buffer the buffer which contains the PDU
	 * @see PDUHeader#setData(ByteBuffer)
	 */
	private void setHeader(ByteBuffer buffer) throws NotEnoughDataInByteBufferException {
		checkHeader();
		header.setData(buffer);
		sequenceNumberChanged = true;
	}

	/** Creates the binary PDU header from the header fields of the PDU. */
	private ByteBuffer getHeader() {
		checkHeader();
		return header.getData();
	}

	/**
	 * Parses the binary buffer and obtains all optional parameters
	 * which the buffer contains, sets the optional parameter fields.
	 * The optional parameter fields which the PDU can contain must be
	 * registered by the derived class using <code>registerOptional</code>.
	 * Or there can be extra optional parameters with application/smsc specific tags,
	 * which aren't defined in the SMPP specification.
	 * The optional parameters defined in SMPP are accessible using appropriate
	 * getter functions in the derived PDU classes, the extra optional
	 * parameters are accessible with generic function <code>getExtraOptional</code>.
	 * The buffer can't contain another data then the optional parameters.
	 *
	 * @param buffer the buffer with the optional parameters
	 * @exception UnexpectedOptionalParameterException if the optional
	 *            parameter read from the buffer cna't be contained
	 *            int this PDU
	 * @see #getOptionalBody()
	 * @see #getExtraOptional(short)
	 * @see TLV
	 */
	private void setOptionalBody(ByteBuffer buffer)
		throws NotEnoughDataInByteBufferException, UnexpectedOptionalParameterException, TLVException {
		short tag;
		short length;
		ByteBuffer tlvHeader;
		ByteBuffer tlvBuf;
		TLV tlv = null;
		while (buffer.length() > 0) {
			// we prepare buffer with one parameter
			tlvHeader = buffer.readBytes(Data.TLV_HEADER_SIZE);
			tag = tlvHeader.removeShort();
			tlv = findOptional(optionalParameters, tag);
			if (tlv == null) {
				// ok, got extra optional parameter not defined in SMPP spec
				// will keep it as octets
				tlv = new TLVOctets(tag);
				registerExtraOptional(tlv);
			}
			length = tlvHeader.removeShort();
			tlvBuf = buffer.removeBuffer(Data.TLV_HEADER_SIZE + length);
			tlv.setData(tlvBuf);
		}
	}

	/**
	 * Creates buffer with all the optional parameters which have set
	 * their value, both from the optional parameters defined in SMPP
	 * and extra optional parameters.
	 * @see #setOptionalBody(ByteBuffer)
	 * @see TLV#hasValue()
	 * @see TLV#getData()
	 * @see TLV
	 */
	private ByteBuffer getOptionalBody() throws ValueNotSetException {
		ByteBuffer optBody = new ByteBuffer();
		optBody.appendBuffer(getOptionalBody(optionalParameters));
		optBody.appendBuffer(getOptionalBody(extraOptionalParameters));
		return optBody;
	}

	/**
	 * Creates buffer with all the optional parameters contained in 
	 * the <code>optionalParameters</code> list which have set
	 * their value. For getting data of the optional parameter calls
	 * a method <code>getData</code> of the <code>TLV</code> class.
	 * @see #setOptionalBody(ByteBuffer)
	 * @see TLV#hasValue()
	 * @see TLV#getData()
	 * @see TLV
	 */
	private ByteBuffer getOptionalBody(Vector optionalParameters) throws ValueNotSetException {
		ByteBuffer optBody = new ByteBuffer();
		int size = optionalParameters.size();
		TLV tlv = null;
		for (int i = 0; i < size; i++) {
			tlv = (TLV) optionalParameters.get(i);
			if ((tlv != null) && tlv.hasValue()) {
				optBody.appendBuffer(tlv.getData());
			}
		}
		return optBody;
	}

	/**
	 * Registeres a TLV as an optional parameter which can be containd in
	 * the PDU. Derived classes are expected that they will define appropriate
	 * TLVs and register them using this method. Only registered TLVs
	 * can be read as optional parameters from binary PDU received from SMSC.
	 * @param tlv the TLV to be registered as an optional parameter
	 * @see TLV
	 */
	protected void registerOptional(TLV tlv) {
		if (tlv != null) {
			optionalParameters.add(tlv);
		}
	}

	/**
	 * Registeres a TLV as an extra optional parameter which can be contained in
	 * the PDU. Extra optional parameter is TLV not defined in SMPP spec.
	 * The reason for this method is that if you know what type and size
	 * certain extra optional parameter has to be, then you can create an instance
	 * of appropriate TLV class, e.g. <code>TLVInt</code> class and register it as
	 * the carrying TLV instead of using the generic <code>TLVOctets</code> class.
	 * @param tlv the TLV to be registered as an extra optional parameter
	 * @see TLV
	 */
	protected void registerExtraOptional(TLV tlv) {
		if (tlv != null) {
			extraOptionalParameters.add(tlv);
		}
	}

	/**
	 * Searches for registered or extra TLV with the given TLV tag.
	 * Returns the found TLV or null if not found. Used when parsing
	 * the optional part of the binary PDU data.
	 * @param tag the tag of the TLV required
	 * @return the found TLV
	 * @see #setOptionalBody(ByteBuffer)
	 * @see #registerOptional(TLV)
	 * @see #registerExtraOptional(TLV)
	 * @see TLV
	 */
	private TLV findOptional(Vector optionalParameters, short tag) {
		int size = optionalParameters.size();
		TLV tlv = null;
		for (int i = 0; i < size; i++) {
			tlv = (TLV) optionalParameters.get(i);
			if (tlv != null) {
				if (tlv.getTag() == tag) {
					return tlv;
				}
			}
		}
		return null;
	}

	/**
	 * Replaces the TLV in the extra optional parameters list with the
	 * new tlv provided as a parameter. If the tlv doesn't exist in the list,
	 * adds it to the list.
	 */
	private void replaceExtraOptional(TLV tlv) {
		int size = extraOptionalParameters.size();
		TLV existing = null;
		short tlvTag = tlv.getTag();
		for (int i = 0; i < size; i++) {
			existing = (TLV) extraOptionalParameters.get(i);
			if ((existing != null) && (existing.getTag() == tlvTag)) {
				extraOptionalParameters.set(i, tlv);
				return;
			}
		}
		registerExtraOptional(tlv); // the optional param wasn't found
	}

	/**
	 * Sets the extra optional parameter.
	 */
	public void setExtraOptional(TLV tlv) {
		replaceExtraOptional(tlv);
	}

	/**
	 * Creates new generic extra optional parameter with tag and data provided;
	 * uses TLVOctets for the parameter.
	 */
	public void setExtraOptional(short tag, ByteBuffer data) throws TLVException {
		TLV tlv = new TLVOctets(tag, data);
		setExtraOptional(tlv);
	}

	/**
	 * Finds and returns extra optional parameter with the provided 
	 * tag; if not found returns null.
	 */
	public TLV getExtraOptional(short tag) {
		TLV tlv = findOptional(extraOptionalParameters, tag);
		return tlv;
	}

	/** Checks if the header field is null and if not, creates it. */
	private void checkHeader() {
		if (header == null) {
			header = new PDUHeader();
		}
	}

	/**
	 * Returns the length of this PDU.
	 * The length is only valid if you probe the PDU which was parsed from
	 * binary data received from SMSC. If you created the PDU and filled in the
	 * filds of the PDU, the length returned by this function will be very
	 * likely incorrect.
	 */
	public int getCommandLength() {
		checkHeader();
		return header.getCommandLength();
	}

	/**
	 * Returns the command id of the PDU object.
	 * The command id can be either read from the binary data received from SMSC
	 * or can be set by derived class as the command id of the PDU which is
	 * represented by the class.
	 */
	public int getCommandId() {
		checkHeader();
		return header.getCommandId();
	}

	/** Returns the command status of the PDU. */
	public int getCommandStatus() {
		checkHeader();
		return header.getCommandStatus();
	}

	/**
	 * Returns the sequence number of the PDU.
	 * If the PDU is created by yourself and not parsed from binary data
	 * received from SMSC, then the sequence number will be very likely
	 * incorrect until you didn't set it previously by calling function
	 * <code>assignSequenceNumber</code> or <code>setSequenceNumber</code>.
	 * @see #assignSequenceNumber()
	 * @see #setSequenceNumber(int)
	 */
	public int getSequenceNumber() {
		checkHeader();
		return header.getSequenceNumber();
	}

	/**
	 * Sets the length of the PDU. Don't do it manually, it won't have
	 * any wffect.
	 */
	public void setCommandLength(int cmdLen) {
		checkHeader();
		header.setCommandLength(cmdLen);
	}

	/** Sets the command id. */
	public void setCommandId(int cmdId) {
		checkHeader();
		header.setCommandId(cmdId);
	}

	/**
	 * Sets the command status, i.e. error status of the PDU.
	 */
	public void setCommandStatus(int cmdStatus) {
		checkHeader();
		header.setCommandStatus(cmdStatus);
	}

	/**
	 * Sets the sequence number of the PDU. 
	 * For PDUs whic are about to be sent to SMSC the sequence number is
	 * generated automatically in the <code>Transmitter</code> class and
	 * under normal cicumstances there is no need to set it explicitly.
	 */
	public void setSequenceNumber(int seqNr) {
		checkHeader();
		header.setSequenceNumber(seqNr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -