📄 pdu.java
字号:
throws InvalidPDUException, PDUException { int initialBufLen = buffer.length(); try { setValid(VALID_NONE); // first try read header if (buffer.length()<Data.PDU_HEADER_SIZE) { if (debug.active(DPDU)) { debug.write(DPDU,"PDU.setData() not enough data for header in the buffer " + buffer.getHexDump()); } } // get the header from the buffer ByteBuffer headerBuf = buffer.removeBytes(Data.PDU_HEADER_SIZE); if (debug.active(DPDU)) { debug.write(DPDU,"PDU.setData() parsing header " + headerBuf.getHexDump()); } setHeader(headerBuf); setValid(VALID_HEADER); // now read pdu's body for hex dump if (debug.active(DPDU)) { if (getCommandLength()>Data.PDU_HEADER_SIZE) { ByteBuffer tempBodyBuf = buffer.readBytes(getCommandLength()-Data.PDU_HEADER_SIZE); debug.write(DPDU,"PDU.setData() parsing body " + tempBodyBuf.getHexDump()); } else { debug.write(DPDU,"PDU.setData() no data for body"); } } // parse the body setBody(buffer); setValid(VALID_BODY); if ((initialBufLen - buffer.length()) < getCommandLength()) { // i.e. parsed less than indicated by command length => // must have optional parameters int optionalLength = getCommandLength() + buffer.length() - initialBufLen; debug.write(DPDU, "have "+optionalLength+" bytes left."); ByteBuffer optionalBody = buffer.removeBuffer(optionalLength); setOptionalBody(optionalBody); } setValid(VALID_ALL); } catch (NotEnoughDataInByteBufferException e) { 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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -