#include "UpcCommTask.h" #include "RtcTask.h" #include "RtcDrv.h" #include "RunEnvTask.h" #include "OutPutGpioTask.h" #include "arch/ZtmsLwip.h" #include "lwip/sys.h" #include "netif/tivaif.h" #include "driverlib/sysctl.h" #include "ToolCheck.h" #include "WatchdogTask.h" #include "FileSysTask.h" #include "ToolDelay.h" #include #include #define TASK_COMM_RECV_DATA_BUFLEN 4200 // TCP接收缓存 #define TASK_COMM_HANDLE_DATA_BUFLEN 2100 // 数据处理存放缓存 #define TASK_COMM_HANDLE_DATA_COUNT 10 // 数据缓存条数 #define TASK_COMM_SEND_DATA_BUFLEN 2100 #define TASK_COMM_DATA_IDLING 0 // 空闲态 #define TASK_COMM_DATA_SORTING 1 // 分拣态 #define TASK_COMM_DATA_HANDLING 2 // 处理态 /********************************类型定义************************************/ typedef struct{ unsigned char HandleDataBuf[TASK_COMM_HANDLE_DATA_BUFLEN]; unsigned char HandleFlag; unsigned short HandleCount; } TASK_COMM_HANDLE; /***************************设备类型与设备ID**********************************/ static unsigned int gDeviceType = 201; // 设备类型 static unsigned int gDeviceId = 4; // 设备ID /****************************网络连接参数*************************************/ static ZTMS_NETWORK_IPADDR gLocalIpAddr = {41,244,64,61}; // 本机默认IP地址 static unsigned short gLocalIpPort = 55000; // 本系统通信的默认IP地址 static ZTMS_NETWORK_IPADDR gMaskAddr = {255,255,255,0}; // 本机默认子网掩码 static ZTMS_NETWORK_IPADDR gGwAddr = {41,244,64,254}; // 本机默认网关 static ZTMS_NETWORK_IPADDR gDestIpAddr = {41,244,64,56}; // 目标默认IP地址 static unsigned short gDestIpPort = 55000; // 目标默认端口号 static ip_addr_t gDestIp; // 目标默认IP的转换地址 static struct netconn *gTaskUpcCommTcpNetconn = NULL; static struct netconn *gTaskUpcCommTcpClientNetconn = NULL; /*****************************标志状态位************************************/ static int gTaskUpcCommRecvWatchdogId = -1; // 网络通信任务的看门狗ID static int gTaskUpcCommExtractWatchdogId = -1; // 网络通信任务的看门狗ID static int gTaskUpcCommHandleWatchdogId = -1; // 网络通信任务的看门狗ID static int gTaskNetPortSta = 0; // 关于物理网口部分连接状态 static int gTaskTcpConnSta = 0; // TCP通信连接的状态 /******************************接收发送缓存*********************************/ static unsigned char gTaskUpcCommRecvDataBuf[TASK_COMM_RECV_DATA_BUFLEN] = {0}; //TCP接收缓存 static unsigned short gTaskUpcCommRecvDataBufRecvLocal = 0; // 接收的数据缓存的当前下标 static unsigned short gTaskUpcCommRecvDataBufHandleLocal = 0; // 处理的数据缓存当前下标 static unsigned char gTaskUpcCommSendDataBuf[TASK_COMM_SEND_DATA_BUFLEN] = {0}; //TCP发送缓存 // 存放一定数量已经初步处理过的缓存 static TASK_COMM_HANDLE gTaskUpcCommHandleDataBuf[TASK_COMM_HANDLE_DATA_COUNT] = {{0}}; /********************************静态函数声明*******************************/ static void TaskUpcCommTcpSocketConn(void); // TCP连接函数 static void TaskUpcCommStartRecv(void); static void TaskUpcCommClearDataStatus(unsigned char CountId); // 清楚数据内部处理状态 static void TaskUpcCommNormalAck(unsigned short PlatNum, unsigned short PlatId, uint8_t Result); // ACK回复 static unsigned char gSendBufTmp[1050] = {0}; // 临时发送数据保存 void TaskUpcCommRecv(void *arg) { unsigned int RealWbyte; int ret; /* 将通信接收任务开启写入日志 */ do { ret = TaskFileLogWrite("TaskUpcCommRecv: Join in!!\n", strlen("TaskUpcCommRecv: Join in!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommRecvWatchdogId); OSTimeDly(1); } while (ret > 0); while (1) { /* 建立TCP连接 */ TaskUpcCommTcpSocketConn(); /* TCP连接成功 */ do { ret = TaskFileLogWrite("TaskUpcCommRecv: TCP connect!!\n", strlen("TaskUpcCommRecv: TCP connect!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommRecvWatchdogId); OSTimeDly(1); // 需要TCP不停处于接收态 } while (ret > 0); /* 开始接收 */ TaskUpcCommStartRecv(); } } /* 从接收缓存中提取一组完成的数据 */ void TaskUpcCommExtractData(void* arg) { int i = 0; unsigned int RealWbyte; int ret; /* 将接收缓存提取数据任务开启写入日志 */ do { ret = TaskFileLogWrite("TaskUpcCommExtractData: Join in!!\n", strlen("TaskUpcCommExtractData: Join in!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommExtractWatchdogId); OSTimeDly(1); } while (ret > 0); while (1) { TaskWatchdogFreed(gTaskUpcCommExtractWatchdogId); OSTimeDly(1); if (gTaskUpcCommRecvDataBufHandleLocal == gTaskUpcCommRecvDataBufRecvLocal) { continue; } if (gTaskUpcCommRecvDataBuf[gTaskUpcCommRecvDataBufHandleLocal] == 0x7f) { for (i = 0; i < TASK_COMM_HANDLE_DATA_COUNT; i++) { if (gTaskUpcCommHandleDataBuf[i].HandleFlag == TASK_COMM_DATA_SORTING) { if (gTaskUpcCommHandleDataBuf[i].HandleCount < 18) { // 18为数据包最小单位长度 /* 该帧数据错误,将该帧数据变成空闲态,并清空内部长度 */ gTaskUpcCommHandleDataBuf[i].HandleFlag = TASK_COMM_DATA_IDLING; gTaskUpcCommHandleDataBuf[i].HandleCount = 0; break; } else { /* 将数据保存在帧数据中,表示一帧数据的完成 */ gTaskUpcCommHandleDataBuf[i].HandleDataBuf[gTaskUpcCommHandleDataBuf[i].HandleCount] = gTaskUpcCommRecvDataBuf[gTaskUpcCommRecvDataBufHandleLocal]; gTaskUpcCommHandleDataBuf[i].HandleCount++; gTaskUpcCommHandleDataBuf[i].HandleFlag = TASK_COMM_DATA_HANDLING; break; } } } if ((i < TASK_COMM_HANDLE_DATA_COUNT) && (gTaskUpcCommHandleDataBuf[i].HandleFlag == TASK_COMM_DATA_HANDLING)) { gTaskUpcCommRecvDataBufHandleLocal++; // 数据处理完成的跳出之一,因此该字节处理完成,且为完成一帧数据获取的跳出 gTaskUpcCommRecvDataBufHandleLocal = (unsigned short)(gTaskUpcCommRecvDataBufHandleLocal % TASK_COMM_RECV_DATA_BUFLEN); continue; } for (i = 0; i < TASK_COMM_HANDLE_DATA_COUNT; i++) { /* 上面的逻辑排除了接收态,所以只剩空闲态 */ if (gTaskUpcCommHandleDataBuf[i].HandleFlag == TASK_COMM_DATA_IDLING) { gTaskUpcCommHandleDataBuf[i].HandleDataBuf[gTaskUpcCommHandleDataBuf[i].HandleCount] = gTaskUpcCommRecvDataBuf[gTaskUpcCommRecvDataBufHandleLocal]; gTaskUpcCommHandleDataBuf[i].HandleCount++; gTaskUpcCommHandleDataBuf[i].HandleCount = (unsigned short)(gTaskUpcCommHandleDataBuf[i].HandleCount % TASK_COMM_HANDLE_DATA_BUFLEN); gTaskUpcCommHandleDataBuf[i].HandleFlag = TASK_COMM_DATA_SORTING; break; } } /* 如果没有空闲态,则写入日志文件 */ if (i >= TASK_COMM_HANDLE_DATA_COUNT) { do { ret = TaskFileLogWrite("TaskUpcCommExtractData: Buf Full!!\n", strlen("TaskUpcCommExtractData: Buf Full!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommExtractWatchdogId); OSTimeDly(1); } while (ret > 0); } } else { for (i = 0; i < TASK_COMM_HANDLE_DATA_COUNT; i++) { if (gTaskUpcCommHandleDataBuf[i].HandleFlag == TASK_COMM_DATA_SORTING) { gTaskUpcCommHandleDataBuf[i].HandleDataBuf[gTaskUpcCommHandleDataBuf[i].HandleCount] = gTaskUpcCommRecvDataBuf[gTaskUpcCommRecvDataBufHandleLocal]; gTaskUpcCommHandleDataBuf[i].HandleCount++; gTaskUpcCommHandleDataBuf[i].HandleCount = (unsigned short)(gTaskUpcCommHandleDataBuf[i].HandleCount % TASK_COMM_HANDLE_DATA_BUFLEN); break; } } } gTaskUpcCommRecvDataBufHandleLocal++; // 数据处理完成的跳出之一,因此该字节处理完成 gTaskUpcCommRecvDataBufHandleLocal = (unsigned short)(gTaskUpcCommRecvDataBufHandleLocal % TASK_COMM_RECV_DATA_BUFLEN); } } /* 从一组完整的数据中解析数据 */ void TaskUpcCommHandleData(void* arg) { unsigned int RealWbyte; int ret; unsigned char i; int k; int j; unsigned char crc = 0; unsigned int TmpId; unsigned int TmpType; unsigned short MessageId; unsigned short MessageNum; unsigned short MessageLen; /* 将解析数据任务开启写入日志 */ do { ret = TaskFileLogWrite("TaskUpcCommHandleData: Join in!!\n", strlen("TaskUpcCommHandleData: Join in!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommHandleWatchdogId); OSTimeDly(1); } while (ret > 0); while (1) { OSTimeDly(10); k = 0; TaskWatchdogFreed(gTaskUpcCommHandleWatchdogId); for (i = 0; i < TASK_COMM_HANDLE_DATA_COUNT; i++) { if (gTaskUpcCommHandleDataBuf[i].HandleFlag == TASK_COMM_DATA_HANDLING) { break; } } if (i >= TASK_COMM_HANDLE_DATA_COUNT) { continue; } /* 进行数据包解析 */ for (j = 1; j < gTaskUpcCommHandleDataBuf[i].HandleCount - 1; j++) { if (gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j] == 0x7f) { TaskUpcCommClearDataStatus(i); break; } else if (gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j] == 0x7e) { j++; if (gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j] == 0x01) { gTaskUpcCommHandleDataBuf[i].HandleDataBuf[k] = 0x7e; } else if (gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j] == 0x02) { gTaskUpcCommHandleDataBuf[i].HandleDataBuf[k] = 0x7f; } else { TaskUpcCommClearDataStatus(i); break; } } else { gTaskUpcCommHandleDataBuf[i].HandleDataBuf[k] = gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j]; } k++; } if (j < gTaskUpcCommHandleDataBuf[i].HandleCount - 1) { continue; } /* 提取消息中的终端消息ID */ MessageId = (unsigned short)((gTaskUpcCommHandleDataBuf[i].HandleDataBuf[0] << 8) | gTaskUpcCommHandleDataBuf[i].HandleDataBuf[1]); /* 提取消息中的终端类型 */ TmpType = (((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[2]) << 24) | (((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[3]) << 16) | (((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[4]) << 8) | gTaskUpcCommHandleDataBuf[i].HandleDataBuf[5]; /* 提取消息中的终端ID */ TmpId = (((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[6]) << 24) | (((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[7]) << 16) | (((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[8]) << 8) | gTaskUpcCommHandleDataBuf[i].HandleDataBuf[9]; /* 提取消息中的终端消息流水号 */ MessageNum = (unsigned short)((gTaskUpcCommHandleDataBuf[i].HandleDataBuf[14] << 8) | gTaskUpcCommHandleDataBuf[i].HandleDataBuf[15]); /* 提取消息的消息体长度 */ MessageLen = (unsigned short)((((unsigned short)(gTaskUpcCommHandleDataBuf[i].HandleDataBuf[10] & 0x03)) << 8) | gTaskUpcCommHandleDataBuf[i].HandleDataBuf[11]); crc = 0; /* 比对终端类型与终端ID和测试软件是不是一致 */ if ((TmpType != gDeviceType) || (TmpId != gDeviceId)) { TaskUpcCommClearDataStatus(i); continue; } /* 判断使用的校验方式,并进行校验,目前只支持Crc0x131的校验方式 */ if ((gTaskUpcCommHandleDataBuf[i].HandleDataBuf[10] & 0x0c) == 0x0c) { ToolCheckCrc8_0x31(gTaskUpcCommHandleDataBuf[i].HandleDataBuf, k - 1, &crc); if (crc != gTaskUpcCommHandleDataBuf[i].HandleDataBuf[k - 1]) { TaskUpcCommClearDataStatus(i); continue; } } else { TaskUpcCommClearDataStatus(i); continue; } if ((gTaskUpcCommHandleDataBuf[i].HandleDataBuf[10] & 0x20) == 0x20) { if (MessageLen != (k - 19)) { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); TaskUpcCommClearDataStatus(i); continue; } else { j = 18; } } else { if (MessageLen != (k - 17)) { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); TaskUpcCommClearDataStatus(i); continue; } else { j = 16; } } if (MessageId == PLAT_ACK_MESSAGE_ID) { /* 下面是对平台ACK的处理 */ TaskUpcCommClearDataStatus(i); // 不对ACK进行处理 } else if (MessageId == PLAT_CONF_TERMINAL_TIME_MESSAGE_ID) { uint64_t Time; DRV_RTC_TIME RtcTime; do { ret = TaskFileLogWrite("TaskUpcComm: CMD TIME SYNC!!\n", strlen("TaskUpcComm: CMD TIME SYNC!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommHandleWatchdogId); OSTimeDly(1); } while (ret > 0); if (MessageLen != 8) { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); TaskUpcCommClearDataStatus(i); continue; } Time = (((uint64_t)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j]) << 56) | (((uint64_t)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 1]) << 48) | (((uint64_t)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 2]) << 40) | (((uint64_t)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 3]) << 32) | (((uint64_t)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 4]) << 24) | (((uint64_t)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 5]) << 16) | (((uint64_t)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 6]) << 8) | ((uint64_t)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 7]); RtcTime.year = Time / 10000000000; RtcTime.month = (Time / 100000000) % 100; RtcTime.date = (Time / 1000000) % 100; RtcTime.hour = (Time / 10000) % 100; RtcTime.minute = (Time / 100) % 100; RtcTime.second = Time % 100; if (0 > TaskRtcSyncSet(&RtcTime)) { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_OK); } TaskUpcCommClearDataStatus(i); } else if (MessageId == PLAT_ASK_TERMINAL_DATA_MESSAGE_ID) { /* 平台请求数据 */ unsigned short ConfMessage; unsigned char Num; do { ret = TaskFileLogWrite("TaskUpcComm: CMD ASK DATA!!\n", strlen("TaskUpcComm: CMD ASK DATA!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommHandleWatchdogId); OSTimeDly(1); } while (ret > 0); ConfMessage = (((unsigned short)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j]) << 8) | ((unsigned short)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 1]); Num = gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 2]; if (ConfMessage == TASK_RUN_ENV_MESSGAE_ID) { if (Num == 0x01) { TaskRunEnvEnable(); TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_OK); } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_NO_SUP); } } else if (ConfMessage == TASK_OUTPUT_GPIO_MESSGAE_ID) { if (Num == 0x01) { TaskOutPutGpioEnable(); TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_OK); } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_NO_SUP); } } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_NO_SUP); } TaskUpcCommClearDataStatus(i); } else if (MessageId == PLAT_ASK_TERMINAL_FILE_MESSAGE_ID) { /* 平台请求终端文件 */ int rt; unsigned char FileType; unsigned char FileOperation; unsigned int time; unsigned short Year; unsigned char Mon; unsigned char Day; do { ret = TaskFileLogWrite("TaskUpcComm: CMD ASK FILE!!\n", strlen("TaskUpcComm: CMD ASK FILE!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommHandleWatchdogId); OSTimeDly(1); } while (ret > 0); if (0 == gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j]) { FileType = FILE_LOG_TYPE; } else if (5 == gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j]) { FileType = FILE_DATA_TYPE; } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_NO_SUP); TaskUpcCommClearDataStatus(i); continue; } if (0 == gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 1]) { FileOperation = FILE_UPLOAD; } else if (1 == gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 1]) { FileOperation = FILE_DELETE; } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); TaskUpcCommClearDataStatus(i); continue; } time = (((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 2]) << 24) | (((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 3]) << 16) | (((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 4]) << 8) | ((unsigned int)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 5]); Year = time / 10000; Mon = (time % 10000) / 100; Day = time % 100; if (FileType == FILE_DATA_TYPE) { if (TASK_RUN_ENV_MESSGAE_ID == ((((unsigned short)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 6]) << 8) | ((unsigned short)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 7]))) { while (1) { rt = TaskFileEnableSend(FILE_DATA_TYPE, Year, Mon, Day, FileOperation, TASK_RUN_FILE_TYPE); if (rt == 0) { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_OK); break; } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); break; } } } else if (TASK_OUTPUT_GPIO_MESSGAE_ID == ((((unsigned short)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 6]) << 8) | ((unsigned short)gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j + 7]))) { while (1) { rt = TaskFileEnableSend(FILE_DATA_TYPE, Year, Mon, Day, FileOperation, TASK_OUTPUT_GPIO_FILE_TYPE); if (rt == 0) { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_OK); break; } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); break; } } } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_NO_SUP); TaskUpcCommClearDataStatus(i); continue; } } else if (FileType == FILE_LOG_TYPE) { while (1) { rt = TaskFileEnableSend(FILE_LOG_TYPE, Year, Mon, Day, FileOperation, NULL); if (rt == 0) { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_OK); break; } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); break; } } } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); } TaskUpcCommClearDataStatus(i); } else if (MessageId == PLAT_ASK_TERMINAL_RESTART_MESSAGE_ID) { do { ret = TaskFileLogWrite("TaskUpcComm: CMD ASK RESTART!!\n", strlen("TaskUpcComm: CMD ASK RESTART!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommHandleWatchdogId); OSTimeDly(1); } while (ret > 0); /* 平台请求重启设备 */ TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_OK); TaskUpcCommClearDataStatus(i); ToolDelayMs(1000); SysCtlReset(); } else if (MessageId == PLAT_CONF_RELAY_CONTROL_MESSAGE_ID) { do { ret = TaskFileLogWrite("TaskUpcComm: CMD CTRL GPIO!!\n", strlen("TaskUpcComm: CMD CTRL GPIO!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommHandleWatchdogId); OSTimeDly(1); } while (ret > 0); TaskOutPutGpioSet(OTN_CHANNEL_ID, gTaskUpcCommHandleDataBuf[i].HandleDataBuf[j]); TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_OK); TaskUpcCommClearDataStatus(i); } else { TaskUpcCommNormalAck(MessageNum, MessageId, TASK_ACK_ERR); TaskUpcCommClearDataStatus(i); } } } /* 发送函数 */ uint32_t TaskUpcCommSendMessage(uint16_t MessageId, uint16_t *Serial, uint8_t *SendBuf, uint32_t SendBufLen) { uint32_t i = 0; uint32_t j = 0; uint32_t k = 0; uint32_t e =0; unsigned int SendLen = 0; uint32_t RealSendLen = 0; uint16_t SendPiece = 0; // 发送条数,用来记录是否具有分包 uint16_t MessageProperties = 0; // 消息属性 if (Serial == NULL) { return 0; } SendPiece = (SendBufLen / 1023) + 1; //计算总共需要发几条信息 for (i = 0; i < SendPiece; i++) { if (SendPiece != 1) { if (i != (SendPiece - 1)) { MessageProperties = 0x2000 | 0x0c00 | 1023; } else { MessageProperties = 0x2000 | 0x0c00 | (SendBufLen % 1023); } } else { MessageProperties = 0x0000 | 0x0c00 | SendBufLen; } j = 0; /* 消息ID */ gSendBufTmp[j] = (uint8_t)((MessageId & 0xff00) >> 8); j++; gSendBufTmp[j] = (uint8_t)(MessageId & 0x00ff); j++; /* 设备类型 */ gSendBufTmp[j] = (uint8_t)((gDeviceType & 0xff000000) >> 24); j++; gSendBufTmp[j] = (uint8_t)((gDeviceType & 0x00ff0000) >> 16); j++; gSendBufTmp[j] = (uint8_t)((gDeviceType & 0x0000ff00) >> 8); j++; gSendBufTmp[j] = (uint8_t)(gDeviceType & 0x000000ff); j++; /* 设备ID号 */ gSendBufTmp[j] = (uint8_t)((gDeviceId & 0xff000000) >> 24); j++; gSendBufTmp[j] = (uint8_t)((gDeviceId & 0x00ff0000) >> 16); j++; gSendBufTmp[j] = (uint8_t)((gDeviceId & 0x0000ff00) >> 8); j++; gSendBufTmp[j] = (uint8_t)(gDeviceId & 0x000000ff); j++; /* 消息体属性 */ gSendBufTmp[j] = (uint8_t)((MessageProperties & 0xff00) >> 8); j++; gSendBufTmp[j] = (uint8_t)(MessageProperties & 0x00ff); j++; /* 协议版本号 */ gSendBufTmp[j] = 0x00; j++; gSendBufTmp[j] = 0x01; j++; /* 消息流水号 */ gSendBufTmp[j] = (uint8_t)(((*Serial) & 0xff00) >> 8); j++; gSendBufTmp[j] = (uint8_t)((*Serial) & 0x00ff); j++; /* 消息包装项 + 消息内容 */ if (SendPiece != 1) { /* 消息总包数 */ gSendBufTmp[j] = (uint8_t)((SendPiece & 0xff00) >> 8); j++; gSendBufTmp[j] = (uint8_t)(SendPiece & 0x00ff); j++; /* 包序号 */ gSendBufTmp[j] = (uint8_t)(((i + 1) & 0xff00) >> 8); j++; gSendBufTmp[j] = (uint8_t)((i + 1) & 0x00ff); j++; if (i != (SendPiece - 1)) { memcpy(&gSendBufTmp[j], &(SendBuf[1023 * i]), 1023); j += 1023; } else { memcpy(&gSendBufTmp[j], &(SendBuf[1023 * i]), SendBufLen % 1023); j += (SendBufLen % 1023); } } else { if ((SendBuf != NULL) && (SendBufLen != 0)) { memcpy(&gSendBufTmp[j], SendBuf, SendBufLen); j += SendBufLen; } } /* 进行校验 */ gSendBufTmp[j] = 0; ToolCheckCrc8_0x31(gSendBufTmp, j, &gSendBufTmp[j]); j++; /* 进行转义 */ e = 0; gTaskUpcCommSendDataBuf[e] = 0x7f; // 标志位 e++; for (k = 0; k < j; k++) { if (gSendBufTmp[k] == 0x7e) { gTaskUpcCommSendDataBuf[e] = 0x7e; e++; gTaskUpcCommSendDataBuf[e] = 0x01; e++; } else if (gSendBufTmp[k] == 0x7f) { gTaskUpcCommSendDataBuf[e] = 0x7e; e++; gTaskUpcCommSendDataBuf[e] = 0x02; e++; } else { gTaskUpcCommSendDataBuf[e] = gSendBufTmp[k]; e++; } } gTaskUpcCommSendDataBuf[e] = 0x7f; // 标志位 e++; /* 发送数据 */ if (gTaskTcpConnSta == 1) { netconn_write_partly(gTaskUpcCommTcpClientNetconn, gTaskUpcCommSendDataBuf, e, NETCONN_COPY, &SendLen); RealSendLen += SendLen; } else { return 0; } RealSendLen += e; } return RealSendLen; } /* 初始化网口任务 */ void TaskUpcCommInit(void) { err_t err = ERR_OK; /* 转换目标地址 */ gDestIp.addr = htonl((((unsigned int)gDestIpAddr.Addr0) << 24) | (((unsigned int)gDestIpAddr.Addr1) << 16) | (((unsigned int)gDestIpAddr.Addr2) << 8) | ((unsigned int)gDestIpAddr.Addr3)); /* 初始化网口 */ ZtmsLwipInit(gLocalIpAddr, gMaskAddr, gGwAddr); /* 等待网络口初始化完成 */ do { OSTimeDly(10); gTaskNetPortSta = ZtmsGetNetStatus(); } while (gTaskNetPortSta == 0); /* 创建TCP通信套接字 */ do { OSTimeDly(10); gTaskUpcCommTcpNetconn = netconn_new(NETCONN_TCP); } while (gTaskUpcCommTcpNetconn == NULL); /* bind IP */ do { OSTimeDly(10); err = netconn_bind(gTaskUpcCommTcpNetconn, IP_ADDR_ANY, gLocalIpPort); } while (err == ERR_OK); do { OSTimeDly(10); err = netconn_listen(gTaskUpcCommTcpNetconn); } while (err == ERR_OK); /* 设置接收超时时间20ms */ gTaskUpcCommTcpNetconn->recv_timeout = 20; /* 注册看门狗 */ gTaskUpcCommRecvWatchdogId = TaskWatchdogRegEvent("TaskUpcCommRecv"); gTaskUpcCommExtractWatchdogId = TaskWatchdogRegEvent("TaskUpcCommExtract"); gTaskUpcCommHandleWatchdogId = TaskWatchdogRegEvent("TaskUpcCommHandle"); } static void TaskUpcCommStartRecv(void) { struct netbuf *RecvNetBuf; err_t err = ERR_OK; unsigned int RealWbyte; int ret; while ((gTaskNetPortSta == 1) && (gTaskTcpConnSta == 1)) { err = netconn_recv(gTaskUpcCommTcpClientNetconn, &RecvNetBuf); /* 如果接收不等于超时也不等于接收成功 */ if (err != ERR_TIMEOUT && err != ERR_OK) { gTaskTcpConnSta = 0; gTaskNetPortSta = ZtmsGetNetStatus(); continue; // 进行条件判断时会自动跳出 } if (err == ERR_OK) { int i; CPU_SR_ALLOC(); OS_ENTER_CRITICAL(); //关中断 for (i = 0; i < RecvNetBuf->p->len; i++) { gTaskUpcCommRecvDataBuf[gTaskUpcCommRecvDataBufRecvLocal] = ((unsigned char *)RecvNetBuf->p->payload)[i]; gTaskUpcCommRecvDataBufRecvLocal++; gTaskUpcCommRecvDataBufRecvLocal = gTaskUpcCommRecvDataBufRecvLocal % TASK_COMM_RECV_DATA_BUFLEN; } OS_EXIT_CRITICAL(); } gTaskNetPortSta = ZtmsGetNetStatus(); netbuf_delete(RecvNetBuf); TaskWatchdogFreed(gTaskUpcCommRecvWatchdogId); OSTimeDly(1); // 需要TCP不停处于接收态 } /* 当接收循环跳出时,代表着出现了错误,写入日志文件 */ do { ret = TaskFileLogWrite("TaskUpcCommStartRecv: TCP Disconnect or Cable Disconnect!!\n", strlen("TaskUpcCommStartRecv: TCP Disconnect or Cable Disconnect!!\n"), &RealWbyte); TaskWatchdogFreed(gTaskUpcCommRecvWatchdogId); OSTimeDly(1); } while (ret > 0); /* 关闭连接 */ netconn_close(gTaskUpcCommTcpClientNetconn); netconn_delete(gTaskUpcCommTcpClientNetconn); gTaskUpcCommTcpClientNetconn = NULL; } /* TCP套接字连接服务器 */ static void TaskUpcCommTcpSocketConn(void) { err_t err = ERR_OK; do { /* 等待网络口初始化完成 */ do { TaskWatchdogFreed(gTaskUpcCommRecvWatchdogId); OSTimeDly(10); gTaskNetPortSta = ZtmsGetNetStatus(); } while (gTaskNetPortSta == 0); /* 等待连接 */ err = netconn_accept(gTaskUpcCommTcpNetconn, &gTaskUpcCommTcpClientNetconn); } while (err != ERR_OK); gTaskTcpConnSta = 1; gTaskUpcCommTcpClientNetconn->recv_timeout = 200; gTaskUpcCommTcpClientNetconn->pcb.tcp->so_options |= SOF_KEEPALIVE; } static void TaskUpcCommClearDataStatus(unsigned char CountId) { gTaskUpcCommHandleDataBuf[CountId].HandleFlag = TASK_COMM_DATA_IDLING; gTaskUpcCommHandleDataBuf[CountId].HandleCount = 0; } static void TaskUpcCommNormalAck(unsigned short PlatNum, unsigned short PlatId, uint8_t Result) { uint8_t Ack[5] = {0}; static unsigned short Serial = 0; Ack[0] = (uint8_t)((PlatNum & 0xff00) >> 8); Ack[1] = (uint8_t)(PlatNum & 0x00ff); Ack[2] = (uint8_t)((PlatId & 0xff00) >> 8); Ack[3] = (uint8_t)(PlatId & 0x00ff); Ack[4] = Result; TaskUpcCommSendMessage(0x0000, &Serial, Ack, sizeof(Ack)); Serial++; }