#ifndef INTERFACE_NETWORK_H
#define INTERFACE_NETWORK_H

/* --------------------------------------------------------------------
 *
 *  GGGGGG  NN    N
 *  G       N N   N
 *  G  GGG  N  N  N - Audio
 *  G    G  N   N N
 *  GGGGGG  N    NN
 *
 *  Copyright (c) 2021, GN-Audio
 * -------------------------------------------------------------------- */

 /**
  * @file Interface_Network.h
  * @brief Defines the network-related interfaces for the Jabra SDK.
  * Developer information can be found in the SDK documentation.
  */

  /****************************************************************************/
  /*                              INCLUDE FILES                               */
  /****************************************************************************/
#include "Common.h"

/****************************************************************************/
/*                     EXPORTED TYPES and DEFINITIONS                       */
/****************************************************************************/

typedef struct _IPv4Status
{
    bool InterfaceEnabled;
    bool DHCPEnabled;
    bool ConnectionStatus;
    struct _IP
    {
        uint8_t octet1;
        uint8_t octet2;
        uint8_t octet3;
        uint8_t octet4;
    } IP, SubNetMask;
} IPv4Status;

/**
 * @brief     Enables or disables remote management. If enabling and there are no active network interfaces (eth/wlan),
 *            it will automatically enable the Ethernet interface as well since remote mgmnt requires a network.
 *            If a timeout is specified, it will wait for an interface to be IP-configured before returning.
 * @param[in] deviceID  ID for a specific device
 * @param[in] enable    Enable state: true=enabled, false=disabled
 * @param[in] timeout   Time to wait for ethernet interface to become ready. Set to 0 to return immediately.
 * @return Return_Ok            Remote management is enabled
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Device_WriteFail     Failed while writing to device
 * @return NetworkRequest_Fail  Management was enabled, but no working network interface was available at the time of return.
 * @see Jabra_GetEthernetIPv4Status
 */
LIBRARY_API Jabra_ReturnCode Jabra_EnableRemoteManagement(unsigned short deviceID, bool enable, unsigned int timeout);

/**
 * @brief       Get whether remote management is enabled on a networked device.
 * @param[in]   deviceID ID for a specific device
 * @param[out]  enable   Enable state: true=enabled, false=disabled
 *                       Will only be written to if return value == Return_Ok.
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail A NULL pointer was passed
 * @return Device_ReadFails     Failed while reading from device
 */
LIBRARY_API Jabra_ReturnCode Jabra_IsRemoteManagementEnabled(unsigned short deviceID, bool* enable);

/**
 * @brief       Enables or disables the ethernet on a networked device. WLAN will become disabled if enabled.
 * @param[in]   deviceID ID for a specific device
 * @param[in]   enable   Enable state: true=enabled, false=disabled
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Device_ReadFails     Failed while reading from device
 * @return NetworkRequest_Fail  WLAN could not be shutdown to activate Ethernet
 */
LIBRARY_API Jabra_ReturnCode Jabra_EnableEthernet(unsigned short deviceID, bool enable);

/**
 * @brief       Enables or disables the WLAND on a networked device. Ethernet will become disabled if enabled.
 * @param[in]   deviceID ID for a specific device
 * @param[in]   enable   Enable state: true=enabled, false=disabled
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Device_ReadFails     Failed while reading from device
 * @return NetworkRequest_Fail  Ethernet could not be shutdown to activate WLAN
 */
LIBRARY_API Jabra_ReturnCode Jabra_EnableWLAN(unsigned short deviceID, bool enable);

typedef struct _ProxySettings
{
    enum _ProxyType      // See curl documentation for explanation of proxy types,
    {                    // e.g. https://everything.curl.dev/libcurl/proxies
        PROXY_HTTP = 0,
        PROXY_HTTPS,
        PROXY_SOCKS4,
        PROXY_SOCKS4A,
        PROXY_SOCKS5,
        PROXY_SOCKS5H
    } Type;
    char* URL;           // Pointer to NULL-terminated string containing RFC 3986+ proxy address
    char* Hostname;      // Pointer to NULL-terminated string containing proxy hostname
    unsigned short Port; // Port number
    char* Username;      // Pointer to NULL-terminated string containing the login username for the proxy
    char* Password;      // Pointer to NULL-terminated string containing the login password for the proxy
} ProxySettings;

/**
 * @brief     Configures Xpress management related settings on a network-capable device.
 *            Will enable Ethernet interface if no network interfaces are available.
 *            To set up the device with WLAN, use Jabra_ConnectWLANInterface first.
 *            In case of NetworkRequest_Fail or Return_Timeout return codes, the
 *            proxy configuration and Xpress URL will revert to the previous values.
 * @param[in] deviceID          ID for a specific device
 * @param[in] xpressurl         Pointer to NULL-terminated string containing the URL for the Xpress management backend.
 *                              Protocol is always assumed to be HTTPS no matter the prefix of the URL.
                                Setting URL pointer to NULL will disable management.
 * @param[in] proxy             Pointer to proxy settings - set to NULL if not using proxy (default)
 * @param[in] timeout           Maximum allowed execution time for the entire operation.
 *                              In the worst cast the flow is:
 *                              1. Enabling network interface
 *                              2. Waiting for DHCP resolution
 *                              3. Startup of management service
 *                              4. DNS resolution of specified URL
 *                              5. HTTPS request and parsing the response
 *                              The recommended value is 30'000 ms.
 *                              Setting timeout=0 will configure the device and return immediately without checking the validity of the xpressurl.
 * @return Return_Ok            Device was successfully configured for stand-alone remote management
 * @return Device_Unknown       deviceID is unknown
 * @return Return_ParameterFail A parameter was missing or incorrect
 * @return Not_Supported        Functionality is not supported on this device
 * @return Device_WriteFail     Failed while writing to device
 * @return NetworkRequest_Fail  URL was unreachable - see Jabra_GetXpressManagementNetworkStatus
 * @return Return_Timeout       URL validation did not complete before timeout (when timeout>0)
 * @see Jabra_GetXpressManagementNetworkStatus
 * @see Jabra_ConnectWLANInterface
 */
LIBRARY_API Jabra_ReturnCode Jabra_ConfigureXpressManagement(unsigned short deviceID, const char* xpressurl, const ProxySettings* proxy, unsigned int timeout);

/**
 * @brief     Gets the resulting libcurl errorcode and message from the last call to
 *            Jabra_ConfigureXpressManagement() if it returned NetworkRequest_Fail.
 * @param[in]  deviceID         ID for a specific device
 * @param[out] errorcode        Pointer to int that will receive libcurl error code. If NULL, no error code will be returned.
 * @param[out] message          Pointer to buffer that will receive libcurl error message. If NULL, no error message will be returned.
 * @param[in]  buffersize       Size of buffer pointed to by 'message' (including NULL terminator). Ignored if errormessage==NULL.
 * @return false                Last call to Jabra_ConfigureXpressManagement() did not produce an errorcode/message.
 * @return true                 An error code/message is available. In case of errorcode==0 it means the last request was successful
 *                              and the message will be empty.
 *                              If 'errorcode' or 'message' pointers are non-NULL, they will receive the information.
 * @see Jabra_ConfigureXpressManagement
 */
LIBRARY_API bool Jabra_GetXpressManagementNetworkStatus(unsigned short deviceID, unsigned short* errorcode, char* message, int buffersize);

/**
 * @brief     Set Xpress server URL. Will block until URL has been validated or timeout reached.
 *            In case of NetworkRequest_Fail or Return_Timeout return codes, URL will still be set,
 *            so if this is not wanted, clear the URL by setting url to an empty string.
 * @param[in] deviceID  ID for a specific device
 * @param[in] url       Pointer to char buffer containing NULL-terminated URL
 * @param[in] timeout   Time to wait for URL validation in ms. Set to 0 to return immediately.
 * @return Return_Ok            URL was changed and verified successfully
 * @return Device_Unknown       deviceID is unknown
 * @return Return_ParameterFail A NULL pointer was passed
 * @return Device_WriteFail     Failed while writing to device
 * @return System_Error         Some unspecified system error occurred
 * @return NetworkRequest_Fail  URL was evaluated to be incorrect or unreachable
 * @return Return_Timeout       URL validation did not complete before timeout
 */
LIBRARY_API Jabra_ReturnCode Jabra_SetXpressUrl(unsigned short deviceID, const char* url, unsigned int timeout);

/**
 * @brief       Get Xpress server URL.
 * @param[in]   deviceID    ID for a specific device
 * @param[out]  url         Pointer to a buffer where the URL string will be written
 *                          Must be preallocated by the caller
 * @param[in]   size        Size of preallocated buffer 'url'. Max limit 2kB
 * @return Return_Ok            Call was successful. Will also return Return_Ok if url is not set
 * or device does not support xpress features, however output string will be "".
 * @return Device_Unknown       deviceID is unknown
 * @return Return_ParameterFail A NULL pointer was passed or buffer is too small
 * @return Device_ReadFails     Failed while reading from device
  */
LIBRARY_API Jabra_ReturnCode Jabra_GetXpressUrl(unsigned short deviceID, char* url, int size);

/**
 * @brief       Set password for password provisioning.
 * @param[in]   deviceID    ID for a specific device
 * @param[in]   password    Pointer to char buffer containing NULL-terminated password
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Return_ParameterFail A NULL pointer was passed
 * @return Device_WriteFail     Failed while writing to device
 */
LIBRARY_API Jabra_ReturnCode Jabra_SetPasswordProvisioning(unsigned short deviceID, const char* password);

/**
 * @brief       Get the password for provisioning.
 * @param[in]   deviceID    ID for a specific device
 * @param[out]  password    Pointer to a buffer where the password string will be written
 *                          Must be preallocated by the caller
 * @param[in]   size        Size of preallocated buffer 'password'. Max limit 2kB
 * @return Return_Ok            Call was successful. Will also return Return_Ok if password is not set
 * or device does not support password provisioning, however output string will be "".
 * @return Device_Unknown       deviceID is unknown
 * @return Return_ParameterFail A NULL pointer was passed or buffer is too small
 * @return Device_ReadFails     Failed while reading from device
 */
LIBRARY_API Jabra_ReturnCode Jabra_GetPasswordProvisioning(unsigned short deviceID, char* password, int size);

/**
 * @brief       Notify the app connected to an Xpress capable device whether device is being remotely managed.
 * @param[in]   deviceID    ID for a specific device
 * @param[in]   isConnected true=connection to the backend is established, false=is not established
 * @return Return_Ok            Call was successful. Unsupported devices will silently
 * ignore this, so Return_Ok does not imply that the feature is supported.
 * @return Device_Unknown       deviceID is unknown
 * @return Device_WriteFail     Failed while writing to device
 */
LIBRARY_API Jabra_ReturnCode Jabra_NotifyXpressConnectionStatus(unsigned short deviceID, bool isConnected);

/**
 * @brief       Notify the app connected to an Xpress capable device whether device is being remotely managed.
 * @param[in]   deviceID    ID for a specific device
 * @param[in]   isConnected true=connection to the backend is established, false=is not established
 * @param[in]   errorcode   libcurl error code
 * @param[in]   errorstring error message in case of error. Can be NULL if no message.
 * @return Return_Ok            Call was successful. Unsupported devices will silently
 * ignore this, so Return_Ok does not imply that the feature is supported.
 * @return Device_Unknown       deviceID is unknown
 * @return Device_WriteFail     Failed while writing to device
 */
LIBRARY_API Jabra_ReturnCode Jabra_NotifyXpressConnectionStatusExtended(unsigned short deviceID, bool isConnected, unsigned short errorcode, const char* errorstring);

/**
 * @brief Registration for Xpress connection status change callback.
 * Parameters are identical to those of Jabra_NotifyXpressConnectionStatus*
 * @param[in] xpressConnectionStatus Callback method to be called when the Xpress connection status is changed
 */
LIBRARY_API void Jabra_RegisterXpressConnectionStatusCallback(void(*xpressConnectionStatus)(unsigned short, bool));
/**
 * @brief Registration for Xpress connection status change callback.
 * Parameters are identical to those of Jabra_NotifyXpressConnectionStatus*
 * @param[in] xpressConnectionExtendedStatus Callback method to be called when the Xpress connection status is changed
 */
LIBRARY_API void Jabra_RegisterXpressConnectionStatusExtendedCallback(void(*xpressConnectionExtendedStatus)(unsigned short, bool, unsigned short, char*));

/**
 * @brief Gets the status of the Ethernet connection; Enable, DHCP, Connected states and IP + subnet mask.
 *
 * @param[in] deviceID          ID for a specific device
 * @param[out] ethernetStatus   Pointer to an IPv4Status struct that will be filled with the details of the Ethernet connection.
 *
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail A NULL pointer was passed
 * @return Device_ReadFails     Failed while reading from device
*/
LIBRARY_API Jabra_ReturnCode Jabra_GetEthernetIPv4Status(const unsigned short deviceID, IPv4Status* ethernetStatus);

/**
 * @brief Gets the status of the WLAN connection; Enable, DHCP, Connected states and IP + subnet mask.
 *
 * @param[in] deviceID          ID for a specific device
 * @param[out] wlanStatus       Pointer to an IPv4Status struct that will be filled with the details of the WLAN connection.
 *
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail A NULL pointer was passed
 * @return Device_ReadFails     Failed while reading from device
*/
LIBRARY_API Jabra_ReturnCode Jabra_GetWLANIPv4Status(const unsigned short deviceID, IPv4Status* wlanStatus);

typedef enum _NetworkInterface {
    Interface_Ethernet = 0,
    Interface_WLAN = 1,
    Interface_Bluetooth = 2
} NetworkInterface;

typedef enum _NetworkInterfaceStatus {
    NETWORK_LINK_DOWN = 0,
    NETWORK_LINK_UP = 1,
    NETWORK_IPADDRESS_SET = 2,
    NETWORK_IPADDRESS_REMOVED = 3,
    NETWORK_INTERFACE_DOWN = 4,
    NETWORK_INTERFACE_UP = 5
} NetworkInterfaceStatus;

/**
 * @brief Registration for network interface status change callback.
 * @param[in] networkStatus Pointer to callback method to be called when the status of a network interface changes.
 *                          Set to NULL to remove callback.
 * Parameters of callback are:
 * deviceID         ID for a specific device
 * ifc              Interface where the change happened
 * status           New status
 */
LIBRARY_API void Jabra_RegisterNetworkStatusChangedCallback(void(*networkStatus)(unsigned short, NetworkInterface, NetworkInterfaceStatus));

/**
 * @brief Gets the MAC address of an interface.
 *
 * @param[in]  deviceID         ID for a specific device
 * @param[in]  netIF            Selected interface
 * @param[out] MACaddr          Pointer to a buffer that will receive the MAC address.
 *                              The size of the buffer needs to be at least 6 bytes as this is the amount of data that will be written.
 *
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail A NULL pointer was passed
 * @return Device_ReadFails     Failed while reading from device
*/
LIBRARY_API Jabra_ReturnCode Jabra_GetMACAddress(const unsigned short deviceID, NetworkInterface netIF, uint8_t* MACaddr);

/**
 * @brief Gets the diagnostic log file and writes it to a file on local file system
 * For PanaCast 50, this requires prior call to #Jabra_TriggerDiagnosticLogGeneration()
 * in order to prepare the file for download
 *
 * @param[in] deviceID          ID for a specific device
 * @param[in] FileName          Destination file name on local file system
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return File_Not_Accessible  File is not ready on device
 * @return FileWrite_Fail       Destination file writing failed
 */
LIBRARY_API Jabra_ReturnCode Jabra_GetDiagnosticLogFile(const unsigned short deviceID, const char* const FileName);

/**
 * @brief Type definition of function pointer to use for
 * #Jabra_TriggerDiagnosticLogGeneration.
 */
typedef void(*DiagnosticLogReadyEventHandler)(const unsigned short deviceID);

/**
 * @brief Trigger generation of diagnostic log.
 * @param[in] deviceID          ID for a specific device
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Device_WriteFail     Failed while writing to device
 */
LIBRARY_API Jabra_ReturnCode Jabra_TriggerDiagnosticLogGeneration(const unsigned short deviceID);

/**
 * @brief Registration for diagnostic log event.
 * @param[in] callback          Callback method, called when diagnosticLog event is
 * received from device. Set to NULL to disable
 * @see Jabra_TriggerDiagnosticLogGeneration
 * @see Jabra_GetDiagnosticLogFile
 */
LIBRARY_API void Jabra_RegisterDiagnosticLogCallback(DiagnosticLogReadyEventHandler const callback);

typedef enum _NetworkAuthMode
{
    AUTH_NONE = 0,
    AUTH_MSCHAPv2 = 1,
    AUTH_CERT = 2
} NetworkAuthMode;

/**
 * @brief Configure IEEE 802.1X network authentication mode for network interface.
 * @param[in] deviceID          ID for a specific device
 * @param[in] interf            Interface to be configured (Ethernet or WLAN)
 * @param[in] auth              Authentication mode
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Device_WriteFail     Failed while writing to device
 */
LIBRARY_API Jabra_ReturnCode Jabra_SetNetworkAuthenticationMode(const unsigned short deviceID, NetworkInterface interf, NetworkAuthMode auth);

/**
 * @brief Get current IEEE 802.1X network authentication mode for network interface.
 * @param[in] deviceID          ID for a specific device
 * @param[in] interf            Interface to be queried (Ethernet or WLAN)
 * @param[out] auth             Pointer to NetworkAuthMode that will receive current auth mode
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail A NULL pointer was passed
 * @return Device_ReadFails     Failed while reading from device
 */
LIBRARY_API Jabra_ReturnCode Jabra_GetNetworkAuthenticationMode(const unsigned short deviceID, NetworkInterface interf, NetworkAuthMode* auth);

/**
 * @brief Configure IEEE 802.1X identity for a network interface.
 * @param[in] deviceID          ID for a specific device
 * @param[in] interf            Interface to be configured (Ethernet or WLAN)
 * @param[in] username          Pointer to NULL-terminated string containing the user name or NULL pointer to clear value
 *                              Maximum length 55 characters
 * @param[in] password          Pointer to NULL-terminated string containing the password or NULL pointer to clear value
 *                              Maximum length 55 characters
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail Username or password too long
 * @return Device_WriteFail     Failed while writing to device
 */
LIBRARY_API Jabra_ReturnCode Jabra_SetNetworkAuthenticationIdentity(const unsigned short deviceID, NetworkInterface interf, const char* username, const char* password);

typedef enum _WLANProtocol
{
    PROTO_UNSUPPORTED = 0,
    PROTO_WPA_PERSONAL = 1,
    PROTO_WPA2_PERSONAL = 2,
    PROTO_WPA_ENTERPRISE = 3,
    PROTO_WPA2_ENTERPRISE = 4
} WLANProtocol;

/**
 * @brief Connects the WLAN interface to a specific SSID.
 * If successful, the Ethernet interface will be disabled since only a single interface can be operational.
 * If unsuccessful, the WLAN interface will be disabled and Ethernet returned to the previous state.
 * @param[in] deviceID          ID for the device
 * @param[in] SSID              Pointer to NULL-terminated string containing the SSID of the target network
 *                              Maximum length 32 characters
 *                              Set to NULL to disable WLAN interface - the remaining parameters will be ignored
 * @param[in] protocol          Protocol of target network: WPA or WPA2
 * @param[in] fastTransition    Enable Fast BSS Transition (802.11r) (only for WPA2)
 * @param[in] password          Pointer to NULL-terminated string containing the password used for WPA(2)-Personal
 *                              Maximum length 63 characters
 *                              In case of WPA(2)-Enterprise, use Jabra_SetNetworkAuthenticationMode() and
 *                              Jabra_SetNetworkAuthenticationIdentity() prior to calling this function
 * @param[in] timeout           Timeout in [ms] to wait for interface to receive IP before returning NetworkRequest_Fail
 *                              The recommended value is 30'000 ms
 *                              Setting timeout=0 will configure the device and return immediately without waiting for the interface to become ready
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return NetworkRequest_Fail  Failed while trying to configure interface before timeout
 * @return Return_ParameterFail SSID/password too long or invalid authentication method
 * @return Device_ReadFails     Failed while reading from device
 * @return Device_WriteFail     Failed while writing to device
 * @see Jabra_SetNetworkAuthenticationIdentity
 * @see Jabra_SetNetworkAuthenticationMode
 * @see Jabra_ConfigureXpressManagement
 * @see Jabra_GetWLANConfiguration
 */
LIBRARY_API Jabra_ReturnCode Jabra_ConnectWLANInterface(const unsigned short deviceID, const char* const SSID, const WLANProtocol protocol, const bool fastTransition, const char* const password, unsigned int timeout);

typedef struct _Jabra_WLANNetworkProperties
{
    uint8_t BSSID[6];       // Access point MAC address
    char* SSID;             // Network name (NULL terminated)
    uint16_t Frequency;     // Band center frequency [MHz]
    int SignalStrength;     // Signal strength [dBm]
    unsigned int CountAuthenticationTypes; // Number of elements in 'Protocol' and 'FastTransition'
    WLANProtocol* Protocol;  // Protocol/auth(s)
    bool* FastTransition;    // Fast BSS Transition (802.11r)
} Jabra_WLANNetworkProperties;

typedef struct _Jabra_WLANScanResult
{
    unsigned int Count;      // Number of elements in 'NetworkProperties'
    Jabra_WLANNetworkProperties* NetworkProperties;
} Jabra_WLANScanResult;

typedef void (*WLANScanCallback)(unsigned short deviceID, Jabra_WLANScanResult ScanResults);
/**
 * @brief Starts scanning for nearby Wireless LAN networks from a WLAN enabled device.
 * When the scan has completed, the callback will be called with the list of discovered networks.
 * An ongoing scan can be canceled by calling this function again with a NULL callback.
 * In order to do the scan, the WLAN interface will be enabled. Since only a single interface
 * can be active this means that the Ethernet interface will become disabled as the scan is started.
 *
 * @param[in] deviceID          ID for the device
 * @param[in] callback          Callback function to receive a list of discovered networks
 *                              Set to NULL to cancel an ongoing scan
 *                              The callback will contain a Jabra_WLANScanResult - this needs to be freed with Jabra_FreeWLANScanResult at the end of the callback function.
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Device_WriteFail     Failed while writing to device
 * @see Jabra_FreeWLANScanResult
 * @see Jabra_ConnectWLANInterface
 */
LIBRARY_API Jabra_ReturnCode Jabra_StartWLANScan(const unsigned short deviceID, WLANScanCallback callback);

/**
 * @brief Frees the memory allocated in a Jabra_WLANScanResult as received in a callback from Jabra_StartWLANScan.
 * @param[in] ScanResults       Pointer to struct containing the results of a previous network scan.
 * @see Jabra_StartWLANScan
 */
LIBRARY_API void Jabra_FreeWLANScanResult(Jabra_WLANScanResult* ScanResults);

typedef enum _Jabra_WLANConnectionStatus {
    WLAN_CONNECTED = 0,
    WLAN_DISCONNECTED = 1,
    WLAN_NETWORK_NOT_FOUND = 2,
    WLAN_CONNECTION_FAILED = 3,
    WLAN_AUTH_FAILED = 4,
    WLAN_INVALID_PSK = 5,
    WLAN_WRONG_CONFIG = 0x80
} Jabra_WLANConnectionStatus;

typedef void (*WLANConnectionStatusCallback)(unsigned short deviceID, Jabra_WLANConnectionStatus status);

/**
 * @brief Registers a callback that will receive WLAN connection status results/errors.
 * Use this to get more detailed information on why a WLAN connection attempt failed after
 * using Jabra_ConnectWLANInterface.
 *
 * @param[in] callback          Callback function to receive the connection result code
 *                              Set to NULL to unregister callback
 * @see Jabra_ConnectWLANInterface
 */
LIBRARY_API void Jabra_RegisterWLANConnectionStatusCallback(WLANConnectionStatusCallback callback);

typedef enum _Jabra_CertificateType {
    CERTIFICATE_DEVICE = 0,                  // Device certificate
    CERTIFICATE_PROXY_SERVER_CA = 1,         // Proxy CA root certificate
    CERTIFICATE_IEEE8021X_CLIENT = 2,        // Client certificate used in IEEE 802.1x authentication
    CERTIFICATE_IEEE8021X_SERVER_CA = 3      // Server CA root certificate used in IEEE 802.1x authentication
} Jabra_CertificateType;

typedef enum _Jabra_CertificateSigningRequestType {
    CERTIFICATE_DEVICE_CSR = 0,              // CSR for device certificate
    CERTIFICATE_IEEE8021X_CLIENT_CSR = 1,    // CSR for IEEE802.1x client authentication certificate
} Jabra_CertificateSigningRequestType;

/**
 * @brief Uploads a certificate in PEM format to the certificate store of the device.
 * For usage with proxy server or IEEE 802.1x authentication.
 * Uploading a certificate will replace the existing certificate (of the same type) on the device.
 * 
 * @param[in] deviceID          ID for the device
 * @param[in] type              Which certificate to apply
 * @param[in] certificate       Pointer to NULL-terminated string containing the certificate to install.
 *                              If 'certificate' == NULL, the installed certificate will be deleted.
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail 'type' was invalid
 * @return Device_WriteFail     Failed while writing to device
 * @see Jabra_SetNetworkAuthenticationMode
 * @see Jabra_GenerateCertificateSigningRequest
 */
LIBRARY_API Jabra_ReturnCode Jabra_InstallCertificate(unsigned short deviceID, Jabra_CertificateType type, const char* certificate);

/**
 * @brief Returns a certificate signing request in PEM format to be used for generating a client
 * certificate. When the client certificate is ready, it can be installed using
 * Jabra_InstallCertificate.
 *
 * @param[in] deviceID          ID for the device
 * @param[in] type              Which CSR to generate
 * @param[out] csr              Pointer to location of generated certificate signing request.
 *                              As memory is allocated by SDK, the CSR should be freed by calling Jabra_FreeString
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail 'type' was invalid or 'csr' was NULL
 * @return Device_ReadFails     Failed while reading from device
 * @return Device_WriteFail     Failed while writing to device
 * @see Jabra_SetNetworkAuthenticationMode
 * @see Jabra_InstallCertificate
 * @see Jabra_FreeString
 */
LIBRARY_API Jabra_ReturnCode Jabra_GenerateCertificateSigningRequest(unsigned short deviceID, Jabra_CertificateSigningRequestType type, char** csr);

typedef enum _Jabra_WLANStatus
{
    WLANSTATUS_CONNECTED = 0,
    WLANSTATUS_DISCONNECTED = 1,
    WLANSTATUS_DISABLED = 2
} Jabra_WLANStatus;

typedef struct _Jabra_WLANConfiguration
{
    char* SSID;                         // Name of target network
    WLANProtocol Protocol;              // WPA/WPA2-Personal/Enterprise
    bool FastTransition;                // Fast BSS Transition(802.11r)
    NetworkAuthMode AuthenticationMode; // Only specified for Enterprise networks - Personal always use PSK
    bool ProxyEnabled;                  // true: Device is set up with a proxy server for communication (details are write-only)
} Jabra_WLANConfiguration;

typedef struct _Jabra_ConnectedWLANConfiguration
{
    uint8_t BSSID[6];                      // Access point MAC address
    uint16_t Frequency;                    // Band center frequency [MHz]
    int SignalStrength;                    // Signal strength [dBm]
    Jabra_WLANConfiguration NetworkConfig; // Configuration of connected network
} Jabra_ConnectedWLANConfiguration;

/**
 * @brief Returns a struct containing the properties of the WLAN configuration.
 * For security purposes, some details such as pre-shared key and EAP details are not contained
 * as they are write only.
 *
 * @param[in] deviceID          ID for the device
 * @param[out] properties       Pointer to struct to hold configuration
 *                              As memory is allocated by SDK, the struct should be freed by calling Jabra_FreeWLANConfiguration
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail 'properties' was NULL
 * @return Device_ReadFails     Failed while reading from device or WLAN not configured
 * @see Jabra_ConnectWLANInterface
 * @see Jabra_FreeWLANConfiguration
 */
LIBRARY_API Jabra_ReturnCode Jabra_GetWLANConfiguration(unsigned short deviceID, Jabra_WLANConfiguration* properties);

/**
 * @brief Returns the properties of the connected WLAN network.
 * For security purposes, some details such as pre-shared key and EAP details are not included.
 * Note that the results of this function may differ from Jabra_GetWLANConfiguration which
 * returns the device configuration.
 *
 * @param[in] deviceID          ID for the device
 * @param[out] properties       Pointer to struct to hold configuration
 *                              As memory is allocated by SDK, the struct should be freed by calling Jabra_FreeConnectedWLANConfiguration
 * @return Return_Ok            Call was successful
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_ParameterFail 'properties' was NULL
 * @return Device_ReadFails     Failed while reading from device
 * @return Device_BadState      WLAN is disabled
 * @return Device_NotConnected  WLAN is enabled but not connected
 * @see Jabra_ConnectWLANInterface
 * @see Jabra_FreeConnectedWLANConfiguration
 */
LIBRARY_API Jabra_ReturnCode Jabra_GetConnectedWLANConfiguration(unsigned short deviceID, Jabra_ConnectedWLANConfiguration* properties);

/**
 * @brief Frees the memory allocated in a Jabra_WLANConfiguration struct.
 * @param[in,out] properties       Pointer to struct to be freed. SSID pointer will be set to NULL after freeing.
 * @see Jabra_GetWLANConfiguration
 */
LIBRARY_API void Jabra_FreeWLANConfiguration(Jabra_WLANConfiguration* properties);

/**
 * @brief Frees the memory allocated in a Jabra_ConnectedWLANConfiguration struct.
 * @param[in,out] properties       Pointer to struct to be freed. SSID pointer will be set to NULL after freeing.
 * @see Jabra_GetConnectedWLANConfiguration
 */
LIBRARY_API void Jabra_FreeConnectedWLANConfiguration(Jabra_ConnectedWLANConfiguration* properties);

/**
 * @brief Checks a managed device whether it is currently able to connect to the Xpress server.
 *
 * @param[in] deviceID          ID for the device
 * @param[out] lastUpdate       Optional - pointer to return the number of seconds since last status update from device.
 *                              If not NULL, it will be set when the return value is either Return_Ok or NetworkRequest_Fail.
 * @return Return_Ok            Device was able to successfully connect to the configured Xpress server
 * @return Device_Unknown       deviceID is unknown
 * @return Not_Supported        Functionality is not supported on this device
 * @return Return_Timeout       Timeout while waiting for response from device
 * @return NetworkRequest_Fail  Server responded with invalid data (incorrect URL?)
 * @return Device_BadState      Management is disabled
 * @see Jabra_ConfigureXpressManagement
 * @see Jabra_SetXpressUrl
 * @see Jabra_GetXpressUrl
 */
LIBRARY_API Jabra_ReturnCode Jabra_IsXpressConnected(unsigned short deviceID, unsigned int* lastUpdate);

#endif /* INTERFACE_NETWORK_H */
