Packages
smppex
0.3.1
3.3.0
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
retired
3.1.0
retired
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.4.0
2.3.3
2.3.2
2.3.1
2.3.0
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.1.0
2.0.1
2.0.0
1.0.1
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
SMPP 3.4 protocol and framework implemented in Elixir
Current section
Files
Jump to
Current section
Files
lib/smppex/protocol/optional_fields_builder.ex
defmodule SMPPEX.Protocol.OptionalFieldsBuilder do
@moduledoc false
import SMPPEX.Protocol.Pack
import SMPPEX.Protocol.TlvFormat
use Bitwise
@spec build(map) :: {:ok, iodata} | {:error, any}
def build(fields) when is_map(fields) do
fields |> Map.to_list |> build([])
end
defp build([], built), do: {:ok, built}
defp build([{name, value} | rest], built) when is_atom(name) do
case id_by_name(name) do
{:ok, id} -> build([{id, value} | rest], built)
:unknown -> {:error, "Can't find id for name #{inspect name}"}
end
end
defp build([{id, value} | rest], built) do
case build_tlv(id, value) do
{:ok, bin} -> build(rest, [bin | built])
{:error, error} -> {:error, {"Error building optional fields", error}}
end
end
defp build_tlv(id, value) do
case build_value(id, value) do
{:ok, bin} -> tlv(id, bin)
{:error, error} -> {:error, {"Invalid value for Tag #{inspect id}", error}}
end
end
defp build_value(id, value) do
format = format_by_id(id)
case format do
{:ok, format} -> build_value_with_format(value, format)
:unknown -> build_value_without_format(value)
end
end
@invalid_octet_string "TLV Octet String: invalid value"
@invalid_unknown_tlv_value "TLV: value for unknown Tag is not binary"
defp build_value_with_format(value, {:integer, size}), do: integer(value, size)
defp build_value_with_format(value, {:c_octet_string, {:max, size}}), do: c_octet_string(value, {:max, size})
defp build_value_with_format(value, {:octet_string, size}) when is_integer(size), do: octet_string(value, size)
defp build_value_with_format(value, {:octet_string, {_from, _to}})
when not is_binary(value) do
{:error, @invalid_octet_string}
end
defp build_value_with_format(value, {:octet_string, {from, to}})
when byte_size(value) > to or byte_size(value) < from do
{:error, @invalid_octet_string}
end
defp build_value_with_format(value, {:octet_string, {_from, _to}}), do: {:ok, value}
defp build_value_without_format(value) when not is_binary(value), do: {:error, @invalid_unknown_tlv_value}
defp build_value_without_format(value), do: {:ok, value}
end