1、问题点:当RCU网络状态异常的情况下,网络还处于协商状态下,还未进入正常通讯环节时,取电变化不会进行判断。这会导致取电变化上报与实际产生取电状态时间点对不上。 2、将BLV_C1F_Module代码上传至Gitea,之前代码修改记录请查看 .\BasicCode\Readme.txt
449 lines
15 KiB
C
449 lines
15 KiB
C
#include "DNS.h"
|
||
#include "CH57xNET.H"
|
||
#include "DBG.h"
|
||
|
||
#define CH57xNET_DBG 1
|
||
/* 变量定义 */
|
||
UINT8 DNS_SERVER_IP[4]={223,5,5,5}; /* DNS服务器1 */
|
||
UINT8 DNS_SERVER_IP2[4]={114,114,114,114}; /* DNS服务器2 */
|
||
#define IPPORT_DOMAIN 53 /* DNS默认端口 */
|
||
UINT16 MSG_ID = 0x1100; /* 标识 */
|
||
//UINT32 count = 0;
|
||
//UINT8 dns_buf[MAX_DNS_BUF_SIZE];
|
||
UINT8* dns_buf = NULL;
|
||
|
||
//UINT8 url_dn4[] = "www.boonlive-rcu.com";
|
||
/*******************************************************************************
|
||
* Function Name : get16
|
||
* Description : 将缓冲区UINT8数据转为UINT16格式数据
|
||
* Input : s -UINT8类型数据
|
||
* Output : None
|
||
* Return : 转化后的UINT16类型数据
|
||
*******************************************************************************/
|
||
UINT16 get16(UINT8 * s)
|
||
{
|
||
UINT16 i;
|
||
|
||
i = *s++ << 8;
|
||
i = i + *s;
|
||
return i;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* Function Name : ParseName
|
||
* Description : 分析完整的域名
|
||
* Input : msg -指向报文的指针
|
||
compressed -指向报文中主域名的指针
|
||
buf -缓冲区指针,用于存放转化后域名
|
||
* Output : None
|
||
* Return : 压缩报文的长度
|
||
*******************************************************************************/
|
||
int ParseName(UINT8 * msg, UINT8 * compressed, char * buf)
|
||
{
|
||
UINT16 slen; /* 当前片段长度*/
|
||
UINT8 * cp;
|
||
int clen = 0; /* 压缩域名长度 */
|
||
int indirect = 0;
|
||
int nseg = 0; /* 域名被分割的片段总数 */
|
||
|
||
cp = compressed;
|
||
for (;;){
|
||
slen = *cp++; /* 首字节的计数值*/
|
||
if (!indirect) clen++;
|
||
if ((slen & 0xc0) == 0xc0){ /* 计数字节高两比特为1,用于压缩格式 */
|
||
if (!indirect) clen++;
|
||
indirect = 1;
|
||
cp = &msg[((slen & 0x3f)<<8) + *cp]; /* 按计数字节数值指针偏移到指定位置 */
|
||
slen = *cp++;
|
||
}
|
||
if (slen == 0) break; /* 计数为0,结束 */
|
||
if (!indirect) clen += slen;
|
||
while (slen-- != 0) *buf++ = (char)*cp++;
|
||
*buf++ = '.';
|
||
nseg++;
|
||
}
|
||
if (nseg == 0){
|
||
/* 根域名; */
|
||
*buf++ = '.';
|
||
}
|
||
*buf++ = '\0';
|
||
return clen; /* 压缩报文长度 */
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* Function Name : DnsQuestion
|
||
* Description : 分析响应报文中的问题记录部分
|
||
* Input : msg -指向响应报文的指针
|
||
cp -指向问题记录的指针
|
||
* Output : None
|
||
* Return : 指向下一记录的指针
|
||
*******************************************************************************/
|
||
UINT8 * DnsQuestion(UINT8 * msg, UINT8 * cp)
|
||
{
|
||
int len;
|
||
char name[MAX_DNS_BUF_SIZE];
|
||
|
||
len = ParseName(msg, cp, name);
|
||
cp += len;
|
||
cp += 2; /* 类型 */
|
||
cp += 2; /* 类 */
|
||
return cp;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* Function Name : DnsAnswer
|
||
* Description : 分析响应报文中的回答记录部分
|
||
* Input : msg -指向响应报文的指针
|
||
cp -指向回答记录的指针
|
||
psip
|
||
* Output : None
|
||
* Return :指向下一记录的指针
|
||
*******************************************************************************/
|
||
UINT8 * DnsAnswer(UINT8 * msg, UINT8 * cp, UINT8 * pSip)
|
||
{
|
||
int len, type;
|
||
char name[MAX_DNS_BUF_SIZE];
|
||
|
||
len = ParseName(msg, cp, name);
|
||
cp += len;
|
||
type = get16(cp);
|
||
cp += 2; /* 类型 */
|
||
cp += 2; /* 类 */
|
||
cp += 4; /* 生存时间 */
|
||
cp += 2; /* 资源数据长度 */
|
||
switch ( type ){
|
||
case TYPE_A:
|
||
pSip[0] = *cp++;
|
||
pSip[1] = *cp++;
|
||
pSip[2] = *cp++;
|
||
pSip[3] = *cp++;
|
||
break;
|
||
case TYPE_CNAME:
|
||
case TYPE_MB:
|
||
case TYPE_MG:
|
||
case TYPE_MR:
|
||
case TYPE_NS:
|
||
case TYPE_PTR:
|
||
len = ParseName(msg, cp, name);
|
||
cp += len;
|
||
break;
|
||
case TYPE_HINFO:
|
||
case TYPE_MX:
|
||
case TYPE_SOA:
|
||
case TYPE_TXT:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return cp;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* Function Name : parseMSG
|
||
* Description : 分析响应报文中的资源记录部分
|
||
* Input : msg -指向DNS报文头部的指针
|
||
cp -指向响应报文的指针
|
||
* Output : None
|
||
* Return :成功返回1,否则返回0
|
||
*******************************************************************************/
|
||
|
||
UINT8 parseMSG(struct dhdr * pdhdr, UINT8 * pbuf, UINT8 * pSip)
|
||
{
|
||
UINT16 tmp;
|
||
UINT16 i;
|
||
UINT8 * msg;
|
||
UINT8 * cp;
|
||
|
||
msg = pbuf;
|
||
memset(pdhdr, 0, sizeof(*pdhdr));
|
||
pdhdr->id = get16(&msg[0]);
|
||
tmp = get16(&msg[2]);
|
||
if (tmp & 0x8000) pdhdr->qr = 1;
|
||
pdhdr->opcode = (tmp >> 11) & 0xf;
|
||
if (tmp & 0x0400) pdhdr->aa = 1;
|
||
if (tmp & 0x0200) pdhdr->tc = 1;
|
||
if (tmp & 0x0100) pdhdr->rd = 1;
|
||
if (tmp & 0x0080) pdhdr->ra = 1;
|
||
pdhdr->rcode = tmp & 0xf;
|
||
pdhdr->qdcount = get16(&msg[4]);
|
||
pdhdr->ancount = get16(&msg[6]);
|
||
pdhdr->nscount = get16(&msg[8]);
|
||
pdhdr->arcount = get16(&msg[10]);
|
||
/* 分析可变数据长度部分*/
|
||
cp = &msg[12];
|
||
/* 查询问题 */
|
||
for (i = 0; i < pdhdr->qdcount; i++)
|
||
{
|
||
cp = DnsQuestion(msg, cp);
|
||
}
|
||
/* 回答 */
|
||
for (i = 0; i < pdhdr->ancount; i++)
|
||
{
|
||
cp = DnsAnswer(msg, cp, pSip);
|
||
}
|
||
/*授权 */
|
||
for (i = 0; i < pdhdr->nscount; i++)
|
||
{
|
||
/*待解析*/ ;
|
||
}
|
||
/* 附加信息 */
|
||
for (i = 0; i < pdhdr->arcount; i++)
|
||
{
|
||
/*待解析*/ ;
|
||
}
|
||
if(pdhdr->rcode == 0) return 1; /* rcode = 0:成功 */
|
||
else return 0;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* Function Name : put16
|
||
* Description :UINT16 格式数据按UINT8格式存到缓冲区
|
||
* Input : s -缓冲区首地址
|
||
i -UINT16数据
|
||
* Output : None
|
||
* Return : 偏移指针
|
||
*******************************************************************************/
|
||
UINT8 * put16(UINT8 * s, UINT16 i)
|
||
{
|
||
*s++ = i >> 8;
|
||
*s++ = i;
|
||
return s;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* Function Name : MakeDnsQuery
|
||
* Description : 制作DNS查询报文
|
||
input : op - 递归
|
||
* name - 指向待查域名指针
|
||
* buf - DNS缓冲区.
|
||
* len - 缓冲区最大长度.
|
||
* Output : None
|
||
* Return : 指向DNS报文指针
|
||
*******************************************************************************/
|
||
UINT16 MakeDnsQueryMsg(UINT16 op, char * name, UINT8 * buf, UINT16 len)
|
||
{
|
||
UINT8 *cp;
|
||
char *cp1;
|
||
char tmpname[MAX_DNS_BUF_SIZE];
|
||
char *dname;
|
||
UINT16 p;
|
||
UINT16 dlen;
|
||
|
||
//printf("Domain name:%s \n",name);
|
||
cp = buf;
|
||
MSG_ID++;
|
||
cp = put16(cp, MSG_ID); /* 标识 */
|
||
p = (op << 11) | 0x0100;
|
||
cp = put16(cp, p); /* 0x0100:Recursion desired */
|
||
cp = put16(cp, 1); /* 问题数:1 */
|
||
cp = put16(cp, 0); /* 资源记录数:0 */
|
||
cp = put16(cp, 0); /* 资源记录数:0 */
|
||
cp = put16(cp, 0); /* 额外资源记录数:0 */
|
||
|
||
strcpy(tmpname, name);
|
||
dname = tmpname;
|
||
dlen = strlen(dname);
|
||
for (;;){ /* 按照DNS请求报文域名格式,把URI写入到buf里面去 */
|
||
cp1 = strchr(dname, '.');
|
||
if (cp1 != NULL) len = cp1 - dname;
|
||
else len = dlen;
|
||
*cp++ = len;
|
||
if (len == 0) break;
|
||
strncpy((char *)cp, dname, len);
|
||
cp += len;
|
||
if (cp1 == NULL)
|
||
{
|
||
*cp++ = 0;
|
||
break;
|
||
}
|
||
dname += len+1; /* dname首地址后移 */
|
||
dlen -= len+1; /* dname长度减小 */
|
||
}
|
||
cp = put16(cp, 0x0001); /* type :1------ip地址 */
|
||
cp = put16(cp, 0x0001); /* class:1-------互联网地址 */
|
||
return ((UINT16)(cp - buf));
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* Function Name : DnsQuery
|
||
* Description : 进行DNS查询
|
||
input : s -socket索引
|
||
* name - 指向待查域名指针
|
||
pSip -查询结果
|
||
* Output : None
|
||
* Return : 查询结果。成功返回1,失败返回2
|
||
*******************************************************************************/
|
||
//UINT8 DnsQuery2(UINT8* s, UINT8 * name, UINT8 * pSip)
|
||
//{
|
||
// struct dhdr dhp;
|
||
|
||
// UINT8 ret;
|
||
// UINT32 len;
|
||
// if(Status >1 ){
|
||
// count++;
|
||
// DelayMs(10);
|
||
// if( count>20000 ){
|
||
//#if CH57xNET_DBG
|
||
// printf("DNS Fail!!!!!\n");
|
||
//#endif
|
||
// count=0;
|
||
// Status = 0;
|
||
// return 2;
|
||
// }
|
||
// }
|
||
// if(Status == 1)
|
||
// {
|
||
// DNS_SocketParamInit(s, DNS_SERVER_IP, 4000, IPPORT_DOMAIN);
|
||
// //UDPSocketParamInit(*s,DNS_SERVER_IP,4000,IPPORT_DOMAIN);
|
||
// Status = 2;
|
||
//#if CH57xNET_DBG
|
||
// printf(" 2 status = %d!\n",Status);
|
||
//#endif
|
||
// }
|
||
// if(Status ==2)
|
||
// {
|
||
// len = MakeDnsQueryMsg(0,(char *)name, dns_buf, MAX_DNS_BUF_SIZE);
|
||
// ret = CH57xNET_SocketSend(*s,dns_buf,&len);
|
||
// if ( ret ) return(0);
|
||
// else{
|
||
// Status = 3;
|
||
//#if CH57xNET_DBG
|
||
// printf("status = 3!\n");
|
||
//#endif
|
||
// }
|
||
// }
|
||
// if(Status ==4)
|
||
// {
|
||
// //CH57xNET_SocketClose(*s,TCP_CLOSE_NORMAL );
|
||
// return(parseMSG(&dhp, dns_buf, pSip)); /*解析响应报文并返回结果*/
|
||
//
|
||
// }
|
||
// return 0;
|
||
//}
|
||
|
||
/*******************************************************************************
|
||
* Function Name : DnsQuery_Task
|
||
* Description : 进行DNS查询
|
||
input : s -socket索引
|
||
* name - 指向待查域名指针
|
||
pSip -查询结果
|
||
* Output : None
|
||
* Return : 查询结果。成功返回1,失败返回2
|
||
*用 法 : 循环调用
|
||
*******************************************************************************/
|
||
UINT8 DnsQuery_Task(UINT8* s, UINT8 * name, UINT8 * pSip)
|
||
{
|
||
static uint32_t dnschange_wait_tick1 = 0;
|
||
switch(server_info.dns_sta)
|
||
{
|
||
case DNS_INIT:
|
||
{
|
||
if(dns_buf == NULL) dns_buf = (UINT8*)malloc(MAX_DNS_BUF_SIZE/2); //为DNS分配空间
|
||
UINT8 ret = DNS_SocketParamInit(s, DNS_SERVER_IP, 4000, IPPORT_DOMAIN); //创建DNS用的套接字
|
||
if(ret == CH57xNET_ERR_SUCCESS)
|
||
{
|
||
server_info.dns_sta = DNS_DATA_SEND;
|
||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS socket创建成功,DNS Server IP:%d.%d.%d.%d",\
|
||
DNS_SERVER_IP[0],DNS_SERVER_IP[1],DNS_SERVER_IP[2],DNS_SERVER_IP[3]);
|
||
}
|
||
else
|
||
{
|
||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS socket重新创建,DNS Server IP:%d.%d.%d.%d",\
|
||
DNS_SERVER_IP[0],DNS_SERVER_IP[1],DNS_SERVER_IP[2],DNS_SERVER_IP[3]);
|
||
server_info.dns_sta = DNS_ClOSE; //2023-03-06
|
||
server_info.dns_fail++; //2023-03-06
|
||
}
|
||
}
|
||
break;
|
||
|
||
case DNS_INIT1:
|
||
{
|
||
if(dns_buf == NULL) dns_buf = (UINT8*)malloc(MAX_DNS_BUF_SIZE/2); //为DNS分配空间
|
||
UINT8 ret = DNS_SocketParamInit(s, DNS_SERVER_IP2, 4000, IPPORT_DOMAIN); //创建DNS用的套接字
|
||
if(ret == CH57xNET_ERR_SUCCESS)
|
||
{
|
||
server_info.dns_sta = DNS_DATA_SEND;
|
||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS socket创建成功,DNS Server IP:%d.%d.%d.%d",\
|
||
DNS_SERVER_IP2[0],DNS_SERVER_IP2[1],DNS_SERVER_IP2[2],DNS_SERVER_IP2[3]);
|
||
}
|
||
else
|
||
{
|
||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS socket重新创建,DNS Server IP:%d.%d.%d.%d",\
|
||
DNS_SERVER_IP2[0],DNS_SERVER_IP2[1],DNS_SERVER_IP2[2],DNS_SERVER_IP2[3]);
|
||
server_info.dns_sta = DNS_ClOSE; //2023-03-06
|
||
server_info.dns_fail++; //2023-03-06
|
||
}
|
||
}
|
||
break;
|
||
|
||
case DNS_DATA_SEND:
|
||
{
|
||
UINT32 len = MakeDnsQueryMsg(0,(char *)name, dns_buf, MAX_DNS_BUF_SIZE); //数据组包
|
||
UINT8 ret = CH57xNET_SocketSend(*s, dns_buf, &len); //发送到DNS服务器
|
||
if(ret == CH57xNET_ERR_SUCCESS)
|
||
{
|
||
|
||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS等待接收");
|
||
}
|
||
else Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS发送失败");
|
||
server_info.wait_cot = SysTick_10ms;
|
||
server_info.dns_sta = DNS_WAIT_RECV;
|
||
server_info.dns_flg = 0x00;
|
||
}
|
||
break;
|
||
|
||
case DNS_WAIT_RECV: //如果DNS成功,会在接收数据后关闭套接字
|
||
|
||
if(server_info.dns_flg == 1) //如果成功获取到服务器ip
|
||
{
|
||
struct dhdr dhp;
|
||
UINT8 rev = 0; //将该套接字索引清零
|
||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS 耗时:%d0ms", SysTick_10ms - server_info.wait_cot);
|
||
|
||
rev = parseMSG(&dhp, dns_buf, pSip); /*这个函数的返回值是0x01:成功,0x00:失败*/
|
||
|
||
CH57xNET_SocketClose(*s,SOCK_STAT_CLOSED );
|
||
|
||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"释放DNS套接字");
|
||
|
||
if(rev == 0x01) /*parseMSG 解析响应报文并返回结果 2022-06-08*/
|
||
{
|
||
return 0x01; //解析成功
|
||
}else {
|
||
server_info.dns_fail++;
|
||
server_info.dns_sta = DNS_ClOSE;
|
||
dnschange_wait_tick1 = SysTick_10ms;
|
||
}
|
||
|
||
}
|
||
else if(SysTick_10ms - server_info.wait_cot > 200) //等待接收超时
|
||
{
|
||
server_info.wait_cot = SysTick_10ms;
|
||
server_info.dns_sta = DNS_ClOSE;
|
||
server_info.dns_fail++;
|
||
}
|
||
break;
|
||
case DNS_ClOSE:
|
||
free(dns_buf); //释放DNS空间
|
||
dns_buf = NULL;
|
||
CH57xNET_SocketClose(*s,SOCK_STAT_CLOSED ); //将该套接字索引清零
|
||
if(server_info.dns_fail == 0x01)
|
||
{
|
||
if(SysTick_10ms - dnschange_wait_tick1 > 50)
|
||
{
|
||
Dbg_Println(DBG_BIT_NET_STATUS_bit,"切换DNS域名解析服务器");
|
||
dnschange_wait_tick1 = SysTick_10ms;
|
||
server_info.dns_sta = DNS_INIT1;
|
||
}
|
||
}
|
||
else if(server_info.dns_fail >= 0x02)
|
||
{
|
||
*s = 0;
|
||
server_info.dns_fail = 0x00;
|
||
return 0x02; //解析失败
|
||
}
|
||
break;
|
||
}
|
||
return 0;
|
||
}
|