
#define	_IN_OPERATOR_C

#include "operator.h"

#include "serial.h"
#include "delay.h"
#include "tcpserver.h"
#include "filetrans.h"
#include "trigger.h"
#include "stapp.h"
#include "paras.h"

#include "extendboards.h"

#if (CUR_CORE_BOARD == CORE_BOARD_APP)

#include "workctrl.h"
#include "installment.h"
#include "error.h"

#else

#include "cpuid.h"

#endif

//---------------------------------------------------------------

int ReceiveMcParas(OperPacket * pPkt);
int CreateMcParas(OperPacket * pPkt, int type, int id);
void CleanBuffAfterAction(void);

//---------------------------------------------------------------

#if (OPERATOR_PORT == COMM_ETHERNET)

SocketCtrl * g_pOperatorSocket = NULL;
#define OPERATOR_SIDX	TCP_SERVER_SN_BEG				// udp socket

// 发送数据
int OperatorSendData(u8 * pDatBuf, int len)
{
	return EthernetSendData(g_pOperatorSocket, pDatBuf, len);
}

// 接收数据
int OperatorGetData(u8 * pDat, int expectLen)
{
	return EthernetGetData(g_pOperatorSocket, pDat, expectLen);
}

// 已接收数据长度
int OperatorGetRsLen(void)
{
	return EthernetGetRsLen(g_pOperatorSocket);
}

// 得到发送缓冲区空闲长度
int OperatorGetSdFreeLen(void)
{
	return EthernetGetSdFreeLen(g_pOperatorSocket);
}

#endif

DataExFuns g_operDataExFuns;

//---------------------------------------------------------------

int SendOperCommData(const u8 * pDatBuf, int len)
{
	printf("SendOperCommData is Empty\r\n");
	return 0;
}

int GetOperCommData(u8 * pDat, int expectLen)
{
	printf("GetOperCommData is Empty\r\n");
	return 0;
}

int GetOperRsvLen(void)
{
	printf("GetOperRsvLen is Empty\r\n");
	return 0;
}

int GetOperTrsFreeLen(void)
{
	printf("GetOperTrsFreeLen is Empty\r\n");
	return 0;
}

void InitOperator(void)
{
#if (OPERATOR_PORT == COMM_ETHERNET)
	InitEthernet();

	g_pOperatorSocket = GetCtrlFromSocketIdx(OPERATOR_SIDX);

	g_operDataExFuns.SendCommData = OperatorSendData;
	g_operDataExFuns.GetCommData = OperatorGetData;
	g_operDataExFuns.GetRsvLen = OperatorGetRsLen;
	g_operDataExFuns.GetTrsFreeLen = OperatorGetSdFreeLen;
	g_operDataExFuns.Delay = DelayMs;

	AddTriggerToList(1000, NULL, EthernetServiceRun);		// 1000ms 添加以太网服务

#elif (OPERATOR_PORT == COMM_USART1)
	InitUsart1(B115200, '8', 'N', '1');

	g_operDataExFuns.SendCommData = Usart1SendData;
	g_operDataExFuns.GetCommData = Usart1GetData;
	g_operDataExFuns.GetRsvLen = Usart1GetRsLen;
	g_operDataExFuns.GetTrsFreeLen = Usart1GetSdFreeLen;
	g_operDataExFuns.Delay = DelayMs;

#else

	g_operDataExFuns.SendCommData = SendOperCommData;
	g_operDataExFuns.GetCommData = GetOperCommData;
	g_operDataExFuns.GetRsvLen = GetOperRsvLen;
	g_operDataExFuns.GetTrsFreeLen = GetOperTrsFreeLen;
	g_operDataExFuns.Delay = DelayMs;

#endif

}

// 请求文件数据包
void RequestFileData(u8 fileType, u8 fileIdx, u16 fileId, int datblockIdx)
{
	int rslt;
	OperPacket operpkt;
	DataPacket* pDatpkt = (DataPacket*)(&operpkt);

	memset(pDatpkt, 0, LEN_NORMAL_PACKET);

	operpkt.requestDatBlock.cmdCode = DCMD_REQUEST_DAT;
	operpkt.requestDatBlock.fileType = fileType;
	operpkt.requestDatBlock.fileIdx = fileIdx;
	operpkt.requestDatBlock.fileId = fileId;
	operpkt.requestDatBlock.datBlockIdx = datblockIdx;	// 数据包索引（每个包1024字节)

	rslt = PacketAFLDP(&(operpkt.packet));
	if (rslt != 0)
	{
//		printf("error at call PacketAFLDP in SendMcStatus\r\n");
	}
	else
	{
		rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);

		if (rslt != 0)
		{
	//		printf("error at call SendAPacket in SendMcStatus\r\n");
		}
	}
}

#if (CUR_CORE_BOARD != CORE_BOARD_BOOT)

void OperatorTask(void)
{
	int rslt;
	
	OperPacket operpkt;
	DataPacket* pDatpkt = (DataPacket*)(&operpkt);

	// 读取操作箱命令
	rslt = GetANormalPacket(&g_operDataExFuns, pDatpkt);

	// 分析数据包，并执行
	if (rslt > 0)	// 收到数据包
	{
		switch(operpkt.packet.fldp.cmd)			// 先按固定长度解析
		{
			case UCMD_GET_MC_INFO:					// 读取机器信息
			{
				printf("get mc info cmd, toggle=%d\r\n", operpkt.getMcInfo.toggle);
				rslt = CreateMcInfo(&operpkt, operpkt.getMcInfo.toggle);
				if (rslt == 0)
				{
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTask UCMD_GET_MC_INFO \r\n");
					}
				}
				else
				{
					printf("error at call CreateMcInfo in OperatorTask UCMD_GET_MC_INFO \r\n");
				}
				break;
			}
			case UCMD_GET_MC_STATUS:				// 读取机器状态
			{
			//	printf("get mc status cmd, toggle=%d\r\n", operpkt.getMcStatus.toggle);
				rslt = CreateMcStatus(&operpkt, operpkt.getMcStatus.toggle);
				if (rslt == 0)
				{
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTask UCMD_GET_MC_STATUS \r\n");
					}
				}
				else
				{
					printf("error at call CreateMcStatus in OperatorTask UCMD_GET_MC_STATUS \r\n");
				}
				break;
			}
			case UCMD_GET_MC_PARAS:			// 读取机器参数
			{
				printf("get mc paras cmd\r\n");
				rslt = CreateMcParas(&operpkt, operpkt.getMcParas.paraType, operpkt.getMcParas.paraId);
				if (rslt == 0)
				{
				//	int temp = GetMsSoftTimer();
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 10000);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTask UCMD_GET_MC_PARAS \r\n");
					}
				}
				else
				{
					printf("error at call CreateMcParas in OperatorTask UCMD_GET_MC_PARAS \r\n");
				}
				break;
			}
			case UCMD_GET_MEM_DATA:			// 读取内存数据
				break;
			case UCMD_GET_SENSORS:			// 读取传感信号
			{
				//printf("get mc sensors cmd\r\n");
				rslt = CreateSensorsStatus(&operpkt);
				if (rslt == 0)
				{
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTask UCMD_GET_SENSORS \r\n");
					}
				}
				else
				{
					printf("error at call CreateSensorsStatus in OperatorTask UCMD_GET_SENSORS \r\n");
				}
				break;
			}
			case UCMD_GET_SENSORS_BMP:			// 读取有效传感器位图
			{
				printf("get mc sensors bmp cmd\r\n");
				rslt = CreateSensorsBmp(&operpkt);
				if (rslt == 0)
				{
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTask UCMD_GET_SENSORS_BMP \r\n");
					}
				}
				else
				{
					printf("error at call CreateSensorsBmp in OperatorTask UCMD_GET_SENSORS_BMP \r\n");
				}
				break;
			}
			case UCMD_GET_FILE_INFO:		// 读取文件信息
			{
				rslt = CreateFileInfo(&operpkt);
				if (rslt == 0)
				{
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 1000);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTask UCMD_GET_FILE_INFO \r\n");
					}
				}
				else
				{
					printf("error at call CreateFileInfo in OperatorTask UCMD_GET_FILE_INFO \r\n");
				}
				break;
			}
			case UCMD_GET_TRANS_RESULT:		// 读取传输结果
			{
				printf("1. get trans result cmd\r\n");
				rslt = CreateTransResult(&operpkt);
				if (rslt == 0)
				{
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 1000);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTask UCMD_GET_TRANS_RESULT \r\n");
					}
				}
				else
				{
					printf("error at call CreateTransResult in OperatorTask UCMD_GET_TRANS_RESULT \r\n");
				}

				break;
			}
			case UCMD_SET_MC_CONFIG:		// 设置机器配置
			{
				break;
			}
			case UCMD_SET_MC_STATUS:		// 设置机器状态
			{
				printf("SetMcStatus when stop\r\n");
				SetMcStatus(operpkt.setMcStatus.staCode, operpkt.setMcStatus.para);
				break;
			}
			case UCMD_SET_MC_PARAS:			// 设置机器参数
			{
				printf("receive set mc para cmd\r\n");
				ReceiveMcParas(&operpkt);
				break;
			}
			case UCMD_SET_MEM_DATA:			// 设置内存数据
			{
				break;
			}
			case UCMD_SET_FILE_PARAS:		// 设置文件参数
			{
				ReceiveFileParas(&operpkt);
				break;
			}
			case UCMD_SET_FILE_EXDATA:		// 设置文件扩展数据
			{
				ReceiveFileExData(&operpkt);
				break;
			}
			case UCMD_SET_EXEC_PROGRESS:	// 设置执行进度
			{
				SetExecProgress(&operpkt);
				break;
			}
			case UCMD_SET_INSTALLMENT:		// 设置分期密码
			{
				int rslt;
				printf("set installment\r\n");
				rslt = SetInstallMent((char*)(operpkt.setInstallment.exData));

				RefreshWorkTimeEn();

				if (rslt >= 0)
				{
					ReportError(ERR_INSTALLMENT_OK);		// 密码设置成功
				}
				else
				{
					ReportError(ERR_INSTALLMENT_FAIL);		// 密码设置失败
				}
				break;
			}
			case UCMD_SET_ELAPSED_TIME:		// 设置经过的时间
			{
				printf("set elapsed, type=%d, time = %d\r\n", operpkt.setElapsedTime.type, operpkt.setElapsedTime.time);

				if (g_workCtrl.cansetelapsed == 0)
				{
					u32 time;
					s32 val;
					time = operpkt.setElapsedTime.time;
					if (time > 5000*3600)			// 5000小时
					{
						time = 5000*3600;
					}
					time /= 60;		// 分钟
					val = time;
					val *= -1;

					if (abs(val) < 60)
					{
						printf("close time=%d min\r\n", val);
					}
					else if (abs(val) < 1440)
					{
						s32 hour, min;
						hour = val / 60;
						min = val % 60;
						printf("close time=%d hour %d min\r\n", hour, min);
					}
					else
					{
						s32 day, hour, min;
						day = val / 1440;
						hour = val % 1440;
						min = hour % 60;
						hour /= 60;
						printf("close time=%d day %d hour %d min\r\n", day, hour, min);
					}
					RefWorkableTimer(val);
					
					RefreshWorkTimeEn();
					g_workCtrl.cansetelapsed = 1;
				}
				else
				{
					printf("has set elapsed already\r\n");
				}
				break;
			}
			//---------------

			case UCMD_ACT_BYHAND:			// 手动控制命令
			{
				ReportError(ERR_NONE);
				ControlByHand(&operpkt);

				CleanBuffAfterAction();

				break;
			}
			case UCMD_MC_WORK:				// 机器工作命令
			{
				ReportError(ERR_NONE);
				ControlWork(&operpkt);
				CleanBuffAfterAction();
				break;
			}
			case UCMD_MOVE_TO:				// 框架移动到
			{
				MoveFrameTo(&operpkt);
				break;
			}
			case UCMD_MOVE_OFST:			// 框架移动偏移量
			{
				MoveFrameAsOfst(&operpkt);
				break;
			}
			case UCMD_START_TRANS:			// 启动文件传输
			{
				StartReceiveFile(&operpkt);
				SaveFileIdxFromDatafile();
				if (IsNewDatFile(0) == FALSE)
				{
					SetFileOkFlag(0);
				}
				break;
			}
			case UCMD_TRANS_FILE_DATA:		// 文件传输命令
			{
				u32 thistimer, oldtimer;
				oldtimer = GetMsSoftTimer();
				do
				{
					int svrslt = SavePreProc();
					if (svrslt == 2 || svrslt < 0)
					{
						break;
					}
					thistimer = GetMsSoftTimer();
					if ((thistimer - oldtimer) > 3000)
					{
						oldtimer = thistimer;
						SendStatus(1);	// 发送状态,防止界面断开连接
					}
				}while(1);

				ReceiveFileData(&operpkt);
				if (IsNewDatFile(0) == TRUE)
				{
					SetFileOkFlag(1);				// 文件接收标志
				}

				break;
			}
			case UCMD_SET_FILE_LIST:		// 设置文件列表
			{
				ResetFileList(&operpkt);
				SaveFileIdxFromDatafile();
				break;
			}
			case UCMD_BOARD_UPDATE:			// 外围板升级
			{
				// 机头板协议,上位机不需要知道对应的节点ID,只需告知节点类型和机头号即可
				// 换色板协议 需告知第几块
				printf("update ex board, protocolType=%d, nodetype=%d, nodeId=%d\r\n", operpkt.updateBoard.protocolType, operpkt.updateBoard.nodetype, operpkt.updateBoard.nodeId);
				StartBoardUpdate(operpkt.updateBoard.protocolType, operpkt.updateBoard.nodetype, operpkt.updateBoard.nodeId);
				DelayRef(1);
				break;
			}
			case UCMD_MC_UPDATE:			// 下位机升级
			{
				printf("receive updat mc cmd\r\n");
				DelayRef(100);
				StartAppUpdate(1); 			// 升级并重启
				break;
			}
			case UCMD_GET_FILE_LIST:		// 获取下位机文件列表
			{
				rslt = CreateFileList(&operpkt, g_datFile.fileIdxMap);
				if (rslt == 0)
				{
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTask UCMD_GET_FILE_LIST \r\n");
					}
				}
				else
				{
					printf("error at call CreateMcStatus in OperatorTask UCMD_GET_FILE_LIST \r\n");
				}
				break;
			}
			case UCMD_SET_DEF_PARA	:		// 设置默认参数
			{
				printf("receive set def para cmd\r\n");
				char * info = "set mc and wk def para";
				SendDebugInfo(info);
				WriteDefMcPara();
				WriteDefWkPara();
				break;
			}
			case UCMD_SET_MVANGDEF_PARA:	// 设置动框角度默认参数
			{
				printf("receive set move angle def para cmd\r\n");
				char * info = "set mv angle def para";
				SendDebugInfo(info);
				WriteDefMvAngPara();
				break;
			}
			case UCMD_SET_HEADDEF_PARA:	// 设置机头板默认参数
			{
				printf("set head def para, nodetype=%d, id=%d\r\n", operpkt.setDefParas.nodetype, operpkt.setDefParas.id);
				char buf[1024];
				sprintf(buf, "set head def para, nodetype=%d", operpkt.setDefParas.nodetype);
				SendDebugInfo(&buf[0]);
				SetBoardNvPara(BN_PROTOCOL_HEAD, operpkt.setDefParas.nodetype, operpkt.setDefParas.id, 255, 0, 0);
				break;
			}
			case UCMD_SET_COLORDEF_PARA:		// 设置换色板默认参数
			{
				printf("set color def para, boardnum=%d\r\n", operpkt.setDefParas.id);
				char buf[1024];
				sprintf(buf, "set color def para, id=%d", operpkt.setDefParas.id);
				SendDebugInfo(&buf[0]);
				SetBoardNvPara(BN_PROTOCOL_COLOR, 0, operpkt.setDefParas.id, 255, 0, 0);
				break;
			}
			case UCMD_TRA_BOARD:			// 机头板遍历
			{
				printf("traverse cmd, protocolType=%d, nodeId=%d, nodeType=%d, traNum=%d\r\n", operpkt.traverse.protocolType,
						operpkt.traverse.nodeId, operpkt.traverse.nodeType, operpkt.traverse.traNum);
				TraverseTask(operpkt.traverse.protocolType,
							 operpkt.traverse.nodeId,
							 operpkt.traverse.nodeType,
							 operpkt.traverse.traNum);
				break;
			}
			case UCMD_GET_BOARD_VER:		// 读取外围板程序版本
			{
				RequestBoardVer();
				DelayRef(100);
#if (MAX_SUPPORT_COLOR > 0)
				ColorControl * color = NULL;
				for (int i = 1; i < MAX_SUPPORT_COLOR+1; i++)
				{
					color = GetColorFromList(i+1);
					if (color->verFlag == 1)
					{
						color->verFlag = 0;
						rslt = CreateBoardVer(&operpkt, BN_PROTOCOL_COLOR, color->nodeId, 0, &color->regVal);
						if (rslt == 0)
						{
							rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
							if (rslt != 0)
							{
								printf("error at call SendAPacket in OperatorTask DCMD_SEND_BOARDVER \r\n");
							}
						}
						else
						{
							printf("error at call CreateBoardVer in OperatorTask DCMD_SEND_BOARDVER \r\n");
						}
					}
				}
#endif
#if (MAX_SUPPORT_HEAD > 0)
				HeadControl * head = NULL;
				for (int i = 1; i < MAX_SUPPORT_HEAD+1; i++)
				{
					head = GetHeadFromList(i+1);
					if (head->verFlag == 1)
					{
						head->verFlag = 0;
						rslt = CreateBoardVer(&operpkt, BN_PROTOCOL_HEAD, head->nodeId, head->nodeTye, &head->regVal);
						if (rslt == 0)
						{
							rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
							if (rslt != 0)
							{
								printf("error at call SendAPacket in OperatorTask DCMD_SEND_BOARDVER \r\n");
							}
						}
						else
						{
							printf("error at call CreateBoardVer in OperatorTask DCMD_SEND_BOARDVER \r\n");
						}
					}
				}
#endif
#if (MAX_SUPPORT_EXTIO > 0)
				ExtIOControl * extio = NULL;
				for (int i = 1; i < MAX_SUPPORT_EXTIO+1; i++)
				{
					extio = GetExtIOFromList(i+1);
					if (extio->verFlag == 1)
					{
						extio->verFlag = 0;
						rslt = CreateBoardVer(&operpkt, BN_PROTOCOL_EXTIO, extio->nodeId, 0, &extio->regVal);
						if (rslt == 0)
						{
							rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
							if (rslt != 0)
							{
								printf("error at call SendAPacket in OperatorTask DCMD_SEND_BOARDVER \r\n");
							}
						}
						else
						{
							printf("error at call CreateBoardVer in OperatorTask DCMD_SEND_BOARDVER \r\n");
						}
					}
				}
#endif
				break;
			}
#if (RD_HEAD_PARA_NUM > 0)
			case UCMD_GET_HEAD_PARA:	// 读取机头板参数
			{
				/*
				 * 20220601 此种实现方式的前提是总线检测成功
				 * 上位机不需要知道具体的节点ID,只负责告知下位机节点类型(如平绣,毛巾,缠绕)和对应的机头号即可
				*/
				int i, hdnm;
				hdnm = operpkt.boardPara.nodeId;	// 对应机头号
				for (i = 1; i < MAX_SUPPORT_HEAD+1; i++)
				{
					HeadControl * phd = GetHeadFromList(i+1);
					if (phd->nodeTye == operpkt.boardPara.nodeType)
					{// 若广播,则读取相应节点类型的第一个节点
						if (hdnm <= 1)
						{
							break;
						}
						else
						{
							hdnm--;
						}
					}
				}

				if (i <= MAX_SUPPORT_HEAD)		// 找到对应的节点
				{
					printf("read head=%d para\r\n", i);
					RequestAHeadNvPara(i);	// 读取某个节点的参数
					DelayRef(100);
					HeadControl * head = GetHeadFromList(i+1);
					if (head->nvParaFlag == 1)
					{
						head->nvParaFlag = 0;
						int id = 0;;
						if (head->nodeTye == FLAT_EMB_HEAD)
						{
							id = 1;
						}
						else if (head->nodeTye == CHENILLE_HEAD)
						{
							id = 2;
						}
						else if (head->nodeTye == COIL_HEAD)
						{
							id = 3;
						}
						rslt = CreateHeadBoardPara(&operpkt, i, operpkt.boardPara.nodeType, GetBoardNvPara(id));
						if (rslt == 0)
						{
							printf("send head para\r\n");
							rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
							if (rslt != 0)
							{
								printf("error at call SendAPacket in OperatorTask DCMD_SEND_HEADPARA \r\n");
							}
						}
						else
						{
							printf("error at call CreateHeadBoardPara in OperatorTask DCMD_SEND_HEADPARA \r\n");
						}
					}
					else
					{
						printf("receive err\r\n");
						ReportError(ERR_READ_HEAD_PARA);
					}
				}
				else		// 总线检测错误
				{
					printf("not find node\r\n");
					ReportError(ERR_READ_HEAD_PARA);
				}
				break;
			}
			case UCMD_GET_COLOR_PARA:		// 读取换色控制板参数
			{
				if (operpkt.boardPara.nodeId != 0)		// 不支持广播读取
				{
					ColorControl * color = GetColorFromList(operpkt.boardPara.nodeId+1);
					if (color != NULL)
					{
						color->refNvPara = 1;
						DelayRef(100);
						if (color->nvParaFlag == 1)
						{
							color->nvParaFlag = 0;
							int id = 0;;
							if (operpkt.boardPara.nodeId == 2)
							{// 毛巾换色板
								id = 4;
							}
							rslt = CreateColorBoardPara(&operpkt, operpkt.boardPara.nodeId, GetBoardNvPara(id));
							if (rslt == 0)
							{
								printf("send color para, nodeid=%d\r\n", operpkt.boardPara.nodeId);
								rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
								if (rslt != 0)
								{
									printf("error at call SendAPacket in OperatorTask UCMD_GET_COLOR_PARA \r\n");
								}
							}
							else
							{
								printf("error at call CreateColorBoardPara in OperatorTask UCMD_GET_COLOR_PARA \r\n");
							}
						}
						else
						{
							printf("receive err\r\n");
							ReportError(ERR_READ_COLOR_PARA);
						}
					}
				}
				else
				{
					printf("not support broadcast read color para\r\n");
				}
				break;
			}
#endif
			case UCMD_GET_HEAD_NVPARAS:		// 选择性读取机头参数
			{// 可读取任意机头 任意参数块参数,并打包发送给上位机
				printf("get head type=%d id=%d nvparaid=%d\r\n", operpkt.boardPara.nodeType, operpkt.boardPara.nodeId, operpkt.boardPara.paraid);
				u32 buf[32] = {0};
				int rslt = RequestHeadNvParas(operpkt.boardPara.nodeType, operpkt.boardPara.nodeId, operpkt.boardPara.paraid, &buf[0]);
				if (rslt == 0)
				{
					rslt = CreateHeadNvParas(&operpkt, operpkt.boardPara.nodeType, operpkt.boardPara.nodeId, operpkt.boardPara.paraid, (u8*)(&buf[0]));
					if (rslt == 0)
					{
						printf("send head nv paras\r\n");
						rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
						if (rslt != 0)
						{
							printf("error at call SendAPacket in OperatorTask UCMD_GET_HEAD_NVPARAS \r\n");
						}
					}
					else
					{
						printf("error at call CreateHeadNvParas in OperatorTask UCMD_GET_HEAD_NVPARAS \r\n");
					}
				}
				else
				{
					printf("read head nv paras error, rslt=%d\r\n", rslt);
					ReportError(ERR_READ_HEAD_PARA);
				}
				break;
			}

			case UCMD_SET_HEAD_PARA:		// 设置机头板参数
			{
				printf("set head para, nodetype=%d, nodeId=%d\r\n", operpkt.boardPara.nodeType, operpkt.boardPara.nodeId);
				BoardFilePacketCtrl boardpkt;
				ParaDataFromOperToCan(BN_PROTOCOL_HEAD, &operpkt, &boardpkt);
				break;
			}

			case UCMD_SET_COLOR_PARA:		// 设置换色控制板参数
			{
				printf("set color para, boardnum=%d\r\n", operpkt.boardPara.nodeId);
				BoardFilePacketCtrl boardpkt;
				ParaDataFromOperToCan(BN_PROTOCOL_COLOR, &operpkt, &boardpkt);
				break;
			}

			case UCMD_SET_HEAD_NVPARA:		// 选择性设置机头参数
			{
				printf("set head type=%d id=%d paraid=%d nvpara\r\n", operpkt.boardPara.nodeType, operpkt.boardPara.nodeId, operpkt.boardPara.paraid);
//				SetHeadNvPara(operpkt.boardPara.nodeType, operpkt.boardPara.nodeId, operpkt.boardPara.paraid, (u32*)(&operpkt.boardPara.exData));
				break;
			}

			default:
			{
				break;
			}
		}
	}
//	SavePreProc();
}

void CleanBuffAfterAction(void)
{
	int ret;
	int temp, timer;

	timer = GetMsSoftTimer();
	do
	{
		ret = ReadBuffEmpty(&g_operDataExFuns);		// 清空接收缓冲区
		if (ret == 0)
		{
			break;
		}
		else
		{
			printf("ReadBuffEmpty rslt=%d\r\n", ret);
		}
		DelayRef(1);
		temp = GetMsSoftTimer();
		if (temp - timer > 10)
		{
			printf("CleanBuffAfterAction timout\r\n");
			break;
		}
	}while(1);
}

// 发送运行状态
void SendMcStatus(int force)
{
	int rslt;
	OperPacket operpkt;
	DataPacket* pDatpkt = (DataPacket*)(&operpkt);

	if (IsStatusChanged() != 0 || force != 0)
	{
		rslt = CreateMcStatus(&operpkt, 0);
		if (rslt == 0)
		{
			rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
//			printf("SendMcStatus\r\n");
			if (rslt != 0)
			{
//				printf("error at call SendAPacket in SendMcStatus\r\n");
			}
		}
		else
		{
			printf("error at call CreateMcStatus in SendMcStatus\r\n");
		}

		SetLightStaByCode(g_workCtrl.cursta.errorCode);
	}
}
// --------------------------------------------

int IsSocketConnected(void)
{
#if (OPERATOR_PORT == COMM_ETHERNET)
    if (g_pOperatorSocket->status == STA_CONNECT)
    {
        return TRUE;
    }
#endif
    return FALSE;
}

int IsNewOperCmd(void)
{
	int rslt;

	OperPacket operpkt;
	DataPacket* pDatpkt = (DataPacket*)(&operpkt);

	rslt = GetANormalPacket(&g_operDataExFuns, pDatpkt);
	if (rslt > 0)	// 收到数据包
	{
		return TRUE;
	}
#if (OPERATOR_PORT == COMM_ETHERNET)
	if (IsSocketConnected() != TRUE)
	{
//		return TRUE;
	}
#endif

	return FALSE;
}

void OperatorTaskWhenRun(int revfile)
{
	int rslt;
	
	OperPacket operpkt;
	DataPacket* pDatpkt = (DataPacket*)(&operpkt);

	// 读取操作箱命令
	rslt = GetANormalPacket(&g_operDataExFuns, pDatpkt);

	// 分析数据包，并执行
	if (rslt > 0)	// 收到数据包
	{
		switch(operpkt.packet.fldp.cmd)			// 先按固定长度解析
		{
		case UCMD_GET_MC_STATUS:		// 读取机器状态
		{
			printf("get mc status cmd when run\r\n");
			rslt = CreateMcStatus(&operpkt, operpkt.getMcStatus.toggle);
			if (rslt == 0)
			{
				rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 0);
				if (rslt != 0)
				{
					printf("error at call SendAPacket in OperatorTaskWhenRun UCMD_GET_MC_STATUS \r\n");
				}
			}
			else
			{
				printf("error at call CreateMcStatus in OperatorTaskWhenRun UCMD_GET_MC_STATUS \r\n");
			}
			break;
		}
		case UCMD_GET_MC_PARAS:			// 读取机器参数
		{
			printf("get mc paras cmd\r\n");
			rslt = CreateMcParas(&operpkt, operpkt.getMcParas.paraType, operpkt.getMcParas.paraId);
			if (rslt == 0)
			{
			//	int temp = GetMsSoftTimer();
				rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 10000);
				if (rslt != 0)
				{
					printf("error at call SendAPacket in OperatorTask UCMD_GET_MC_PARAS \r\n");
				}
			}
			else
			{
				printf("error at call CreateMcParas in OperatorTask UCMD_GET_MC_PARAS \r\n");
			}
			break;
		}
		case UCMD_SET_MC_STATUS:		// 设置机器状态
		{
			printf("SetMcStatus when run\r\n");
			SetMcStatus(operpkt.setMcStatus.staCode, operpkt.setMcStatus.para);
			break;
		}
		case UCMD_MC_WORK:				// 机器工作命令
		{
			printf("get control work cmd when run\r\n");
			ControlWorkWhenWorking(&operpkt);
			break;
		}
		case UCMD_GET_FILE_INFO:		// 读取文件信息
		{
			if (revfile == 1)
			{
				rslt = CreateFileInfo(&operpkt);
				if (rslt == 0)
				{
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 1000);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTaskWhenRun UCMD_GET_FILE_INFO \r\n");
					}
				}
				else
				{
					printf("error at call CreateFileInfo in OperatorTaskWhenRun UCMD_GET_FILE_INFO \r\n");
				}
			}
			break;
		}
		case UCMD_GET_TRANS_RESULT:		// 读取传输结果
		{
			if (revfile == 1)
			{
				printf("3. get trans result cmd\r\n");
				rslt = CreateTransResult(&operpkt);
				if (rslt == 0)
				{
					rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 1000);
					if (rslt != 0)
					{
						printf("error at call SendAPacket in OperatorTaskWhenRun UCMD_GET_TRANS_RESULT \r\n");
					}
				}
				else
				{
					printf("error at call CreateTransResult in OperatorTaskWhenRun UCMD_GET_TRANS_RESULT \r\n");
				}
			}
			break;
		}
		case UCMD_SET_FILE_PARAS:		// 设置文件参数
		{
			if (revfile == 1)
			{
				ReceiveFileParas(&operpkt);
			}
			break;
		}
		case UCMD_START_TRANS:			// 启动文件传输
		{
			if (revfile == 1)
			{
				StartReceiveFile(&operpkt);
				SaveFileIdxFromDatafile();
				if (IsNewDatFile(0) == FALSE)
				{
					SetFileOkFlag(0);
				}
			}
			break;
		}
		case UCMD_TRANS_FILE_DATA:		// 文件传输命令
		{
			if (revfile == 1)
			{
				ReceiveFileData(&operpkt);
				if (IsNewDatFile(0) == TRUE)
				{
					SetFileOkFlag(1);				// 文件接收标志
				}
			}
			break;
		}
		case UCMD_SET_FILE_LIST:		// 设置文件列表
		{
			ResetFileList(&operpkt);
			SaveFileIdxFromDatafile();
			break;
		}

		case UCMD_SET_EXEC_PROGRESS:	// 设置执行进度
		{
			if (revfile == 1)
			{
				SetExecProgress(&operpkt);
			}
			break;
		}

		default:
			printf("get cmd = 0x%x when run\r\n", operpkt.packet.fldp.cmd);
			break;
		}
	}
	if (revfile == 1)
	{
//		SavePreProc();
	}
}

int ReceiveMcParas(OperPacket * pPkt)
{
	int rslt;

	rslt = 0;
	if (pPkt == NULL)
	{
		return -1;
	}

//-----------

	//printf("ReceiveParas type = %d, exlen=%d\r\n", pPkt->setParas.paraType, pPkt->setParas.exLen);

	if (pPkt->setParas.paraType == SEW_MCPARA_MACH)
	{
		if (pPkt->setParas.exLen == sizeof(g_mcPara))
		{
			memcpy((u8*)(&g_mcPara), pPkt->setParas.exData, sizeof(g_mcPara));
			CheckMcParaRange();
			SaveMcPara();
			RefreshParas(PARA_MC_VALID);
			SetNewParasFlag(PARA_MC_VALID);
			rslt = 0;
		}
		else if (pPkt->setParas.exLen == sizeof(u32))
		{
			SetAMcPara(pPkt->setParas.paraId, *((u32*)(pPkt->setParas.exData)));
			SaveMcPara();
			RefreshParas(PARA_MC_VALID);
			SetNewParasFlag(PARA_MC_VALID);
		}
		else
		{
			rslt = -2;
		}
	}
	else if (pPkt->setParas.paraType == SEW_MCPARA_WORK)
	{
		if (pPkt->setParas.exLen == sizeof(g_wkPara))
		{
			memcpy((u8*)(&g_wkPara), pPkt->setParas.exData, sizeof(g_wkPara));
			CheckWkParaRange();
			SaveWkPara();
			RefreshParas(PARA_WK_VALID);
			SetNewParasFlag(PARA_WK_VALID);
			rslt = 0;
		}
		else if (pPkt->setParas.exLen == sizeof(u32))
		{
			SetAWkPara(pPkt->setParas.paraId, *((u32*)(pPkt->setParas.exData)));
			SaveWkPara();
			RefreshParas(PARA_WK_VALID);
			SetNewParasFlag(PARA_WK_VALID);
		}
		else
		{
			rslt = -2;
		}
	}
	else if (pPkt->setParas.paraType == EMB_MVSTANG_PARA)	// 起始动框角度
	{
		if (pPkt->setParas.exLen == sizeof(g_angPara))
		{
			memcpy((u8*)(&g_angPara), pPkt->setParas.exData, sizeof(g_angPara));
			SaveAngPara();
			rslt = 0;
			printf("receive angle para\r\n");
		}
		else if (pPkt->setParas.exLen == sizeof(u16))
		{
			SetAAnglePara(pPkt->setParas.paraId, *((u16*)pPkt->setParas.exData));
			SaveAngPara();
		}
		else
		{
			rslt = -2;
		}
	}
	else if (pPkt->setParas.paraType == EMB_PATCH_DATA_IDX)		// 贴布绣数据,按针(绣花机)
	{
		if (pPkt->setParas.exLen == 1024)
		{
			memcpy((u8*)(&g_patchData), pPkt->setParas.exData, sizeof(g_patchData));
			printf("receive patch data (idx) para\r\n");
			rslt = 0;
		}
		else
		{
			rslt = -2;
		}
	}
	else
	{
		printf("other para\r\n");
	}

	return rslt;
}

int CreateMcParas(OperPacket * pPkt, int type, int id)
{
	int rslt;
	if (pPkt == NULL)
	{
		return -1;
	}

	memset(pPkt, 0, LEN_NORMAL_PACKET);

	pPkt->sendMcParas.cmdCode = DCMD_SEND_MC_PARAS;
	pPkt->sendMcParas.paraType = type;
	pPkt->sendMcParas.paraId = id;
	if (id == 0)
	{
		if (type == SEW_MCPARA_MACH)
		{
			rslt = PacketAVLDP(&(pPkt->packet), (u8*)(&g_mcPara), sizeof(g_mcPara));
		}
		else if (type == SEW_MCPARA_WORK)
		{
			rslt = PacketAVLDP(&(pPkt->packet), (u8*)(&g_wkPara), sizeof(g_wkPara));
		}
		else if (type == EMB_MVSTANG_PARA)		// 起始动框角度参数
		{
			rslt = PacketAVLDP(&(pPkt->packet), (u8*)(&g_angPara), sizeof(g_angPara));
		}
		else
		{
			rslt = -2;
		}
	}
	else
	{
		if (type == SEW_MCPARA_MACH)
		{
			u32 val = GetAMcPara(id);
			rslt = PacketAVLDP(&(pPkt->packet), (u8*)(&val), sizeof(u32));
		}
		else if (type == SEW_MCPARA_WORK)
		{
			u32 val = GetAWkPara(id);
			rslt = PacketAVLDP(&(pPkt->packet), (u8*)(&val), sizeof(u32));
		}
	}

	if (rslt != 0)
	{
		printf("error at call PacketAVLDP in CreateMcParas\r\n");
	}

	return rslt;

}

#else


__WEAK int CreateMemDatList(OperPacket * pPkt, u32 begAddr, u16 rdSize){return 0;};
__WEAK int SetMemDats(u32 setAddr, u8 * buff, u16 len){return 0;};

int CreateMcInfoWhenBoot(OperPacket * pPkt, int toggle)
{
	int rslt;
	MCInfo info;
	CpuId id;
	u32 cpuid;

	if (pPkt == NULL)
	{
		return -1;
	}

	memset(pPkt, 0, LEN_NORMAL_PACKET);
	memset(&info, 0, sizeof(MCInfo));

	pPkt->sendMcInfo.cmdCode = DCMD_SEND_MC_INFO;
	pPkt->sendMcInfo.toggle = (u16)toggle;

	GetVersionStr(info.softwareVerStr);		// 软件版本信息

	GetBuildStr(info.buildInfoStr);			// 编译时间信息

	// 板卡ID信息
	cpuid = 0;
	GetCpuID(&id);
	cpuid += id.dword.dword1;
	cpuid += id.dword.dword2;
	cpuid += id.dword.dword3;
	cpuid += id.dword.dword4;
	sprintf(info.boardId, "CPUID: %u", cpuid);

	printf("create system info as follow:\r\n");

	printf("%s\r\n", info.softwareVerStr);      	// 软件版本
	printf("%s\r\n", info.buildInfoStr);        	// 编译日期信息
	printf("%s\r\n", info.boardId);             	// 板卡ID

	rslt = PacketAVLDP(&(pPkt->packet), (u8*)(&(info)), sizeof(MCInfo));
	if (rslt != 0)
	{
		printf("error at call PacketAVLDP in CreateMcInfoWhenBoot\r\n");
	}

	return rslt;
}

void OperatorTaskWhenBoot(void)
{
	int rslt;

	OperPacket operpkt;
	DataPacket* pDatpkt = (DataPacket*)(&operpkt);

	// 读取操作箱命令
	rslt = GetANormalPacket(&g_operDataExFuns, pDatpkt);

	// 分析数据包，并执行
	if (rslt > 0)	// 收到数据包
	{
		switch(operpkt.packet.fldp.cmd)			// 先按固定长度解析
		{
		case UCMD_GET_MC_INFO:					// 读取机器信息
		{
			printf("get mc info cmd, toggle=%d\r\n", operpkt.getMcInfo.toggle);
			rslt = CreateMcInfoWhenBoot(&operpkt, operpkt.getMcInfo.toggle);
			if (rslt == 0)
			{
				rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 1000);
				if (rslt != 0)
				{
					printf("error at call SendAPacket in OperatorTaskWhenBoot UCMD_GET_MC_INFO \r\n");
				}
			}
			else
			{
				printf("error at call CreateMcInfo in OperatorTaskWhenBoot UCMD_GET_MC_INFO \r\n");
			}
			break;
		}
		case UCMD_GET_MEM_DATA:			// 读取内存数据
		{
			rslt = CreateMemDatList(&operpkt, operpkt.getMemData.begAddr, operpkt.getMemData.rdSize);
			if (rslt == 0)
			{
				rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 1000);
				if (rslt != 0)
				{
					printf("error at call OperatorTaskWhenBoot in OperatorTask UCMD_GET_MEM_DATA \r\n");
				}
			}
			else
			{
				printf("error at call OperatorTaskWhenBoot in OperatorTask UCMD_GET_MEM_DATA \r\n");
			}
			break;
		}

		case UCMD_SET_MEM_DATA:			// 设置内存数据
		{
			SetMemDats(operpkt.setMemData.begAddr, operpkt.setMemData.exData, operpkt.setMemData.exLen);
			break;
		}

		case UCMD_GET_FILE_INFO:		// 读取文件信息
		{
			rslt = CreateFileInfo(&operpkt);
			if (rslt == 0)
			{
				rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 1000);
				if (rslt != 0)
				{
					printf("error at call SendAPacket in OperatorTask UCMD_GET_FILE_INFO \r\n");
				}
			}
			else
			{
				printf("error at call CreateFileInfo in OperatorTask UCMD_GET_FILE_INFO \r\n");
			}
			break;
		}
		case UCMD_GET_TRANS_RESULT:		// 读取传输结果
		{
			printf("2. get trans result cmd\r\n");
			rslt = CreateTransResult(&operpkt);
			if (rslt == 0)
			{
				rslt = SendAPacket(&g_operDataExFuns, pDatpkt, 1000);
				if (rslt != 0)
				{
					printf("error at call SendAPacket in OperatorTask UCMD_GET_TRANS_RESULT \r\n");
				}
			}
			else
			{
				printf("error at call CreateTransResult in OperatorTask UCMD_GET_TRANS_RESULT \r\n");
			}
			break;
		}
		case UCMD_START_TRANS:			// 启动文件传输
			StartReceiveFile(&operpkt);
		//	SaveFileIdxFromDatafile();
			break;
		case UCMD_TRANS_FILE_DATA:		// 文件传输命令
			ReceiveFileData(&operpkt);
			break;

		case UCMD_MC_UPDATE:			// 下位机升级
			printf("get update cmd\r\n");
			StartAppUpdate(0); 			// 升级并重启
			break;

		default:
			break;
		}
	}
}

#endif

//------------------------------------------------------

int SendDebugInfo(char * pStr)
{
	int rslt;

	OperPacket pkt;

	memset(&pkt, 0, LEN_NORMAL_PACKET);

	pkt.sendDebugInfo.cmdCode = DCMD_SEND_DEBUG_INFO;

	rslt = PacketAVLDP(&(pkt.packet), (u8*)(pStr), strlen(pStr));
	if (rslt != 0)
	{
		printf("error at call PacketAVLDP in SendDebugInfo\r\n");
	}
	else
	{
		rslt = SendAPacket(&g_operDataExFuns, (DataPacket *)(&pkt), 0);
	}

	return rslt;
}

int SendFileParas(int beginX, int beginY)
{
	int rslt;
	OperPacket pkt;
	DataFilePara newPara;

	memset(&pkt, 0, LEN_NORMAL_PACKET);

	newPara.anchorX = beginX;
	newPara.anchorY = beginY;
	newPara.beginX = beginX;
	newPara.beginY = beginY;

	pkt.setFileParas.cmdCode = UCMD_SET_FILE_PARAS;

	rslt = PacketAVLDP(&(pkt.packet), (u8*)(&newPara), sizeof(DataFilePara));
	if (rslt != 0)
	{
		printf("error at call PacketAVLDP in SendFileParas\r\n");
	}
	else
	{
		rslt = SendAPacket(&g_operDataExFuns, (DataPacket *)(&pkt), 0);
	}

	return rslt;
}



