g0b1vetx-board/Comm/net-app.c
2023-04-29 09:09:12 +08:00

590 lines
14 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "net-app.h"
//#include "eth-board.h"
//#include "ec200-board.h"
//#include "uart-board.h"
//#include "stm32l0xx_hal.h"
//#include "save-board.h"
//#include "sysinfo-app.h"
#include "proto-sl651.h"
//#include "sluice-control.h"
//#include "base64.h"
//#include "log.h"
//#include "ff-collected.h"
#include "fifo-board.h"
#if !defined(LOG_TAG)
#define LOG_TAG "NET"
#endif
#include <elog.h>
// 这里处理网络通信的数据不管是以太网还是4g都在这里处理
#define UTH uEth
typedef enum
{
YmodmApplication,
YmodemToDo,
YmodmSendFileName,
YmodmAck,
YmodmC,
YmodmHead,
Ymodm1024,
YmodmERROR,
YmodmEOT,
YModmIdle
} YmodemState_t; // = YmodmApplication;
NetPacket_t g_fifo_netpacket[10];
static int IsInitialized = 0;
static struct
{
uint32_t unifTimer; // 时段报时间
uint32_t linkTimer; // 心跳报时间
uint32_t flowTimer; // 流量计时间
int retryCount;
YmodemState_t State;
int Error;
int IsFirstConnection; // 第一次链接成功
int UpdateLock; // 升级锁
} g_netinfo;
static struct
{
char updatePacket[64]; // 升级请求 包
int delayTimer; // 收到升级命令后延迟5s 进入升级
int PacketSize; // 数据报大小
uint32_t ssNumber;
uint32_t cTimer;
} g_ymodeinfo;
#pragma pack(1) /*1字节对齐*/
static struct rx_data_t
{
uint8_t header[2];
uint8_t devid[5];
uint8_t centerid;
uint8_t password[2];
uint8_t type;
uint8_t flag;
uint8_t payloadsize;
uint8_t payStart;
struct
{
uint16_t synNum;
uint8_t payLoad[512];
} Payload;
uint8_t payStop;
uint16_t crc;
} g_rx_data;
#pragma pack()/*还原默认对齐*/
static Fifo_t g_NetFifo;
static NetFunc_t NetFunc;
static uint16_t ymodemCRC16 (uint8_t *Pushdata, uint16_t length);
//static int NETModifyPara(char *data, int length);
//static int NETReadPara(char *data, int max);
//static int netDownloadHandle (uint8_t type, char *data, int length);
static int netUploadHandle (char *data);
static void netSendPacket (void);
static void netInit (void);
// 上报基础参数
static void netWritebaseParams (void);
static void netWriteInterfaceParams (void);
static void netWriteSluiceParams (void);
static void netWriteWaterParams (void);
void NetSystemTick (void)
{
if (g_netinfo.unifTimer > 1)
{
g_netinfo.unifTimer--;
}
if (g_netinfo.flowTimer > 1)
{
g_netinfo.flowTimer--;
}
if (g_netinfo.linkTimer > 1)
{
g_netinfo.linkTimer--;
}
if (g_ymodeinfo.delayTimer > 1)
{
g_ymodeinfo.delayTimer--;
}
if (g_ymodeinfo.cTimer > 1)
{
g_ymodeinfo.cTimer--;
}
}
// 如下为网络队列调用函数wirebuffer 不等于多个writebyte
void NET_FifoWritebuffer (char *buffer, int size)
{
NetPacket_t packet;
packet.data_size = size;
memcpy (packet.data, buffer, size);
FifoWrite (&g_NetFifo, (char *) &packet, sizeof (packet)); // 数据写入队列中去
}
void NET_FifoWriteByte (char byte)
{
NetPacket_t packet;
packet.data_size = 1;
packet.data[0] = byte;
FifoWrite (&g_NetFifo, (char *) &packet, sizeof (packet)); // 数据写入队列中去
}
// N 1024 filename <<<<<<<<<<<<<<<<<<<< 文件名,切包大小
// 06 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// C C <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// SOH[128] 00 >>>>>>>>>>>>>>>>>>>>>>>>> CRC //第一报
// ACK <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// STX[256/1024] 01 >>>>>>>>>>>>>>>>>>>> CRC //第一报
// ACK <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// STX[256/1024] 01 >>>>>>>>>>>>>>>>>>>> CRC //第一报
// ACK <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// EOT >>>>>>>>>>>>>>>>>>>> CRC //第一报
// NAK <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 17 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/**
* @brief Receive a file using the ymodem protocol
* @param buf: Address of the first byte
* @retval -1: error 1 first packet received 2: 1024 packet received 5:EOT packet received
*/
int32_t Ymodem_Receive (uint8_t *buf, int length)
{
// 获取序号
g_ymodeinfo.ssNumber = buf[1];
// g_ssNumber = buf[1];
uint16_t rCrc, cCrc;
int ret = 0;
// 计算CRC校验
cCrc = ymodemCRC16 (buf, length - 2);
rCrc = ( (uint16_t) buf[length - 2] << 8) + (uint16_t) buf[length - 1];
log_d ("CCRC:%04X rCrc:%04X\r\n", cCrc, rCrc);
if (cCrc != rCrc)
{
for (int i = 0; i < length; i++)
{
log_d ("%02X ", buf[i]);
}
return -1; // 升级失败
}
log_d ("\r\n");
log_d ("....................%d\r\n", buf[1]);
if (buf[0] == SOH)
{
log_d ("FileName:%s\r\n", &buf[3]);
//SaveWriteFirmware (g_ymodeinfo.ssNumber, &buf[3], 128);
ret = 1;
}
else if (buf[0] == STX)
{
if (g_ymodeinfo.PacketSize == 1024)
{
//SaveWriteFirmware (g_ymodeinfo.ssNumber, &buf[3], 1024);
}
else if (g_ymodeinfo.PacketSize == 256)
{
//SaveWriteFirmware256 (g_ymodeinfo.ssNumber, &buf[3], 256);
}
ret = 2;
}
else
{
ret = -1;
}
return ret;
}
static uint16_t ymodemCRC16 (uint8_t *Pushdata, uint16_t length)
{
uint16_t crc = 0;
while (length--)
{
crc ^= (uint16_t) (* (Pushdata++)) << 8;
for (int i = 0; i < 8; i++)
{
if (crc & 0x8000)
{
crc = (crc << 1) ^ 0x1021;
}
else
{
crc = crc << 1;
}
}
}
return crc;
}
extern int netDownloadHandle (uint8_t type, char *data, int length);
void NetTask (void)
{
char rxdata[1200];
//char rxdata_decode[256];
int rsize, tx_size;//rdsize = 0, ;
char tx_data[256];
int ret = 0;
uint16_t paysize;
// int payloadsize = 0;
//char * p;
// 初始化网络驱动
if (IsInitialized == 0)
{
netInit();
g_netinfo.State = YmodmApplication;
IsInitialized = 1;
log_d ("Initializing network...");
}
// 验证网络驱动是否初始化成功
if (NetFunc.Init == NULL)
{
log_d ("NetFunc.Init failed\n");
return;
}
if (NetFunc.IsIdle() == 1) // 网络空闲 发送网络数据
{
// dbg_printf("NetFunc.IsIdle\n");
netSendPacket();
}
switch (g_netinfo.State)
{
case YmodmApplication: // 走业务数据
if (NetFunc.IsReady() == 1)
{
/* 处理接受到的数据--------------------------------------------*/
memset (rxdata, 0, 1200);
rsize = NetFunc.ReadData (rxdata, 1200);
// 解析数据
//hexstr_to_hexbyte (rxdata, (char *) &g_rx_data, rsize);
//dbg_printf("%s\r\n",rxdata);
//dbg_printf("%04X\r\n",g_rx_data.payloadsize);
paysize = ( (uint16_t) (g_rx_data.flag & 0x0F) << 8) + (uint16_t) g_rx_data.payloadsize ;
//g_rx_data.payloadsize = (g_rx_data.payloadsize & 0x0FFF) ;
g_rx_data.payStop = g_rx_data.Payload.payLoad[paysize - 2];
g_rx_data.crc = ( (uint16_t) g_rx_data.Payload.payLoad[paysize - 1] << 8) + (uint16_t) g_rx_data.Payload.payLoad[paysize];
//g_rx_data.Payload.payLoad[paysize] = 0;
log_d ("<<<<<<<<<<<<rx_size:%d\r\n", paysize);
log_d ("Header: %X%X\r\n", g_rx_data.header[0], g_rx_data.header[1]);
log_d ("devid: %02X%02X%02X%02X%02X\r\n",
g_rx_data.devid[0],
g_rx_data.devid[1],
g_rx_data.devid[2],
g_rx_data.devid[3],
g_rx_data.devid[4]);
log_d ("center: %d,pass:%02X%02X,type:%02X,flag:%04X\r\n", g_rx_data.centerid, g_rx_data.password[0], g_rx_data.password[1], g_rx_data.type, g_rx_data.flag);
log_d ("payloadsize:%d\r\n", paysize);
log_d ("start:%d,seq:%d\r\n", g_rx_data.payStart, g_rx_data.Payload.synNum);
for (int i = 0; i < paysize - 2; i++)
{
log_d ("%02X ", g_rx_data.Payload.payLoad[i]);
}
log_d ("\r\n");
log_d ("payStop:%d,crc:%04x\r\n", g_rx_data.payStop, g_rx_data.crc);
//log3_printf("center: %d,pass:%02X%02X,type:%02X,flag:%02X\r\n", g_rx_data.centerid, g_rx_data.password[0],g_rx_data.password[1],g_rx_data.type,g_rx_data.flag);
// 校验CRC
// 数据长度
// payloadsize = rxdata_decode[12]-2; // 取payloadsize 去掉两位序列号
// log3_printf("Header:%X%X\r\n",rxdata_decode[0],rxdata_decode[1]);
// log3_printf("DevAddr%02X%02X%02X%02X%02X\r\n",rxdata_decode[2],rxdata_decode[3],rxdata_decode[4],rxdata_decode[5],rxdata_decode[6]);
// log3_printf("Payload size:%X\r\n",payloadsize);
// // 接受到远程升级命令
if (netDownloadHandle (g_rx_data.type, (char *) g_rx_data.Payload.payLoad, paysize - 2) == 0xE0)
{
g_netinfo.State = YmodemToDo;
g_ymodeinfo.delayTimer = 5000;
}
}
// tx_size = netUploadHandle (tx_data);
// if (tx_size > 0)
// {
// FifoWritebuffer (tx_data, tx_size);
// }
break;
case YmodemToDo: // 已经接受到升级命令等待5S业务数据发送完成进入升级
{
if (g_ymodeinfo.delayTimer == 1) // 升级时间到
{
g_ymodeinfo.delayTimer = 0;
NetFunc.ReSubTopic ("update"); // 链接到升级服务器
g_netinfo.State = YmodmSendFileName;
g_netinfo.retryCount = 5;
}
break;
}
case YmodmSendFileName:
if (NetFunc.IsIdle() == 1)
{
g_netinfo.retryCount--;
// packet.data_size = PP_AddHeader (0x2F, state, 4, packet.data) ;
// FifoWrite (&g_NetFifo, (char *) &packet, sizeof(packet)); // 数据写入队列中去
NET_FifoWritebuffer (g_ymodeinfo.updatePacket, strlen (g_ymodeinfo.updatePacket));
g_netinfo.State = YmodmAck; /// g_isStart = 2;
g_ymodeinfo.delayTimer = 3000; // 等待 3s
}
if (g_netinfo.retryCount == 0) // 如果超过5次尝试没有链接升级服务器就认为升级失败
{
NET_FifoWriteByte (YMFILD);
// packet.data_size = 1;
// packet.data[0] = lFAIL;
// FifoWrite(&g_NetFifo, (char *)&packet, sizeof(packet)); // 数据写入队列中去
g_ymodeinfo.delayTimer = 1000;
g_netinfo.State = YmodmERROR;
}
break;
case YmodmAck:
if (NetFunc.IsReady() == 1)
{
rsize = NetFunc.ReadData (rxdata, 1200);
if (rxdata[0] == 0x06 && rsize == 1)
{
g_netinfo.State = YmodmC;
log_d ("YmodemState = YmodmC\r\n");
g_ymodeinfo.cTimer = 1000;
}
}
// 如果超过1s 没有收到服务器的应答,重复发送文件名,尝试再次升级
if (g_ymodeinfo.delayTimer == 1)
{
g_ymodeinfo.delayTimer = 0;
g_netinfo.State = YmodmSendFileName;
}
break;
case YmodmC: // 收到服务器的应答后,进入升级
if (g_ymodeinfo.cTimer == 1)
{
g_ymodeinfo.cTimer = 2000;
NET_FifoWriteByte ('C');
}
if (NetFunc.IsReady() == 1) //接受到C的应答
{
g_netinfo.State = YmodmHead;
log_d ("YmodemState = YmodmHead\r\n");
}
break;
case YmodmHead:
rsize = NetFunc.ReadData (rxdata, 1200);
ret = Ymodem_Receive ( (uint8_t *) rxdata, rsize);
if (ret == 1)
{
g_netinfo.State = Ymodm1024; //
NET_FifoWriteByte (ACK);
NET_FifoWriteByte ('C');
g_ymodeinfo.delayTimer = 3000;
log_d ("YmodemState = Ymodm1024\r\n");
}
else // 数据获取失败,重新发起文件链接请求
{
g_netinfo.State = YmodmSendFileName;
}
break;
case Ymodm1024:
if (NetFunc.IsReady() == 1)
{
g_ymodeinfo.delayTimer = 3000;
rsize = NetFunc.ReadData (rxdata, 1200);
if (rsize == 1 && rxdata[0] == EOT) // 升级错误
{
g_netinfo.State = YmodmEOT;
log_d ("YmodemState = YmodmEOT1\r\n");
break;
}
// -1: error 1 first packet received 2: 1024 packet received 5:EOT packet received
ret = Ymodem_Receive ( (uint8_t *) rxdata, rsize);
if (ret == 2)
{
NET_FifoWriteByte (ACK);
break;
}
else if (ret == -1)
{
NET_FifoWriteByte (YMFILD);
g_ymodeinfo.delayTimer = 1000;
g_netinfo.State = YmodmERROR;
}
}
if (g_ymodeinfo.delayTimer == 1)
{
g_ymodeinfo.delayTimer = 0;
log_d ("YmodemState = YmodmERROR\r\n");
}
break;
case YmodmEOT:
NET_FifoWriteByte (NAK);
NET_FifoWriteByte (YMSUCCE);
g_netinfo.State = YModmIdle;
g_ymodeinfo.delayTimer = 1000; // 等待 1S 数据结束后重启
break;
case YmodmERROR:
{
if (g_ymodeinfo.delayTimer == 1)
{
g_ymodeinfo.delayTimer = 0;
//NetFunc.ReSubTopic (SysInfo.baseTopic);
g_netinfo.State = YmodmApplication; //();
}
// 发送错误,上报升级失败,切换到 业务层等待重新升级
break;
}
case YModmIdle:
{
if (g_ymodeinfo.delayTimer == 1)
{
//FactorySetFlashUpdate(); // 进入升级
//HAL_NVIC_SystemReset(); // 重启
g_ymodeinfo.delayTimer = 0;
}
break;
}
default:
break;
}
if (NetFunc.IsConnected() == 1)
{
if (g_netinfo.IsFirstConnection == 0)
{
g_netinfo.IsFirstConnection = 1;
//NETSendRegist();
log_d ("First join network\r\n");
}
}
NetFunc.Task(); // NetFunc.Task();
}
static void netSendPacket (void)
{
NetPacket_t packet;
if (FifoRead (&g_NetFifo, (char *) &packet, sizeof (NetPacket_t)) == 0)
{
NetFunc.WriteData (packet.data, packet.data_size);
log_d ("tx:>>>>>>>>>>>>>>>>>>%d\r\n", packet.data_size);
}
}
// 上报回调数据
static int netUploadHandle (char *data)
{
char payload[128] = {0};
int payload_size = 0;
int size = 0;
if (g_netinfo.unifTimer == 1)
{
// payload_size = PP_PacketUnifData (payload); // 打包业务层数据
// size = PP_AddHeader (0x31, payload, payload_size, data);
// g_netinfo.unifTimer = SL651_TIME_UNIF;
}
else if (g_netinfo.linkTimer == 1)
{
// if (FF_ReadEcodeData() == 0XFFFFFFFF)
// {
// payload[0] = 0;
// }
// else
// {
// payload[0] = 1;
// }
// if (FF_ReadLeveData() == 0XFFFFFFFF)
// {
// payload[1] = 0;
// }
// else
// {
// payload[1] = 1;
// }
size = PP_AddHeader (0x2F, payload, 4, data);
g_netinfo.linkTimer = SL651_TIME_HEART;
}
else if (g_netinfo.flowTimer == 1) // 请求流量计数据
{
g_netinfo.flowTimer = SL651_TIME_FLOW;
}
else
{
size = 0;
}
return size;
}
static void netInit (void)
{
// if (SysInfo.baseNetDev == EC200_MQTT) // EC200
// {
// NetFunc.Init = EC200Init;
// NetFunc.IsConnected = EC200IsConnected;
// NetFunc.IsReady = EC200RxIsReady;
// NetFunc.ReadData = EC200ReadData;
// NetFunc.WriteData = EC200WriteData;
// NetFunc.IsIdle = EC200IsIdle;
// NetFunc.ReSubTopic = EC200ReSubTopic;
// NetFunc.Task = EC200Task;
// g_ymodeinfo.PacketSize = 1024;
// }
// else if (SysInfo.baseNetDev == ETH_MQTT) // ETH
// {
// NetFunc.Init = EthMqttInit;
// NetFunc.IsConnected = EthMqttIsConnect;
// NetFunc.IsReady = EthMqttIsReady;
// NetFunc.ReadData = EthMqttReadData;
// NetFunc.WriteData = EthMqttWriteData;
// NetFunc.IsIdle = EthMqttIsIdle;
// NetFunc.ReSubTopic = EthMqttReSubTopic;
// NetFunc.Task = EthMqttTask;
// g_ymodeinfo.PacketSize = 1024;
// }
// else
// {
// //
// return;
// }
NetFunc.Init();
FifoInit (&g_NetFifo, (char *) g_fifo_netpacket, 3);
log_d ("fifo Init\n");
// g_netinfo.unifTimer = SL651_TIME_UNIF;
// g_netinfo.linkTimer = SL651_TIME_HEART;
// g_netinfo.flowTimer = SL651_TIME_FLOW;
}
//// 将要发送的数据写入队列
//void NET_WriteBuffer(NetPacket_t packet)
//{
// FifoWritebuffer (packet.data, packet.data_size);
// //return 0;
//}
//// 应答E3 回复读取的数据
//void NETSendConfig (char *data)
//{
// NetPacket_t packet;
// packet.data_size = PP_AddHeader (0xE3, data, strlen (data), packet.data);
// FifoWrite (&g_NetFifo, (char *) &packet, sizeof (packet));
//}