This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC3235MODSF:Azure 上载到 Blob 不能使用 CA 身份验证

Guru**** 2558250 points
Other Parts Discussed in Thread: CC3235MODSF

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/826725/cc3235modsf-azure-upload-to-blob-not-working-with-ca-authentication

器件型号:CC3235MODSF

我使用具有 Azure IoT Hub 插件的 CC3235MODSF 连接到 Azure IoT Hub、以便将文件上载到 blob 存储并与设备双胞胎同步状态。 我选择了 MQTT 协议、以便可以使用器件的双重属性。 设备双功能在对称密钥身份验证和使用 X.509证书的证书颁发机构身份验证方面都能很好地发挥作用。 问题是,当我使用证书颁发机构身份验证时,上载到 blob 存储失败。

我使用 IoTHubClient_LL_UploadMultipleBlocksToBlobEx 函数启动上载、回调返回 file_upload_error。 同样、这仅在证书颁发机构身份验证时失败。

是否有办法解决此问题,或者 CA 身份验证是否不支持文件上载? 它确实可以在 PC 上与 C#演示配合使用、但 SimpleLink 实现可能不同。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Anthony、

    您能否首先在 Azure 应用程序上启用日志记录、以便更好地了解失败的原因? 这是通过 设置 PROV_OPTION _LOG_TRACE 选项来完成的。 例如:

    bool traceOn =真;
    。
    。
    。
    IoTHubClient_LL_setOption (handle、proV_option_log_trace、traceOn);
    

    此外、您还必须链接插件随附的库的调试版本、例如更改:
    ${COM_TI_Azure_CC32XX_INSTALL_DIR}/source/third_party/azure-iot-pal-simplelink/build_all/pal/lib/ccs/m4/pal_sl_release.a
    至:
    ${COM_TI_Azure_CC32XX_INSTALL_DIR}/source/third_party/azure-iot-pal-simplelink/build_all/pal/lib/ccs/m4/pal_sl_debug.a

    BR、
    Gerardo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我使用的是来自[ https://github.com/TexasInstruments/azure-iot-pal-simplelink](github.com/.../azure-iot-pal-simplelink]的 azure-IoT-PAL-simplelink-3.20.00.02 、其中包含 azure-IoT-SDK-c 版本1.2.14。

    尝试使用 X.509身份验证上载文件时、我会收到以下错误日志。 事件和设备双胞胎按预期工作。

    错误:时间:星期三8月7日19:24:37 2019文件:../../pal/src/httpapi_sl.c 函数:HTTPAPI_ExecuteRequest 行:324 HttpClient_sendRequest 失败、ret=-3003
    错误:时间:星期三8月7日19:24:37 2019文件:../../sdk/c-utility/src/httpapiex.c 函体:HTTPAPIEX_ExecuteRequest 行:475无法恢复发送到工作状态
    错误:时间:星期三8月7日19:24:38 2019文件:../../sdk/iothub_client/src/iothub_client_ll_uploadtoblob.c Func:send_http_Request 行:137无法访问 HTTPAPIEX_ExecuteRequest
    错误:时间:星期三8月7日19:24:38 2019文件:../../sdk/iothub_client/src/iothub_client_ll_uploadtoblob.c Func:IoTHubClient_LL_UploadToBlob_Step1and2 Line:405 Unable to HTTPAPIEX_ExecuteRequest
    错误:时间:星期三8月7日19:24:38 2019文件:../../sdk/iothub_client/src/iothub_client_ll_uploadtoblob.c Func:IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl Line:768 IoTHubClient_LL_UploadToBlob_Step1中出现错误

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Anthony、

    从我们发送请求时的日志中、我们得到的响应无效。 当从服务器接收到的响应不是有效的 HTTP/1.1或 HTTP/1.0响应时,返回错误消息-3003。 您能否在 httpclient.c 的 getStatus()函数的1.1版或1.0版的验证失败部分中设置断点? 并查看从服务器返回的数据是什么?

    谢谢、
    Gerardo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

     当响应无效时,cli->validBufStart 的值显示为空。  调用 SlNetSock_recv 时,CLI_>buf 根本不会被填满。  SlNetSock_recv 返回4。

    使用对称密钥身份验证时、响应为 HTTP/1.1 200正常、符合预期。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Anthony、

     SlNetSock_recv()的返回值使我认为它收到了4个字节的数据,这不是我们所期望的,但可能有助于我们了解错误是什么。  调用 slNetSock_recv()后,您能否在 Variables 视图中查看 cli->buf 的内容并查看前4个字节是什么?

    谢谢、
    Gerardo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    cli->buf 中的前四个字节全部为零。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Anthony、

    您是否可以发布示例代码? 在发布之前、请确保删除您的连接字符串和任何其他机密信息。

    谢谢、
    Gerardo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Anthony、

    这是否得到了解决?

    Todd

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    未解决。 我将在今天发布代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    #include 
    #include 
    
    #include "iothub_client.h"
    #include "iothub_message.h"
    #include "azure_c_shared_utility/threadapi.h"
    #include "azure_c_shared_utility/crt_abstrations.h"
    #include "azure_c_shared_utils/platform.h"
    
    #include "mcert_rom_utils"#include "rom_rom_rom_rom_us.trine.h"#include "rom_rom_rom_ot_rom_us.trus.md小时#include "#include "#include "rom_utils"#包含"rom_rom_ot_rom_rom_ot_rom_rom_rom_utils"#include #include "#include "rom_ot_rom_rom_rom_ot_rom_rom_us.trus"#include #include "ine"#
    
    
    
    
    
    
    
    
    #define Azure_IOT root_CA_filename "/cert/ms.pem
    #define X509_CERT "/cert/device_cert.pem
    #define X509_key "/cert/device_key.pem
    
    静态 const char* connectionString ="hostname=MyHostName.azure-devices.net;DeviceId=MyDeviceName;x509=true";
    
    静态 int callbackCounter;
    静态 char msgText[1024];
    静态 char propText[1024];
    静态 bool g_continueRunning;
    #define MESSAGE_COUNT 5
    #define DOWORK_LOOP_NUM 3
    
    typedef 结构体 event_instance_tag
    {
    IOTHUB_MESSAGE_Handle 消息 Handle;
    size_t messageTrackingId;//用于跟踪用户回调中的消息。
    } event_instance;
    
    static int block_count = 0;
    static int file_offset = 0;
    static int file_size = 0;
    
    #define MAX_BYTES 256
    
    unsigned char dataBuf[MAX_Bytes];
    
    //#define overwrite_Certs
    #ifdef overwrite_Certs
    static bool overwriteCerts = true;
    #else
    static bool overwriteCerts = dif= f*;= f=#def=#define=/=#def=#define
    
    
    
    FlashFile ====
    *使用 SimpleLink WiFi API 将文件刷写到 SFLASH
    *
    *返回成功写入的字节数或失败时写入的字节数*
    /
    int FlashFile (const char * path、const uint8_t * buffer、uint32_t len)
    {
    int32_t ret =-1;
    int32_t fileHandle;
    
    if (路径&&缓冲器){
    fileHandle = sl_FsOpen ((unsigned char *) path、
    SL_FS_create | SL_FS_CREATE_SECURE | SL_FS_CREATE_NOSIGNATURE
    | SL_FS_CREASE_PUBLICE_WRITE | SL_FS_OVERWRITE
    | sl_FS_CREASE_MAX_SIZE (len)、NULL);
    if (fileHandle > 0){
    RET = sl_FsWrite (fileHandle、0、(unsigned char *) buffer、len);
    sl_FsClose (fileHandle、NULL、0);
    }
    }
    
    返回(RET);
    }
    
    /*
    ==== 闪存证书====
    *将缓冲区的内容(PEM 格式)刷写到
    CertName 指定的*文件名/路径
    中
    的实用程序函数* void flashCerts (uint8_t * CertName、uint8_t * buffer、uint32_t bufflen)
    {
    INT STATUS = 0;
    int16_t slStatus = 0;
    slfsFileInfo_t fsFileInfo;
    
    /*检查证书文件是否已存在*/
    slStatus = sl_FsGetInfo (CertName、0、&fsFileInfo);
    
    /*如果证书不存在,请将其写入(或在指定时覆盖)*/
    if (slStatus = sl_error_fs_file_no_exists || overwriteCerts = true){
    
    printf ("正在刷写证书文件...");
    
    状态= FlashFile (((const char *) CertName、buffer、bufflen);
    
    如果(状态< 0){
    printf ("错误:无法将文件%s 写入闪存(%d)\n"、
    CertName,status);
    while (1);
    }
    printf ("已成功将文件%s 写入闪存\n"、CertName);
    }
    }
    
    静态 IOTHUB_CLIENT_FILE_LOAD_GET_DATA_RESULT getDataCallback (IOTHUB_CLIENT_FILE_LOAD_RESULT 结果、无符号字符 const **数据、size_t*大小、void*上下文)
    {
    uint32_t length = 0;
    
    (无效)上下文;
    如果(结果= file_upload_OK)
    {
    if (data!= NULL && size!= NULL)
    {
    length =(file_size - file_offset > MAX_Bytes)? max_bytes:file_size - file_offset;
    
    如果(长度==0)
    {
    //将数据设置为 NULL 和/或将大小设置为零表示上载已完成。
    *数据=空;
    *大小= 0;
    
    (void) printf ("表示上载已完成(%d 块已上载)\r\n"、block_count);
    }
    其他
    {
    对于(int i = 0;i < length;i++)
    {
    dataBuf[i]= i;
    }
    
    *data =(const unsigned char*)&dataBuf;
    *大小=长度;
    block_count++;
    file_offset += length;
    
    (void) printf ("上载%d 个字节的%d\r\n"、file_offset、file_size);
    }
    }
    其他
    {
    //对该回调的最后一次调用是为了表示上载先前提供的数据块的结果。
    //注意:在最后一次调用中,数据和大小指针为 NULL。
    
    (void) printf ("对 getDataCallback 的最后一次调用(上传%DTH 块的结果:%s)\r\n"、block_count、enum_To_string (IOTHUB_client_file_upload_result、result));
    }
    }
    其他
    {
    (void) printf ("接收到意外结果%s\r\n、enum_To_string (IOTHUB_client_file_upload_result、result));
    }
    
    //此回调返回 IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_OK 以指示上载应继续。
    //要中止上载,应返回 IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_ABORT
    返回 IOTHUB_CLIENT_file_upload_get_data_OK;
    }
    
    静态 int deviceMethodCallback (const char* method_name、const unsigned char* payload、size_t size、unsigned char** Response、size_t* Response_size、void* userContextCallback)
    {
    (空) userContextCallback;
    (无效)有效载荷;
    (空)大小;
    
    INT 结果;
    
    if (strcmp ("restart"、method_name)=0)
    {
    const char deviceMethodResponse[]="{\"Response\":\"重新启动\"}";
    *RESPONSE_SIZE = sizeof (deviceMethodResponse)-1;
    *RESPONSE = malloc (*RESPONSE_SIZE);
    (void) memcpy (*响应、deviceMethodResponse、*响应_size);
    结果= 200;
    printf ("设备重新启动\r\n");
    }
    其他
    {
    //忽略所有其它条目。
    const char deviceMethodResponse[]="{}";
    *RESPONSE_SIZE = sizeof (deviceMethodResponse)-1;
    *RESPONSE = malloc (*RESPONSE_SIZE);
    (void) memcpy (*响应、deviceMethodResponse、*响应_size);
    结果=-1;
    }
    
    返回结果;
    }
    
    静态 IOTHUBMESSAGE_OPT_RESPULSE_Result ReceiveMessageCallback (IOTHUB_MESSAGE_Handle 消息、void* userContextCallback)
    {
    INT_COUNTER =(int*) userContextCallback;
    const char* buffer;
    size_t size;
    map_handle mapProperties;
    const char* MessageID;
    const char* correlationId;
    
    //消息属性
    if ((MessageID = IoTHubMessage_GetMessageId (message))= NULL)
    {
    MessageID =" ";
    }
    
    if ((correlationId = IoTHubMessage_GetCorrelationId (message))= NULL)
    {
    相关关系 ID =" ";
    }
    
    //消息内容
    if (IoTHubMessage_GetByteArray (message、(const unsigned char**)&buffer、&size)!= IOTHUB_MESSAGE_OK)
    {
    (void) printf ("无法检索消息数据\r\n);
    }
    其他
    {
    (void) printf ("已接收消息[%d]\r\n 消息 ID:%s\r\n 关联 ID:%s\r\n 数据:<<<<%.*s>>& size=%d\r\n"、*计数器、MessageID、相关关系 ID、(int)size、 缓冲器、(int)大小);
    //如果收到工作'quit',则停止运行
    if (size =(strlen ("quit")* sizeof (char))&& memcmp (buffer、"quit"、size)= 0)
    {
    G_continueRunning = false;
    }
    }
    
    //从消息检索属性
    mapProperties = IoTHubMessage_Properties (message);
    if (mapProperties!= NULL)
    {
    const char*const*键;
    const char*const*值;
    size_t propertyCount = 0;
    if (Map_GetInternals (mapProperties、&keys、&values、&propertyCount)== map_OK)
    {
    如果(propertyCount >0)
    {
    size_t 索引;
    
    printf ("消息属性:\r\n");
    对于(index = 0;index < propertyCount;index++)
    {
    (空) printf ("\tKey:%s 值:%s\r\n、keys[index]、values[index]);
    }
    (void) printf ("\r\n");
    }
    }
    
    
    /*此处提供了一些特定于器件的操作代码... *
    (*计数器)++;
    返回 IOTHUBMESSAGE_ACCEPTED;
    }
    
    静态 void deviceTwinCallback (device_TWIN_UPDATE_STATE UPDATE_STATE、const unsigned char* payload、size_t size、void* userContextCallback)
    {
    printf ("接收到的设备双回调:%s\r\n、有效载荷);
    
    (空) update_state;
    (空)大小;
    (空) userContextCallback;
    }
    
    静态空 SendConfirmationCallback (IOTHUB_CLIENT_CONFIRMATION_RESULT RESULT RESULT RESULT RESULT RESULT RESULT RESULT RESULT RESULT RESULT RESULT RESULT RES
    
    event_instance* eventInstance=(event_instance*) userContextCallback;
    size_t id = eventInstance->messageTrackingId;
    
    (void) printf ("已收到消息跟踪 ID 的确认[%d]=%d、结果=%s\r\n "、callbackCounter、(int) id、enum_TO_string (IOTHUB_CLIENT_CONFIRMATION_RESULT、RESULT));
    /*此处提供了一些特定于器件的操作代码... *
    callbackCounter++;
    IoTHubMessage_Destroy (eventInstance->messageHandle);
    }
    
    void ioithub_client_sample_MQTT_run (void)
    {
    IOTHUB_CLIENT_LL_Handle iotHubClientHandle;
    
    事件实例消息[message_count];
    
    G_ContinueRunning = true;
    srand( unsigned int)time(NULL);
    double avgWindSpeed = 10.0;
    双微温度= 20.0;
    双微湿度= 60.0;
    
    callbackCounter = 0;
    int receiveContext = 0;
    
    /*闪存证书文件*/
    flashCerts (((uint8_t *) Azure、IOT、root_ca_filename、(uint8_t *)证书、
    strlen (certificates));
    
    #ifdef certificate_AUTH
    /*刷写客户端证书*/
    /*
    需要*-1以避免在 PEM 末尾闪烁 NULL 字符
    *字符串。
    *
    flashCerts (((uint8_t *) x509_CERT、client_cert_pem、
    client_cert_pem_len - 1);
    
    /*刷写私钥*/
    /*
    需要*-1以避免在 PEM 末尾闪烁 NULL 字符
    *字符串。
    *
    flashCerts (((uint8_t *) x509_key、client_private_key_pem、
    client_private_key_pem_len - 1);
    #endif // certificate_AUTH
    
    if (platform_init()!= 0)
    {
    (void) printf ("初始化平台失败。\r\n");
    }
    其他
    {
    if (((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString (connectionString、MQTT_Protocol))= NULL)
    {
    (空) printf ("错误:iotHubClientHandle 为 NULL!\r\n");
    }
    其他
    {
    bool traceOn =真;
    IoTHubClient_LL_setOption (iotHubClientHandle、option_log_trace、traceOn);
    
    #ifdef certificate_AUTH
    if (((IoTHubClient_LL_setOption (iotHubClientHandle、option_X509_CERT、X509_CERT)!= IOTHUB_CLIENT_OK)||
    (IoTHubClient_LL_setOption (iotHubClientHandle、option_X509_private_key、X509_key)!= IOTHUB_CLIENT_OK)
    {
    (void) printf ("未能为 x509设置选项、中止\r\n);
    }
    其他
    {
    #endif // certificate_AUTH
    
    
    (空) IoTHubClient_LL_SetDeviceMethodCallback (iotHubClientHandle、deviceMethodCallback、NULL);
    (空) IoTHubClient_LL_SetDeviceTwinCallback (iotHubClientHandle、deviceTwinCallback、NULL);
    
    /*设置消息回拨,以便我们可以接收命令。 *
    if (IoTHubClient_LL_SetMessageCallback (iotHubClientHandle、ReceiveMessageCallback、&receiveContext)!= IOTHUB_CLIENT_OK)
    {
    (空) printf (“错误:IoTHubClient_LL_SetMessageCallback ......... 失败!\r\n");
    }
    其他
    {
    (空) printf ("IoTHubClient_LL_SetMessageCallback...成功。\r\n");
    
    (void) printf ("正在开始上传文件...\r\n");
    
    file_size = 4096;
    file_offset = 0;
    
    if (IoTHubClient_LL_UploadMultipleBlocksToBlobEx (iotHubClientHandle、(const char*)"upload_test.bin"、getDataCallback、NULL)!= IOTHUB_CLIENT_OK)
    {
    (void) printf ("数据文件上传失败\n");
    }
    其他
    {
    (void) printf ("数据文件已创建\n"\n);
    }
    
    /*现在我们已准备好接收命令,接下来我们发送一些消息*/
    int 迭代器= 0;
    双温度= 0;
    双湿度= 0;
    操作
    {
    if (迭代器< message_count)
    {
    温度= minTemperature +(rand()% 10);
    湿度=微湿度+(rand()% 20);
    sprintf_s (msgText、sizeof (msgText)、"{\"deviceId\":\"、\" windSpeed\":%.2f、\" temperature\":%.2f、\"湿度\":%.2f}"、avgWindSpeed +(rand (%)、湿度+ 4)、湿度+温度
    if ((messages[iter].messageHandle = IoTHubMessage_CreateFromByteArray ((const unsigned char*) msgText、strlen (msgText)))= NULL)
    {
    (void) printf ("错误:iotHubMessageHandle 为 NULL!\r\n");
    }
    其他
    {
    
    (空) IoTHubMessage_SetMessageId (messages[iter].messageHandle、"MSG_ID");
    (空) IoTHubMessage_SetCorrelationId (messages[iter].messageHandle、"core_ID");
    
    messages[iterator].messageTrackingId =迭代器;
    map_handle propMap = IoTHubMessage_Properties (messages[iter].messageHandle);
    (void) sprintf_s (propText、sizeof (propText)、温度> 28? "true":"false");
    if (Map_AddOrUpdate (propMap、"temperatureAlert"、propText)!= map_OK)
    {
    (void) printf ("错误:map_AddOrUpdate 失败!\r\n");
    }
    
    if (IoTHubClient_LL_SendEventAsync (iotHubClientHandle、messages[iter].messageHandle、SendConfirmationCallback、&messages[iter])!= IOTHUB_CLIENT_OK)
    {
    (空) printf (“错误:IoTHubClient_LL_SendEventAsync ......... 失败!\r\n");
    }
    其他
    {
    (空) printf ("IoTHubClient_LL_SendEventAsync 可接受消息[%d]、用于传输到物联网集线器。\r\n"、(int)迭代器);
    }
    }
    迭代器++;
    }
    IoTHubClient_LL_DoWork (iotHubClientHandle);
    
    ThreadAPI_SLEEP (1);
    
    } while (g_continueRunning);
    
    (void) printf ("iothub_client_sample_mqTT 已获得退出消息、请调用 DoWork %d 更多时间来完成最终发送...\r\n"、DOWORK_LOOP_NUM);
    size_t 索引= 0;
    对于(INDEX = 0;INDEX < DOWORK_LOOP_NUM;index++)
    {
    IoTHubClient_LL_DoWork (iotHubClientHandle);
    ThreadAPI_SLEEP (1);
    }
    }
    #ifdef certificate_AUTH
    }
    #endif // certificate_AUTH
    IoTHubClient_LL_Destroy (iotHubClientHandle);
    }
    platform_deinit();
    }
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Anthony、

    我能够再现您的代码问题、我将进一步调查并报告我发现的问题。

    此致、
    Gerardo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Anthony、

    Gerardo 正在度假、下周结束时他将回来。

    Todd

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Anthony、

    只是想让您了解一下它的状态。 我一直在进行一些调试、并且能够找到有关发生这种情况的更多信息、问题是我们在握手完成后收到 TLS 握手问候请求消息、如下所示:

    来自网络的输入(69字节)
    0000:1603 00 40 BD 0e 86 A4 D8 F9 d6 f0 6e D7 BA....@… N.
    0010:10 61 0f be 71 93 C6 8b ea 17 61 55 0f 1e f0 c0 .a.q A..
    0020:80 a0 CD 8e 6F 2a A9 9c 7c E6 B6 A8 31 3f 65 40……o*……1?e@
    0030:61 0c 5c 61 77 9f 77 5b 9f C8 20 97 AC 63 5a 8f a\aw.w[..CZ。
    0040:5F F1 B2 0A 2c _...、

    解密后的输入有效载荷(4字节)
    0000:00 00 00 00

    这就是导致错误的原因。 由于握手已经成功完成、我仍在努力弄清楚为什么我们甚至会收到此消息。  

    此致、
    Gerardo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Anthony、

    我们了解了导致问题的原因、当我们连接到 Azure 服务器时、它们在初始握手期间不会对我们进行身份验证。 然后、握手完成后、我们发出第一个请求、他们将尝试触发另一个 TLS 握手、以便对我们进行身份验证。 现在、我们将咨询 NWP 专家、了解 CC32XX 当前是否支持 TLS 重新协商、这正是解决此问题所需的。

    感谢您的耐心等待、
    Gerardo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Gerardo、

    感谢您对此进行深入研究。 希望有一个好的解决方案。

    Anthony

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Anthony、

    遗憾的是、由于硬件限制、WiFi 堆栈不支持 TLS 重新协商、因此目前我们无法支持此功能。 我在内部提交了一个错误以跟踪此情况、您可以通过错误 ID AZUREIOT-64来引用它。

    此致、
    Gerardo