// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.lowpan.thread;

using fuchsia.lowpan;

// FYI: The source for this 254 length is the Thread Specification.
const MAX_DATASET_TLV_LEN uint8 = 254;

/// Datatype for containing a Thread dataset in raw TLV form.
/// Functionally equivalent to type [`otOperationalDatasetTlvs`][1].
///
/// The details of the Thread TLV format are documented in the
/// [Thread Specification](https://www.threadgroup.org/ThreadSpec).
///
/// [1]: https://openthread.io/reference/struct/ot-operational-dataset-tlvs#structot_operational_dataset_tlvs
alias OperationalDatasetTlvs = bytes:MAX_DATASET_TLV_LEN;

/// Protocol for connecting to [`Dataset`] on a LoWPAN device.
@discoverable
protocol DatasetConnector {
    /// Connects to the [`Dataset`] protocol on the
    /// named LoWPAN device.
    ///
    /// The name of the interface can be learned by calling
    /// [`fuchsia.lowpan/Lookup.GetDevices`].
    ///
    /// If there is an error in processing this request
    /// the given channel is closed and an epitaph code used
    /// to describe the reason for the failure:
    ///
    /// * `ZX_ERR_INVALID_ARGUMENT`: The given interface name
    ///   was not formatted correctly or otherwise invalid.
    /// * `ZX_ERR_NOT_FOUND`: No interface was found with the
    ///   given name.
    /// * `ZX_ERR_NOT_SUPPORTED`: The interface exists but
    ///   does not support this protocol.
    Connect(resource struct {
        name fuchsia.lowpan.InterfaceName;
        server_end server_end:Dataset;
    });
};

/// Thread Operational Dataset Protocol.
///
/// This protocol can expose PII.
///
/// This protocol provides methods related to the management of the
/// Thread operational dataset in raw TLV form.
protocol Dataset {
    /// Fetches and returns the active Thread operational dataset in raw
    /// TLV form. Functionally equivalent to [`otDatasetGetActiveTlvs()`][2].
    ///
    /// This method returns the active dataset, or nothing in the case that
    /// there is no active operational dataset.
    ///
    /// Any error that prevents the operation from completing successfully
    /// will result in the protocol being closed.
    ///
    /// [2]: https://openthread.io/reference/group/api-operational-dataset#otdatasetgetactivetlvs
    GetActiveTlvs() -> (struct {
        dataset OperationalDatasetTlvs:optional;
    });

    /// Sets the active Thread Operational Dataset in raw TLV form.
    /// Functionally equivalent to [`otDatasetSetActiveTlvs()`][3].
    ///
    /// This method returns once the operation has completed successfully.
    ///
    /// Any error that prevents the operation from completing successfully
    /// will result in the protocol being closed.
    ///
    /// [3]: https://openthread.io/reference/group/api-operational-dataset#otdatasetsetactivetlvs
    SetActiveTlvs(struct {
        dataset OperationalDatasetTlvs;
    }) -> ();

    /// Requests that all nodes on the current network attach to the thread
    /// network described by given dataset.
    ///
    /// Functionally equivalent to `ot-br-posix`'s [`AttachAllNodesTo`][4].
    ///
    /// If this device is not currently provisioned, then calling this method
    /// is equivalent to calling [`SetActiveTlvs()`].
    ///
    /// The transition of all nodes to the new network may take as long as
    /// five minutes.
    ///
    /// This method returns once the transition has been scheduled successfully.
    /// Any error that prevents the scheduling of this operation from
    /// completing successfully (such as being provided with an incomplete
    /// dataset) will result in the protocol being closed.
    ///
    /// [4]: https://github.com/openthread/ot-br-posix/blob/0b5c6e1ecb8152ef6cea57c09b8a37a020fc4d6f/src/dbus/server/introspect.xml#L67-L73
    AttachAllNodesTo(struct {
        dataset OperationalDatasetTlvs;
    }) -> ();
};
