diff --git a/libraries/platform/iot_network.h b/libraries/platform/iot_network.h
index 77eba836b6..651f0d0ac1 100644
--- a/libraries/platform/iot_network.h
+++ b/libraries/platform/iot_network.h
@@ -48,6 +48,19 @@ typedef enum IotNetworkError
IOT_NETWORK_SYSTEM_ERROR /**< An error occurred when calling a system API. */
} IotNetworkError_t;
+/**
+ * @ingroup platform_datatypes_enums
+ * @brief Disconnect reasons for [the network close callback](@ref platform_network_function_closecallback).
+ */
+typedef enum IotNetworkCloseReason
+{
+ IOT_NETWORK_NOT_CLOSED = 0, /**< Not closed, still open */
+ IOT_NETWORK_SERVER_CLOSED, /**< Server closed connection. */
+ IOT_NETWORK_TRANSPORT_FAILURE, /**< Transport failed. */
+ IOT_NETWORK_CLIENT_CLOSED, /**< Client closed connection. */
+ IOT_NETWORK_UNKNOWN_CLOSED /**< Unknown close reason. */
+} IotNetworkCloseReason_t;
+
/**
* @page platform_network_functions Networking
* @brief Functions of the network abstraction component.
@@ -62,21 +75,25 @@ typedef enum IotNetworkError
* Together, they represent a network stack.
* - @functionname{platform_network_function_create}
* - @functionname{platform_network_function_setreceivecallback}
+ * - @functionname{platform_network_function_setclosecallback}
* - @functionname{platform_network_function_send}
* - @functionname{platform_network_function_receive}
* - @functionname{platform_network_function_close}
* - @functionname{platform_network_function_destroy}
* - @functionname{platform_network_function_receivecallback}
+ * - @functionname{platform_network_function_closecallback}
*/
/**
* @functionpage{IotNetworkInterface_t::create,platform_network,create}
* @functionpage{IotNetworkInterface_t::setReceiveCallback,platform_network,setreceivecallback}
+ * @functionpage{IotNetworkInterface_t::setCloseCallback,platform_network,setclosecallback}
* @functionpage{IotNetworkInterface_t::send,platform_network,send}
* @functionpage{IotNetworkInterface_t::receive,platform_network,receive}
* @functionpage{IotNetworkInterface_t::close,platform_network,close}
* @functionpage{IotNetworkInterface_t::destroy,platform_network,destroy}
* @functionpage{IotNetworkReceiveCallback_t,platform_network,receivecallback}
+ * @functionpage{IotNetworkReceiveCallback_t,platform_network,closecallback}
*/
/**
@@ -94,6 +111,178 @@ typedef void ( * IotNetworkReceiveCallback_t )( IotNetworkConnection_t pConnecti
void * pContext );
/* @[declare_platform_network_receivecallback] */
+/**
+ * @brief Provide an asynchronous notification of network closing
+ *
+ * A function with this signature may be set with @ref platform_network_function_setclosecallback
+ * to be invoked when the network connection is closed.
+ *
+ * @param[in] pConnection The connection that was closed, defined by
+ * the network stack.
+ * @param[in] reason The reason the connection was closed
+ * @param[in] pContext The third argument passed to @ref platform_network_function_setclosecallback.
+ */
+/* @[declare_platform_network_closecallback] */
+typedef void ( * IotNetworkCloseCallback_t )( IotNetworkConnection_t pConnection,
+ IotNetworkCloseReason_t reason,
+ void * pContext );
+/* @[declare_platform_network_closecallback] */
+
+/**
+ * @brief Create a new network connection.
+ *
+ * This function allocates resources and establishes a new network connection.
+ * @param[in] pServerInfo Represents information needed to set up the
+ * new connection, defined by the network stack.
+ * @param[in] pCredentialInfo Represents information needed to secure the
+ * new connection, defined by the network stack.
+ * @param[out] pConnection Set to represent a new connection, defined by the
+ * network stack.
+ *
+ * @return Any #IotNetworkError_t, as defined by the network stack.
+ */
+/* @[declare_platform_network_create] */
+typedef IotNetworkError_t ( * IotNetworkCreate_t )( IotNetworkServerInfo_t pServerInfo,
+ IotNetworkCredentials_t pCredentialInfo,
+ IotNetworkConnection_t * pConnection );
+/* @[declare_platform_network_create] */
+
+/**
+ * @brief Register an @ref platform_network_function_receivecallback.
+ *
+ * Sets an @ref platform_network_function_receivecallback to be called
+ * asynchronously when data arrives on the network. The network stack
+ * should invoke this function "as if" it were the thread routine of a
+ * detached thread.
+ *
+ * Each network connection may only have one receive callback at any time.
+ * @ref platform_network_function_close is expected to remove any active
+ * receive callbacks.
+ *
+ * @param[in] pConnection The connection to associate with the receive callback.
+ * @param[in] receiveCallback The function to invoke for incoming network data.
+ * @param[in] pContext A value to pass as the first parameter to the receive callback.
+ *
+ * @return Any #IotNetworkError_t, as defined by the network stack.
+ *
+ * @see platform_network_function_receivecallback
+ */
+/* @[declare_platform_network_setreceivecallback] */
+typedef IotNetworkError_t ( * IotNetworkSetReceiveCallback_t )( IotNetworkConnection_t pConnection,
+ IotNetworkReceiveCallback_t receiveCallback,
+ void * pContext );
+/* @[declare_platform_network_setreceivecallback] */
+
+/**
+ * @brief Register an @ref platform_network_function_closecallback.
+ *
+ * Sets an @ref platform_network_function_closecallback to be called
+ * asynchronously when the network connection closes. The network stack
+ * should invoke this function "as if" it were the thread routine of a
+ * detached thread.
+ *
+ * Each network connection may only have one close callback at any time.
+ * @ref platform_network_function_close is expected to remove any active
+ * close callbacks.
+ *
+ * @param[in] pConnection The connection to associate with the close callback.
+ * @param[in] receiveCallback The function to invoke for incoming network close events.
+ * @param[in] pContext A value to pass as the first parameter to the close callback.
+ *
+ * @return Any #IotNetworkError_t, as defined by the network stack.
+ *
+ * @see platform_network_function_closecallback
+ */
+/* @[declare_platform_network_setclosecallback] */
+typedef IotNetworkError_t ( * IotNetworkSetCloseCallback_t )( IotNetworkConnection_t pConnection,
+ IotNetworkCloseCallback_t closeCallback,
+ void * pContext );
+/* @[declare_platform_network_setclosecallback] */
+
+/**
+ * @brief Send data over a return connection.
+ *
+ * Attempts to transmit `messageLength` bytes of `pMessage` across the
+ * connection represented by `pConnection`. Returns the number of bytes
+ * actually sent, `0` on failure.
+ *
+ * @param[in] pConnection The connection used to send data, defined by the
+ * network stack.
+ * @param[in] pMessage The message to send.
+ * @param[in] messageLength The length of `pMessage`.
+ *
+ * @return The number of bytes successfully sent, `0` on failure.
+ */
+/* @[declare_platform_network_send] */
+typedef size_t ( * IotNetworkSend_t )( IotNetworkConnection_t pConnection,
+ const uint8_t * pMessage,
+ size_t messageLength );
+/* @[declare_platform_network_send] */
+
+/**
+ * @brief Block and wait for incoming network data.
+ *
+ * Wait for a message of size `bytesRequested` to arrive on the network and
+ * place it in `pBuffer`.
+ *
+ * @param[in] pConnection The connection to wait on, defined by the network
+ * stack.
+ * @param[out] pBuffer Where to place the incoming network data. This buffer
+ * must be at least `bytesRequested` in size.
+ * @param[in] bytesRequested How many bytes to wait for. `pBuffer` must be at
+ * least this size.
+ *
+ * @return The number of bytes successfully received. This should be
+ * `bytesRequested` when successful. Any other value may indicate an error.
+ */
+/* @[declare_platform_network_receive] */
+typedef size_t ( * IotNetworkReceive_t )( IotNetworkConnection_t pConnection,
+ uint8_t * pBuffer,
+ size_t bytesRequested );
+/* @[declare_platform_network_receive] */
+
+/**
+ * @brief Close a network connection.
+ *
+ * This function closes the connection, but does not release the resources
+ * used by the connection. This allows calls to other networking functions
+ * to return an error and handle a closed connection without the risk of
+ * crashing. Once it can be guaranteed that `pConnection` will no longer be
+ * used, the connection can be destroyed with @ref platform_network_function_destroy.
+ *
+ * In addition to closing the connection, this function should also remove
+ * any active [receive callback](@ref platform_network_function_receivecallback).
+ *
+ * @param[in] pConnection The network connection to close, defined by the
+ * network stack.
+ *
+ * @return Any #IotNetworkError_t, as defined by the network stack.
+ *
+ * @note It must be safe to call this function on an already-closed connection.
+ */
+/* @[declare_platform_network_close] */
+typedef IotNetworkError_t ( * IotNetworkClose_t )( IotNetworkConnection_t pConnection );
+/* @[declare_platform_network_close] */
+
+/**
+ * @brief Free resources used by a network connection.
+ *
+ * This function releases the resources of a closed connection. It should be
+ * called after @ref platform_network_function_close.
+ *
+ * @param[in] pConnection The network connection to destroy, defined by
+ * the network stack.
+ *
+ * @return Any #IotNetworkError_t, as defined by the network stack.
+ *
+ * @attention No function should be called on the network connection after
+ * calling this function. This function must be safe to call from a
+ * [receive callback](@ref platform_network_function_receivecallback).
+ */
+/* @[declare_platform_network_destroy] */
+typedef IotNetworkError_t ( * IotNetworkDestroy_t )( IotNetworkConnection_t pConnection );
+/* @[declare_platform_network_destroy] */
+
/**
* @ingroup platform_datatypes_paramstructs
* @brief Represents the functions of a network stack.
@@ -103,134 +292,13 @@ typedef void ( * IotNetworkReceiveCallback_t )( IotNetworkConnection_t pConnecti
*/
typedef struct IotNetworkInterface
{
- /**
- * @brief Create a new network connection.
- *
- * This function allocates resources and establishes a new network connection.
- * @param[in] pServerInfo Represents information needed to set up the
- * new connection, defined by the network stack.
- * @param[in] pCredentialInfo Represents information needed to secure the
- * new connection, defined by the network stack.
- * @param[out] pConnection Set to represent a new connection, defined by the
- * network stack.
- *
- * @return Any #IotNetworkError_t, as defined by the network stack.
- */
- /* @[declare_platform_network_create] */
- IotNetworkError_t ( * create )( IotNetworkServerInfo_t pServerInfo,
- IotNetworkCredentials_t pCredentialInfo,
- IotNetworkConnection_t * pConnection );
- /* @[declare_platform_network_create] */
-
- /**
- * @brief Register an @ref platform_network_function_receivecallback.
- *
- * Sets an @ref platform_network_function_receivecallback to be called
- * asynchronously when data arrives on the network. The network stack
- * should invoke this function "as if" it were the thread routine of a
- * detached thread.
- *
- * Each network connection may only have one receive callback at any time.
- * @ref platform_network_function_close is expected to remove any active
- * receive callbacks.
- *
- * @param[in] pConnection The connection to associate with the receive callback.
- * @param[in] receiveCallback The function to invoke for incoming network data.
- * @param[in] pContext A value to pass as the first parameter to the receive callback.
- *
- * @return Any #IotNetworkError_t, as defined by the network stack.
- *
- * @see platform_network_function_receivecallback
- */
- /* @[declare_platform_network_setreceivecallback] */
- IotNetworkError_t ( * setReceiveCallback )( IotNetworkConnection_t pConnection,
- IotNetworkReceiveCallback_t receiveCallback,
- void * pContext );
- /* @[declare_platform_network_setreceivecallback] */
-
- /**
- * @brief Send data over a return connection.
- *
- * Attempts to transmit `messageLength` bytes of `pMessage` across the
- * connection represented by `pConnection`. Returns the number of bytes
- * actually sent, `0` on failure.
- *
- * @param[in] pConnection The connection used to send data, defined by the
- * network stack.
- * @param[in] pMessage The message to send.
- * @param[in] messageLength The length of `pMessage`.
- *
- * @return The number of bytes successfully sent, `0` on failure.
- */
- /* @[declare_platform_network_send] */
- size_t ( * send )( IotNetworkConnection_t pConnection,
- const uint8_t * pMessage,
- size_t messageLength );
- /* @[declare_platform_network_send] */
-
- /**
- * @brief Block and wait for incoming network data.
- *
- * Wait for a message of size `bytesRequested` to arrive on the network and
- * place it in `pBuffer`.
- *
- * @param[in] pConnection The connection to wait on, defined by the network
- * stack.
- * @param[out] pBuffer Where to place the incoming network data. This buffer
- * must be at least `bytesRequested` in size.
- * @param[in] bytesRequested How many bytes to wait for. `pBuffer` must be at
- * least this size.
- *
- * @return The number of bytes successfully received. This should be
- * `bytesRequested` when successful. Any other value may indicate an error.
- */
- /* @[declare_platform_network_receive] */
- size_t ( * receive )( IotNetworkConnection_t pConnection,
- uint8_t * pBuffer,
- size_t bytesRequested );
- /* @[declare_platform_network_receive] */
-
- /**
- * @brief Close a network connection.
- *
- * This function closes the connection, but does not release the resources
- * used by the connection. This allows calls to other networking functions
- * to return an error and handle a closed connection without the risk of
- * crashing. Once it can be guaranteed that `pConnection` will no longer be
- * used, the connection can be destroyed with @ref platform_network_function_destroy.
- *
- * In addition to closing the connection, this function should also remove
- * any active [receive callback](@ref platform_network_function_receivecallback).
- *
- * @param[in] pConnection The network connection to close, defined by the
- * network stack.
- *
- * @return Any #IotNetworkError_t, as defined by the network stack.
- *
- * @note It must be safe to call this function on an already-closed connection.
- */
- /* @[declare_platform_network_close] */
- IotNetworkError_t ( * close )( IotNetworkConnection_t pConnection );
- /* @[declare_platform_network_close] */
-
- /**
- * @brief Free resources used by a network connection.
- *
- * This function releases the resources of a closed connection. It should be
- * called after @ref platform_network_function_close.
- *
- * @param[in] pConnection The network connection to destroy, defined by
- * the network stack.
- *
- * @return Any #IotNetworkError_t, as defined by the network stack.
- *
- * @attention No function should be called on the network connection after
- * calling this function. This function must be safe to call from a
- * [receive callback](@ref platform_network_function_receivecallback).
- */
- /* @[declare_platform_network_destroy] */
- IotNetworkError_t ( * destroy )( IotNetworkConnection_t pConnection );
- /* @[declare_platform_network_destroy] */
+ IotNetworkCreate_t create; /**< @brief create network connection. */
+ IotNetworkSetReceiveCallback_t setReceiveCallback; /**< @brief set receive callback. */
+ IotNetworkSetCloseCallback_t setCloseCallback; /**< @brief set close callback. */
+ IotNetworkSend_t send; /**< @brief send data. */
+ IotNetworkReceive_t receive; /**< @brief block and wait for receive data. */
+ IotNetworkClose_t close; /**< @brief close network connection. */
+ IotNetworkDestroy_t destroy; /**< @brief destroy network connection. */
} IotNetworkInterface_t;
/**
diff --git a/ports/common/include/iot_network_mbedtls.h b/ports/common/include/iot_network_mbedtls.h
index 9475a086fa..3cb5bc4441 100644
--- a/ports/common/include/iot_network_mbedtls.h
+++ b/ports/common/include/iot_network_mbedtls.h
@@ -82,18 +82,18 @@
*/
const IotNetworkInterface_t * IotNetworkMbedtls_GetInterface( void );
- /**
- * @brief One-time initialization function for this network stack.
- *
- * This function performs internal setup of this network stack. It must be
- * called once (and only once) before calling any other function in this network
- * stack. Calling this function more than once without first calling
- * #IotNetworkMbedtls_Cleanup may result in a crash.
- *
- * @return #IOT_NETWORK_SUCCESS or #IOT_NETWORK_FAILURE.
- *
- * @warning No thread-safety guarantees are provided for this function.
- */
+/**
+ * @brief One-time initialization function for this network stack.
+ *
+ * This function performs internal setup of this network stack. It must be
+ * called once (and only once) before calling any other function in this network
+ * stack. Calling this function more than once without first calling
+ * #IotNetworkMbedtls_Cleanup may result in a crash.
+ *
+ * @return #IOT_NETWORK_SUCCESS or #IOT_NETWORK_FAILURE.
+ *
+ * @warning No thread-safety guarantees are provided for this function.
+ */
IotNetworkError_t IotNetworkMbedtls_Init( void );
/**
@@ -124,6 +124,14 @@ IotNetworkError_t IotNetworkMbedtls_SetReceiveCallback( IotNetworkConnection_t p
IotNetworkReceiveCallback_t receiveCallback,
void * pContext );
+/**
+ * @brief An implementation of #IotNetworkInterface_t::setCloseCallback for
+ * mbed TLS.
+ */
+IotNetworkError_t IotNetworkMbedtls_SetCloseCallback( IotNetworkConnection_t pConnection,
+ IotNetworkCloseCallback_t closeCallback,
+ void * pContext );
+
/**
* @brief An implementation of #IotNetworkInterface_t::send for mbed TLS.
*/
diff --git a/ports/common/include/iot_network_openssl.h b/ports/common/include/iot_network_openssl.h
index a973318635..357595bca7 100644
--- a/ports/common/include/iot_network_openssl.h
+++ b/ports/common/include/iot_network_openssl.h
@@ -128,6 +128,14 @@ IotNetworkError_t IotNetworkOpenssl_SetReceiveCallback( IotNetworkConnection_t p
IotNetworkReceiveCallback_t receiveCallback,
void * pContext );
+/**
+ * @brief An implementation of #IotNetworkInterface_t::setCloseCallback for
+ * systems with OpenSSL.
+ */
+IotNetworkError_t IotNetworkOpenssl_SetCloseCallback( IotNetworkConnection_t pConnection,
+ IotNetworkCloseCallback_t closeCallback,
+ void * pContext );
+
/**
* @brief An implementation of #IotNetworkInterface_t::send for systems
* with OpenSSL.
diff --git a/ports/common/src/iot_network_mbedtls.c b/ports/common/src/iot_network_mbedtls.c
index 82d522f9b3..e8371ac2f7 100644
--- a/ports/common/src/iot_network_mbedtls.c
+++ b/ports/common/src/iot_network_mbedtls.c
@@ -156,6 +156,8 @@ typedef struct _networkConnection
IotNetworkReceiveCallback_t receiveCallback; /**< @brief Network receive callback, if any. */
void * pReceiveContext; /**< @brief The context for the receive callback. */
+ IotNetworkCloseCallback_t closeCallback; /**< @brief Network close callback, if any. */
+ void * pCloseContext; /**< @brief The context for the close callback. */
IotMutex_t callbackMutex; /**< @brief Synchronizes the receive callback with calls to destroy. */
IotSemaphore_t destroyNotification; /**< @brief Notifies the receive callback that the connection was destroyed. */
@@ -410,6 +412,17 @@ static void _receiveThread( void * pArgument )
}
}
+ /**
+ * If a close callback has been defined, invoke it now; since we
+ * don't know what caused the close, use "unknown" as the reason.
+ */
+ if( pConnection->closeCallback != NULL )
+ {
+ pConnection->closeCallback( pConnection,
+ IOT_NETWORK_UNKNOWN_CLOSED,
+ pConnection->pCloseContext );
+ }
+
/* Wait for the call to network destroy, then destroy the connection. */
IotSemaphore_Wait( &( pConnection->destroyNotification ) );
_destroyConnection( pConnection );
@@ -930,7 +943,12 @@ IotNetworkError_t IotNetworkMbedtls_SetReceiveCallback( IotNetworkConnection_t p
IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_SYSTEM_ERROR );
}
- /* Set the callback and parameter. */
+ /* Set the callback (must be non-NULL) and parameter. */
+ if( receiveCallback == NULL )
+ {
+ IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_BAD_PARAMETER );
+ }
+
pConnection->receiveCallback = receiveCallback;
pConnection->pReceiveContext = pContext;
@@ -978,6 +996,26 @@ IotNetworkError_t IotNetworkMbedtls_SetReceiveCallback( IotNetworkConnection_t p
/*-----------------------------------------------------------*/
+IotNetworkError_t IotNetworkMbedtls_SetCloseCallback( IotNetworkConnection_t pConnection,
+ IotNetworkCloseCallback_t closeCallback,
+ void * pContext )
+{
+ IotNetworkError_t status = IOT_NETWORK_BAD_PARAMETER;
+
+ if( closeCallback != NULL )
+ {
+ /* Set the callback and parameter. */
+ pConnection->closeCallback = closeCallback;
+ pConnection->pCloseContext = pContext;
+
+ status = IOT_NETWORK_SUCCESS;
+ }
+
+ return status;
+}
+
+/*-----------------------------------------------------------*/
+
size_t IotNetworkMbedtls_Send( IotNetworkConnection_t pConnection,
const uint8_t * pMessage,
size_t messageLength )
diff --git a/ports/common/src/iot_network_metrics.c b/ports/common/src/iot_network_metrics.c
index 8bd0b6a1e8..304ec8008b 100644
--- a/ports/common/src/iot_network_metrics.c
+++ b/ports/common/src/iot_network_metrics.c
@@ -126,71 +126,73 @@ static IotMutex_t _connectionListMutex;
/* OpenSSL networking include. */
#include "iot_network_openssl.h"
- /**
- * @brief Pointer to the metrics-wrapped network creation function.
- */
+/**
+ * @brief Pointer to the metrics-wrapped network creation function.
+ */
static IotNetworkError_t ( * _networkCreate )( IotNetworkServerInfo_t,
IotNetworkCredentials_t,
IotNetworkConnection_t * ) = IotNetworkOpenssl_Create;
- /**
- * @brief Pointer to the metrics-wrapped network close function.
- */
+/**
+ * @brief Pointer to the metrics-wrapped network close function.
+ */
static IotNetworkError_t ( * _networkClose )( IotNetworkConnection_t ) = IotNetworkOpenssl_Close;
- /**
- * @brief Pointer to the function that retrieves the socket for a connection.
- */
+/**
+ * @brief Pointer to the function that retrieves the socket for a connection.
+ */
static int ( * _getSocket )( IotNetworkConnection_t ) = IotNetworkOpenssl_GetSocket;
- /**
- * @brief An #IotNetworkInterface_t that wraps network abstraction functions with
- * metrics.
- */
+/**
+ * @brief An #IotNetworkInterface_t that wraps network abstraction functions with
+ * metrics.
+ */
static const IotNetworkInterface_t _networkMetrics =
{
.create = _metricsNetworkCreate,
.setReceiveCallback = IotNetworkOpenssl_SetReceiveCallback,
+ .setCloseCallback = IotNetworkOpenssl_SetCloseCallback,
.send = IotNetworkOpenssl_Send,
.receive = IotNetworkOpenssl_Receive,
.close = _metricsNetworkClose,
.destroy = IotNetworkOpenssl_Destroy
};
-#else
+#else /* if IOT_NETWORK_USE_OPENSSL == 1 */
/* mbed TLS networking include. */
#include "iot_network_mbedtls.h"
- /**
- * @brief Pointer to the metrics-wrapped network creation function.
- */
+/**
+ * @brief Pointer to the metrics-wrapped network creation function.
+ */
static IotNetworkError_t ( * _networkCreate )( IotNetworkServerInfo_t,
IotNetworkCredentials_t,
IotNetworkConnection_t * ) = IotNetworkMbedtls_Create;
- /**
- * @brief Pointer to the metrics-wrapped network close function.
- */
+/**
+ * @brief Pointer to the metrics-wrapped network close function.
+ */
static IotNetworkError_t ( * _networkClose )( IotNetworkConnection_t ) = IotNetworkMbedtls_Close;
- /**
- * @brief Pointer to the function that retrieves the socket for a connection.
- */
+/**
+ * @brief Pointer to the function that retrieves the socket for a connection.
+ */
static int ( * _getSocket )( IotNetworkConnection_t ) = IotNetworkMbedtls_GetSocket;
- /**
- * @brief An #IotNetworkInterface_t that wraps network abstraction functions with
- * metrics.
- */
+/**
+ * @brief An #IotNetworkInterface_t that wraps network abstraction functions with
+ * metrics.
+ */
static const IotNetworkInterface_t _networkMetrics =
{
.create = _metricsNetworkCreate,
.setReceiveCallback = IotNetworkMbedtls_SetReceiveCallback,
+ .setCloseCallback = IotNetworkMbedtls_SetCloseCallback,
.send = IotNetworkMbedtls_Send,
.receive = IotNetworkMbedtls_Receive,
.close = _metricsNetworkClose,
.destroy = IotNetworkMbedtls_Destroy
};
-#endif
+#endif /* if IOT_NETWORK_USE_OPENSSL == 1 */
/*-----------------------------------------------------------*/
diff --git a/ports/common/src/iot_network_openssl.c b/ports/common/src/iot_network_openssl.c
index ba69d01b54..fa1c27a821 100644
--- a/ports/common/src/iot_network_openssl.c
+++ b/ports/common/src/iot_network_openssl.c
@@ -111,6 +111,8 @@ typedef struct _networkConnection
IotNetworkReceiveCallback_t receiveCallback; /**< @brief Network receive callback, if any. */
void * pReceiveContext; /**< @brief The context for the receive callback. */
+ IotNetworkCloseCallback_t closeCallback; /**< @brief Network close callback, if any. */
+ void * pCloseContext; /**< @brief The context for the close callback. */
} _networkConnection_t;
/*-----------------------------------------------------------*/
@@ -122,6 +124,7 @@ static const IotNetworkInterface_t _networkOpenssl =
{
.create = IotNetworkOpenssl_Create,
.setReceiveCallback = IotNetworkOpenssl_SetReceiveCallback,
+ .setCloseCallback = IotNetworkOpenssl_SetCloseCallback,
.send = IotNetworkOpenssl_Send,
.receive = IotNetworkOpenssl_Receive,
.close = IotNetworkOpenssl_Close,
@@ -181,6 +184,17 @@ static void * _networkReceiveThread( void * pArgument )
pConnection->pReceiveContext );
}
+ /**
+ * If a close callback has been defined, invoke it now; since we
+ * don't know what caused the close, use "unknown" as the reason.
+ */
+ if( pConnection->closeCallback != NULL )
+ {
+ pConnection->closeCallback( pConnection,
+ IOT_NETWORK_UNKNOWN_CLOSED,
+ pConnection->pCloseContext );
+ }
+
IotLogDebug( "Network receive thread for socket %d terminating.",
pConnection->socket );
@@ -752,28 +766,53 @@ IotNetworkError_t IotNetworkOpenssl_SetReceiveCallback( IotNetworkConnection_t p
IotNetworkReceiveCallback_t receiveCallback,
void * pContext )
{
+ IotNetworkError_t status = IOT_NETWORK_BAD_PARAMETER;
int posixError = 0;
- IotNetworkError_t status = IOT_NETWORK_SUCCESS;
- /* Set the callback and parameter. */
- pConnection->receiveCallback = receiveCallback;
- pConnection->pReceiveContext = pContext;
+ /* The receive callback must be non-NULL) */
+ if( receiveCallback != NULL )
+ {
+ /* Set the callback and parameter. */
+ pConnection->receiveCallback = receiveCallback;
+ pConnection->pReceiveContext = pContext;
- posixError = pthread_create( &pConnection->receiveThread,
- NULL,
- _networkReceiveThread,
- pConnection );
+ posixError = pthread_create( &pConnection->receiveThread,
+ NULL,
+ _networkReceiveThread,
+ pConnection );
- if( posixError != 0 )
- {
- IotLogError( "Failed to create socket %d network receive thread. errno=%d.",
- pConnection->socket,
- posixError );
- status = IOT_NETWORK_SYSTEM_ERROR;
+ if( posixError != 0 )
+ {
+ IotLogError( "Failed to create socket %d network receive thread. errno=%d.",
+ pConnection->socket,
+ posixError );
+ status = IOT_NETWORK_SYSTEM_ERROR;
+ }
+ else
+ {
+ pConnection->receiveThreadCreated = true;
+ status = IOT_NETWORK_SUCCESS;
+ }
}
- else
+
+ return status;
+}
+
+/*-----------------------------------------------------------*/
+
+IotNetworkError_t IotNetworkOpenssl_SetCloseCallback( IotNetworkConnection_t pConnection,
+ IotNetworkCloseCallback_t closeCallback,
+ void * pContext )
+{
+ IotNetworkError_t status = IOT_NETWORK_BAD_PARAMETER;
+
+ if( closeCallback != NULL )
{
- pConnection->receiveThreadCreated = true;
+ /* Set the callback and parameter. */
+ pConnection->closeCallback = closeCallback;
+ pConnection->pCloseContext = pContext;
+
+ status = IOT_NETWORK_SUCCESS;
}
return status;