// Copyright © 2025-2026 Kvaser AB, all rights reserved

// This header was created for version 0.3.1 of CL API. It is intended to be ABI compatible between
// minor releases, starting with version 1.0.0

#ifndef CL_API_H
#define CL_API_H

// Generated header, do not edit manually!

#include <stdint.h>
#include <stddef.h>

// If building on windows and using the shared library version of cl_api, you 
// need to define CL_API_USE_DLL. This can be done either through your build
// system or by defining it in code before including this header.
#if defined(CL_API_USE_DLL) && defined(_MSC_VER)
    #define CL_API __declspec(dllimport)
#else
    /// @brief CL_API will be expanded to __declspec(dllimport) on windows, on Linux it expands to
    /// nothing
    #define CL_API
#endif

#if defined(_WIN32)
    #define CL_CC __stdcall
#else
    /// @brief CL_CC will be expanded to __stdcall when compiling for 32bit windows applications, on Linux and 64bit windows it expands to
    /// nothing (use default calling convention for the platform).
    #define CL_CC
#endif


/**
 * The current version of cl_interface_status_t, it will get bumped when fields
 * are added to \ref cl_interface_status_t and is used to track what data can be
 * populated into this struct as the shared library grows, without the need to
 * modify or rebuild the user's application (consumer of this API).
 */
#define CL_INTERFACE_STATUS_T_VERSION 1

typedef enum cl_status_t {
  CL_STATUS_SUCCESS = 0,
  /**
   * The attempted operation was not permitted
   */
  CL_STATUS_OPERATION_NOT_PERMITTED = 10,
  /**
   * The attempted operation failed
   */
  CL_STATUS_OPERATION_FAILED = 11,
  /**
   * The attempted operation is not supported by this device
   */
  CL_STATUS_OPERATION_NOT_SUPPORTED_BY_DEVICE = 12,
  /**
   * The attempted operation is not supported by this interface
   */
  CL_STATUS_OPERATION_NOT_SUPPORTED_BY_INTERFACE = 13,
  /**
   * The attempted operation is not supported by the currently running device firmware
   */
  CL_STATUS_OPERATION_NOT_SUPPORTED_BY_DEVICE_FIRMWARE = 14,
  /**
   * Catchall for unexpected network errors
   */
  CL_STATUS_UNKNOWN_NETWORK_ERROR = 102,
  /**
   * Failed device connection
   */
  CL_STATUS_UNABLE_TO_CONNECT = 103,
  /**
   * Failed to write to TCP socket
   */
  CL_STATUS_SOCKET_WRITE_ERROR = 105,
  /**
   * Failed to read from TCP socket
   */
  CL_STATUS_SOCKET_READ_ERROR = 106,
  /**
   * Failed to open file
   */
  CL_STATUS_FILE_OPEN_ERROR = 150,
  /**
   * Failed to read file
   */
  CL_STATUS_FILE_READ_ERROR = 151,
  /**
   * Failed to create threads
   */
  CL_STATUS_THREADING_ERROR = 160,
  /**
   * Encountered an unimplemented function
   */
  CL_STATUS_NOT_IMPLEMENTED = 200,
  /**
   * The given buffer was too small to fit the requested data
   */
  CL_STATUS_BUFFER_TOO_SMALL = 201,
  /**
   * Found a device that has newer, incompatible firmware with this version of CL API
   */
  CL_STATUS_DEVICE_NOT_SUPPORTED_BY_CLIENT = 205,
  /**
   * A function was called incorrectly, for instance calling cl_interface_get_status with a
   * cl_interface_status_t without a struct_size/version set.
   */
  CL_STATUS_INVALID_USAGE = 207,
  /**
   * Encountered a string with invalid utf-8
   */
  CL_STATUS_INVALID_UTF8 = 208,
  /**
   * Some other error occurred
   */
  CL_STATUS_UNSPECIFIED_ERROR = 1000,
} cl_status_t;

/**
 * Enum containing possible update results
 */
typedef enum cl_firmware_update_result_t {
  CL_UF_STATUS_SUCCESS = 0,
  CL_UF_STATUS_TRANSFER_ERROR = 1,
  CL_UF_STATUS_FIRMWARE_FAILED_SIGNATURE_CHECK = 2,
  CL_UF_STATUS_FIRMWARE_CORRUPT = 3,
  CL_UF_STATUS_FIRMWARE_FOR_OTHER_DEVICE = 4,
  CL_UF_STATUS_UNKNOWN_ERROR = 5,
} cl_firmware_update_result_t;

/**
 * @brief Interface type
 */
typedef enum cl_interface_type_t {
  CL_INTERFACE_TYPE_T1 = 0,
  _RESERVED = 1,
  CL_INTERFACE_TYPE_T = 2,
} cl_interface_type_t;

/**
 * @brief Ethernet link speed
 */
enum cl_link_speed_t
#ifdef __cplusplus
  : uint32_t
#endif // __cplusplus
 {
  CL_ETH_LINK_SPEED_INVALID = 0,
  CL_ETH_LINK_SPEED_10MBIT_HALF_DUPLEX = 1,
  CL_ETH_LINK_SPEED_10MBIT_FULL_DUPLEX = 2,
  CL_ETH_LINK_SPEED_100MBIT_HALF_DUPLEX = 4,
  CL_ETH_LINK_SPEED_100MBIT_FULL_DUPLEX = 8,
  CL_ETH_LINK_SPEED_1000MBIT_HALF_DUPLEX = 16,
  CL_ETH_LINK_SPEED_1000MBIT_FULL_DUPLEX = 32,
};
#ifndef __cplusplus
typedef uint32_t cl_link_speed_t;
#endif // __cplusplus

/**
 * @brief Ethernet role
 */
enum cl_link_role_t
#ifdef __cplusplus
  : uint32_t
#endif // __cplusplus
 {
  CL_ETH_LINK_ROLE_INVALID = 0,
  CL_ETH_LINK_ROLE_LEADER = 1,
  CL_ETH_LINK_ROLE_LEADER_PREFERRED = 2,
  CL_ETH_LINK_ROLE_FOLLOWER = 4,
  CL_ETH_LINK_ROLE_FOLLOWER_PREFERRED = 8,
};
#ifndef __cplusplus
typedef uint32_t cl_link_role_t;
#endif // __cplusplus

/**
 * @brief Ethernet link state
 */
typedef enum cl_link_state_t {
  CL_ETH_LINK_STATE_DOWN,
  CL_ETH_LINK_STATE_UP,
} cl_link_state_t;

/**
 * The different possible TC10 states
 */
typedef enum cl_tc10_state_t {
  CL_TC10_STATE_NORMAL = 0,
  CL_TC10_STATE_SLEEP = 1,
  CL_TC10_STATE_SLEEP_FAILED = 2,
  CL_TC10_STATE_SLEEP_ABORTED = 3,
  CL_TC10_STATE_UNKNOWN = 4,
} cl_tc10_state_t;

/**
 * The available TC10 commands
 */
typedef enum cl_tc10_command_t {
  CL_TC10_CMD_SLEEP = 0,
  CL_TC10_CMD_WAKE_UP = 1,
} cl_tc10_command_t;

/**
 * @brief Ethernet auto negotiation
 */
typedef enum cl_aneg_mode_t {
  CL_ETH_ANEG_MODE_DISABLED = 0,
  CL_ETH_ANEG_MODE_IEEE_ANEG_ENABLED = 1,
} cl_aneg_mode_t;

/**
 * @brief cl_client_t is the opaque pointer type used as a handle for all client operations
 */
typedef struct cl_client_t cl_client_t;

/**
 * @brief cl_device_iterator is the opaque pointer type used as a device list iterator
 */
typedef struct cl_device_iterator_t cl_device_iterator_t;

/**
 * @brief cl_device_list_t is the opaque pointer type used as a handle a collection of devices
 */
typedef struct cl_device_list_t cl_device_list_t;

/**
 * @brief cl_device_t is the opaque pointer type used as a handle for all device operations
 */
typedef struct cl_device_t cl_device_t;

/**
 * @brief cl_interface_iterator_t is the opaque pointer type used as a interface list iterator
 */
typedef struct cl_interface_iterator_t cl_interface_iterator_t;

/**
 * @brief cl_interface_list_t is the opaque pointer type used as a handle a collection of
 * interfaces
 */
typedef struct cl_interface_list_t cl_interface_list_t;

/**
 * @brief cl_interface_t is the opaque pointer type used as a handle for all interface operations
 */
typedef struct cl_interface_t cl_interface_t;

/**
 * @brief cl_device_list__ptr_t is used as in parameter to functions that "return" a
 * cl_device_list_t*
 */
typedef struct cl_device_list_t *cl_device_list_ptr_t;

/**
 * @brief cl_interface_list_ptr_t is used as in parameter to functions that "return" a
 * cl_interface_list_t*
 */
typedef struct cl_interface_list_t *cl_interface_list_ptr_t;

/**
 * @brief Struct containing function pointers to callbacks, to be called throughout the update
 * process. Used with \ref cl_device_update_firmware_from_blob and \ref cl_device_update_firmware_from_path.
 */
typedef struct cl_firmware_update_callbacks_t {
  /**
   * @brief User data, will be used as the first argument to all callback functions
   */
  void *user_data;
  /**
   * @brief Callback called when update is starting
   * @param[in] user_data The previously given user_data
   * @param[in] total_transfer_bytes The total size of the firmware
   */
  void (CL_CC *update_starting)(void *user_data, size_t total_transfer_bytes);
  /**
   * @brief Callback called when a chunk has been sent to the device
   * @param[in] user_data The previously given user_data
   * @param[in] transferred_bytes The amount of bytes transferred up to this point
   */
  void (CL_CC *report_progress)(void *user_data, size_t transferred_bytes);
  /**
   * @brief Callback called when upload is done and device is validating firmware and writing it to its flash memory
   * @param[in] user_data The previously given user_data
   */
  void (CL_CC *start_finalizing)(void *user_data);
  /**
   * @brief Callback called when the update is finished
   * @param[in] user_data The previously given user_data
   * @param[in] update_result A \ref cl_firmware_update_result_t
   */
  void (CL_CC *update_finished)(void *user_data, enum cl_firmware_update_result_t update_result);
} cl_firmware_update_callbacks_t;

/**
 * @brief Ethernet interface status. Has a link state (UP/DOWN), and if it is
 * up, it'll also contain a speed and role that is determined by what was
 * negotiated (or set, if not using aneg) for the link.
 */
typedef struct cl_eth_interface_status_t {
  cl_link_speed_t link_speed;
  cl_link_role_t link_role;
  enum cl_link_state_t link_state;
} cl_eth_interface_status_t;

/**
 * @brief Interface status contains the status for an interface. It consists
 * of struct_size, struct_version, interface_type and eth_interface_status.
 *
 * The struct_size and struct_version are there to allow for this
 * struct to grow in future versions of this API without breaking the ABI.
 * To use it you'll want to initialize it before use as follows:
 * @code
 * cl_interface_status_t interface_status = {
 *     .struct_size = sizeof(interface_status),
 *     .struct_version = CL_INTERFACE_STATUS_T_VERSION,
 * };
 * cl_status_t status = cl_interface_get_status(interface, &interface_status);
 * @endcode
 */
typedef struct cl_interface_status_t {
  size_t struct_size;
  uint32_t struct_version;
  enum cl_interface_type_t interface_type;
  struct cl_eth_interface_status_t eth_interface_status;
} cl_interface_status_t;

/**
 * @brief Ethernet config. Contains an auto negotiation setting (IEEE aneg
 * enabled or disabled), one or more speed settings (ORed) and one or more
 * link roles (ORed)
 */
typedef struct cl_eth_config_t {
  /**
   * flag containing ORed enumerations from cl_link_speed_t
   */
  uint32_t link_speed;
  /**
   * flag containing ORed enumerations from cl_link_role_t
   */
  uint32_t link_role;
  enum cl_aneg_mode_t aneg_mode;
} cl_eth_config_t;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/**
 * @brief Returns the API version
 * @param major the major version
 * @param minor the minor version
 * @param patch the patch version
 */
CL_API void CL_CC cl_get_api_version(uint32_t *major, uint32_t *minor, uint32_t *patch);

/**
 * @brief This is a helper to format an EAN number using the format
 * XX-XXXXX-XXXXX-X
 * @param ean The EAN to format
 * @param buffer Te buffer to place the resulting string in
 * @param buffer_size The size of the buffer
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API enum cl_status_t CL_CC cl_format_ean(uint64_t ean, char *buffer, size_t buffer_size);

/**
 * @brief This is a helper to format a serial number using the format
 * 0000000 (essentially just a "%07lu" format string)
 * @param ean The serial number to format
 * @param buffer Te buffer to place the resulting string in
 * @param buffer_size The size of the buffer
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_format_serial_number(uint64_t serial_number,
                                               char *buffer,
                                               size_t buffer_size);

/**
 * @brief Creates a client handle, to be used for all general library functions, must be freed with cl_client_destroy to free memery.
 * @return a new client handle
 */
CL_API
struct cl_client_t *CL_CC cl_client_create(void);

/**
 * @brief Frees the given client handle
 * @param client the client handle to free
 */
CL_API void CL_CC cl_client_destroy(struct cl_client_t *client);

/**
 * @brief Uses DNS-SD to scan for cl devices on the local network (ethernet
 * over USB)
 * @param client The client handle to use for the scan
 * @param device_list in parameter to store the scan result in
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_client_scan_for_devices(struct cl_client_t *client,
                                                  cl_device_list_ptr_t *device_list);

/**
 * @brief Uses DNS-SD to scan for cl devices on the local network (ethernet
 * over USB). This version of the function has an adjustable timeout to
 * allow shorter or longer scan time. Default scan time is 1000ms.
 * @param client The client handle to use for the scan
 * @param device_list in parameter to store the scan result in
 * @param timeout_ms the timeout to use
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_client_scan_for_devices_with_timeout(struct cl_client_t *client,
                                                               cl_device_list_ptr_t *device_list,
                                                               uint32_t timeout_ms);

/**
 * @brief Finds a device from the given index
 * @param index the index to find
 * @param device_list device list to search in
 * @return the device, or NULL if out of bounds
 */
CL_API
struct cl_device_t *CL_CC cl_device_list_find_by_index(size_t index,
                                                       cl_device_list_ptr_t device_list);

/**
 * @brief Finds a device from the given ean and serial number
 * @param ean a pointer to a serial number (will be ignored if NULL)
 * @param serial_number The device's serial number
 * @param device_list device list to search in
 * @return the device, or NULL if no match or multiple matches
 */
CL_API
struct cl_device_t *CL_CC cl_device_list_find_by_info(const uint64_t *ean,
                                                      uint64_t serial_number,
                                                      cl_device_list_ptr_t device_list);

/**
 * @brief Frees the given device_list
 * @param device_list device list to free
 */
CL_API void CL_CC cl_device_list_destroy(cl_device_list_ptr_t device_list);

/**
 * @brief Creates a device iterator. To be used with cl_device_iterator_next.
 * cl_device_iterator_destroy must be called to free memory when done with the iterator.
 * @param device_list The device list to iterate over
 * @return the device iterator object
 */
CL_API
struct cl_device_iterator_t *CL_CC cl_device_iterator_create(cl_device_list_ptr_t device_list);

/**
 * @brief Frees the given device iterotor.
 * @param iterator The iterator to free
 */
CL_API void CL_CC cl_device_iterator_destroy(struct cl_device_iterator_t *iterator);

/**
 * @brief Gets the next device.
 * @param iterator A cl_device_iterator_t created with cl_device_iterator_create
 * @return NULL if there is no next device.
 */
CL_API struct cl_device_t *CL_CC cl_device_iterator_next(struct cl_device_iterator_t *iterator);

/**
 * @brief Gets the interfaces for the given device
 * @param device The target device
 * @param interface_list A pointer to the cl_interface_list_ptr_t (pointer to pointer)
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_get_interfaces(struct cl_device_t *device,
                                                cl_interface_list_ptr_t *interface_list);

/**
 * @brief Gets the device name. The returned string will be null terminated.
 * @param device The target device
 * @param buffer A buffer to place the device name in
 * @param buffer_size The size of the buffer
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_get_name(struct cl_device_t *device,
                                          char *buffer,
                                          size_t buffer_size);

/**
 * @brief Gets the device nickname. The returned string will be null terminated.
 * @param device The target device
 * @param buffer A buffer to place the device nickname in
 * @param buffer_size The size of the buffer
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_get_nickname(struct cl_device_t *device,
                                              char *buffer,
                                              size_t buffer_size);

/**
 * @brief Sets the given null terminated device_nickname
 * @param device The target device
 * @param name A null terminated string
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API enum cl_status_t CL_CC cl_device_set_nickname(struct cl_device_t *device, const char *name);

/**
 * @brief Gets the 64bit firmware EAN
 * @param device The target device
 * @param ean Out parameter
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API enum cl_status_t CL_CC cl_device_get_firmware_ean(struct cl_device_t *device, uint64_t *ean);

/**
 * @brief Gets the 64bit feature EAN
 * @param device The target device
 * @param ean Out parameter
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API enum cl_status_t CL_CC cl_device_get_feature_ean(struct cl_device_t *device, uint64_t *ean);

/**
 * @brief Gets the firmware version as a semver string
 * @param device The target device
 * @param buffer Buffer to store the string in
 * @param buffer_size Size of the buffer
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_get_firmware_version(struct cl_device_t *device,
                                                      char *buffer,
                                                      size_t buffer_size);

/**
 * @brief Gets the bootloader version as a semver string
 * @param device The target device
 * @param buffer Buffer to store the version string in
 * @param buffer_size Size of the buffer
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_get_bootloader_version(struct cl_device_t *device,
                                                        char *buffer,
                                                        size_t buffer_size);

/**
 * @brief Gets the PCB revision as a string
 * @param device The target device
 * @param buffer Buffer to store the PCB revision string in
 * @param buffer_size Size of the buffer
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_get_pcb_revision(struct cl_device_t *device,
                                                  char *buffer,
                                                  size_t buffer_size);

/**
 * @brief Sends a new firmware blob to the device
 * @param device The target device
 * @param firmware_blob Raw firmware blob
 * @param size Size of blob in bytes
 * @param callbacks A cl_firmware_update_callbacks_t structure containing function pointers to
 * call during the firmware update. It is safe for the struct pointer to be NULL, as well as any of
 * the function pointers (if they're not of interest).
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_update_firmware_from_blob(struct cl_device_t *device,
                                                           const char *firmware_blob,
                                                           size_t size,
                                                           const struct cl_firmware_update_callbacks_t *callbacks);

/**
 * @brief Sends a new firmware from file at the given path to the device
 * @param device The target device
 * @param firmware_path File path to firmware file
 * @param callbacks A cl_firmware_update_callbacks_t structure containing function pointers to
 * call during the firmware update. It is safe for the struct pointer to be NULL, as well as any of
 * the function pointers (if they're not of interest).
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_update_firmware_from_path(struct cl_device_t *device,
                                                           const char *firmware_path,
                                                           const struct cl_firmware_update_callbacks_t *callbacks);

/**
 * @brief Gets the device manufacturing date as string
 * @param device The target device
 * @param timestamp Unix timestamp when device was manufactured
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_get_manufacturing_date(struct cl_device_t *device,
                                                        uint64_t *timestamp);

/**
 * @brief Gets the 64bit serial_number
 * @param device The target device
 * @param serial_number Out parameter
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_device_get_serial_number(struct cl_device_t *device,
                                                   uint64_t *serial_number);

/**
 * @brief Gets the 64bit EAN
 * @param device The target device
 * @param ean Out parameter
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API enum cl_status_t CL_CC cl_device_get_ean(struct cl_device_t *device, uint64_t *ean);

/**
 * @brief Trigger identify device sequence (flash device LEDs)
 * @param device The target device
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API enum cl_status_t CL_CC cl_device_identify(struct cl_device_t *device);

/**
 * @brief Frees the given interface_list
 * @param interface_list interface list to free
 */
CL_API void CL_CC cl_interface_list_destroy(cl_interface_list_ptr_t interface_list);

/**
 * @brief Creates an iterator to be used to access the interfaces from an \ref cl_interface_list_t
 * @param interface_list An interface list
 * @note This iterator must be freed with cl_interface_iterator_destroy to free memory.
 * @return A \ref cl_interface_iterator_t
 */
CL_API
struct cl_interface_iterator_t *CL_CC cl_interface_iterator_create(struct cl_interface_list_t *interface_list);

/**
 * @brief Frees the given interface iterotor.
 * @param iterator The iterator to free
 */
CL_API void CL_CC cl_interface_iterator_destroy(struct cl_interface_iterator_t *iterator);

/**
 * @brief Gets the next interface.
 * @param iterator A cl_interface_iterator_t created with cl_interface_iterator_create
 * @return NULL if there is no next interface.
 */
CL_API
struct cl_interface_t *CL_CC cl_interface_iterator_next(struct cl_interface_iterator_t *iterator);

/**
 * @brief Gets the interface nickname
 * @param interface The target interface
 * @param buffer A buffer to place the interface nickname in
 * @param buffer_size The size of the buffer
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_interface_get_nickname(struct cl_interface_t *interface,
                                                 char *buffer,
                                                 size_t buffer_size);

/**
 * @brief Sets the given null terminated interface nickname
 * @param interface The target interface
 * @param name A null terminated string
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_interface_set_nickname(struct cl_interface_t *interface,
                                                 const char *name);

/**
 * @brief Gets the interface status.
 * @param interface The target interface
 * @param status The returned interface status, see \ref cl_interface_status_t for
 * more info.
 * @note When link is down, this function will return the active configuration, and if it's up
 * it'll return the negotiated configuration.
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_interface_get_status(struct cl_interface_t *interface,
                                               struct cl_interface_status_t *status);

/**
 * @brief Reads the current tc10 state for the given interface.
 * @param interface The target interface
 * @param state Pointer to \ref cl_tc10_state_t to store result in
 * @note Only T1 interfaces support this function, others will return
 * CL_STATUS_OPERATION_NOT_SUPPORTED_BY_INTERFACE
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_interface_get_tc10_state(struct cl_interface_t *interface,
                                                   enum cl_tc10_state_t *state);

/**
 * @brief Sends the given tc10 command to the given interface
 * @param interface The target interface
 * @param command The tc10 command to send, see \ref cl_tc10_command_t for possible values
 * @note Only T1 interfaces support this function, others will return
 * CL_STATUS_OPERATION_NOT_SUPPORTED_BY_INTERFACE
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_interface_send_tc10_command(struct cl_interface_t *interface,
                                                      enum cl_tc10_command_t command);

/**
 * @brief Gets the interface link configuration for an ethernet interface.
 * @param interface The target interface
 * @param mode The config to get. See \ref cl_eth_config_t,
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_interface_eth_get_config(struct cl_interface_t *interface,
                                                   struct cl_eth_config_t *config);

/**
 * @brief Sets the interface link mode for an ethernet interface.
 * @param interface The target interface
 * @param config The config to set. See \ref cl_eth_config_t,
 * @note Only configs returned by \ref cl_interface_eth_get_supported_configs are possible
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_interface_eth_set_config(struct cl_interface_t *interface,
                                                   struct cl_eth_config_t config);

/**
 * @brief Gets the supported configuration options for the given interface.
 * @param interface The target interface
 * @param config The new config
 * @note Some interfaces will respond with CL_STATUS_OPERATION_NOT_SUPPORTED_BY_INTERFACE if it
 * can not be directly controlled. For instance the T interface in Arcus 100/1000BASE-T1 H-MTD
 * follows the negotiated link on the T1 side (since they're directly linked without an ethernet
 * switch between them).
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API
enum cl_status_t CL_CC cl_interface_eth_get_supported_configs(struct cl_interface_t *interface,
                                                              struct cl_eth_config_t *config);

/**
 * @brief Triggers identify interface sequence (flash interface LEDs) to help identify the given
 * interface
 * @param interface The target interface
 * @return status code, see \ref cl_status_t for possible codes
 */
CL_API enum cl_status_t CL_CC cl_interface_identify(struct cl_interface_t *interface);

#ifdef __cplusplus
}  // extern "C"
#endif  // __cplusplus

#endif  /* CL_API_H */
