MSP430F5529+CC3100物联网测试装置仅响应部分测试网站

物联网 微控制器 无线上网
2021-06-16 02:43:47

最近,我一直在使用 Texas Instrument 的 MSP430F5529 微控制器和 CC3100 网络处理器进行物联网项目。为了进行评估,我使用了 MSP430F5529 发射台和CC3100 助推器我正在尝试让设备连接到云。我已经成功实现了连接到www.openweathermap.org的 CC3100获取天气示例应用程序这是来自CC3100 SDK 示例应用程序的示例该程序成功接收并响应来自www.openweathermap.org网站。应用程序使用 GET 方法从网站发出请求。

我还成功地针对www.mocky.io测试了代码设备收到状态代码 200 OK 响应。但是当我针对requestb.in测试站点进行测试时,我既没有收到 408 超时错误响应代码,也没有收到 302 的 URL 重定向响应代码。

#define WEATHER_SERVER  "api.openweathermap.org"
#define TEST_SERVER  "requestb.in"
//#define TEST_SERVER  "www.mocky.io"

#define PREFIX_BUFFER   "GET /data/2.5/weather?q="
#define POST_BUFFER     "&APPID=xxxxxxxxxxxxxxxxxx&mode=xml&units=imperial HTTP/1.1\r\nHost:api.openweathermap.org\r\nAccept: */"
#define POST_BUFFER2    "*\r\n\r\n"

#define PREFIX_BUFFER_TEST    "GET /1m75pgt1"
#define POST_BUFFER_TEST_1    " HTTP/1.1\r\nHost:requestb.in\r\nAccept: */"
#define POST_BUFFER_TEST_2    "\r\n\r\n"*

//#define PREFIX_BUFFER_TEST      "GET /v2/5967a65d1100007d16b6c2b4"
//#define POST_BUFFER_TEST_1    " HTTP/1.1\r\nHost:www.mocky.io\r\nAccept: */"
//#define POST_BUFFER_TEST_2    "\r\n\r\n"*

下面是主要的,其中包括一些设置条件。为简洁起见,删除了一些错误处理代码。

 int main(int argc, char** argv)
{
    _i32 retVal = -1;

    retVal = initializeAppVariables();
    ASSERT_ON_ERROR(retVal);



    /* Stop WDT and initialize the system-clock of the MCU */
    stopWDT();
    initClk();


    /*
     * Following function configures the device to default state by cleaning
     * the persistent settings stored in NVMEM (viz. connection profiles &
     * policies, power policy etc)
     *
     * Applications may choose to skip this step if the developer is sure
     * that the device is in its default state at start of application
     *
     * Note that all profiles and persistent settings that were done on the
     * device will be lost
     */
    retVal = configureSimpleLinkToDefaultState();


    /*
     * Assumption is that the device is configured in station mode already
     * and it is in its default state
     */
    retVal = sl_Start(0, 0, 0);

    /* Connecting to WLAN AP */
    retVal = establishConnectionWithAP();

    retVal = getCredentials();

    retVal = disconnectFromAP();

    return 0;
}

下面是调用获取数据的getCredentials()代码。

<!-- language: lang-c -->
static _i32 getCredentials()
{
    _i32 retVal = -1;

    pal_Strcpy((char *)g_DeviceData.HostName, TEST_SERVER);

    retVal = getHostIP_Device();

    g_DeviceData.SockID = createConnection();
    ASSERT_ON_ERROR(g_DeviceData.SockID);

    retVal = getData();
    ASSERT_ON_ERROR(retVal);

    retVal = sl_Close(g_DeviceData.SockID);
    ASSERT_ON_ERROR(retVal);

    return 0;
}

下面是我收到错误getdata()函数。

/*!
    \brief This function Obtains the required data from the server

    \param[in]      none

    \return         0 on success, -ve otherwise

    \note

    \warning
*/
static _i32 getData()
{
    _u8 *p_startPtr = NULL;
    _u8 *p_endPtr = NULL;
    _u8* p_bufLocation = NULL;
    _i32 retVal = -1;

    pal_Memset(g_DeviceData.Recvbuff, 0, sizeof(g_DeviceData.Recvbuff));

    /* Puts together the HTTP GET string. */
    p_bufLocation = g_DeviceData.SendBuff;

    pal_Strcpy(p_bufLocation, PREFIX_BUFFER_TEST);
    p_bufLocation += pal_Strlen(PREFIX_BUFFER_TEST);

    pal_Strcpy(p_bufLocation, POST_BUFFER_TEST_1);
    p_bufLocation += pal_Strlen(POST_BUFFER_TEST_1);

    pal_Strcpy(p_bufLocation, POST_BUFFER_TEST_2);

    /* Send the HTTP GET string to the open TCP/IP socket. */
    retVal = sl_Send(g_DeviceData.SockID, g_DeviceData.SendBuff, pal_Strlen(g_DeviceData.SendBuff), 0);
    if(retVal != pal_Strlen(g_DeviceData.SendBuff))
        ASSERT_ON_ERROR(HTTP_SEND_ERROR);

    /* Receive response */
    retVal = sl_Recv(g_DeviceData.SockID, &g_DeviceData.Recvbuff[0], MAX_SEND_RCV_SIZE, 0);
    if(retVal <= 0)
        ASSERT_ON_ERROR(HTTP_RECV_ERROR);

    g_DeviceData.Recvbuff[pal_Strlen(g_DeviceData.Recvbuff)] = '\0';
    return SUCCESS;
}

接入点的安全设置为

#define SEC_TYPE        SL_SEC_TYPE_WPA_WPA2    /* Security type of the Access point */

最后,很少有使用 CC3100 制造的 POC 传感器设备需要将数据传输到云端。为简单起见,我们使用的是 boosterpack,最终我们需要让 POC 传感器设备通过 Wifi 与云通信。

2个回答

不同之处在于 requestb.in 站点需要 HTTP over TLS with SNI

这是一个相当复杂的 HTTP/HTTPS协议和安全问题,可能在 SE 系统的其他地方更好地解决,并且主要涉及您正在测试服务的细节而不是您最终可能要做的任何物联网项目。但只要它留在这里……requestb.in


在端口 80 上尝试 HTTP 时调试 requestb.in 响应代码

你说:

但是当我针对 requestb.in 测试站点进行测试时,我既没有收到 408 超时错误响应代码,也没有收到 302 的 URL 重定向响应代码。

让我们看看发生了什么:

curl -i http://requestb.in/xxxxxxxx
HTTP/1.1 301 Moved Permanently
Location: https://requestb.in/xxxxxxxx

HTTP 状态 301 是“永久移动”,而您期望的 302 有时用于临时重定向。由于他们可能不打算让您在端口 80 上的普通 TCP 套接字上使用 HTTP,因此他们发送永久重定向是更正确的响应。

如果您捕获了 _was_ 发送的状态代码,而不是仅仅列出两个 _were 未发送的状态代码,那将会更有帮助

无论如何,服务器告诉我们必须使用 HTTPS。


那么您需要做什么才能通过 HTTPS 连接到服务器?

在基本层面上,HTTPS 只是意味着通过使用 TLS(或之前的 SSL)保护的连接来传输 HTTP,而不是通过普通的 TCP 套接字进行传输。

您的 CC3100 支持 TLS 和 SSL,并且有一些关于修改 SDK 的 HTTP 客户端示例以通过建立安全通道来执行 HTTPS 连接的最少信息,请访问http://processors.wiki.ti.com/index.php /CC3100_HTTP_Client

然而,在这种情况下requestb.in可能还不够。

如果您要将一个非常简单的 GET 请求通过管道传输到 openssl 的s_client命令中(或在 CC3100 上做同样的事情)

(echo -en "GET /xxxxxxxx HTTP/1.1\nHost: requestb.in\n\n" ; sleep 10) | \
openssl s_client -connect requestb.in:443

sleep这是让 openssl 在输入结束时等待响应而不是挂断)

你会得到一个奇怪的错误:

SSL 例程:SSL23_GET_SERVER_HELLO:sslv3 警报握手失败

您可能认为这与 SSL 与 TLS 版本有关,但实际上是因为requestb.in需要称为Server Name Indication (Wikipedia) 的东西这实际上意味着您需要告诉 SSL 堆栈告诉服务器它应该作为哪个服务器名称进行身份验证。

继续命令行演示,我们只需添加一个-servername参数:

(echo -en "GET /xxxxxxxx HTTP/1.1\nHost: requestb.in\n\n" ; sleep 10) |\
openssl s_client -connect requestb.in:443 -servername requestb.in

如果这是使用有效 requestb.in 实例的 URL 哈希完成的,它会产生一个结果,并在创建该结果的浏览器的日志面板中可见。


在 CC3xxx 上实现服务器名称指示 (SNI)

有些论坛的帖子表明在CC3xxx的TLS实现不支持SNI,而且,有没有具体的计划,以补充这一点; 但是,您可以验证是否仍然如此。

但重要的是要记住,涉及到一棵网络层树:

WiFi
  IP packets
    TCP session
      TLS session
        HTTP protocol

由于 CC3100 允许您使用 TCP(实际上您已经在现有代码中这样做了),您可以自由地“自带”支持 SNI 的 TLS 实现。例如,这篇博文讨论了将mbed TLS(以前称为 PolarSSL)库移植到 CC3xxx 并提到 SNI 作为功能。

TL; 博士

requestb.in是一个具有挑战性的目标,因为它要求您通过 TLS 保护的会话使用 HTTP 并实现Server Name Indication如果与此主机交谈不是您最终项目的一部分,您可能会发现最好直接转到那些主机 - 那些旨在与物联网设备上的最小嵌入式客户端一起使用的主机可能会被配置为使事情变得更容易不使用 SNI。

如果您养成捕获遇到的问题的详细信息的习惯,它也会更有效率 - 嵌入式开发总是难以调试,并且您通过日志记录或调试器捕获的有关故障的信息越少,花在猜测上的时间就越多.

openweathermap.org 和 www.mocky.io 很有可能都支持 http 或 80 端口。以下是一些线索。

openweathermap.org

打开天气图

openweathermap-url

www.mocky.io

嘲讽

模拟网址

看起来 requestb.in 仅支持 HTTPS 或端口 443。

请求输入

请求b

requestb-url

这可能解释了这个问题。以下是一些可能有帮助的参考资料。

在 CC3100 数据表中没有提到使用 HTTPS 的 CC3100。所有引用仅针对 HTTP。这可能更好地解释了这个问题。附在数据表中的除外的下方。

CC3100 - 数据表除外

看起来每个数据表 CC3120 都支持 HTTPS。下面的附件是数据表中的除外。对 HTTPS 的引用很少。

CC3100 - 数据表除外

最有可能的前进道路是用 CC3120 替换 CC3100。

参考: