传输接口
简介
coreMQTT 和 coreHTTP 不依赖于任何特定的 TCP/IP 堆栈。 因此,您需提供传输接口结构体才能使用 coreMQTT 或 coreHTTP 库。传输接口的实例包含在单个网络连接上发送和接收数据所需的函数指针和上下文数据。FreeRTOS 发行版包括传输接口的示例实现,您可在您的应用程序中使用此实现。
自定义实现
如果示例实现与底层网络或 TLS 堆栈不匹配,则应用程序可提供自身的传输接口实现。一个实现包含两个部分。第一部分是包装底层数据流(例如,套接字句柄或 TLS 上下文)的网络上下文数据结构体的定义。第二部分是一对可在网络上下文中发送和接收数据的函数——这两个函数只包装在具有传输接口结构体所需原型的函数中,您已经用来发送和接收函数的网络。 下文展示了一个有效示例。
传输接口结构体定义如下:
struct NetworkContext;
typedef struct NetworkContext NetworkContext_t;
typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
void * pBuffer,
size_t bytesToRecv );
typedef int32_t ( * TransportSend_t )( NetworkContext_t * pNetworkContext,
const void * pBuffer,
size_t bytesToSend );
typedef struct TransportOutVector
{
const void * iov_base;
size_t iov_len;
} TransportOutVector_t;
typedef int32_t ( * TransportWritev_t )( NetworkContext_t * pNetworkContext,
TransportOutVector_t * pIoVec,
size_t ioVecCount );
typedef struct TransportInterface
{
TransportRecv_t recv; /* Receive function (see above) */
TransportSend_t send; /* Send function (see above) */
TransportWritev_t writev; /* Writev function (see above) */
NetworkContext_t * pNetworkContext; /* Network context (see above) */
} TransportInterface_t;
传输接口结构体
有效示例
本示例介绍了如何创建适用于 FreeRTOS-Plus-TCP 堆栈的传输接口
(此示例仅作演示之用,FreeRTOS 源代码下载文件已包含适用于 FreeRTOS-Plus-TCP 的传输接口)。 为简单起见,此示例是使用没有 TLS 或其它加密形式的 TCP
。 IoT 生产设备应始终使用加密
连接,而且 FreeRTOS 下载文件中包含使用
带 TLS 堆栈的 FreeRTOS-Plus-TCP 的传输接口。
起点
在创建网络传输接口前,请务必确保您的应用程序可以
成功发送和接收网络上的数据——
如此一来,传输接口仅包装已在运行的发送和接收函数
。
定义 NetworkContext 结构体
FreeRTOS-Plus-TCP 套接字
存储在 Socket_t 类型的变量中。 因此,NetworkContext 结构体
可定义为:
struct NetworkContext
{
Socket_t tcpSocket;
};
定义仅包含 FreeRTOS-Plus-TCP 套接字的 NetworkContext 结构体。
实现发送和接收包装器
接下来,FreeRTOS-Plus-TCP
发送和
接收函数需要
由具有传输接口发送和接收函数所需的原型的函数来包装
。 下述示例还演示了如何
从 NetworkContext 参数中获取发送和接收函数使用的套接字:
int32_t transport_recv( NetworkContext_t * pNetworkContext,
void * pBuffer,
size_t bytesToRecv )
{
int32_t socketStatus = 1;
if( bytesToRecv == 1 )
{
socketStatus = ( int32_t ) FreeRTOS_recvcount( pPlaintextTransportParams->tcpSocket );
}
if( socketStatus > 0 )
{
socketStatus = FreeRTOS_recv( pNetworkContext->tcpSocket, pBuffer, bytesToRecv, 0 );
}
return socketStatus;
}
int32_t transport_send( NetworkContext_t * pNetworkContext,
const void * pBuffer,
size_t bytesToSend )
{
int32_t socketStatus;
socketStatus = FreeRTOS_send( pNetworkContext->tcpSocket, pBuffer, bytesToSend, 0 );
if( socketStatus == -pdFREERTOS_ERRNO_ENOSPC )
{
socketStatus = 0;
}
return socketStatus;
}
实现适用于 FreeRTOS-Plus-TCP 的传输发送和接收函数
填充 TransportInterface_t 结构体
最后,下述代码显示了如何
用
NetworkContext 结构体,以及上文定义的
transport_send () 和
transport_recv () 函数填充传输接口结构体的过程:
void init_transport_from_socket( Socket_t tcpSocket,
NetworkContext_t * pNetworkContext,
TransportInterface_t * pTransport )
{
pNetworkContext->tcpSocket = tcpSocket;
pTransport->recv = transport_recv;
pTransport->send = transport_send;
pTransport->writev = NULL;
pTransport->pNetworkContext = pNetworkContext;
}
定义 transport_interface.h 中声明的网络上下文
示例实现
包括明文通信和 TLS 通信示例。我们强烈建议生产应用程序使用 TLS 进行通信。正如 MQTT TLS 演示所展示的那样,它所提供的传输接口经过身份验证,并被加密过。
FreeRTOS 下载文件中所包含的传输接口实现被拆分为两份文件,一份是 TCP 堆栈专用的包装器 C 文件,另一份是专门针对所选 TCP 堆栈和 TLS 堆栈一起使用情况的 C 补充文件。 例如,若想要一同使用 FreeRTOS-Plus-TCP 和 mbedTLS,请从源代码分发中的 network_transport/freertos_plus_tcp 目录构建 sockets_wrapper.c,然后从 using_mbedtls 子目录构建 using_mbedtls.c。
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.