Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Use void* for network context pointers. #236

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions MigrationGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ void eventCallback(
MQTTDeserializedInfo_t * pDeserializedInfo
);
// Network send.
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
int32_t networkSend( void * pContext, const void * pBuffer, size_t bytes );
// Network receive.
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
int32_t networkRecv( void * pContext, void * pBuffer, size_t bytes );

MQTTContext_t mqttContext;
TransportInterface_t transport;
Expand Down Expand Up @@ -183,9 +183,9 @@ void eventCallback(
MQTTDeserializedInfo_t * pDeserializedInfo
);
// Network send.
int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
int32_t networkSend( void * pContext, const void * pBuffer, size_t bytes );
// Network receive.
int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
int32_t networkRecv( void * pContext, void * pBuffer, size_t bytes );

MQTTContext_t mqttContext;
TransportInterface_t transport;
Expand Down
13 changes: 3 additions & 10 deletions docs/doxygen/porting.dox
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,17 @@ A port must implement functions corresponding to the following functions pointer
- [Transport Receive](@ref TransportRecv_t): A function to receive bytes from a network.
@code
int32_t (* TransportRecv_t )(
NetworkContext_t * pNetworkContext, void * pBuffer, size_t bytesToRecv
void * pNetworkContext, void * pBuffer, size_t bytesToRecv
);
@endcode
- [Transport Send](@ref TransportSend_t): A function to send bytes over a network.
@code
int32_t (* TransportSend_t )(
NetworkContext_t * pNetworkContext, const void * pBuffer, size_t bytesToSend
void * pNetworkContext, const void * pBuffer, size_t bytesToSend
);
@endcode

The above two functions take in a pointer to a @ref NetworkContext_t, the typename of a
`struct NetworkContext`. The NetworkContext struct must also be defined by the port, and
ought to contain any information necessary to send and receive data with the @ref TransportSend_t
and @ref TransportRecv_t implementations, respectively:
@code
struct NetworkContext {
// Fields necessary for the transport implementations, e.g. a TCP socket descriptor.
};
The above two functions take in a void pointer to an implementation-defined context.
@endcode

@section mqtt_porting_time Time Function
Expand Down
22 changes: 13 additions & 9 deletions source/core_mqtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,13 +773,13 @@ static int32_t sendMessageVector( MQTTContext_t * pContext,
{
if( pContext->transportInterface.writev != NULL )
{
sendResult = pContext->transportInterface.writev( pContext->transportInterface.pNetworkContext,
sendResult = pContext->transportInterface.writev( pContext->pNetworkContext,
pIoVectIterator,
vectorsToBeSent );
}
else
{
sendResult = pContext->transportInterface.send( pContext->transportInterface.pNetworkContext,
sendResult = pContext->transportInterface.send( pContext->pNetworkContext,
pIoVectIterator->iov_base,
pIoVectIterator->iov_len );
}
Expand Down Expand Up @@ -858,7 +858,7 @@ static int32_t sendBuffer( MQTTContext_t * pContext,

while( ( bytesSentOrError < ( int32_t ) bytesToSend ) && ( bytesSentOrError >= 0 ) )
{
sendResult = pContext->transportInterface.send( pContext->transportInterface.pNetworkContext,
sendResult = pContext->transportInterface.send( pContext->pNetworkContext,
pIndex,
bytesToSend - ( size_t ) bytesSentOrError );

Expand Down Expand Up @@ -968,7 +968,7 @@ static int32_t recvExact( const MQTTContext_t * pContext,

while( ( bytesRemaining > 0U ) && ( receiveError == false ) )
{
bytesRecvd = recvFunc( pContext->transportInterface.pNetworkContext,
bytesRecvd = recvFunc( pContext->pNetworkContext,
pIndex,
bytesRemaining );

Expand Down Expand Up @@ -1655,7 +1655,7 @@ static MQTTStatus_t receiveSingleIteration( MQTTContext_t * pContext,
assert( pContext->networkBuffer.pBuffer != NULL );

/* Read as many bytes as possible into the network buffer. */
recvBytes = pContext->transportInterface.recv( pContext->transportInterface.pNetworkContext,
recvBytes = pContext->transportInterface.recv( pContext->pNetworkContext,
&( pContext->networkBuffer.pBuffer[ pContext->index ] ),
pContext->networkBuffer.size - pContext->index );

Expand Down Expand Up @@ -2274,7 +2274,7 @@ static MQTTStatus_t receiveConnack( const MQTTContext_t * pContext,
* returned after a transport receive timeout, an error, or a successful
* receive of packet type and length. */
status = MQTT_GetIncomingPacketTypeAndLength( pContext->transportInterface.recv,
pContext->transportInterface.pNetworkContext,
pContext->pNetworkContext,
pIncomingPacket );

/* The loop times out based on 2 conditions.
Expand Down Expand Up @@ -2467,6 +2467,7 @@ static MQTTStatus_t validatePublishParams( const MQTTContext_t * pContext,

MQTTStatus_t MQTT_Init( MQTTContext_t * pContext,
const TransportInterface_t * pTransportInterface,
void * pNetworkContext,
MQTTGetCurrentTimeFunc_t getTimeFunction,
MQTTEventCallback_t userCallback,
const MQTTFixedBuffer_t * pNetworkBuffer )
Expand All @@ -2475,14 +2476,16 @@ MQTTStatus_t MQTT_Init( MQTTContext_t * pContext,

/* Validate arguments. */
if( ( pContext == NULL ) || ( pTransportInterface == NULL ) ||
( pNetworkBuffer == NULL ) )
( pNetworkBuffer == NULL ) || ( pNetworkContext == NULL ) )
{
LogError( ( "Argument cannot be NULL: pContext=%p, "
"pTransportInterface=%p, "
"pNetworkBuffer=%p",
"pNetworkBuffer=%p, "
"pNetworkContext=%p",
( void * ) pContext,
( void * ) pTransportInterface,
( void * ) pNetworkBuffer ) );
( void * ) pNetworkBuffer,
( void * ) pNetworkContext ) );
status = MQTTBadParameter;
}
else if( getTimeFunction == NULL )
Expand Down Expand Up @@ -2511,6 +2514,7 @@ MQTTStatus_t MQTT_Init( MQTTContext_t * pContext,

pContext->connectStatus = MQTTNotConnected;
pContext->transportInterface = *pTransportInterface;
pContext->pNetworkContext = pNetworkContext;
pContext->getTime = getTimeFunction;
pContext->appCallback = userCallback;
pContext->networkBuffer = *pNetworkBuffer;
Expand Down
6 changes: 3 additions & 3 deletions source/core_mqtt_serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ static uint8_t * encodeString( uint8_t * pDestination,
* @return The Remaining Length of the incoming packet.
*/
static size_t getRemainingLength( TransportRecv_t recvFunc,
NetworkContext_t * pNetworkContext );
void * pNetworkContext );

/**
* @brief Retrieves, decodes and stores the Remaining Length from the network
Expand Down Expand Up @@ -799,7 +799,7 @@ static void serializePublishCommon( const MQTTPublishInfo_t * pPublishInfo,
}

static size_t getRemainingLength( TransportRecv_t recvFunc,
NetworkContext_t * pNetworkContext )
void * pNetworkContext )
{
size_t remainingLength = 0, multiplier = 1, bytesDecoded = 0, expectedSize = 0;
uint8_t encodedByte = 0;
Expand Down Expand Up @@ -2561,7 +2561,7 @@ MQTTStatus_t MQTT_DeserializeAck( const MQTTPacketInfo_t * pIncomingPacket,
/*-----------------------------------------------------------*/

MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength( TransportRecv_t readFunc,
NetworkContext_t * pNetworkContext,
void * pNetworkContext,
MQTTPacketInfo_t * pIncomingPacket )
{
MQTTStatus_t status = MQTTSuccess;
Expand Down
13 changes: 9 additions & 4 deletions source/include/core_mqtt.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ typedef struct MQTTContext
*/
TransportInterface_t transportInterface;

/**
* @brief The transport interface context for this MQTT connection.
*/
void * pNetworkContext;

/**
* @brief The buffer used in sending and receiving packets from the network.
*/
Expand Down Expand Up @@ -289,9 +294,9 @@ typedef struct MQTTDeserializedInfo
* MQTTDeserializedInfo_t * pDeserializedInfo
* );
* // Network send.
* int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
* int32_t networkSend( void * pContext, const void * pBuffer, size_t bytes );
* // Network receive.
* int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
* int32_t networkRecv( void * pContext, void * pBuffer, size_t bytes );
*
* MQTTContext_t mqttContext;
* TransportInterface_t transport;
Expand Down Expand Up @@ -360,9 +365,9 @@ MQTTStatus_t MQTT_Init( MQTTContext_t * pContext,
* MQTTDeserializedInfo_t * pDeserializedInfo
* );
* // Network send.
* int32_t networkSend( NetworkContext_t * pContext, const void * pBuffer, size_t bytes );
* int32_t networkSend( void * pContext, const void * pBuffer, size_t bytes );
* // Network receive.
* int32_t networkRecv( NetworkContext_t * pContext, void * pBuffer, size_t bytes );
* int32_t networkRecv( void * pContext, void * pBuffer, size_t bytes );
*
* MQTTContext_t mqttContext;
* TransportInterface_t transport;
Expand Down
6 changes: 3 additions & 3 deletions source/include/core_mqtt_serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,7 @@ MQTTStatus_t MQTT_SerializePingreq( const MQTTFixedBuffer_t * pFixedBuffer );
*
* // TransportRecv_t function for reading from the network.
* int32_t socket_recv(
* NetworkContext_t * pNetworkContext,
* void * pNetworkContext,
* void * pBuffer,
* size_t bytesToRecv
* );
Expand Down Expand Up @@ -1162,7 +1162,7 @@ MQTTStatus_t MQTT_DeserializeAck( const MQTTPacketInfo_t * pIncomingPacket,
*
* // TransportRecv_t function for reading from the network.
* int32_t socket_recv(
* NetworkContext_t * pNetworkContext,
* void * pNetworkContext,
* void * pBuffer,
* size_t bytesToRecv
* );
Expand Down Expand Up @@ -1201,7 +1201,7 @@ MQTTStatus_t MQTT_DeserializeAck( const MQTTPacketInfo_t * pIncomingPacket,
*/
/* @[declare_mqtt_getincomingpackettypeandlength] */
MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength( TransportRecv_t readFunc,
NetworkContext_t * pNetworkContext,
void * pNetworkContext,
MQTTPacketInfo_t * pIncomingPacket );
/* @[declare_mqtt_getincomingpackettypeandlength] */

Expand Down
53 changes: 11 additions & 42 deletions source/interface/transport_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,34 +58,14 @@
* - [Transport Receive](@ref TransportRecv_t)
* - [Transport Send](@ref TransportSend_t)
*
* Each of the functions above take in an opaque context @ref NetworkContext_t.
* Each of the functions above take in an opaque context.
* The functions above and the context are also grouped together in the
* @ref TransportInterface_t structure:<br><br>
* @snippet this define_transportinterface
* <br>
*
* @transportsectionimplementation
*
* The following steps give guidance on implementing the transport interface:
*
* -# Implementing @ref NetworkContext_t<br><br>
* @snippet this define_networkcontext
* <br>
* @ref NetworkContext_t is the incomplete type <b>struct NetworkContext</b>.
* The implemented struct NetworkContext must contain all of the information
* that is needed to receive and send data with the @ref TransportRecv_t
* and the @ref TransportSend_t implementations.<br>
* In the case of TLS over TCP, struct NetworkContext is typically implemented
* with the TCP socket context and a TLS context.<br><br>
* <b>Example code:</b>
* @code{c}
* struct NetworkContext
* {
* struct MyTCPSocketContext tcpSocketContext;
* struct MyTLSContext tlsContext;
* };
* @endcode
* <br>
* -# Implementing @ref TransportRecv_t<br><br>
* @snippet this define_transportrecv
* <br>
Expand All @@ -99,27 +79,28 @@
* <br><br>
* <b>Example code:</b>
* @code{c}
* int32_t myNetworkRecvImplementation( NetworkContext_t * pNetworkContext,
* int32_t myNetworkRecvImplementation( void * pNetworkContext,
* void * pBuffer,
* size_t bytesToRecv )
* {
* int32_t bytesReceived = 0;
* bool callTlsRecvFunc = true;
* NetworkContext_t * pContext = ( NetworkContext_t * ) pNetworkContext;
*
* // For a single byte read request, check if data is available on the network.
* if( bytesToRecv == 1 )
* {
* // If no data is available on the network, do not call TLSRecv
* // to avoid blocking for socket timeout.
* if( TLSRecvCount( pNetworkContext->tlsContext ) == 0 )
* if( TLSRecvCount( pContext->tlsContext ) == 0 )
* {
* callTlsRecvFunc = false;
* }
* }
*
* if( callTlsRecvFunc == true )
* {
* bytesReceived = TLSRecv( pNetworkContext->tlsContext,
* bytesReceived = TLSRecv( pContext->tlsContext,
* pBuffer,
* bytesToRecv,
* MY_SOCKET_TIMEOUT );
Expand Down Expand Up @@ -152,12 +133,13 @@
* <br><br>
* <b>Example code:</b>
* @code{c}
* int32_t myNetworkSendImplementation( NetworkContext_t * pNetworkContext,
* int32_t myNetworkSendImplementation( void * pNetworkContext,
* const void * pBuffer,
* size_t bytesToSend )
* {
* int32_t bytesSent = 0;
* bytesSent = TLSSend( pNetworkContext->tlsContext,
* NetworkContext_t * pContext = ( NetworkContext_t * ) pNetworkContext;
* bytesSent = TLSSend( pContext->tlsContext,
* pBuffer,
* bytesToSend,
* MY_SOCKET_TIMEOUT );
Expand All @@ -179,18 +161,6 @@
* @endcode
*/

/**
* @transportstruct
* @typedef NetworkContext_t
* @brief The NetworkContext is an incomplete type. An implementation of this
* interface must define struct NetworkContext for the system requirements.
* This context is passed into the network interface functions.
*/
/* @[define_networkcontext] */
struct NetworkContext;
typedef struct NetworkContext NetworkContext_t;
/* @[define_networkcontext] */

/**
* @transportcallback
* @brief Transport interface for receiving data on the network.
Expand Down Expand Up @@ -218,7 +188,7 @@ typedef struct NetworkContext NetworkContext_t;
* has occurred.
*/
/* @[define_transportrecv] */
typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
typedef int32_t ( * TransportRecv_t )( void * pNetworkContext,
void * pBuffer,
size_t bytesToRecv );
/* @[define_transportrecv] */
Expand All @@ -240,7 +210,7 @@ typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
* has occurred.
*/
/* @[define_transportsend] */
typedef int32_t ( * TransportSend_t )( NetworkContext_t * pNetworkContext,
typedef int32_t ( * TransportSend_t )( void * pNetworkContext,
const void * pBuffer,
size_t bytesToSend );
/* @[define_transportsend] */
Expand Down Expand Up @@ -288,7 +258,7 @@ typedef struct TransportOutVector
* has occurred.
*/
/* @[define_transportwritev] */
typedef int32_t ( * TransportWritev_t )( NetworkContext_t * pNetworkContext,
typedef int32_t ( * TransportWritev_t )( void * pNetworkContext,
TransportOutVector_t * pIoVec,
size_t ioVecCount );
/* @[define_transportwritev] */
Expand All @@ -303,7 +273,6 @@ typedef struct TransportInterface
TransportRecv_t recv; /**< Transport receive function pointer. */
TransportSend_t send; /**< Transport send function pointer. */
TransportWritev_t writev; /**< Transport writev function pointer. */
NetworkContext_t * pNetworkContext; /**< Implementation-defined network context. */
} TransportInterface_t;
/* @[define_transportinterface] */

Expand Down
4 changes: 2 additions & 2 deletions test/cbmc/include/network_interface_stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
*
* @return Any value from INT32_MIN to INT32_MAX.
*/
int32_t NetworkInterfaceReceiveStub( NetworkContext_t * pNetworkContext,
int32_t NetworkInterfaceReceiveStub( void * pNetworkContext,
void * pBuffer,
size_t bytesToRecv );

Expand All @@ -54,7 +54,7 @@ int32_t NetworkInterfaceReceiveStub( NetworkContext_t * pNetworkContext,
*
* @return Any value from INT32_MIN to INT32_MAX.
*/
int32_t NetworkInterfaceSendStub( NetworkContext_t * pNetworkContext,
int32_t NetworkInterfaceSendStub( void * pNetworkContext,
const void * pBuffer,
size_t bytesToSend );

Expand Down
Loading