基于SECS协议开发的简明教程(5)

接着前面4篇SECS/GEM开发教程系列。

  1. 基于SECS协议开发的简明教程(1)-怎么搭建支持SECS工程
  2. 基于SECS协议开发的简明教程(2)-怎么编辑交换数据的ID
  3. 基于SECS协议开发的简明教程(3)-怎么收/发控制命令和数据消息
  4. 基于SECS协议开发的简明教程(4)-怎么添加处理自定义SnFn消息
     

本文主讲SEMI的基于SECS协议开发的最关键一步——如何重写SnFn,并自己解析收到的数据内容。

其实就只需要用的以下7个基类方法,便可熟练完成收到的SnFn数据的解析

public:
	//return: LIST, if List, outCnt=Item Count, else ItemFormat, outCnt=bytes
	ListItemData * GetDataType(HSMSHeader* hdr,eFormatCode &outFC, int &outCnt);
	ListItemData *FindFirstItem(HSMSHeader* hdr, eFormatCode &outFC, int &outLen);
	ListItemData *FindNextItem(eFormatCode &outFC, int &outLen);
	
public:
	//overload, same as above
	// if return true, the data info storaged in the second paramter: item
	// if return false, no data or illegal data
	bool GetDataType(HSMSHeader* hdr,ItemData &item);
	bool  FindFirstItem(HSMSHeader* hdr, ItemData &item);
	bool  FindNextItem(ItemData &item);
	//For Nested List_1.
	ListItemData *GetChildSiblingItem_N(ListItemData* entry, eFormatCode &outFC, int &outLen);

还是举例说明:

我们以S10F3,接收单文本消息,并显示在操作界面为例。自然是要解析数据,当然你要重写一下S10F3的实现体了,具体如下:


//显示远程发来的消息并显示在面板上
int CMainClassName::S10F3(HSMSHeader *pHdr, HCOMM hComm)
{
	ItemData item;
	BYTE ACKC = 0;
	bool bFindCmd = false;
	SenderBuffer sender(this);
	HSMSHeader header = (*pHdr);

	bool bRet = GetDataType(pHdr, item); //返回true则数据在item指示,返回false无数据

	char buf[2048] = { 0 };
	CStringA str;

    //数据格式参照E5的S10F3对照,一一对应

	if (bRet && LIST == item.format)
	{

		bool bRet = FindFirstItem(pHdr, item);
		if (bRet) str = "S10F3\n";

		while (bRet)
		{
			if (BINARY == item.format)
			{
				CStringA TID;
				TID.Format("TID: %d\n", GetIntData(INT_1B, item.data));
				str += TID;
				bFindCmd = true;
			}
			if (ASCII == item.format)
			{

				memcpy(buf, item.data, item.len);
				CString s(buf);
				str += "TEXT: ";
				str += s;
				str += "\n";
				bFindCmd = true;
			}

			bRet = FindNextItem(item);
		}
	}

    //这一段是回复后台的
	sender.Begin();
	get_header_of_Data_message_reply(header);
	sender.Add_HSMSHeader(&header);

	sender.Add_ITEM_Header(BINARY, 1);
	bFindCmd ? ACKC = 0 : ACKC = 1;
	sender.Add_BINARY(ACKC);

	sender.End();
    sender.Send();


    //显示在面板上
	USES_CONVERSION;
	m_panel.SetWindowText(A2T(str));
	return 0;
}

再举例讲一个,S2F41,远程命令相关的,同样也是override一下S2F41。然后判断数据的类型是否是E5里面S2F41的LIST,然后对照着LIST的各个item的类型和含义去解析。


int CMainClassName::S2F41(HSMSHeader *pHdr, HCOMM hComm)
{
	ItemData item;
	BYTE HCAK = 0;
	SenderBuffer sender(this);
	HSMSHeader header = (*pHdr);

	bool bRet = GetDataType(pHdr, item);
	bool bFindCmd = false;
	CStringA cmdstr;

	BYTE *pCount = NULL;
	int nCount = 0; 

	if (bRet && item.format == LIST)
	{
		bRet = FindFirstItem(pHdr, item);

		if (bRet) cmdstr = "S2F41\n";


		if (ASCII == item.format)
		{
			char *pdata = (char *)malloc(item.len + 1);
			ZeroMemory(pdata, item.len + 1);

			memcpy(pdata, item.data, item.len);

			CStringA data(pdata);

			data.Trim();	data.MakeUpper();
			if (-1 != data.Find("START"))
			{
				bFindCmd = true;
				//::MessageBox(NULL, "Remote CMD: START", "EQP Demo", 0);
			}
			else if (-1 != data.Find("STOP"))
			{
				bFindCmd = true;
				//::MessageBox(NULL, "Remote CMD: STOP", "EQP Demo", 0);
			}
			else if (-1 != data.Find("PAUSE"))
			{
				bFindCmd = true;
				//::MessageBox(NULL, "Remote CMD: PAUSE", "EQP Demo", 0);
			}
			else if (-1 != data.Find("RESUME"))
			{
				bFindCmd = true;
				//::MessageBox(NULL, "Remote CMD: RESUME", "EQP Demo", 0);
			}
			else
			{
			}
		}
	}




	//以下部分是收到数据,给HOST的应答

	sender.Begin();

	get_header_of_Data_message_reply(header);

	sender.Add_HSMSHeader(&header);

	sender.Add_LIST_Header(2);

	sender.BeginList();

	sender.Add_ITEM_Header(BINARY, 1);
	bFindCmd ? HCAK = 0 : HCAK = 6;
	sender.Add_BINARY(HCAK);

	
	sender.Add_LIST_Header(0);
	sender.BeginList();
	sender.EndList();
	

	sender.EndList();
	sender.End();
    sender.Sender();


	return 0;
}

其实最详细的解析过程,在附带Demo里面的secs_Logs.cpp里面的两个方法,有最为详细的过程,可以参照。

void ParseToLogfile(HSMSHeader *pHdr);
void GenerateLogString(ListItemData* entry,	eFormatCode fc,
	int Len,int blanks);

因为两个接口是把接收到的数据写入.log日志的,所以它自然包含了完整的数据解析。

这部分也可以下载SECS SDK复制附带的Demo里面的代码。

如有疑问或咨询,请评论留言或在CSDN站内消息联系。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌志辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值