hal_ti/simplelink/source/ti/net/slnetif.h

631 lines
28 KiB
C

/*
* Copyright (c) 2017-2019, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*****************************************************************************/
/* Include files */
/*****************************************************************************/
#ifndef __SL_NET_IF_H__
#define __SL_NET_IF_H__
#include <stdint.h>
#include <stdbool.h>
#include <ti/net/slnetsock.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!
\defgroup SlNetIf SlNetIf group
\short Controls standard stack/interface options and capabilities
*/
/*!
\addtogroup SlNetIf
@{
*/
/*****************************************************************************/
/* Macro declarations */
/*****************************************************************************/
/* Interface ID bit pool to be used in interface add and in socket creation */
#define SLNETIF_ID_1 (1 << 0) /**< Interface ID 1 */
#define SLNETIF_ID_2 (1 << 1) /**< Interface ID 2 */
#define SLNETIF_ID_3 (1 << 2) /**< Interface ID 3 */
#define SLNETIF_ID_4 (1 << 3) /**< Interface ID 4 */
#define SLNETIF_ID_5 (1 << 4) /**< Interface ID 5 */
#define SLNETIF_ID_6 (1 << 5) /**< Interface ID 6 */
#define SLNETIF_ID_7 (1 << 6) /**< Interface ID 7 */
#define SLNETIF_ID_8 (1 << 7) /**< Interface ID 8 */
#define SLNETIF_ID_9 (1 << 8) /**< Interface ID 9 */
#define SLNETIF_ID_10 (1 << 9) /**< Interface ID 10 */
#define SLNETIF_ID_11 (1 << 10) /**< Interface ID 11 */
#define SLNETIF_ID_12 (1 << 11) /**< Interface ID 12 */
#define SLNETIF_ID_13 (1 << 12) /**< Interface ID 13 */
#define SLNETIF_ID_14 (1 << 13) /**< Interface ID 14 */
#define SLNETIF_ID_15 (1 << 14) /**< Interface ID 15 */
#define SLNETIF_ID_16 (1 << 15) /**< Interface ID 16 */
#define SLNETIF_MAX_IF (16) /**< Maximum interface */
/* this macro returns 0 when only one bit is set and a number when it isn't */
#define ONLY_ONE_BIT_IS_SET(x) (((x > 0) && ((x & (x - 1)) == 0))?true:false)
/* Interface connection status bit pool to be used in set interface connection status function */
#define SLNETIF_STATUS_DISCONNECTED (0)
#define SLNETIF_STATUS_CONNECTED (1)
/*!
\brief Interface state bit pool to be used in set interface state function
*/
typedef enum
{
SLNETIF_STATE_DISABLE = 0,
SLNETIF_STATE_ENABLE = 1
} SlNetIfState_e;
/*!
\brief Address type enum to be used in get ip address function
*/
typedef enum
{
SLNETIF_IPV4_ADDR = 0,
SLNETIF_IPV6_ADDR_LOCAL = 1,
SLNETIF_IPV6_ADDR_GLOBAL = 2
} SlNetIfAddressType_e;
/* Address config return values that can be retrieved in get ip address function */
#define SLNETIF_ADDR_CFG_UNKNOWN (0)
#define SLNETIF_ADDR_CFG_DHCP (1)
#define SLNETIF_ADDR_CFG_DHCP_LLA (2)
#define SLNETIF_ADDR_CFG_STATIC (4)
#define SLNETIF_ADDR_CFG_STATELESS (5)
#define SLNETIF_ADDR_CFG_STATEFUL (6)
/* Security object types for load Sec Obj function */
#define SLNETIF_SEC_OBJ_TYPE_RSA_PRIVATE_KEY (1)
#define SLNETIF_SEC_OBJ_TYPE_CERTIFICATE (2)
#define SLNETIF_SEC_OBJ_TYPE_DH_KEY (3)
/*!
Check if interface state is enabled.
\sa SlNetIf_queryIf()
*/
#define SLNETIF_QUERY_IF_STATE_BIT (1 << 0)
/*!
Check if interface connection status is connected.
\sa SlNetIf_queryIf()
*/
#define SLNETIF_QUERY_IF_CONNECTION_STATUS_BIT (1 << 1)
/*!
Enable last partial match in an interface search, if no existing
interface matches the query completely.
\sa SlNetIf_queryIf()
*/
#define SLNETIF_QUERY_IF_ALLOW_PARTIAL_MATCH_BIT (1 << 2)
/*****************************************************************************/
/* Structure/Enum declarations */
/*****************************************************************************/
/*!
\brief SlNetIf_Config_t structure contains all the function callbacks that are expected to be filled by the relevant network stack interface \n
Each interface has different capabilities, so not all the API's must be supported therefore an API's can be defined as:
- <b>Mandatory API's</b> - must be supported by the interface in order to be part of SlNetSock layer
- <b>Non-Mandatory API's</b> - can be supported, but not mandatory for basic SlNetSock proper operation
\note Interface that is not supporting a non-mandatory API should set it to \b NULL in its function list
\sa SlNetIf_Config_t
*/
typedef struct SlNetIf_Config_t
{
/* socket related API's */
int16_t (*sockCreate) (void *ifContext, int16_t domain, int16_t type, int16_t protocol, void **sdContext); /*!< \b Mandatory API \n The actual implementation of the interface for ::SlNetSock_create */
int32_t (*sockClose) (int16_t sd, void *sdContext); /*!< \b Mandatory API \n The actual implementation of the interface for ::SlNetSock_close */
int32_t (*sockShutdown) (int16_t sd, void *sdContext, int16_t how); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_shutdown */
int16_t (*sockAccept) (int16_t sd, void *sdContext, SlNetSock_Addr_t *addr, SlNetSocklen_t *addrlen, uint8_t flags, void **acceptedSdContext); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_accept */
int32_t (*sockBind) (int16_t sd, void *sdContext, const SlNetSock_Addr_t *addr, int16_t addrlen); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_bind */
int32_t (*sockListen) (int16_t sd, void *sdContext, int16_t backlog); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_listen */
int32_t (*sockConnect) (int16_t sd, void *sdContext, const SlNetSock_Addr_t *addr, SlNetSocklen_t addrlen, uint8_t flags); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_connect */
int32_t (*sockGetPeerName) (int16_t sd, void *sdContext, SlNetSock_Addr_t *addr, SlNetSocklen_t *addrlen); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_getPeerName */
int32_t (*sockGetLocalName) (int16_t sd, void *sdContext, SlNetSock_Addr_t *addr, SlNetSocklen_t *addrlen); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_getSockName */
int32_t (*sockSelect) (void *ifContext, int16_t nsds, SlNetSock_SdSet_t *readsds, SlNetSock_SdSet_t *writesds, SlNetSock_SdSet_t *exceptsds, SlNetSock_Timeval_t *timeout); /*!< \b Mandatory API \n The actual implementation of the interface for ::SlNetSock_select */
int32_t (*sockSetOpt) (int16_t sd, void *sdContext, int16_t level, int16_t optname, void *optval, SlNetSocklen_t optlen); /*!< \b Mandatory API \n The actual implementation of the interface for ::SlNetSock_setOpt */
int32_t (*sockGetOpt) (int16_t sd, void *sdContext, int16_t level, int16_t optname, void *optval, SlNetSocklen_t *optlen); /*!< \b Mandatory API \n The actual implementation of the interface for ::SlNetSock_getOpt */
int32_t (*sockRecv) (int16_t sd, void *sdContext, void *buf, uint32_t len, uint32_t flags); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_recv */
int32_t (*sockRecvFrom) (int16_t sd, void *sdContext, void *buf, uint32_t len, uint32_t flags, SlNetSock_Addr_t *from, SlNetSocklen_t *fromlen); /*!< \b Mandatory API \n The actual implementation of the interface for ::SlNetSock_recvFrom */
int32_t (*sockSend) (int16_t sd, void *sdContext, const void *buf, uint32_t len, uint32_t flags); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_send */
int32_t (*sockSendTo) (int16_t sd, void *sdContext, const void *buf, uint32_t len, uint32_t flags, const SlNetSock_Addr_t *to, SlNetSocklen_t tolen); /*!< \b Mandatory API \n The actual implementation of the interface for ::SlNetSock_sendTo */
int32_t (*sockstartSec) (int16_t sd, void *sdContext, SlNetSockSecAttrib_t *secAttrib, uint8_t flags); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetSock_startSec */
/* util related API's */
int32_t (*utilGetHostByName) (void *ifContext, char *name, const uint16_t nameLen, uint32_t *ipAddr, uint16_t *ipAddrLen, const uint8_t family); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetUtil_getHostByName */
/* if related API's */
int32_t (*ifGetIPAddr) (void *ifContext, SlNetIfAddressType_e addrType, uint16_t *addrConfig, uint32_t *ipAddr); /*!< \b Mandatory API \n The actual implementation of the interface for ::SlNetIf_getIPAddr */
int32_t (*ifGetConnectionStatus) (void *ifContext); /*!< \b Mandatory API \n The actual implementation of the interface for ::SlNetIf_getConnectionStatus */
int32_t (*ifLoadSecObj) (void *ifContext, uint16_t objType, char *objName, int16_t objNameLen, uint8_t *objBuff, int16_t objBuffLen); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetIf_loadSecObj */
int32_t (*ifCreateContext) (uint16_t ifID, const char *ifName, void **ifContext); /*!< \b Non-Mandatory API \n The actual implementation of the interface for ::SlNetIf_add */
} SlNetIf_Config_t;
/*!
\brief The SlNetIf_t structure holds the configuration of the interface
Its ID, name, flags and the configuration list - ::SlNetIf_Config_t.
*/
typedef struct SlNetIf_t
{
uint32_t ifID;
char *ifName;
int32_t flags;
SlNetIf_Config_t *ifConf;
void *ifContext;
} SlNetIf_t;
/*****************************************************************************/
/* Function prototypes */
/*****************************************************************************/
/*!
\brief Initialize the SlNetIf module
\param[in] flags For future usage,
The value 0 may be used in order to run the
default flags
\return Zero on success, or negative error code on failure
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_init snippet
*/
int32_t SlNetIf_init(int32_t flags);
/*!
\brief Add a new SlNetIf-compatible interface to the system
The SlNetIf_add function allows the application to add specific interfaces
with their priorities and function list.\n
This function gives full control to the application on the interfaces.
\param[in] ifID Specifies the interface which needs
to be added.\n
The values of the interface identifier
is defined with the prefix SLNETIF_ID_
which defined in slnetif.h
\param[in] ifName Specifies the name of the interface,
\b Note: Can be set to NULL, but when set to NULL
cannot be used with SlNetIf_getIDByName()
\param[in] ifConf Specifies the function list for the
interface
\param[in] priority Specifies the priority of the interface
(In ascending order).
Note: maximum priority is 15
\return Zero on success, or negative error code on failure
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_add wifi snippet
\snippet ti/net/test/snippets/slnetif.c SlNetIf_add NDK snippet
\snippet ti/net/test/snippets/slnetif.c SlNetIf_add NDKSec snippet
*/
int32_t SlNetIf_add(uint16_t ifID, char *ifName, const SlNetIf_Config_t *ifConf, uint8_t priority);
/*!
\brief Get interface configuration from interface ID
The SlNetIf_getIfByID function retrieves the configuration of the
requested interface.
\param[in] ifID Specifies the interface which its configuration
needs to be retrieved.\n
The values of the interface identifier is
defined with the prefix SLNETIF_ID_ which
defined in slnetif.h
\return A pointer to the configuration of the
interface on success, or NULL on failure
\sa SlNetIf_add()
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_getIfByID snippet
*/
SlNetIf_t * SlNetIf_getIfByID(uint16_t ifID);
/*!
\brief Query for the highest priority interface, given a list of
interfaces and properties.
\param[in] ifBitmap The bit-wise OR of interfaces to be searched.\n
Note: Zero is currently not valid.
\param[in] queryBitmap The bit-wise OR of additional query criteria.
\remarks @c queryBitmap can be set to :
- #SLNETIF_QUERY_IF_STATE_BIT
- #SLNETIF_QUERY_IF_CONNECTION_STATUS_BIT
- #SLNETIF_QUERY_IF_ALLOW_PARTIAL_MATCH_BIT
\return A pointer to the configuration of a found
interface on success, or NULL on failure
\sa SlNetIf_add()
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_queryIf snippet
*/
SlNetIf_t * SlNetIf_queryIf(uint32_t ifBitmap, uint32_t queryBitmap);
/*!
\brief Get interface Name from interface ID
The SlNetIf_getNameByID function retrieves the name of the requested
interface.
\param[in] ifID Specifies the interface which its name needs
to be retrieved.\n
The values of the interface identifier is
defined with the prefix SLNETIF_ID_ which
defined in slnetif.h
\return A pointer to the name of the interface on
success, or NULL on failure
\sa SlNetIf_add()
\sa SlNetIf_getIDByName()
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_getNameByID snippet
*/
const char * SlNetIf_getNameByID(uint16_t ifID);
/*!
\brief Get interface ID from interface name
The SlNetIf_getIDByName function retrieves the interface identifier of the
requested interface name.
\param[in] ifName Specifies the interface which its interface
identifier needs to be retrieved.\n
\return The interface identifier value of the interface
on success, or negative error code on failure
The values of the interface identifier is
defined with the prefix SLNETIF_ID_ which
defined in slnetif.h
\sa SlNetIf_add()
\sa SlNetIf_getNameByID()
\sa SlNetSock_getIfID()
\note - Input NULL as ifName will return error code.
- When using more than one interface with the same
name, the ID of the highest priority interface
will be returned
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_getIDByName snippet
*/
int32_t SlNetIf_getIDByName(char *ifName);
/*!
\brief Get interface priority
The SlNetIf_getPriority function retrieves the priority of the
interface.
\param[in] ifID Specifies the interface which its priority
needs to be retrieved.\n
The values of the interface identifier is
defined with the prefix SLNETIF_ID_ which
defined in slnetif.h
\return The priority value of the interface on success,
or negative error code on failure
\sa SlNetIf_add()
\sa SlNetIf_setPriority()
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_getPriority snippet
*/
int32_t SlNetIf_getPriority(uint16_t ifID);
/*!
\brief Set interface priority
The SlNetIf_setPriority function sets new priority to the requested interface.
\param[in] ifID Specifies the interface which its priority
needs to be changed.\n
The values of the interface identifier is
defined with the prefix SLNETIF_ID_ which
defined in slnetif.h
\param[in] priority Specifies the priority needs to be set.
(In ascending order)
Note: maximum priority is 15
\return Zero on success, or negative error code on
failure
\sa SlNetIf_add()
\sa SlNetIf_getPriority()
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_setPriority snippet
*/
int32_t SlNetIf_setPriority(uint16_t ifID, uint8_t priority);
/*!
\brief Set interface state
Enable or disable the interface.
\param[in] ifID Specifies the interface which its state
needs to be changed.\n
The values of the interface identifier is
defined with the prefix SLNETIF_ID_ which
defined in slnetif.h
\param[in] ifState Specifies the interface state.\n
The values of the interface state are defined
with the prefix SLNETIF_INTERFACE_ which
defined in slnetif.h
\return Zero on success, or negative error code on
failure
\sa SlNetIf_add()
\sa SlNetIf_getState()
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_setState snippet
*/
int32_t SlNetIf_setState(uint16_t ifID, SlNetIfState_e ifState);
/*!
\brief Get interface state
Obtain the current state of the interface.
\param[in] ifID Specifies the interface which its state needs
to be retrieved.\n
The values of the interface identifier is
defined with the prefix SLNETIF_ID_ which
defined in slnetif.h
\return State of the interface on success, or negative
error code on failure
\sa SlNetIf_add()
\sa SlNetIf_setState()
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_getState snippet
*/
int32_t SlNetIf_getState(uint16_t ifID);
/*!
\brief Get the connection status of an interface
\param[in] ifID Interface ID
\return @c SLNETIF_STATUS_ value on success,
or negative error code on failure
\remark @c ifID should be a value with the @c SLNETIF_ID_
prefix
\sa SlNetIf_add()
\sa SLNETIF_STATUS_CONNECTED
\sa SLNETIF_STATUS_DISCONNECTED
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_getConnectionStatus snippet
*/
int32_t SlNetIf_getConnectionStatus(uint16_t ifID);
/*!
\brief Get IP Address of specific interface
The SlNetIf_getIPAddr function retrieve the IP address of a specific
interface according to the Address Type, IPv4, IPv6 LOCAL
or IPv6 GLOBAL.
\param[in] ifID Specifies the interface which its connection
state needs to be retrieved.\n
The values of the interface identifier is
defined with the prefix SLNETIF_ID_ which
defined in slnetif.h
\param[in] addrType Address type:
- #SLNETIF_IPV4_ADDR
- #SLNETIF_IPV6_ADDR_LOCAL
- #SLNETIF_IPV6_ADDR_GLOBAL
\param[out] addrConfig Address config:
- #SLNETIF_ADDR_CFG_UNKNOWN
- #SLNETIF_ADDR_CFG_DHCP
- #SLNETIF_ADDR_CFG_DHCP_LLA
- #SLNETIF_ADDR_CFG_STATIC
- #SLNETIF_ADDR_CFG_STATELESS
- #SLNETIF_ADDR_CFG_STATEFUL
\param[out] ipAddr IP Address according to the Address Type
\return Zero on success, or negative error code on failure
\sa SlNetIfAddressType_e
\slnetif_not_threadsafe
\par Examples
\snippet ti/net/test/snippets/slnetif.c SlNetIf_getIPAddr snippet
*/
int32_t SlNetIf_getIPAddr(uint16_t ifID, SlNetIfAddressType_e addrType, uint16_t *addrConfig, uint32_t *ipAddr);
/*!
\brief Load/unload/replace a secure object into a network interface/stack
SlNetIf_loadSecObj() loads a named secure object into specific
network stack for future use by secure sockets. To unload the
named secure object, pass a NULL object buffer with the
appropriate name.
\param[in] objType The secure object type:
- #SLNETIF_SEC_OBJ_TYPE_RSA_PRIVATE_KEY
- #SLNETIF_SEC_OBJ_TYPE_CERTIFICATE
- #SLNETIF_SEC_OBJ_TYPE_DH_KEY
\param[in] objName The secure object name
\param[in] objNameLen The secure object name length
\param[in] objBuff The secure object buffer to be loaded, or
NULL if the named object is to be unloaded
\param[in] objBuffLen The secure object buffer length
\param[in] ifBitmap The interfaces which the secure
objects should be loaded to
\remark Loaded secure objects are added to secure attributes using
the SlNetSock_secAttribCreate(),
SlNetSock_secAttribSet(), and
SlNetSock_secAttribDelete() lifecycle APIs. The
loading/unloading of secure objects (via
SlNetIf_loadSecObj()) must be done while the secure
object is not associated with any existing secure
attributes. Restating, you must delete any existing
secure attributes before changing any secure objects
associated with them.
\remark The values of @c ifBitmap typically have the prefix
@c SLNETIF_ID_.
\remark SlNetIf_loadSecObj() internally validates the @c objName,
@c objNameLen, and @c objType arguments, so the
underlying interface/stack functions do not need to
check them again.
\remark For stacks that use file systems (e.g. CC3XXX), @c objName
will be the file name used on the file system.
\remark Note that ownership of @c objBuff after returning from
SlNetIf_loadSecObj() varies by stack/interface, often
depending on how the underlying stack implements it's
TLS support.
- On CC3XXX-based stacks, the TLS support is managed
on a separate network processor, and loading a
secure object results in persisting the secure
object to a file system. As a result, after
successfully calling SlNetIf_loadSecObj(), the @c
objBuff is no longer needed, and can be considered
"owned" by the application.
- On NDK-based stacks, the TLS support is typically
managed by a software library like mbedTLS. As a
result, only a reference to @c objBuff is made
within the SlNetIf_loadSecObj() call, and the
buffer must persist as long as the secure object
remains loaded. Ownership of the buffer returns
to the user only after unloading the secure
object (or resetting the device).
\remark To replace an existing named secure object with another
secure object of the same name, call
SlNetIf_loadSecObj() with the same @c objName.
Resources associated with the previously loaded secure
object will be released and replaced by the new secure
object.
\remark When unloading a named secure object, @c objBuffLen is
ignored.
\return 0 on success, negative on failure. Common errors include:
- #SLNETERR_RET_CODE_INVALID_INPUT
- #SLNETERR_RET_CODE_NO_FREE_SPACE
- #SLNETERR_RET_CODE_MALLOC_ERROR
\sa SlNetSock_setOpt()
\sa SlNetSock_secAttribSet()
\slnetif_not_threadsafe
*/
int32_t SlNetIf_loadSecObj(uint16_t objType, char *objName, int16_t objNameLen, uint8_t *objBuff, int16_t objBuffLen, uint32_t ifBitmap);
/*!
Close the Doxygen group.
@}
*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __SL_NET_IF_H__ */