From e3ae05adb20dd69f64d946ffcd107f98c5af83ad Mon Sep 17 00:00:00 2001 From: Gary Wicker Date: Wed, 6 Nov 2019 12:27:10 -0800 Subject: [PATCH 1/8] Added task pool general failure enum value. --- .../common/include/types/iot_taskpool_types.h | 69 ++----------------- 1 file changed, 5 insertions(+), 64 deletions(-) diff --git a/libraries/standard/common/include/types/iot_taskpool_types.h b/libraries/standard/common/include/types/iot_taskpool_types.h index ac017ddf7b..dc796b7d5e 100644 --- a/libraries/standard/common/include/types/iot_taskpool_types.h +++ b/libraries/standard/common/include/types/iot_taskpool_types.h @@ -51,97 +51,38 @@ typedef enum IotTaskPoolError { /** * @brief Task pool operation completed successfully. - * - * Functions that may return this value: - * - @ref taskpool_function_createsystemtaskpool - * - @ref taskpool_function_create - * - @ref taskpool_function_destroy - * - @ref taskpool_function_setmaxthreads - * - @ref taskpool_function_createjob - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_destroyrecyclablejob - * - @ref taskpool_function_recyclejob - * - @ref taskpool_function_schedule - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_getstatus - * - @ref taskpool_function_trycancel - * */ IOT_TASKPOOL_SUCCESS = 0, /** * @brief Task pool operation failed because at least one parameter is invalid. - * - * Functions that may return this value: - * - @ref taskpool_function_createsystemtaskpool - * - @ref taskpool_function_create - * - @ref taskpool_function_destroy - * - @ref taskpool_function_setmaxthreads - * - @ref taskpool_function_createjob - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_destroyrecyclablejob - * - @ref taskpool_function_recyclejob - * - @ref taskpool_function_schedule - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_getstatus - * - @ref taskpool_function_trycancel - * */ IOT_TASKPOOL_BAD_PARAMETER, /** * @brief Task pool operation failed because it is illegal. - * - * Functions that may return this value: - * - @ref taskpool_function_createjob - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_destroyrecyclablejob - * - @ref taskpool_function_recyclejob - * - @ref taskpool_function_schedule - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_trycancel - * */ IOT_TASKPOOL_ILLEGAL_OPERATION, /** * @brief Task pool operation failed because allocating memory failed. - * - * Functions that may return this value: - * - @ref taskpool_function_createsystemtaskpool - * - @ref taskpool_function_create - * - @ref taskpool_function_setmaxthreads - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_getstatus - * */ IOT_TASKPOOL_NO_MEMORY, /** * @brief Task pool operation failed because of an invalid parameter. - * - * Functions that may return this value: - * - @ref taskpool_function_setmaxthreads - * - @ref taskpool_function_createrecyclablejob - * - @ref taskpool_function_destroyrecyclablejob - * - @ref taskpool_function_recyclejob - * - @ref taskpool_function_schedule - * - @ref taskpool_function_scheduledeferred - * - @ref taskpool_function_getstatus - * - @ref taskpool_function_trycancel - * */ IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS, /** * @brief Task pool cancellation failed. - * - * Functions that may return this value: - * - @ref taskpool_function_trycancel - * */ IOT_TASKPOOL_CANCEL_FAILED, + + /** + * @brief Task pool operation general failure. + */ + IOT_TASKPOOL_GENERAL_FAILURE, } IotTaskPoolError_t; /** From 7b758d8d613c2348ec79ea4b39f360b15567047f Mon Sep 17 00:00:00 2001 From: Gary Wicker Date: Wed, 6 Nov 2019 13:31:40 -0800 Subject: [PATCH 2/8] Update IotTaskPool_strerror with new error value. --- libraries/standard/common/src/iot_taskpool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/standard/common/src/iot_taskpool.c b/libraries/standard/common/src/iot_taskpool.c index 04b34d646c..76c24c69e9 100644 --- a/libraries/standard/common/src/iot_taskpool.c +++ b/libraries/standard/common/src/iot_taskpool.c @@ -922,6 +922,10 @@ const char * IotTaskPool_strerror( IotTaskPoolError_t status ) pMessage = "CANCEL FAILED"; break; + case IOT_TASKPOOL_GENERAL_FAILURE: + pMessage = "GENERAL FAILURE"; + break; + default: pMessage = "INVALID STATUS"; break; From e132ed72704fbc0a1ae5c2baaafd64ff5d2feded Mon Sep 17 00:00:00 2001 From: Gary Wicker Date: Mon, 11 Nov 2019 16:49:55 -0800 Subject: [PATCH 3/8] Add close callback to network interface. --- libraries/platform/iot_network.h | 323 +++++++++++++-------- ports/common/include/iot_network_mbedtls.h | 8 + ports/common/include/iot_network_openssl.h | 8 + ports/common/src/iot_network_mbedtls.c | 39 ++- ports/common/src/iot_network_metrics.c | 2 + ports/common/src/iot_network_openssl.c | 33 +++ 6 files changed, 284 insertions(+), 129 deletions(-) diff --git a/libraries/platform/iot_network.h b/libraries/platform/iot_network.h index 77eba836b6..d540ec921f 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,177 @@ 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 data is available on the network. + * + * @param[in] pConnection The connection on which data is available, 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_setreceivecallback. + */ +/* @[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 +291,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..48e94ec19d 100644 --- a/ports/common/include/iot_network_mbedtls.h +++ b/ports/common/include/iot_network_mbedtls.h @@ -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..0ec66384b3 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. */ @@ -409,6 +411,16 @@ 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 ) ); @@ -930,7 +942,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 +995,26 @@ IotNetworkError_t IotNetworkMbedtls_SetReceiveCallback( IotNetworkConnection_t p /*-----------------------------------------------------------*/ +IotNetworkError_t IotNetworkMbedtls_SetCloseCallback( IotNetworkConnection_t pConnection, + IotNetworkCloseCallback_t closeCallback, + void * pContext ) +{ + IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_BAD_PARAMETER ); + + if( closeCallback != NULL ) + { + /* Set the callback and parameter. */ + pConnection->closeCallback = closeCallback; + pConnection->pCloseContext = pContext; + + status = IOT_NETWORK_SUCCESS; + } + + IOT_FUNCTION_CLEANUP_END(); +} + +/*-----------------------------------------------------------*/ + 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..719c3878b1 100644 --- a/ports/common/src/iot_network_metrics.c +++ b/ports/common/src/iot_network_metrics.c @@ -151,6 +151,7 @@ static IotMutex_t _connectionListMutex; { .create = _metricsNetworkCreate, .setReceiveCallback = IotNetworkOpenssl_SetReceiveCallback, + .setCloseCallback = IotNetworkOpenssl_SetCloseCallback, .send = IotNetworkOpenssl_Send, .receive = IotNetworkOpenssl_Receive, .close = _metricsNetworkClose, @@ -185,6 +186,7 @@ static IotMutex_t _connectionListMutex; { .create = _metricsNetworkCreate, .setReceiveCallback = IotNetworkMbedtls_SetReceiveCallback, + .setCloseCallback = IotNetworkMbedtls_SetCloseCallback, .send = IotNetworkMbedtls_Send, .receive = IotNetworkMbedtls_Receive, .close = _metricsNetworkClose, diff --git a/ports/common/src/iot_network_openssl.c b/ports/common/src/iot_network_openssl.c index ba69d01b54..a11499cfd0 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, @@ -180,6 +183,16 @@ static void * _networkReceiveThread( void * pArgument ) pConnection->receiveCallback( pConnection, 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 ); @@ -781,6 +794,26 @@ IotNetworkError_t IotNetworkOpenssl_SetReceiveCallback( IotNetworkConnection_t p /*-----------------------------------------------------------*/ +IotNetworkError_t IotNetworkOpenssl_SetCloseCallback( IotNetworkConnection_t pConnection, + IotNetworkCloseCallback_t closeCallback, + void * pContext ) +{ + IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_BAD_PARAMETER ); + + if( closeCallback != NULL ) + { + /* Set the callback and parameter. */ + pConnection->closeCallback = closeCallback; + pConnection->pCloseContext = pContext; + + status = IOT_NETWORK_SUCCESS; + } + + IOT_FUNCTION_CLEANUP_END(); +} + +/*-----------------------------------------------------------*/ + size_t IotNetworkOpenssl_Send( IotNetworkConnection_t pConnection, const uint8_t * pMessage, size_t messageLength ) From 1281dbac639c86d5c454d0dd5251fccea41a49bc Mon Sep 17 00:00:00 2001 From: Gary Wicker Date: Tue, 12 Nov 2019 10:57:52 -0800 Subject: [PATCH 4/8] Uncrustify + address PR comments --- libraries/platform/iot_network.h | 25 +++++----- ports/common/include/iot_network_mbedtls.h | 24 +++++----- ports/common/src/iot_network_mbedtls.c | 7 +-- ports/common/src/iot_network_metrics.c | 56 +++++++++++----------- ports/common/src/iot_network_openssl.c | 48 +++++++++++-------- 5 files changed, 84 insertions(+), 76 deletions(-) diff --git a/libraries/platform/iot_network.h b/libraries/platform/iot_network.h index d540ec921f..885b2957e4 100644 --- a/libraries/platform/iot_network.h +++ b/libraries/platform/iot_network.h @@ -54,11 +54,11 @@ typedef enum IotNetworkError */ 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. */ + 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; /** @@ -127,6 +127,7 @@ typedef void ( * IotNetworkCloseCallback_t )( IotNetworkConnection_t pConnection IotNetworkCloseReason_t reason, void * pContext ); /* @[declare_platform_network_closecallback] */ + /** * @brief Create a new network connection. * @@ -291,13 +292,13 @@ typedef IotNetworkError_t ( * IotNetworkDestroy_t )( IotNetworkConnection_t pCon */ typedef struct IotNetworkInterface { - 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. */ + 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 48e94ec19d..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 ); /** diff --git a/ports/common/src/iot_network_mbedtls.c b/ports/common/src/iot_network_mbedtls.c index 0ec66384b3..461c94a178 100644 --- a/ports/common/src/iot_network_mbedtls.c +++ b/ports/common/src/iot_network_mbedtls.c @@ -411,11 +411,12 @@ 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 ) + if( pConnection->closeCallback != NULL ) { pConnection->closeCallback( pConnection, IOT_NETWORK_UNKNOWN_CLOSED, @@ -943,7 +944,7 @@ IotNetworkError_t IotNetworkMbedtls_SetReceiveCallback( IotNetworkConnection_t p } /* Set the callback (must be non-NULL) and parameter. */ - if ( receiveCallback == NULL ) + if( receiveCallback == NULL ) { IOT_SET_AND_GOTO_CLEANUP( IOT_NETWORK_BAD_PARAMETER ); } @@ -1010,7 +1011,7 @@ IotNetworkError_t IotNetworkMbedtls_SetCloseCallback( IotNetworkConnection_t pCo status = IOT_NETWORK_SUCCESS; } - IOT_FUNCTION_CLEANUP_END(); + IOT_FUNCTION_EXIT_NO_CLEANUP(); } /*-----------------------------------------------------------*/ diff --git a/ports/common/src/iot_network_metrics.c b/ports/common/src/iot_network_metrics.c index 719c3878b1..304ec8008b 100644 --- a/ports/common/src/iot_network_metrics.c +++ b/ports/common/src/iot_network_metrics.c @@ -126,27 +126,27 @@ 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, @@ -157,31 +157,31 @@ static IotMutex_t _connectionListMutex; .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, @@ -192,7 +192,7 @@ static IotMutex_t _connectionListMutex; .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 a11499cfd0..45fb0c3289 100644 --- a/ports/common/src/iot_network_openssl.c +++ b/ports/common/src/iot_network_openssl.c @@ -183,11 +183,12 @@ static void * _networkReceiveThread( void * pArgument ) pConnection->receiveCallback( pConnection, 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 ) + if( pConnection->closeCallback != NULL ) { pConnection->closeCallback( pConnection, IOT_NETWORK_UNKNOWN_CLOSED, @@ -765,31 +766,36 @@ IotNetworkError_t IotNetworkOpenssl_SetReceiveCallback( IotNetworkConnection_t p IotNetworkReceiveCallback_t receiveCallback, void * pContext ) { + IOT_FUNCTION_ENTRY( IotNetworkError_t, 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; - } - else - { - pConnection->receiveThreadCreated = true; + 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; + } } - return status; + IOT_FUNCTION_EXIT_NO_CLEANUP(); } /*-----------------------------------------------------------*/ @@ -809,7 +815,7 @@ IotNetworkError_t IotNetworkOpenssl_SetCloseCallback( IotNetworkConnection_t pCo status = IOT_NETWORK_SUCCESS; } - IOT_FUNCTION_CLEANUP_END(); + IOT_FUNCTION_EXIT_NO_CLEANUP(); } /*-----------------------------------------------------------*/ From a582c016b36238299ec35b0ed3f06d36073a6aea Mon Sep 17 00:00:00 2001 From: Gary Wicker Date: Tue, 12 Nov 2019 12:02:49 -0800 Subject: [PATCH 5/8] Simplify SetCloseCallback() functions --- ports/common/src/iot_network_mbedtls.c | 4 ++-- ports/common/src/iot_network_openssl.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/common/src/iot_network_mbedtls.c b/ports/common/src/iot_network_mbedtls.c index 461c94a178..e8371ac2f7 100644 --- a/ports/common/src/iot_network_mbedtls.c +++ b/ports/common/src/iot_network_mbedtls.c @@ -1000,7 +1000,7 @@ IotNetworkError_t IotNetworkMbedtls_SetCloseCallback( IotNetworkConnection_t pCo IotNetworkCloseCallback_t closeCallback, void * pContext ) { - IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_BAD_PARAMETER ); + IotNetworkError_t status = IOT_NETWORK_BAD_PARAMETER; if( closeCallback != NULL ) { @@ -1011,7 +1011,7 @@ IotNetworkError_t IotNetworkMbedtls_SetCloseCallback( IotNetworkConnection_t pCo status = IOT_NETWORK_SUCCESS; } - IOT_FUNCTION_EXIT_NO_CLEANUP(); + return status; } /*-----------------------------------------------------------*/ diff --git a/ports/common/src/iot_network_openssl.c b/ports/common/src/iot_network_openssl.c index 45fb0c3289..63d796dbc7 100644 --- a/ports/common/src/iot_network_openssl.c +++ b/ports/common/src/iot_network_openssl.c @@ -804,7 +804,7 @@ IotNetworkError_t IotNetworkOpenssl_SetCloseCallback( IotNetworkConnection_t pCo IotNetworkCloseCallback_t closeCallback, void * pContext ) { - IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_BAD_PARAMETER ); + IotNetworkError_t status = IOT_NETWORK_BAD_PARAMETER; if( closeCallback != NULL ) { @@ -815,7 +815,7 @@ IotNetworkError_t IotNetworkOpenssl_SetCloseCallback( IotNetworkConnection_t pCo status = IOT_NETWORK_SUCCESS; } - IOT_FUNCTION_EXIT_NO_CLEANUP(); + return status; } /*-----------------------------------------------------------*/ From 5b02381299305e767c4010d99c76b8d05e3105cf Mon Sep 17 00:00:00 2001 From: Gary Wicker Date: Tue, 12 Nov 2019 13:18:29 -0800 Subject: [PATCH 6/8] Address PR comments --- libraries/platform/iot_network.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/platform/iot_network.h b/libraries/platform/iot_network.h index 885b2957e4..692b1e3ede 100644 --- a/libraries/platform/iot_network.h +++ b/libraries/platform/iot_network.h @@ -115,12 +115,12 @@ typedef void ( * IotNetworkReceiveCallback_t )( IotNetworkConnection_t pConnecti * @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 data is available on the network. + * to be invoked when the network connection is closed. * * @param[in] pConnection The connection on which data is available, 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_setreceivecallback. + * @param[in] pContext The third argument passed to @ref platform_network_function_setclosecallback. */ /* @[declare_platform_network_closecallback] */ typedef void ( * IotNetworkCloseCallback_t )( IotNetworkConnection_t pConnection, From cd8768a23c2e46204eb6693e137001c626686085 Mon Sep 17 00:00:00 2001 From: Gary Wicker Date: Tue, 12 Nov 2019 13:33:17 -0800 Subject: [PATCH 7/8] Get rid of compiler warning in openssl build. --- ports/common/src/iot_network_openssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/common/src/iot_network_openssl.c b/ports/common/src/iot_network_openssl.c index 63d796dbc7..fa1c27a821 100644 --- a/ports/common/src/iot_network_openssl.c +++ b/ports/common/src/iot_network_openssl.c @@ -766,7 +766,7 @@ IotNetworkError_t IotNetworkOpenssl_SetReceiveCallback( IotNetworkConnection_t p IotNetworkReceiveCallback_t receiveCallback, void * pContext ) { - IOT_FUNCTION_ENTRY( IotNetworkError_t, IOT_NETWORK_BAD_PARAMETER ); + IotNetworkError_t status = IOT_NETWORK_BAD_PARAMETER; int posixError = 0; /* The receive callback must be non-NULL) */ @@ -795,7 +795,7 @@ IotNetworkError_t IotNetworkOpenssl_SetReceiveCallback( IotNetworkConnection_t p } } - IOT_FUNCTION_EXIT_NO_CLEANUP(); + return status; } /*-----------------------------------------------------------*/ From fabacef21ec3392f2795b55d07d2ff9a85fec1a7 Mon Sep 17 00:00:00 2001 From: Gary Wicker Date: Tue, 12 Nov 2019 14:12:02 -0800 Subject: [PATCH 8/8] Fix documentation for IotNetworkCloseCallback_t. --- libraries/platform/iot_network.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/platform/iot_network.h b/libraries/platform/iot_network.h index 692b1e3ede..651f0d0ac1 100644 --- a/libraries/platform/iot_network.h +++ b/libraries/platform/iot_network.h @@ -117,7 +117,7 @@ typedef void ( * IotNetworkReceiveCallback_t )( IotNetworkConnection_t pConnecti * 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 on which data is available, defined by + * @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.