Project

General

Profile

Bug #1167 » modbus_tcps.cpp

yufeng wu, 01/06/2021 05:06 PM

 
1
// CModbus_TcpS.cpp: implementation of the CModbus_TcpS class.
2
//
3
//MODBUS_tcp  ת????Լ
4

    
5
//#include "stdafx.h"
6
#include "se_log.h"
7
#include "se_btl.h"
8

    
9
#include "modbus_tcps.h"
10
//#include <windows.h>
11

    
12
#ifdef _DEBUG
13
#undef THIS_FILE
14
static char THIS_FILE[]=__FILE__;
15
#define new DEBUG_NEW
16
#endif
17

    
18
//////////////////////////////////////////////////////////////////////
19
// Construction/Destruction
20
//////////////////////////////////////////////////////////////////////
21
CModbus_TcpS::~CModbus_TcpS()
22
{
23
}
24
sint32 CModbus_TcpS::GetNowSecond()
25
{
26
	CSeTime     SE_T;
27
	TCriterionTime tmptime;//sint32
28
	SE_T.GetNow(&tmptime);
29
	return (sint32)tmptime;
30
}
31
void CModbus_TcpS::Init(S_PROTOCOLCFG * pcfg )
32
{
33
	PRawCtrl	=	pcfg->PRawCtrl;
34
	pRxBuf		=	pcfg->pRxBuf;
35
	pTxBuf		=	pcfg->pTxBuf;
36
	pCmdMem		=	pcfg->pCmdMem;
37
	pRtu		=	pcfg->pRtu;
38
	pLink		=	pcfg->pLink;
39
	pTable		=	pcfg->pTable;
40
	pZfDataCtrl	=	pcfg->pZfDataCtrl;
41
//	pHis		=	pcfg->pHis;
42
	m_LastSendTime=GetNowSecond();
43
	m_RcvTimeOuts=pLink->GetRxTimeouts();
44
	if(m_RcvTimeOuts<=0)	m_RcvTimeOuts=10;
45
}
46

    
47
//??Լ???͹???
48
sint32	CModbus_TcpS::TxProc()
49
{
50
	ProcCmd();
51
	return 1;
52
}
53

    
54
/***********************************************************
55
?????
56
***********************************************************/
57
uint8 CModbus_TcpS::ProcCmd()
58
{
59
	sint32 rtuno			=	pLink->GetRtuNo();
60
	unsigned char rtuaddr	=	pRtu->GetRtuAddr(rtuno);
61
	//??????????򵥰?????ɾ??????Ϊû??ң?ط?У
62
	if(pCmdMem->GetResultNum(rtuno)<=0)
63
		return FALSE;
64
	
65
	S_RAWCMD rawcmd;
66
	if(pCmdMem->GetAResult(rtuno,&rawcmd)==0)
67
		return FALSE;
68
	
69

    
70
	while(pCmdMem->GetResultNum(rtuno)>0)
71
	{
72
		if(pCmdMem->GetAResult(rtuno,&rawcmd)==0)
73
			break;
74
		switch(rawcmd.type)
75
		{
76
		case DC_K_CMDRET_DOOPER:
77
		default: //?????????·????????
78
			pCmdMem->DelAResult(rtuno);
79
			break;
80
		}
81
	}
82
	return FALSE;
83
}
84

    
85
void CModbus_TcpS::ProcYKCmd(uint16 YaoKongNo,uint16 YkStatus)
86
{
87
	sint32 rtuno=pLink->GetRtuNo();
88
	unsigned char rtuaddr=pRtu->GetRtuAddr(rtuno);
89
	//??????ֱ??ѹ??????ң?ض???
90
	S_DO_CTL cmdinfo;
91
	S_RAWCMD  rawcmd;
92
	memset(&rawcmd,0,sizeof(S_RAWCMD));
93

    
94
	cmdinfo.funcCode = DC_K_CTL_DOEXE;
95
	cmdinfo.ptAddr = YaoKongNo+1;
96
	cmdinfo.ctlVal = YkStatus;
97
	cmdinfo.retCode = 0;
98

    
99
	rawcmd.type=DC_K_CMD_DOOPER;
100
	rawcmd.len=sizeof(cmdinfo);
101

    
102
	memcpy(rawcmd.data,&cmdinfo,sizeof(cmdinfo));
103
	if(pCmdMem->RptAZfCmd(rtuno,rawcmd)==0)
104
	{
105
		ReturnException(0x05,0x02);
106
		PrintLog(LOG_INFORMATION,"Ӧ??ң?????? ERROR (%d:%d)",YaoKongNo,YkStatus);
107
		return;
108
	}
109

    
110
	//?򵥷???һ??һ????????
111
	unsigned char buf[1024];
112
	
113
	int buflen =0;
114
    buf[buflen]=TransIdHi;  buflen++;
115
    buf[buflen]=TransIdLo;  buflen++;
116
    buf[buflen]=0; buflen++;
117
    buf[buflen]=0;  buflen++;
118
	buf[buflen]=0; buflen++;
119
	buf[buflen]=6; buflen++;
120
	buf[buflen]=rtuaddr; buflen++;
121
	buf[buflen]=5;  buflen++;//fun
122
	buf[buflen]=HIBYTE(YaoKongNo); buflen++; 
123
	buf[buflen]=LOBYTE(YaoKongNo); buflen++; 
124
	buf[buflen]=HIBYTE(YkStatus); buflen++; 
125
	buf[buflen]=LOBYTE(YkStatus); buflen++; 
126

    
127
	PrintLog(LOG_INFORMATION,"Ӧ??ң?????? (%d:%d)",YaoKongNo,YkStatus);
128
	
129
	pTxBuf->Write(buf,buflen);
130
	pLink->RegisterFrm(FRAME_TX_SUC);	
131
	pLink->SetCommStatus(CMST_RX_CNT);
132
	m_LastSendTime = GetNowSecond();
133
}
134

    
135
void	CModbus_TcpS::ReturnException(uint8 func,uint8 expCode)
136
{
137
	sint32 rtuno			=	pLink->GetRtuNo();
138
	unsigned char rtuadd	=	pRtu->GetRtuAddr(rtuno);
139

    
140
	unsigned char buf[20]={0};
141
	
142
	sint32 buflen =0;
143
    buf[buflen]=TransIdHi;  buflen++;
144
    buf[buflen]=TransIdLo;  buflen++;
145
    buf[buflen]=0; buflen++;
146
    buf[buflen]=0;  buflen++;
147
	buf[buflen]=0; buflen++;
148
	buf[buflen]=3; buflen++;
149
	buf[buflen]=rtuadd; buflen++;
150
	buf[buflen]=func|0x80;  buflen++;//fun
151
	buf[buflen]=expCode; buflen++;
152

    
153
	pTxBuf->Write(buf,buflen);
154
	pLink->RegisterFrm(FRAME_TX_SUC);	
155
	pLink->SetCommStatus(CMST_RX_CNT);
156
	m_LastSendTime = GetNowSecond();
157
}
158

    
159
sint32	CModbus_TcpS::SendMeasure(uint16 RegOffset,uint16 RegNum)
160
{
161
	sint32 rtuno	=	pLink->GetRtuNo();
162
	uint8 rtuadd	=	pRtu->GetRtuAddr(rtuno);
163

    
164
	sint32 startno = RegOffset+1;
165

    
166
	S_RDB_ZFYc *ycinfo;
167
	CEasyList *yclist=pZfDataCtrl->GetYcStructList();
168
	sint32 ycnum=yclist->GetListLen();
169
	if(yclist==NULL || ycnum<0 || RegNum*2>255)
170
	{
171
		ReturnException(0x03,0x02);
172
		return 0;
173
	}
174

    
175
	ycinfo = (S_RDB_ZFYc *)((*yclist)[ycnum-1]);
176
	if(ycinfo->YcNo < startno || ycinfo->YcNo<(RegOffset+RegNum))
177
	{
178
		PrintLog(LOG_ERROR,"ת?????ݴ???, MAX YCNO=%d",ycinfo->YcNo);
179
		ReturnException(0x03,0x02);
180
		return 0;
181
	}
182

    
183
	uint8 buf[300]={0};
184
	
185
	uint16 dl = RegNum*2+3;
186
	sint32 buflen =0;
187
    buf[buflen]=TransIdHi;  buflen++;
188
    buf[buflen]=TransIdLo;  buflen++;
189
    buf[buflen]=0; buflen++;
190
    buf[buflen]=0;  buflen++;
191
	buf[buflen]=dl/256; buflen++;
192
	buf[buflen]=dl%256; buflen++;
193
	buf[buflen]=rtuadd; buflen++;
194
	buf[buflen]=3;  buflen++;//fun
195
	buf[buflen]=RegNum*2; buflen++; 
196

    
197

    
198
	sint32 j;
199
	for(j=0;j<yclist->GetListLen();j++)
200
	{
201
		ycinfo=(S_RDB_ZFYc *)((*yclist)[j]);
202
		if(ycinfo->YcNo> (RegNum+RegOffset))break;
203
		if(ycinfo->YcNo<startno)
204
			continue;
205

    
206
		buf[(ycinfo->YcNo-startno)*2+buflen] = ((sint32)(ycinfo->Val))/256; 
207
		buf[(ycinfo->YcNo-startno)*2+1+buflen] = ((sint32)(ycinfo->Val))%256; 
208
		ycinfo->OldVal=ycinfo->Val;///**Modified by WYF20191112 ???Ӹ?????ֵ+??仯??־**/
209
		UNSETBIT(ycinfo->qds, PTMSK_AI_CHANGE );//FEP	
210
//		ycinfo->chgFlag = 0x00;//WIN		
211
	}
212

    
213
	PrintLog(LOG_INFORMATION,"Ӧ??????03: ??ʼ??ַ%d - ????%d)",RegOffset,RegNum);
214
	
215
	pTxBuf->Write(buf,buflen+RegNum*2);
216
	pLink->RegisterFrm(FRAME_TX_SUC);	
217
	pLink->SetCommStatus(CMST_RX_CNT);
218
	m_LastSendTime = GetNowSecond();
219
	return 1;
220
}
221

    
222
sint32	CModbus_TcpS::SendDiOne(uint16 startAddr,uint16 Num)
223
{
224
	sint32 rtuno	=	pLink->GetRtuNo();
225
	uint8 rtuadd	=	pRtu->GetRtuAddr(rtuno);
226

    
227
	sint32 startno = startAddr+1;
228

    
229
	S_RDB_ZFYx *yxinfo;
230
	CEasyList *yxlist=pZfDataCtrl->GetYxStructList();
231
	if(yxlist == NULL || Num>2040)//255*8
232
	{
233
		ReturnException(0x01,0x02);
234
		return 0;
235
	}
236

    
237
	sint32 yxnum=yxlist->GetListLen();
238
	if(yxnum<0 )
239
	{
240
		ReturnException(0x01,0x02);
241
		return 0;
242
	}
243

    
244
	yxinfo = (S_RDB_ZFYx *)((*yxlist)[yxnum-1]);
245
	if(yxinfo->YxNo < startno || yxinfo->YxNo<(startAddr+Num))
246
	{
247
		PrintLog(LOG_ERROR,"ת?????ݴ???, MAX YXNO=%d,startno=%d,Num=%d",yxinfo->YxNo,startno,Num);
248
		ReturnException(0x01,0x02);
249
		return 0;
250
	}
251
	
252
	uint8 buf[300]={0};
253
	
254
	sint32 buflen =0;
255
	sint32 bytecount = (Num+7)/8;
256
	uint16 dl = bytecount+3;
257
    buf[buflen]=TransIdHi;  buflen++;
258
    buf[buflen]=TransIdLo;  buflen++;
259
    buf[buflen]=0; buflen++;
260
    buf[buflen]=0;  buflen++;
261
	buf[buflen]=dl/256; buflen++;
262
	buf[buflen]=dl%256; buflen++;
263
	buf[buflen]=rtuadd; buflen++;
264
	buf[buflen]=0x01;  buflen++;//fun
265
	buf[buflen]=bytecount; buflen++; 
266

    
267

    
268
	sint32 j,byteIdx,bitIdx;
269
	for(j=0;j<yxlist->GetListLen();j++)
270
	{
271
		yxinfo=(S_RDB_ZFYx *)((*yxlist)[j]);
272
		if(yxinfo->YxNo> (Num+startAddr))break;
273
		if(yxinfo->YxNo<startno)
274
			continue;
275
		
276
		if(yxinfo->Val == 1)
277
		{
278
			byteIdx = (yxinfo->YxNo-startno)/8 + buflen;
279
			bitIdx  = (yxinfo->YxNo-startno)%8;
280

    
281
			buf[byteIdx] |= 1<<bitIdx; 
282
		}
283
		else{
284
			byteIdx = (yxinfo->YxNo-startno)/8 + buflen;
285
			bitIdx  = (yxinfo->YxNo-startno)%8;
286
			buf[byteIdx] &= (~(1<<bitIdx)) & 0xff; ///**Modified by WYF20180616 ???ƶ???ȡ??**/
287
//			buf[byteIdx] &= (~1<<bitIdx & 0xff); 
288
		}
289
		yxinfo->OldVal=yxinfo->Val;
290
		UNSETBIT(yxinfo->qds, PTMSK_DI_CHANGE );//FEP
291
//		yxinfo->chgFlag = 0x00;//WIN
292
	}
293

    
294
	PrintLog(LOG_INFORMATION,"Ӧ??????01: ??ʼ??ַ%d - ????%d)",startAddr,Num);
295
	
296
	pTxBuf->Write(buf,buflen+bytecount);
297
	pLink->RegisterFrm(FRAME_TX_SUC);	
298
	pLink->SetCommStatus(CMST_RX_CNT);
299
	m_LastSendTime = GetNowSecond();
300
	return 1;
301
}
302

    
303
//??Լ???պ???
304
sint32	CModbus_TcpS::RxProc()
305
{
306
	sint32 rtuno		=	pLink->GetRtuNo();
307
	uint8 rtuaddr		=	pRtu->GetRtuAddr(rtuno);
308
	
309
	uint8  buf[512];
310
	sint32 buflen = 0 ,datalen = 0,datanum =0;
311
	buflen=pRxBuf->GetReadableSize();
312
	//Added by WYF 20210106
313
	int nowtime=GetNowSecond();
314
	E_RAW_ComStat commstatus = pLink->GetCommStatus();
315
	if ( commstatus==CMST_RX_CNT && (nowtime-m_LastSendTime) >= m_RcvTimeOuts)
316
	{
317
		//??ʱ???ط???ֱ????????һ???ն?
318
		pRxBuf->Move(buflen);
319
		pLink->RegisterFrm(FRAME_RX_TIMEOUT);
320
		pLink->SetCommStatus(CMST_RX_CNT);
321
		PrintLog(LOG_VIOLATION,	" ???????ݳ?ʱ\n");
322
		m_LastSendTime=nowtime;
323
		return -1;
324
	}	
325
	//Added by WYF 20210106	
326
	if(buflen< 12)
327
		return 0;
328

    
329
	if(buflen>500)
330
		buflen=500;
331

    
332
	datalen = pRxBuf->Read(buf, buflen, DEF_BUFF_NOMOVE );
333
	sint32 framelen = buf[4]*256 + buf[5];
334
	if( (framelen+6)<=datalen) //?????㹻
335
	{
336
		if (buf[6]!= rtuaddr)//վַ????
337
		{
338
			pRxBuf->Move(datalen);
339
			return 0;
340
		}
341
		pLink->RegisterFrm(FRAME_RX_SUC);
342
		pLink->SetCommStatus(CMST_TX_CNT);
343
		TransIdHi = buf[0];
344
		TransIdLo = buf[1];
345
		//????????????????
346
		if(buf[7] == 0x01)//????DI????
347
		{
348
			uint16 startAddr = buf[8]*256 + buf[9];
349
			uint16 pntNum = buf[10]*256 + buf[11];
350
			SendDiOne(startAddr,pntNum);
351
		}
352
		else if(buf[7]==0x03)//????AI????
353
		{
354
			uint16 startAddr = buf[8]*256 + buf[9];
355
			uint16 pntNum	= buf[10]*256 + buf[11];
356
			SendMeasure(startAddr,pntNum);
357
		}
358
		else if(buf[7]==0x05)//ң??
359
		{
360
			uint16 m_YaoKongNo = buf[8]*256 + buf[9];
361
			uint16 m_YkStatus	= buf[10]*256 + buf[11];
362
			ProcYKCmd(m_YaoKongNo,m_YkStatus);
363
		}
364
		else if(buf[7]==0x06)//ң??//WYF 20190110
365
		{
366
			uint16 m_YaoKongNo = buf[8]*256 + buf[9];
367
			uint16 m_YkStatus	= buf[10]*256 + buf[11];
368
			ProcYTCmd(m_YaoKongNo,m_YkStatus);
369
		}//WYF 20190110
370
		else
371
			ReturnException(buf[7],0x01);//illegal function
372

    
373
		pRxBuf->Move(framelen+6);
374
	}
375

    
376
	return 1;
377
}
378
//WYF 20190110
379
void CModbus_TcpS::ProcYTCmd(uint16 YaoKongNo,uint16 YkStatus)
380
{
381
	sint32 rtuno=pLink->GetRtuNo();
382
	unsigned char rtuaddr=pRtu->GetRtuAddr(rtuno);
383
	//??????ֱ??ѹ??????ң?ض???
384
	S_AO_CTL cmdinfo;
385
	S_RAWCMD  rawcmd;
386
	memset(&rawcmd,0,sizeof(S_RAWCMD));
387

    
388
	cmdinfo.funcCode = DC_K_CTL_AOEXE;
389
	cmdinfo.ptAddr = YaoKongNo+1;
390
	cmdinfo.ptVal = YkStatus;
391
	cmdinfo.retCode = 0;
392

    
393
	rawcmd.type=DC_K_CMD_AOOPER;
394
	rawcmd.len=sizeof(cmdinfo);
395

    
396
	memcpy(rawcmd.data,&cmdinfo,sizeof(cmdinfo));
397
	if(pCmdMem->RptAZfCmd(rtuno,rawcmd)==0)
398
	{
399
		ReturnException(0x06,0x02);
400
		PrintLog(LOG_INFORMATION,"Ӧ??ң?????? ERROR (%d:%d)",YaoKongNo,YkStatus);
401
		return;
402
	}
403

    
404
	//?򵥷???һ??һ????????
405
	unsigned char buf[1024];
406
	
407
	int buflen =0;
408
    buf[buflen]=TransIdHi;  buflen++;
409
    buf[buflen]=TransIdLo;  buflen++;
410
    buf[buflen]=0; buflen++;
411
    buf[buflen]=0;  buflen++;
412
	buf[buflen]=0; buflen++;
413
	buf[buflen]=6; buflen++;
414
	buf[buflen]=rtuaddr; buflen++;
415
	buf[buflen]=6;  buflen++;//fun
416
	buf[buflen]=HIBYTE(YaoKongNo); buflen++; 
417
	buf[buflen]=LOBYTE(YaoKongNo); buflen++; 
418
	buf[buflen]=HIBYTE(YkStatus); buflen++; 
419
	buf[buflen]=LOBYTE(YkStatus); buflen++; 
420

    
421
	PrintLog(LOG_INFORMATION,"Ӧ??ң?????? (%d:%d)",YaoKongNo,YkStatus);
422
	
423
	pTxBuf->Write(buf,buflen);
424
	pLink->RegisterFrm(FRAME_TX_SUC);
425
	pLink->SetCommStatus(CMST_RX_CNT);
426
	m_LastSendTime = GetNowSecond();
427

    
428
}
429
//WYF 20190110
430

    
431
//??Լ???󴴽?????
432
#ifdef __unix
433
extern "C" CProtocol* CreateProtocol(char *defpara)
434
#else
435
extern "C" __declspec(dllexport)  CProtocol* CreateProtocol(char *defpara)
436
#endif
437
{
438
	CProtocol *pEpv = new CModbus_TcpS;
439
	return pEpv;
440
}
(2-2/3)