The transport interface definition.
Transport Interface Overview
The transport interface is a set of APIs that must be implemented using an external transport layer protocol. The transport interface is defined in transport_interface.h. This interface allows protocols like MQTT and HTTP to send and receive data over the transport layer. This interface does not handle connection and disconnection to the server of interest. The connection, disconnection, and other transport settings, like timeout and TLS setup, must be handled in the user application.
The functions that must be implemented are:
Each of the functions above take in an opaque context NetworkContext_t. The functions above and the context are also grouped together in the TransportInterface_t structure:
typedef struct TransportInterface
{
int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)
Transport interface for receiving data on the network.
Definition: transport_interface.h:221
int32_t(* TransportSend_t)(NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)
Transport interface for sending data over the network.
Definition: transport_interface.h:243
int32_t(* TransportWritev_t)(NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)
Transport interface function for "vectored" / scatter-gather based writes. This function is expected ...
Definition: transport_interface.h:291
struct NetworkContext NetworkContext_t
The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...
Definition: transport_interface.h:191
The transport layer interface.
Definition: transport_interface.h:302
Implementing the Transport Interface
The following steps give guidance on implementing the transport interface:
- Implementing NetworkContext_t
NetworkContext_t is the incomplete type struct NetworkContext. The implemented struct NetworkContext must contain all of the information that is needed to receive and send data with the TransportRecv_t and the TransportSend_t implementations.
In the case of TLS over TCP, struct NetworkContext is typically implemented with the TCP socket context and a TLS context.
Example code: struct NetworkContext
{
struct MyTCPSocketContext tcpSocketContext;
struct MyTLSContext tlsContext;
};
- Implementing TransportRecv_t
void * pBuffer,
size_t bytesToRecv );
This function is expected to populate a buffer, with bytes received from the transport, and return the number of bytes placed in the buffer. In the case of TLS over TCP, TransportRecv_t is typically implemented by calling the TLS layer function to receive data. In case of plaintext TCP without TLS, it is typically implemented by calling the TCP layer receive function. TransportRecv_t may be invoked multiple times by the protocol library, if fewer bytes than were requested to receive are returned.
Example code:
void * pBuffer,
size_t bytesToRecv )
{
int32_t bytesReceived = 0;
bool callTlsRecvFunc = true;
if( bytesToRecv == 1 )
{
if( TLSRecvCount( pNetworkContext->tlsContext ) == 0 )
{
callTlsRecvFunc = false;
}
}
if( callTlsRecvFunc == true )
{
bytesReceived = TLSRecv( pNetworkContext->tlsContext,
pBuffer,
bytesToRecv,
MY_SOCKET_TIMEOUT );
if( bytesReceived < 0 )
{
if( bytesReceived == MY_SOCKET_ERROR_TIMEOUT )
{
bytesReceived = 0;
}
}
}
return bytesReceived;
}
- Implementing TransportSend_t
const void * pBuffer,
size_t bytesToSend );
This function is expected to send the bytes, in the given buffer over the transport, and return the number of bytes sent. In the case of TLS over TCP, TransportSend_t is typically implemented by calling the TLS layer function to send data. In case of plaintext TCP without TLS, it is typically implemented by calling the TCP layer send function. TransportSend_t may be invoked multiple times by the protocol library, if fewer bytes than were requested to send are returned.
Example code:
const void * pBuffer,
size_t bytesToSend )
{
int32_t bytesSent = 0;
bytesSent = TLSSend( pNetworkContext->tlsContext,
pBuffer,
bytesToSend,
MY_SOCKET_TIMEOUT );
if( bytesSent == MY_SOCKET_ERROR_BUFFER_FULL )
{
bytesSent = 0;
}
else if( bytesSent < 0 )
{
}
return bytesSent;
}