Zigbee.Adapter behaviour (zigbee v0.1.0)

Copy Markdown View Source

Behaviour for a Zigbee chip backend: a radio + NCP protocol presented as a normalized coordinator interface.

Zigbee.EZSP.Adapter implements it for Silicon Labs EmberZNet; a future Zigbee.ZNP.Adapter would do the same for TI Z-Stack. Everything above this boundary (Zigbee.Interview, Zigbee.ZCL, Zigbee.ZDO) depends only on this behaviour and the normalized events below, never on a specific chip.

A backend is a process that delivers normalized events to its subscriber:

{:zigbee, :device_joined, %{node_id: _, eui64: _}}
{:zigbee, :message, %Zigbee.Message{}}

Callers usually go through the Zigbee facade, which pairs a backend module with its process in a %Zigbee.Adapter{} handle and dispatches to it.

Summary

Callbacks

Register an application endpoint (must happen before the network is up).

Form a coordinator network. Returns the resulting network parameters.

The coordinator's own identifier: its 64-bit IEEE 802.15.4 extended address (EUI64), the radio's permanent globally-unique hardware address. Raw 8-byte LE.

Version/stack info for the connected radio.

Open the network for joining for seconds (0xFF = no timeout).

Re-establish the network already stored on the radio (rather than forming a new one), re-registering endpoints first. Returns {:ok, params} if a network was restored, or {:error, :no_network} if the radio has none stored.

Reset the coordinator: leave / tear down the current network, clearing stored state.

Send a direct APS unicast; returns the APS sequence number.

Start the backend process, returning its ref (a pid).

Register pid to receive the normalized {:zigbee, _} events.

Types

ref()

@type ref() :: pid() | GenServer.name()

t()

@type t() :: %Zigbee.Adapter{module: module(), ref: ref()}

Callbacks

add_endpoint(ref, endpoint, profile, device_id, in_clusters, out_clusters)

@callback add_endpoint(
  ref(),
  endpoint :: 0..255,
  profile :: 0..65535,
  device_id :: 0..65535,
  in_clusters :: [0..65535],
  out_clusters :: [0..65535]
) :: :ok | {:error, term()}

Register an application endpoint (must happen before the network is up).

form_network(ref, opts)

@callback form_network(ref(), opts :: keyword()) :: {:ok, map()} | {:error, term()}

Form a coordinator network. Returns the resulting network parameters.

identifier(ref)

@callback identifier(ref()) :: {:ok, binary()} | {:error, term()}

The coordinator's own identifier: its 64-bit IEEE 802.15.4 extended address (EUI64), the radio's permanent globally-unique hardware address. Raw 8-byte LE.

info(ref)

@callback info(ref()) :: map()

Version/stack info for the connected radio.

permit_joining(ref, seconds)

@callback permit_joining(ref(), seconds :: non_neg_integer()) :: :ok | {:error, term()}

Open the network for joining for seconds (0xFF = no timeout).

reestablish_network(ref, opts)

@callback reestablish_network(ref(), opts :: keyword()) ::
  {:ok, map()} | {:error, :no_network | term()}

Re-establish the network already stored on the radio (rather than forming a new one), re-registering endpoints first. Returns {:ok, params} if a network was restored, or {:error, :no_network} if the radio has none stored.

reset_network(ref)

@callback reset_network(ref()) :: :ok | {:error, term()}

Reset the coordinator: leave / tear down the current network, clearing stored state.

send_aps(ref, node_id, profile, cluster, dst_endpoint, payload, opts)

@callback send_aps(
  ref(),
  node_id :: 0..65535,
  profile :: 0..65535,
  cluster :: 0..65535,
  dst_endpoint :: 0..255,
  payload :: binary(),
  opts :: keyword()
) :: {:ok, 0..255} | {:error, term()}

Send a direct APS unicast; returns the APS sequence number.

start_link(opts)

@callback start_link(opts :: keyword()) :: {:ok, pid()} | {:error, term()}

Start the backend process, returning its ref (a pid).

subscribe(ref, pid)

@callback subscribe(ref(), pid()) :: :ok

Register pid to receive the normalized {:zigbee, _} events.