defmodule Openflow.Multipart.Group.Reply do defstruct( version: 4, xid: 0, # virtual field datapath_id: nil, aux_id: nil, flags: [], groups: [] ) alias __MODULE__ def ofp_type, do: 18 def new(groups \\ []) do %Reply{groups: groups} end def read(<>) do groups = Openflow.Multipart.Group.read(groups_bin) %Reply{groups: groups} end def append_body(%Reply{groups: groups} = message, %Reply{flags: [:more], groups: continue}) do %{message | groups: [continue | groups]} end def append_body(%Reply{groups: groups} = message, %Reply{flags: [], groups: continue}) do new_groups = [continue | groups] |> Enum.reverse() |> List.flatten() %{message | groups: new_groups} end end defmodule Openflow.Multipart.Group do defstruct( group_id: 0, ref_count: 0, packet_count: 0, byte_count: 0, duration_sec: 0, duration_nsec: 0, bucket_stats: [] ) @ofp_group_stats_size 40 alias __MODULE__ def read(binary) do do_read([], binary) end # private functions defp do_read(acc, ""), do: Enum.reverse(acc) defp do_read(acc, <> = binary) do <> = binary do_read([codec(group_bin) | acc], rest) end defp codec( <> ) do bucket_stats_size = length - @ofp_group_stats_size <> = tail bucket_stats = for <> do %{packet_count: packet_count, byte_count: byte_count} end %Group{ group_id: group_id, ref_count: ref_count, packet_count: packet_count, byte_count: byte_count, duration_sec: duration_sec, duration_nsec: duration_nsec, bucket_stats: bucket_stats } end end