diff --git a/lib/openflow/multipart/aggregate/reply.ex b/lib/openflow/multipart/aggregate/reply.ex index dfecbf0..0dadfa1 100644 --- a/lib/openflow/multipart/aggregate/reply.ex +++ b/lib/openflow/multipart/aggregate/reply.ex @@ -44,7 +44,7 @@ defmodule Openflow.Multipart.Aggregate.Reply do } end - @spec to_binary(t()) :: <<_::192>> + @spec to_binary(t()) :: <<_::64, _::_*8>> def to_binary(aggregate) do << Openflow.Multipart.Reply.header(aggregate)::bytes, diff --git a/lib/openflow/multipart/desc/reply.ex b/lib/openflow/multipart/desc/reply.ex index a995cf2..20158e5 100644 --- a/lib/openflow/multipart/desc/reply.ex +++ b/lib/openflow/multipart/desc/reply.ex @@ -15,22 +15,70 @@ defmodule Openflow.Multipart.Desc.Reply do alias __MODULE__ + @type t :: %Reply{ + version: 4, + datapath_id: String.t() | nil, + aux_id: 0..0xFF | nil, + xid: 0..0xFFFFFFFF, + flags: [], + mfr_desc: String.t(), + hw_desc: String.t(), + sw_desc: String.t(), + serial_num: String.t(), + dp_desc: String.t() + } + @desc_str_len 256 @serial_num_len 32 + @spec ofp_type() :: 19 def ofp_type, do: 19 - def read( - <> - ) do + @spec new( + xid: 0..0xFFFFFFFF, + mfr_desc: String.t(), + hw_desc: String.t(), + sw_desc: String.t(), + serial_num: String.t(), + dp_desc: String.t() + ) :: t() + def new(options \\ []) do %Reply{ - mfr_desc: Openflow.Utils.decode_string(mfr_desc), - hw_desc: Openflow.Utils.decode_string(hw_desc), - sw_desc: Openflow.Utils.decode_string(sw_desc), - serial_num: Openflow.Utils.decode_string(serial_num), - dp_desc: Openflow.Utils.decode_string(dp_desc) + xid: options[:xid] || 0, + mfr_desc: options[:mfr_desc] || "", + hw_desc: options[:hw_desc] || "", + sw_desc: options[:sw_desc] || "", + serial_num: options[:serial_num] || "", + dp_desc: options[:dp_desc] || "" + } + end + + @spec to_binary(t()) :: <<_::64, _::_*8>> + def to_binary(%Reply{} = desc) do + << + Openflow.Multipart.Reply.header(desc)::bytes, + String.pad_trailing(desc.mfr_desc, @desc_str_len, <<0>>)::bytes, + String.pad_trailing(desc.hw_desc, @desc_str_len, <<0>>)::bytes, + String.pad_trailing(desc.sw_desc, @desc_str_len, <<0>>)::bytes, + String.pad_trailing(desc.serial_num, @serial_num_len, <<0>>)::bytes, + String.pad_trailing(desc.dp_desc, @desc_str_len, <<0>>)::bytes + >> + end + + @spec read(<<_::8448>>) :: t() + def read(<< + mfr_desc::size(@desc_str_len)-bytes, + hw_desc::size(@desc_str_len)-bytes, + sw_desc::size(@desc_str_len)-bytes, + serial_num::size(@serial_num_len)-bytes, + dp_desc::size(@desc_str_len)-bytes + >>) do + %Reply{ + mfr_desc: hd(String.split(mfr_desc, <<0>>, parts: 2)), + hw_desc: hd(String.split(hw_desc, <<0>>, parts: 2)), + sw_desc: hd(String.split(sw_desc, <<0>>, parts: 2)), + serial_num: hd(String.split(serial_num, <<0>>, parts: 2)), + dp_desc: hd(String.split(dp_desc, <<0>>, parts: 2)) } end end diff --git a/lib/openflow/multipart/desc/request.ex b/lib/openflow/multipart/desc/request.ex index f0b17c5..999968e 100644 --- a/lib/openflow/multipart/desc/request.ex +++ b/lib/openflow/multipart/desc/request.ex @@ -4,22 +4,28 @@ defmodule Openflow.Multipart.Desc.Request do xid: 0, # virtual field datapath_id: nil, + aux_id: nil, flags: [] ) alias __MODULE__ + @type t :: %Request{ + version: 4, + datapath_id: String.t(), + aux_id: 0..0xFF | nil, + xid: 0..0xFFFFFFFF + } + + @spec ofp_type() :: 18 def ofp_type, do: 18 - def new(xid \\ 0) do - %Request{xid: xid} - end + @spec new(0..0xFFFFFFFF) :: t() + def new(xid \\ 0), do: %Request{xid: xid} - def read("") do - %Request{} - end + @spec read(<<>>) :: t() + def read(""), do: %Request{} - def to_binary(%Request{} = msg) do - Openflow.Multipart.Request.header(msg) - end + @spec to_binary(t()) :: <<_::64>> + def to_binary(%Request{} = msg), do: Openflow.Multipart.Request.header(msg) end diff --git a/test/lib/openflow/ofp_desc_stats_test.exs b/test/lib/openflow/ofp_desc_stats_test.exs new file mode 100644 index 0000000..f732979 --- /dev/null +++ b/test/lib/openflow/ofp_desc_stats_test.exs @@ -0,0 +1,41 @@ +defmodule OfpDescTest do + use ExUnit.Case + + describe "Openflow.Multipart.Desc.Request" do + test "with default values" do + desc = Openflow.Multipart.Desc.Request.new(0) + + desc + |> Openflow.to_binary() + |> Openflow.read() + |> Kernel.elem(1) + |> Kernel.==(desc) + |> assert() + end + end + + describe "Openflow.Multipart.Desc.Reply" do + test "with default values" do + desc = + %Openflow.Multipart.Desc.Reply{ + dp_desc: "None", + hw_desc: "Open vSwitch", + mfr_desc: "Nicira, Inc.", + serial_num: "None", + sw_desc: "2.11.0" + } + |> Map.to_list() + |> Openflow.Multipart.Desc.Reply.new() + |> Openflow.to_binary() + |> Openflow.read() + |> Kernel.elem(1) + + assert desc.xid == 0 + assert desc.mfr_desc == "Nicira, Inc." + assert desc.dp_desc == "None" + assert desc.hw_desc == "Open vSwitch" + assert desc.sw_desc == "2.11.0" + assert desc.serial_num == "None" + end + end +end