尊敬的 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()状态机报告 RecvChunkSize 为0,因此不会从 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);
}
}