接着前面4篇SECS/GEM开发教程系列。
- 基于SECS协议开发的简明教程(1)-怎么搭建支持SECS工程
- 基于SECS协议开发的简明教程(2)-怎么编辑交换数据的ID
- 基于SECS协议开发的简明教程(3)-怎么收/发控制命令和数据消息
- 基于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站内消息联系。