Shared plumbing for the command modules.
All commands share these conventions:
- the first argument is the connection (
mc, the pid or registered name of aMeshcore.Client); - timeouts are milliseconds (Python uses seconds);
- a command returns
{:ok, %Meshcore.Event{}}or{:error, %Meshcore.Event{}}. The error event hastype: :errorand a payload with either:reason(:timeout,:not_connected,:disconnected, …) or:error_code/:code_stringwhen the device rejected the command; - a destination (
Meshcore.Util.destination/0) is a contact map, a hex public key or a raw public key; - programmer errors (malformed destination, wrong key size…) raise
ArgumentError, like Python'sValueError.
Summary
Functions
Encodes the reply path a server should use when answering us.
Sends an anonymous request (command 0x39) to dst.
Sends a binary request (command 0x32) to dst.
Sends raw command bytes and waits for one of the expected event types.
Types
@type mc() :: GenServer.server()
@type result() :: {:ok, Meshcore.Event.t()} | {:error, Meshcore.Event.t()}
Functions
Encodes the reply path a server should use when answering us.
The first byte packs hop_count | hash_mode << 6; the path is reversed by
hop (multi-byte hashes stay intact). Paths are truncated to what the
server's 64 byte buffer can hold.
@spec send_anon_req(mc(), Meshcore.Util.destination(), atom(), keyword()) :: result()
Sends an anonymous request (command 0x39) to dst.
dst need not be a known contact. When it is, the contact's out path is used
as the reply path; otherwise a zero-hop direct reply is requested. A contact
that is currently flooded is temporarily pinned to a zero-hop path (the
servers gate these requests behind direct routing) and reset afterwards.
@spec send_binary_req( mc(), Meshcore.Util.destination(), atom(), binary() | nil, keyword() ) :: result()
Sends a binary request (command 0x32) to dst.
The pending request is registered with the reader atomically when the
:msg_sent acknowledgement arrives, so a response can never overtake the
registration. Options: :timeout and :min_timeout (ms, nil/0 = use the
device's suggestion), :context, :then (see Meshcore.Client.command/4).
@spec send_command(mc(), iodata(), [Meshcore.Event.type()], keyword()) :: result()
Sends raw command bytes and waits for one of the expected event types.
See Meshcore.Client.command/4 for the options. With no expected events the
command is fire-and-forget.