class RTCP::XR

XR: Extended Report RTCP Packet Documentation: RFC 3611, 2.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|reserved |   PT=XR=207   |             length            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              SSRC                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                         report blocks                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

An extended report block has the following format:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      BT       | type-specific |         block length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:             type-specific block contents                      :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The Statistics Summary Report Block has the following format:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     BT=6      |L|D|J|ToH|rsvd.|       block length = 9        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        SSRC of source                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          begin_seq            |             end_seq           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        lost_packets                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        dup_packets                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         min_jitter                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         max_jitter                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         mean_jitter                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         dev_jitter                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| min_ttl_or_hl | max_ttl_or_hl |mean_ttl_or_hl | dev_ttl_or_hl |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Constants

PT_ID

Attributes

padding[R]
report_blocks[R]
ssrc[R]
version[R]

Public Instance Methods

decode(packet_data) click to toggle source
# File lib/rtcp/xr.rb, line 56
def decode(packet_data)
  vprc, packet_type, length, @ssrc = packet_data.unpack('CCnN')
  ensure_packet_type(packet_type)

  @version = vprc >> 6
  @length  = 4 * (length + 1)
  @report_blocks = []

  report_block_data = payload_data(packet_data, @length, 8)

  while report_block_data && report_block_data.length >= 4
    bt, length = report_block_data.unpack('Cxn')
    length = 4 * (length + 1)
    @report_blocks.push case bt
    when 1 # Loss RLE Report Block
      decode_loss_rle(report_block_data)
    when 6 # Statistics Summary Report
      decode_ssr(report_block_data)
    else
      {
        type:   bt,
        length: length,
        data:   report_block_data.slice(4..(length-1))
      }
    end

    report_block_data = report_block_data.slice(length..-1)
  end

  # Padding
  if (vprc & 16 == 16)
    @padding = report_block_data
  elsif (report_block_data != '')
    raise(RTCP::DecodeError, "Packet has undeclared padding")
  end

  self
end

Private Instance Methods

decode_loss_rle(report_block_data) click to toggle source
# File lib/rtcp/xr.rb, line 97
def decode_loss_rle(report_block_data)
  thinning, length, ssrc, begin_seq, end_seq, *values =
    report_block_data.unpack("xCnNn*")

  thinnig = thinning & 15
  length  = 4 * (length + 1)

  chunks = values.collect do |val|
    if (val && 32768) == 32768
      {
        chunk_type: :run_length,
        run_type:   (val >> 14) & 1,
        run_length: val & 16383,
      }
    else
      {
        chunk_type: :bit_vector,
        run_length: val & 32767,
      }
    end
  end

  return {
    type:      :loss_rle,
    thinning:  thinning,
    begin_seq: begin_seq,
    end_seq:   end_seq,
    chunks:    chunks,
  }
end
decode_ssr(report_block_data) click to toggle source
# File lib/rtcp/xr.rb, line 128
def decode_ssr(report_block_data)
  x, ssrc, begin_seq, end_seq, lost_packets, dup_packets, *values =
    report_block_data.unpack("xCx2NnnN6C4")

  report_block = {
    ssrc:      ssrc,
    type:      :statistics_summary,
    begin_seq: begin_seq,
    end_seq:   end_seq,
  }
  @report_blocks.push(report_block)

  if (x & 128 == 128)
    report_block[:lost_packets] = lost_packets
  end

  if (x & 64 == 64)
    report_block[:dup_packets] = dup_packets
  end

  if (x &  32 == 32)
    report_block[:min_jitter] = values[0]
    report_block[:max_jitter] = values[1]
    report_block[:mean_jitter] = values[2]
    report_block[:dev_jitter] = values[3]
  end

  case ((x >> 3) & 3)
  when 1 # IPv4 TTL values
    report_block[:min_ttl]  = values[4]
    report_block[:max_ttl]  = values[5]
    report_block[:mean_ttl] = values[6]
    report_block[:dev_ttl]  = values[7]
  when 2 # IPv6 Hop Limit values
    report_block[:min_hl]  = values[4]
    report_block[:max_hl]  = values[5]
    report_block[:mean_hl] = values[6]
    report_block[:dev_hl]  = values[7]
  end
  report_block
end