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.

[参考译文] CC3120:状态机中可能存在的 OTA 库错误

Guru**** 2539500 points
Other Parts Discussed in Thread: CC3120

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

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/758912/cc3120-possible-ota-library-bug-in-state-machine

器件型号:CC3120

尊敬的 TI:

我相信我在 SimpleLink SDK WiFi 插件2.30.00.10捆绑包中提供的 OTA 库源中发现了一个错误。
源文件 ota_httpclient.c 中的函数 HttpClient_RecvSkipHdr ()相关的问题似乎仅在返回缓冲区中出现 http 标头边界的罕见情况下发生。

HttpClient_RecvSkipHdr(),正如名称所示,假设要去除 http 响应的标头,只返回(部分内容)内容。

但是,如果通过内部调用 HttpClient_Recv (),只在一个 sl_Recv ()调用中从 CC3120检索标头,即返回到"\r\n\r\n"标头边界的数据,则会发生错误。

HttpClient_RecvSkipHdr()将向 OTA_RUN()状态机报告 RecvChunkSize0,因此不会从 OTA_State_Prepare_downloading 状态进展 OTA_State_Downloading 状态。 如果在 HttpClient_Recv()调用中接收到标头后至少有一个字节,则不会发生此问题。

出于我们的目的、我已将 OTA_lib.c 的第468行从"0 >="更改为"0 >"、但这可能不是最佳解决方案。  

所连接的是中的违规函数 。

int16_t HttpClient_RecvSkipHdr (int16_t SockId、
uint8_t *响应 Buf、
Int16_t RespBufSize、
uint32_t * contentLen)
{
int16_t Len;
int32_t 重试= 0;
uint8_t *pBuf;
uint8_t *pEndBuf;
uint8_t *pEndOfContentLen;
uint8_t * pStartOfContentLen;
int16_t ProcesedBytes;

Len = HttpClient_Recv (SockId、pRespBuf、RespBufSize、0、MAX_EAGAIN_retries);
如果(Len < 0)
{
_slOtaLibTraceTM (
"HttpClient_RecvSkipHdr:错误 HttpClient_Recv、status=%ld \r\n、
len);
return (len);
}

/*选中"HTTP/1.1 200"的位置*/
if (len < HTTP_HEADER_MIN_SIZE)
{
_SlOtaLibTrace (("HttpClient_RecvSkipHdr:错误头长度、len=%d\r\n"、
len);
return (ota_http_client_error_resp_hdr_size);
}

/*检查 HTTP 成功*/
if (strncmp (http_header_OK、
(const char *)&pRespBuf[HTTP_HEADER_MIN_SIZE - 3]、3)
{
pRespBuf[HTTP_HEADER_MIN_SIZE]= 0;//仅用于打印*/
_SlOtaLibTrace ("HttpClient_RecvSkipHdr:HTTP 错误代码%s\r\n、
(答复者 f);
返回(OTA_HTTP_CLIENT_ERROR_RESP_STATUS_NOT_OK);
}
pEndBuf = pRespBuf + Len;
pBuf =&pRespBuf[HTTP_HEADER_MIN_SIZE];

/*查找响应结束标头*/
while (1)
{
while ((pEndBuf - pBuf)>=4)
{
/*搜索 CR+LF+CR+LF */
if (strncmp ((const char *) pBuf、"\r\n\r\n"、4)==0)
{
int16_t newSize;
pBuf += 4;
/*现在附加一些数据*/
ProcesedBytes = pBuf - pRespBuf;
/* FIXME:如果 newSize = 0,则调用另一个 HttpClient_RecvAppend()*/ 
newSize = len - ProcesedBytes;
memcpy (pRespBuf、pBuf、newSize);
memset (pRespBuf + newSize、0、ProcesedBytes);
return (newSize);
}

/*搜索 CR+LF */
if (strncmp ((const char *) pBuf、"\r\n"、CRLF_STR_LEN)==0)
{
/*检查来电者是否对"Content-Length "标头的值感兴趣*/
if (contentLen!=空)
{
/*此时 pBuf + CRLF 长度将是标头的开头*/
/*检查此标头是否为"Content-Length (内容长度)"*/
if (strncmp ((const char *) pBuf + CRLF_STR_LEN、
"content-Length "、content_length_STR_LEN)==0)
{
/*找到内容长度标头,解析其值。 *
/* HTTP 标头格式为字段名“:”[字段值] CR+LF */

/*查找下一个 CR+LF ("内容长度"字段值的末尾)*/
/*指向字段值的开头并搜索其结尾(+1表示跳过“:”)*/
pStartOfContentLen = pBuf + CRLF_STR_LEN +
content_length_STR_LEN + 1;
pEndOfContentLen = pStartOfContentLen;

while (strncmp ((const char *) pEndOfContentLen、"\r\n"、
CRLF_STR_LEN)!= 0)
{
pEndOfContentLen += 1;
}

/*将"content-length"值从十进制字符串转换为 int */
* contentLen =(int) strtol (
(const char *) pStartOfContentLen、
(char **)&pEndOfContentLen、decimed_base);
}
}


pBuf += 1;/*仅跳过两个字节*/
}

/*数据包结束,尝试重新接收新数据包*/
ProcesedBytes = pBuf - pRespBuf;
/* FIXME:如果 pRespBuf 以"\r\n\r\n"终止、则 newSize 将计算为零*/ 
Len = HttpClient_RecvAppend (SockId、pRespBuf、RespBufSize、Len、
程序字节);
if (Len <= 0)
{
_slOtaLibTraceTM (
"HttpClient_RecvSkipHdr:错误 HttpClient_Recv、status=%ld \r\n、
len);
return (len);
}
pEndBuf = pRespBuf + Len;
pBuf = pRespBuf;

if (Retry++> HTTP_MAX_retries)
{
_slOtaLibTraceTM (
"HttpClient_RecvSkipHdr:最大重试头的搜索结束\r\n);
返回(OTA_HTTP_CLIENT_ERROR_RESP_HDR_END_NOT_FOUND);
}
}

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

    你是对的。 我们以前有其他用户报告过这种情况。

    e2e.ti.com/.../699513

    我们提交了一个 TT 进行更正、但您所做的是正确的。

    感谢您指出这一点!

    Jesu