Packages
smppex
2.2.3
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_parser.ex
defmodule SMPPEX.Protocol.OptionalFieldsParser do
@moduledoc false
import SMPPEX.Protocol.Unpack
import SMPPEX.Protocol.TlvFormat
@type parse_result :: {:ok, map} | {:error, reason :: term}
@spec parse(binary) :: parse_result
def parse(bin), do: parse(bin, Map.new)
defp parse(<<>>, parsed_fields) do
{:ok, parsed_fields}
end
defp parse(bin, parsed_fields) do
case tlv(bin) do
{:ok, {tag, value}, rest} ->
case parse_format(tag, value) do
{:ok, parsed} ->
parse(rest, Map.put(parsed_fields, tag, parsed))
{:error, error} -> {:error, {"Invalid format for tlv #{inspect tag}", error}}
end
{:error, _} = err -> err
end
end
defp parse_format(tag, value) do
case format_by_id(tag) do
{:ok, format} -> parse_known_tlv(value, format)
:unknown -> {:ok, value} # unknown tlvs are always valid
end
end
defp parse_known_tlv(value, {:integer, size}) do
bit_length = size * 8
case value do
<<int :: big-unsigned-integer-size(bit_length)>> -> {:ok, int}
_ -> {:error, "Invalid integer"}
end
end
defp parse_known_tlv(value, {:c_octet_string, {:max, size}}) do
case c_octet_string(value, {:max, size}) do
{:ok, str, ""} -> {:ok, str}
_ -> {:error, "Invalid c_octet_string"}
end
end
defp parse_known_tlv(value, {:octet_string, size}) when is_integer(size) do
case value do
<< _ :: binary-size(size) >> -> {:ok, value}
_ -> {:error, "Invalid octet_string"}
end
end
defp parse_known_tlv(value, {:octet_string, {from, to}}) do
if byte_size(value) >= from and byte_size(value) <= to do
{:ok, value}
else
{:error, "Invalid octet_string"}
end
end
end