defmodule Openflow.Multipart.Port.Reply do defstruct( version: 4, xid: 0, # virtual field datapath_id: nil, aux_id: nil, flags: [], ports: [] ) alias __MODULE__ def ofp_type, do: 18 def read(<>) do ports = Openflow.Multipart.PortStats.read(ports_bin) %Reply{ports: ports} end def append_body(%Reply{ports: ports} = message, %Reply{flags: [:more], ports: continue}) do %{message | ports: [continue | ports]} end def append_body(%Reply{ports: ports} = message, %Reply{flags: [], ports: continue}) do new_ports = [continue | ports] |> Enum.reverse() |> List.flatten() %{message | ports: new_ports} end end defmodule Openflow.Multipart.PortStats do defstruct( port_number: 0, rx_packets: 0, tx_packets: 0, rx_bytes: 0, tx_bytes: 0, rx_dropped: 0, tx_dropped: 0, rx_errors: 0, tx_errors: 0, rx_frame_err: 0, rx_over_err: 0, rx_crc_err: 0, collisions: 0, duration_sec: 0, duration_nsec: 0 ) alias __MODULE__ def read(binary) do do_read([], binary) end # private functions defp do_read(acc, ""), do: Enum.reverse(acc) defp do_read(acc, <>) do do_read([codec(port_stats_bin) | acc], rest) end defp codec( <> ) do %PortStats{ port_number: port_no, rx_packets: rx_packets, tx_packets: tx_packets, rx_bytes: rx_bytes, tx_bytes: tx_bytes, rx_dropped: rx_dropped, tx_dropped: tx_dropped, rx_errors: rx_errors, tx_errors: tx_errors, rx_frame_err: rx_frame_err, rx_over_err: rx_over_err, rx_crc_err: rx_crc_err, collisions: collisions, duration_sec: duration_sec, duration_nsec: duration_nsec } end end