#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 // 这里处理网络通信的数据,不管是以太网还是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 ("<<<<<<<<<<< 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)); //}