# `ExDlt645.Codec`
[🔗](https://github.com/Ultraluv/ex_dlt645/blob/v0.1.0/lib/ex_dlt645/codec.ex#L35)

Pure functional packet encoder and decoder for DL/T 645-2007 frames.

# `add_33`

```elixir
@spec add_33(binary()) :: binary()
```

Adds 0x33 to each byte modulo 256.

# `checksum`

```elixir
@spec checksum(binary()) :: byte()
```

Calculates the modulo 256 checksum over the given binary.

# `error_reason`

```elixir
@spec error_reason(byte()) :: atom() | {:unknown_error, byte()}
```

Translates a 1-byte error code to a readable reason.

# `func_name`

```elixir
@spec func_name(byte()) :: atom()
```

Returns the symbolic name of a DL/T 645 function code.

# `pack_error_response`

```elixir
@spec pack_error_response(String.t(), byte(), byte(), keyword()) :: binary()
```

Packs an abnormal/error response frame.
Bit 6 of control code is set (0xC0 | func), and payload contains the 1-byte error code.

# `pack_frame`

```elixir
@spec pack_frame(String.t(), byte(), binary(), keyword()) :: binary()
```

Generic frame packer.

# `pack_freeze_request`

```elixir
@spec pack_freeze_request(String.t(), binary(), keyword()) :: binary()
```

Packs a freeze command frame (0x16).

# `pack_read_address_request`

```elixir
@spec pack_read_address_request(keyword()) :: binary()
```

Packs a read address request frame (0x13).
Uses broadcast address `AAAAAAAAAAAA` by default.

# `pack_read_address_response`

```elixir
@spec pack_read_address_response(String.t(), keyword()) :: binary()
```

Packs a normal response frame for read address (0x93).

# `pack_read_request`

```elixir
@spec pack_read_request(
  String.t(),
  non_neg_integer() | binary() | String.t(),
  keyword()
) :: binary()
```

Packs a read data request frame (0x11).

# `pack_read_response`

```elixir
@spec pack_read_response(
  String.t(),
  non_neg_integer() | binary(),
  binary(),
  keyword()
) :: binary()
```

Packs a normal response frame for read data (0x91).

# `pack_sync_time_request`

```elixir
@spec pack_sync_time_request(NaiveDateTime.t() | DateTime.t(), keyword()) :: binary()
```

Packs a broadcast time calibration frame (0x08).
Address is typically `999999999999`.

# `pack_write_address_request`

```elixir
@spec pack_write_address_request(String.t(), String.t(), keyword()) :: binary()
```

Packs a write address request frame (0x15).

# `pack_write_request`

```elixir
@spec pack_write_request(
  String.t(),
  non_neg_integer() | binary() | String.t(),
  binary(),
  binary(),
  binary(),
  keyword()
) :: binary()
```

Packs a write data request frame (0x14).

# `parse_frame`

```elixir
@spec parse_frame(binary()) :: {:ok, ExDlt645.Frame.t()} | {:error, term()}
```

Parses a complete DL/T 645-2007 frame binary.
Returns `{:ok, %ExDlt645.Frame{}}` or `{:error, reason}`.

# `sub_33`

```elixir
@spec sub_33(binary()) :: binary()
```

Subtracts 0x33 from each byte modulo 256.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
