def decode
      @sca_length = take(2, :integer) * 2                # Service center address length
      if @sca_length > 0
        @sca_type = parse_address_type take(2)            # Service center address type
        @sca = parse_address take(@sca_length - 2), @sca_type, @sca_length # Service center address
      end
      @pdu_type = parse_pdu_type take(2, :binary)   # PDU type octet
      @message_reference = take(2) if @pdu_type[:mti] == :sms_submit
      @address_length = take(2, :integer)
      @address_type = parse_address_type take(2)
      @address_length = @address_length.odd? ? @address_length + 1 : @address_length # Always take byte aligned - hexdecimal F is added when odd number
      @address = parse_address take(@address_length), @address_type, @address_length
      @pid = take(2)
      @data_coding_scheme = parse_data_coding_scheme take(2, :binary)
      @sc_timestamp = parse_7byte_timestamp take(14) if [:sms_deliver, :sms_deliver_report].include? @pdu_type[:mti]
      case @pdu_type[:vpf]
      when :absolute
        @validity_period = parse_7byte_timestamp take(14)
      when :relative
        @validity_period = parse_validity_period take(2, :integer)
      end
      @user_data_length = take(2, :integer)
      parse_user_data @user_data_length

      MessagePart.new @address, @message, @sc_timestamp, @validity_period, @user_data_header
    end
def decode
      @sca_length = take(2, :integer) * 2                # Service center address length
      if @sca_length > 0
        @sca_type = parse_address_type take(2)            # Service center address type
        @sca = parse_address take(@sca_length - 2), @sca_type, @sca_length # Service center address
      end
      @pdu_type = parse_pdu_type take(2, :binary)   # PDU type octet
      @message_reference = take(2) if @pdu_type[:mti] == :sms_submit
      @address_length = take(2, :integer)
      @address_type = parse_address_type take(2)
      @address_length = @address_length.odd? ? @address_length + 1 : @address_length # Always take byte aligned - hexdecimal F is added when odd number
      @address = parse_address take(@address_length), @address_type, @address_length
      @pid = take(2)
      @data_coding_scheme = parse_data_coding_scheme take(2, :binary)
      @sc_timestamp = parse_7byte_timestamp take(14) if [:sms_deliver, :sms_deliver_report].include? @pdu_type[:mti]
      case @pdu_type[:vpf]
      when :absolute
        @validity_period = parse_7byte_timestamp take(14)
      when :relative
        @validity_period = parse_validity_period take(2, :integer)
      end
      @user_data_length = take(2, :integer)
      parse_user_data @user_data_length

      MessagePart.new @address, @message, @sc_timestamp, @validity_period, @user_data_header
    end
http://read.pudn.com/downloads150/sourcecode/embed/646395/Short%20Message%20in%20PDU%20Encoding.pdf