Project

General

Profile

Bug #2492 » ModbusEx_LnS.cpp

sSection字段扩容为7,支持rtu99以上 - jingke lu, 08/25/2022 05:35 PM

 
1

    
2
#if defined(WIN32)
3
#include    <io.h>
4
// #include "stdafx.h"
5
#endif
6
#include    <limits.h>
7
#include    <sys/stat.h>
8
#include	<sys/timeb.h>
9
#include	<time.h>
10

    
11
#include "ModbusEx_LnS.h"
12
#include "se_log.h"
13
#include "daq/daq_utl.h"
14

    
15

    
16
extern CRdbTable DEF_DCDLL  RDB_Chan;
17

    
18
unsigned int CRC_16(unsigned char * pSendBuf, int len)//CRC??????
19
{ 
20
    unsigned short wCrc = 0xFFFF;
21
    for(int i=0; i<len;i++)
22
    {
23
        wCrc ^= pSendBuf[i];
24
        for(int j=0; j<8; j++)
25
        {
26
            if(wCrc & 1)
27
            {
28
                wCrc >>= 1; 
29
                wCrc ^= 0xA001; 
30
            }
31
            else
32
                wCrc >>= 1; 
33
        }
34
    }
35
    return wCrc;
36
}
37

    
38

    
39
CModbusExLnS::CModbusExLnS()
40
{
41
// #ifdef LOG_WIN
42
//     m_logger = new Logger("ModbusExLnS", "ModbusExLnS.log");
43
// //     m_logger->WriteLineSeparator("Create a new class instance. ", 2);
44
// #endif
45

    
46
    m_bExitMe = false;
47
	
48
    m_b_InitBuff = 0;
49
    m_bufValueHasReady = 0;
50
    m_bufYC = NULL;
51
    m_bufYX = NULL;
52

    
53
    m_TxDataMaxLen = 1042;
54
    m_FrameObjNum_Max = 512;
55
    m_FrameDINum_Max = m_FrameObjNum_Max * DINumberPerBlock;
56

    
57
    resetIniParam(&m_iniConfig);	
58
}
59

    
60
CModbusExLnS::~CModbusExLnS()
61
{
62
    if (m_iniConfig.rtuConfArray != NULL)
63
    {
64
        delete [] m_iniConfig.rtuConfArray;
65
    }
66

    
67
	m_bExitMe = true;
68
    if (m_bufYX != NULL)
69
        delete [] m_bufYX;
70
    if (m_bufYC != NULL)
71
        delete [] m_bufYC;
72

    
73
#ifdef LOG_WIN
74
    delete m_logger;
75
#endif
76
}
77

    
78
void CModbusExLnS::Init( S_PROTOCOLCFG * pcfg )
79
{
80
// #ifdef LOG_WIN
81
// 	m_logger->WriteFmtStrWithTime_L3("[Init] : ");
82
// #endif
83

    
84
	PRawCtrl    = pcfg->PRawCtrl;
85
	pRxBuf      = pcfg->pRxBuf;
86
	pTxBuf      = pcfg->pTxBuf;
87
	pCmdMem     = pcfg->pCmdMem;
88
	pRtu        = pcfg->pRtu;
89
	pLink       = pcfg->pLink;
90
	pTable      = pcfg->pTable;
91
	pZfDataCtrl = pcfg->pZfDataCtrl;
92

    
93
	sint32 buflen = pRxBuf->GetReadableSize();   
94
	pRxBuf->Move(buflen);
95
	buflen = pTxBuf->GetReadableSize();
96
	pTxBuf->Move(buflen);
97

    
98

    
99
#ifdef LOG_WIN
100
    char logfilename[32] = {0};
101
    sprintf(logfilename, "S_rtu%d_chan%d.log", pLink->GetRtuNo(), pLink->GetChanNo());
102
    m_logger = new Logger("ModbusExLnS", logfilename);
103
    m_logger->WriteLineSeparator("Create a new class instance. ", 2);
104
#endif
105

    
106
    
107
	readIni();
108

    
109
    initBuffer();
110

    
111
    initStation();
112

    
113
	m_hThreadGetData = SE_CreateThread( (PTHREAD_FUNC_DEF)GetData, (void *)this);
114

    
115
}
116

    
117
void CModbusExLnS::initStation()
118
{
119
// #ifdef LOG_WIN
120
// 	m_logger->WriteFmtStrWithTime_L3("[initStation] : ");
121
// #endif
122

    
123
    m_flagSendType = 3;
124
    m_nSendFrameNo = 0;
125
    m_nSendSeqNo = 0;
126

    
127
    m_nYXFrameCount = 0; 
128
    m_nYCFrameCount = 0; 
129

    
130
    pLink->SetCommStatus(CMST_NORMAL);
131
}
132

    
133
void CModbusExLnS::readIni()
134
{
135
// #ifdef LOG_WIN
136
// 	m_logger->WriteFmtStrWithTime_L3("[readIni] : ");
137
// #endif
138

    
139
    char *home = getenv("SEROOT");
140
    if (NULL == home)
141
    {
142
        PrintLog(LOG_ERROR, "????????SEROOTδ????");
143
        return;
144
    }
145
    char filename[256] = {0};
146
#if defined(__unix)
147
    sprintf(filename, "%s%s", home, "/cfg/ModbusExLns.ini");
148
#else
149
    sprintf(filename, "%s%s", home, "\\cfg\\ModbusExLns.ini");
150
#endif
151
    
152
    CReadConf readconf;
153
	char sSection[7];
154
	sint32 rtu_no = 0;
155
    uint32 zfRtu_start = 0;
156
    uint32 zfRtu_count = 0;
157

    
158
	int nTotalRtuNum = readconf.ReadLong("GENERAL", "rtuCount", filename, "1");
159
	for (sint32 rtu_i=0; rtu_i<nTotalRtuNum; rtu_i++)
160
	{
161
        rtu_no = 0;
162
		memset(sSection, 0, sizeof(char)*7);
163
        sprintf(sSection, "RTU_%d", rtu_i+1);
164
        zfRtu_start = readconf.ReadLong(sSection, "zfRtuIndexStart", filename, "0");
165
        zfRtu_count = readconf.ReadLong(sSection, "zfRtuCount", filename, "0");
166
		rtu_no = readconf.ReadLong(sSection, "rtuNo", filename, "0");
167
		if (rtu_no == pLink->GetRtuNo())
168
			break;
169
	}
170

    
171
    m_logger->WriteFmtStrWithTime_L3("[readIni] : local rtu no %d, zf rtu number %d", rtu_no, zfRtu_count);
172
    if (rtu_no <= 0)
173
    {
174
        PrintLog(LOG_ERROR, "RTUδ????");
175
        return;
176
    }
177
    if (zfRtu_count <= 0)
178
    {
179
        PrintLog(LOG_ERROR, "??ת????RTU??????????");
180
        return;
181
    }
182
	m_iniConfig.totalRtus = zfRtu_count;
183

    
184
    m_iniConfig.bufType = (uint8)readconf.ReadLong("GENERAL", "buffType", filename, "0");
185

    
186
    
187
    m_iniConfig.rtuConfArray = new IniRtuParam[zfRtu_count];
188
    for (uint32 zfrtu_i=0; zfrtu_i<zfRtu_count; zfrtu_i++)
189
    {
190
        memset(sSection, 0, sizeof(char)*7);
191
        sprintf(sSection, "RTU%d", zfRtu_start + zfrtu_i);
192
        LPIniRtuParam pRtuPara = m_iniConfig.rtuConfArray + zfrtu_i;
193
		
194
        pRtuPara->rtuNo = readconf.ReadLong(sSection, "rtuNo", filename, "0");
195
        pRtuPara->totalYX = readconf.ReadLong(sSection, "yx", filename, "0");
196
        pRtuPara->totalYC = readconf.ReadLong(sSection, "yc", filename, "0");
197
        
198
        pRtuPara->totalYxBlock = (pRtuPara->totalYX + DINumberPerBlock - 1) / DINumberPerBlock;
199
    }
200

    
201
    setFrameProperty(m_iniConfig.bufType);
202
}
203

    
204
// 
205
sint32	CModbusExLnS::RxProc()
206
{
207
    if ( (m_flagSendType & 0x3) == 0)
208
        m_flagSendType = 0x3;
209

    
210
#if 1
211
    sint32 count = RDB_Chan.GetRcdCount();
212
    if( count>DEF_DCV_MAX_CHANNUM ) 
213
        count = DEF_DCV_MAX_CHANNUM;
214
	S_RDB_Chan * pChan = (S_RDB_Chan * )RDB_Chan.GetRcdAddr(0);
215
    sint32 chanNo = pLink->GetChanNo();
216
    for (int i=0; i<count; i++)
217
    {
218
        if (pChan[i].ChanNo == chanNo)
219
        {
220
            pChan[i].State = EDEV_UP_STATE;
221
            break;
222
        }
223
    }
224
#endif
225

    
226
    pLink->RegisterFrm( FRAME_RX_SUC );
227
//     pLink->SetCommStatus(CMST_NORMAL);
228
    return 1;
229
}
230

    
231
// 
232
sint32 CModbusExLnS::TxProc()
233
{
234
// 	m_logger->WriteFmtStrWithTime_L3("[TxProc] : ");
235

    
236
	if (m_b_InitBuff == 0)
237
    {
238
		if (NULL != m_bufYX)
239
		{
240
			delete [] m_bufYX;
241
			m_bufYX = NULL;
242
		}
243
#ifdef LOG_WIN
244
        m_logger->WriteFmtStrWithTime_L3("[TxProc] : m_iniConfig.yxBytes = %d, m_iniConfig.ycBytes = %d", m_iniConfig.totalBytesYx, m_iniConfig.totalBytesYc);
245
#endif
246

    
247
		if (m_iniConfig.totalBytesYx > 0)
248
			m_bufYX = new uint8[m_iniConfig.totalBytesYx];
249
		if (NULL == m_bufYX)
250
			return 0;
251
		memset(m_bufYX, 0, m_iniConfig.totalBytesYx);
252

    
253
		if (m_iniConfig.totalBytesYc > 0)
254
			m_bufYC = new uint8[m_iniConfig.totalBytesYc];
255
		if (NULL == m_bufYC)
256
			return 0;
257
		memset(m_bufYC, 0, m_iniConfig.totalBytesYc);
258

    
259
        m_b_InitBuff = 1;
260
        while (TRUE) {
261
            if (m_bufValueHasReady == 1)
262
                break;
263
            if (m_bExitMe)
264
                return 1;
265
            SeSleep(10);
266
        }
267
    }
268
    else
269
    {
270
		if (NULL == m_bufYX)
271
			return 0;
272
		if (NULL == m_bufYC)
273
			return 0;
274
    }
275

    
276
//     m_logger->WriteFmtStrWithTime_L3("[TxProc] : send data ...");
277

    
278
    if ( (m_flagSendType & 0x1) == 0x1)
279
    {
280
        if (procSendDI() == 1)
281
            return 1;
282
    }
283
    
284
    if ( (m_flagSendType & 0x2) == 0x2)
285
    {
286
        if (procSendAI() == 1)
287
            return 1;
288
    }
289

    
290
	return 1;
291
}
292

    
293

    
294
void CModbusExLnS::appToLink(uint8 nDataType)
295
{
296
    BYTE * p = m_sendData.databuf;
297
    int len = m_sendData.trailP - m_sendData.headP;
298

    
299
    unsigned int crcValue = CRC_16(p, len);
300
    *m_sendData.trailP++ = crcValue % 0x100;
301
    *m_sendData.trailP++ = crcValue / 0x100;
302

    
303
    len = m_sendData.trailP - m_sendData.headP;
304
       
305
#ifdef LOG_WIN
306
    if (m_logger->IfLogData())
307
    {
308
        if (nDataType == 1)
309
            m_logger->WriteFmtStrWithTime_L3(_T("???ͱ??? (?ֽ??? %d) : DI??%d֡"), len, m_nYXFrameCount);
310
        else if (nDataType == 3)
311
            m_logger->WriteFmtStrWithTime_L3(_T("???ͱ??? (?ֽ??? %d) : AI??%d֡"), len, m_nYCFrameCount);
312
		
313
        TCHAR strLog[MaxCodeLen] = {0};
314
        uint32 real_len = MaxCodeLen - TimeHead;
315
        
316
        uint32 code_line = 1;
317
        _tcscpy(strLog, "\n0001: ");
318
        
319
        int code_index;
320
        for (code_index=0; code_index<len; code_index++)
321
        {
322
            if ( _tcslen(strLog) >= real_len-1) {
323
                m_logger->WriteFmtStrWithTime_L3(strLog);
324
                memset(strLog, 0, sizeof(TCHAR)*MaxCodeLen);
325
                _stprintf(strLog, _T("\n%04d: "), ++code_line);
326
            }
327
            
328
            TCHAR tmpStr[12] = {0};
329
            if ( (code_index+1)/32 > 0 && (code_index+1)%32 == 0) {
330
                if ( (code_index+1) % (MaxLine*MaxLineCodeNum) == 0 )
331
                    _stprintf(tmpStr, _T("%02X  \n"), *(p+code_index));
332
                else
333
                    _stprintf(tmpStr, _T("%02X  \n%04d: "), *(p+code_index), ++code_line);
334
            }
335
            else
336
                _stprintf(tmpStr, _T("%02X  "), *(p+code_index));
337
            
338
            _tcscat(strLog, tmpStr);
339
        }
340
        m_logger->WriteFmtStrWithTime_L3(strLog);
341
    }
342
#endif
343

    
344
//     pLink->RegisterFrmCode(RAW_CODEDIR_DOWN, (char *)p, len);
345
    pTxBuf->Write(p, len);
346
//     pLink->SetCommStatus(CMST_NORMAL);
347

    
348
    pLink->RegisterFrm( FRAME_TX_SUC );
349

    
350
    return;
351
}
352

    
353
// index base 0
354
// ??ͬ??RTU????ͬһ??֡???ͣ?ÿ??֡????????
355
sint32 CModbusExLnS::procSendDI()
356
{
357
    if (NULL == m_bufYX || NULL == m_iniConfig.rtuConfArray)
358
    {
359
        PrintLog(LOG_ERROR, "RTUδ????");
360
        m_flagSendType &= 0xFE;
361
        m_nSendFrameNo = 0;
362
        return 0;
363
    }
364

    
365

    
366
#ifdef LOG_WIN
367
    if (m_nSendFrameNo == 0) {
368
        m_timeBeginYX = GetTickCount();
369
    }
370
#endif
371

    
372
    // save DI into buffer
373
    uint8 *buf = new uint8[m_TxDataMaxLen];
374
    if (NULL == buf)
375
        return 0;
376
    uint32 nPreCopied = m_nSendFrameNo * m_FrameObjNum_Max * 2;
377
    uint8 * dataSrc = m_bufYX + nPreCopied;
378
    uint32 nCopySize = ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYx ) ? (m_iniConfig.totalBytesYx - nPreCopied) : (m_FrameObjNum_Max * 2);
379
    memcpy(buf, dataSrc, nCopySize);
380

    
381
    // DATA_HEAD
382
    DATA_HEAD dataHead;
383
    dataHead.HeadLo = 0xEB;
384
    dataHead.HeadHi = 0x90;
385
    dataHead.SysID = FixSysID_Ans;
386
    dataHead.PacketNoLo = m_nSendSeqNo % 256;
387
    dataHead.PacketNoHi = m_nSendSeqNo / 256;
388
    
389
    uint16 framelen = nCopySize + 8;
390
    dataHead.LenLo = framelen % 256;
391
    dataHead.LenHi = framelen / 256;
392
    
393
    bool bFinishedCycle = false;
394
    if ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYx )
395
        bFinishedCycle = true;
396
    if (bFinishedCycle)
397
        dataHead.FollowupFlag = 0;
398
    else
399
        dataHead.FollowupFlag = 1;
400
    
401
    // DATA_BODY_HEAD
402
    DATA_BODY_HEAD dataBodyHead;    
403
    dataBodyHead.DataType = ReqTypeID_DI;
404
    
405
    uint32 nMaxCount = nCopySize * 8;
406
    dataBodyHead.DataCountLB = nMaxCount & 0xFF;
407
    dataBodyHead.DataCountMB = (nMaxCount >> 8) & 0xFF;
408
    dataBodyHead.DataCountHB = (nMaxCount >> 16) & 0xFF;
409
    
410
    dataBodyHead.DataStAddrLB = nPreCopied & 0xFF;
411
    dataBodyHead.DataStAddrMB = (nPreCopied >> 8) & 0xFF;
412
    dataBodyHead.DataStAddrHB = (nPreCopied >> 16) & 0xFF;
413

    
414
    //
415
    uint8 *ptr = m_sendData.databuf;
416
    m_sendData.headP = m_sendData.trailP = ptr;
417
    
418
    memcpy(ptr, (BYTE *)&dataHead, DataHeadLen);
419
    ptr += DataHeadLen;
420

    
421
    memcpy(ptr, (BYTE *)&dataBodyHead, DataBodyHeadLen);
422
    ptr += DataBodyHeadLen;
423
    
424
    memcpy(ptr, (BYTE *)buf, nCopySize);
425
    ptr += nCopySize;
426
    m_sendData.trailP = ptr;
427
    
428
    appToLink(1);
429
    
430
    m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF;
431
    
432
#ifdef LOG_WIN
433
    m_nYXFrameCount++;
434
#endif
435

    
436
    delete [] buf;
437

    
438
    if (bFinishedCycle)
439
    {
440
        m_flagSendType &= 0xFE;
441
        m_nSendFrameNo = 0;
442
#ifdef LOG_WIN
443
        DWORD curTick = GetTickCount();
444
        DWORD spendTick = GetTickCount() - m_timeBeginYX;
445
        m_logger->WriteFmtStrWithTime_L3(_T("[procSendDI] : ң?? ??????ϣ???ʱ: %us(%ums), ????֡??: %d"), spendTick/1000, spendTick, m_nYXFrameCount);
446
        m_nYXFrameCount = 0;        
447
#endif
448
    }
449
    else
450
        m_nSendFrameNo++;
451

    
452
    return 1;
453
}
454
/* // ??ͬ??RTU?ڲ?ͬ֡
455
sint32 CModbusExLnS::procSendDI()
456
{
457
    if (NULL == m_bufYX || NULL == m_iniConfig.rtuConfArray)
458
    {
459
        PrintLog(LOG_ERROR, "RTUδ????");
460
        m_flagSendType &= 0xFE;
461
        m_nSendFrameNo = 0;
462
        return 0;
463
    }
464

    
465
    // get start RTU
466
    uint32 nRtuNo = 0;    
467
    uint32 nCalcFrames = 0; // total frames have been sent (not include current RTU)
468
    uint32 nTotalFramesRTU = 0; // total frames of current RTU
469
    uint32 nDI_byte_start = 0; // start address of current frame (:= 0~0xFFFFFF)
470
    LPIniRtuParam p_zfRtu = NULL;
471
    while ( nRtuNo < m_iniConfig.totalRtus)
472
    {
473
        p_zfRtu = m_iniConfig.rtuConfArray + nRtuNo;
474
        nTotalFramesRTU = (p_zfRtu->totalYxBlock + MaxObjPerFrame_DI - 1) / MaxObjPerFrame_DI;
475
        if (m_nSendFrameNo < nCalcFrames + nTotalFramesRTU)//SendFrameNo : index base from 0
476
            break;
477
        nCalcFrames += nTotalFramesRTU;
478
        nDI_byte_start += (p_zfRtu->totalYxBlock * 2);
479
        nRtuNo++;
480
    }
481
    if (nRtuNo >= m_iniConfig.totalRtus || NULL == p_zfRtu)
482
    {
483
        PrintLog(LOG_ERROR, "RTU?????????????????????ļ?????ǰRTU %d", nRtuNo+1);
484
        m_flagSendType &= 0xFE;
485
        m_nSendFrameNo = 0;
486
        return 0;
487
    }
488
    
489
    uint32 nRtuFrameNo = m_nSendFrameNo - nCalcFrames; // get frame number which has been sent in current RTU
490
    nDI_byte_start += (MaxObjPerFrame_DI * 2 * nRtuFrameNo);
491
    uint32 nRtuPointStart = (MaxObjPerFrame_DI * DINumberPerBlock) * nRtuFrameNo; // get from which DI start
492
    
493
#ifdef LOG_WIN
494
    if (m_nSendFrameNo == 0) {
495
        m_timeBeginYX = GetTickCount();
496
    }
497
#endif
498

    
499
    // re-calculate max DI
500
    uint32 nRetPoint = p_zfRtu->totalYX - nRtuPointStart;
501
    uint32 nMaxPoint = (MaxObjPerFrame_DI * DINumberPerBlock); // max DI of current frame
502
    nMaxPoint = nRetPoint < nMaxPoint ? nRetPoint : nMaxPoint;
503
  
504
    // save DI into buffer
505
    uint8 buf[1024] = {0};
506
    uint32 nCopySize = (nMaxPoint + 7) / 8;
507
    uint8 *dataSrc = m_bufYX + nDI_byte_start;
508
    memcpy(buf, dataSrc, nCopySize);
509

    
510
    // DATA_HEAD
511
    DATA_HEAD dataHead;
512
    dataHead.HeadLo = 0xEB;
513
    dataHead.HeadHi = 0x90;
514
    dataHead.SysID = FixSysID_Ans;
515
    dataHead.PacketNoLo = m_nSendSeqNo % 256;
516
    dataHead.PacketNoHi = m_nSendSeqNo / 256;
517

    
518
    uint16 nBlock = (nMaxPoint+DINumberPerBlock-1) / DINumberPerBlock;
519
    uint16 framelen = nBlock * 2 + 8;
520
    dataHead.LenLo = framelen % 256;
521
    dataHead.LenHi = framelen / 256;
522

    
523
    bool bFinishedCycle = false;
524
//     if ( (nRtuNo >= m_iniConfig.totalRtus-1) && (nRtuFrameNo >= nTotalFramesRTU-1) )
525
//         bFinishedCycle = true;
526
//     m_logger->WriteFmtStrWithTime_L3("[procSendDI] : nDI_byte_start = %d, nCopySize = %d, m_iniConfig.totalBytesYx = %d",
527
//          nDI_byte_start, nCopySize, m_iniConfig.totalBytesYx);
528
    if ( (nDI_byte_start + (nMaxPoint+15)/16*2) >= m_iniConfig.totalBytesYx)
529
        bFinishedCycle = true;
530
    if (bFinishedCycle)
531
        dataHead.FollowupFlag = 0;
532
    else
533
        dataHead.FollowupFlag = 1;
534

    
535
    dataHead.DataType = ReqTypeID_DI;
536
   
537
    //
538
    uint8 *ptr = m_sendData.databuf;
539
    m_sendData.headP = m_sendData.trailP = ptr;
540
    
541
    memcpy(ptr, (BYTE *)&dataHead, DataHeadLen);
542
    ptr += DataHeadLen;
543
    
544
    uint32 nMaxCount = nMaxPoint;
545
    *ptr++ = nMaxCount & 0xFF;
546
    *ptr++ = (nMaxCount >> 8) & 0xFF;
547
    *ptr++ = (nMaxCount >> 16) & 0xFF;
548
    
549
    *ptr++ = nDI_byte_start & 0xFF;
550
    *ptr++ = (nDI_byte_start >> 8) & 0xFF;
551
    *ptr++ = (nDI_byte_start >> 16) & 0xFF;
552

    
553
    memcpy(ptr, (BYTE *)buf, nBlock*2);
554
    ptr += nBlock * 2;
555
    m_sendData.trailP = ptr;
556

    
557
    appToLink(1);
558

    
559
    m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF;
560

    
561
#ifdef LOG_WIN
562
    m_nYXFrameCount++;
563
#endif
564

    
565
    if (bFinishedCycle)
566
    {
567
        m_flagSendType &= 0xFE;
568
        m_nSendFrameNo = 0;
569
#ifdef LOG_WIN
570
        DWORD curTick = GetTickCount();
571
        DWORD spendTick = GetTickCount() - m_timeBeginYX;
572
        m_logger->WriteFmtStrWithTime_L3(_T("[procSendDI] : ң?? ??????ϣ???ʱ: %us(%ums), ????֡??: %d"), spendTick/1000, spendTick, m_nYXFrameCount);
573
        m_nYXFrameCount = 0;        
574
#endif
575
    }
576
    else
577
        m_nSendFrameNo++;
578

    
579
    return 1;
580
}
581
*/
582

    
583
// ??ͬ??RTU????ͬһ??֡???ͣ?ÿ??֡????????
584
sint32 CModbusExLnS::procSendAI()
585
{
586
    if (NULL == m_bufYC || NULL == m_iniConfig.rtuConfArray)
587
    {
588
        PrintLog(LOG_ERROR, "RTUδ????");
589
        m_flagSendType &= 0xFD;
590
        m_nSendFrameNo = 0;
591
        return 0;
592
    }
593

    
594
#ifdef LOG_WIN
595
    if (m_nSendFrameNo == 0) {
596
        m_timeBeginYC = GetTickCount();
597
    }
598
#endif
599

    
600

    
601
    // save AI into buffer
602
    uint8 *buf = new uint8[m_TxDataMaxLen];
603
    if (NULL == buf)
604
        return 0;
605
    uint32 nPreCopied = m_nSendFrameNo * m_FrameObjNum_Max * 2;
606
    uint8 * dataSrc = m_bufYC + nPreCopied;
607
    uint32 nCopySize = ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYc ) ? (m_iniConfig.totalBytesYc - nPreCopied) : (m_FrameObjNum_Max * 2);
608
    memcpy(buf, dataSrc, nCopySize);
609

    
610

    
611
    // DATA_HEAD
612
    DATA_HEAD dataHead;
613
    dataHead.HeadLo = 0xEB;
614
    dataHead.HeadHi = 0x90;
615
    dataHead.SysID = FixSysID_Ans;
616
    dataHead.PacketNoLo = m_nSendSeqNo % 256;
617
    dataHead.PacketNoHi = m_nSendSeqNo / 256;
618
    
619
    uint16 framelen = nCopySize + 8;
620
    dataHead.LenLo = framelen % 256;
621
    dataHead.LenHi = framelen / 256;
622
    
623
    bool bFinishedCycle = false;
624
    if ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYc )
625
        bFinishedCycle = true;
626
    if (bFinishedCycle)
627
        dataHead.FollowupFlag = 0;
628
    else
629
        dataHead.FollowupFlag = 1;
630
    
631

    
632
    // DATA_BODY_HEAD
633
    DATA_BODY_HEAD dataBodyHead;    
634
    dataBodyHead.DataType = ReqTypeID_AI;
635
    
636
    uint32 nMaxPoint = nCopySize / 2;
637
    dataBodyHead.DataCountLB = nMaxPoint & 0xFF;
638
    dataBodyHead.DataCountMB = (nMaxPoint >> 8) & 0xFF;
639
    dataBodyHead.DataCountHB = (nMaxPoint >> 16) & 0xFF;
640
    
641
    uint32 nInfoAddrStart = nPreCopied / 2;
642
    dataBodyHead.DataStAddrLB = nInfoAddrStart & 0xFF;
643
    dataBodyHead.DataStAddrMB = (nInfoAddrStart >> 8) & 0xFF;
644
    dataBodyHead.DataStAddrHB = (nInfoAddrStart >> 16) & 0xFF;
645
    
646

    
647
    //
648
    uint8 *ptr = m_sendData.databuf;
649
    m_sendData.headP = m_sendData.trailP = ptr;
650
    
651
    memcpy(ptr, (BYTE *)&dataHead, DataHeadLen);
652
    ptr += DataHeadLen;
653
    
654
    memcpy(ptr, (BYTE *)&dataBodyHead, DataBodyHeadLen);
655
    ptr += DataBodyHeadLen;
656
    
657
    memcpy(ptr, (BYTE *)buf, nMaxPoint*2);
658
    ptr += nCopySize;
659
    m_sendData.trailP = ptr;
660
    
661
    PrintLog(LOG_INFORMATION, "????DI??Ӧ֡");
662
    appToLink(3);
663
    
664
    m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF;
665
    
666
#ifdef LOG_WIN
667
    m_nYCFrameCount++;
668
#endif
669

    
670
    delete [] buf;
671
    
672
    if (bFinishedCycle)
673
    {
674
        m_flagSendType &= 0xFD;
675
        m_nSendFrameNo = 0;
676
#ifdef LOG_WIN
677
        DWORD curTick = GetTickCount();
678
        DWORD spendTick = curTick - m_timeBeginYC;
679
        m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ң?? ??????ϣ???ʱ: %us(%ums), ????֡??: %d"), spendTick/1000, spendTick, m_nYCFrameCount);
680
        m_nYCFrameCount = 0;
681
        
682
        spendTick = curTick - m_timeBeginYX;
683
        m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ------>>> ???????? ??????ϣ???ʱ: %us(%ums) <<<------"), spendTick/1000, spendTick);
684
        m_timeBeginYX = m_timeBeginYC = 0;
685
#endif
686
    }
687
    else
688
        m_nSendFrameNo++;
689
    
690
    return 1;
691
}
692
/* // ??ͬ??RTU?ڲ?ͬ֡
693
sint32 CModbusExLnS::procSendAI()
694
{
695
    if (NULL == m_bufYC || NULL == m_iniConfig.rtuConfArray)
696
    {
697
        PrintLog(LOG_ERROR, "RTUδ????");
698
        m_flagSendType &= 0xFD;
699
        m_nSendFrameNo = 0;
700
        return 0;
701
    }
702

    
703
    // get start RTU
704
    uint32 nRtuNo = 0;    
705
    uint32 nCalcFrames = 0; // total frames have been sent (not include current RTU)
706
    uint32 nTotalFramesRTU = 0; // total frames of current RTU
707
    uint32 nInfoAddrStart = 0; // start address of current frame (:= 0~0xFFFFFF)
708
    LPIniRtuParam p_zfRtu = NULL;
709
    while (nRtuNo < m_iniConfig.totalRtus)
710
    {
711
        p_zfRtu = m_iniConfig.rtuConfArray + nRtuNo;
712
        nTotalFramesRTU = p_zfRtu->totalYcFrame;
713
        if (m_nSendFrameNo < nCalcFrames + nTotalFramesRTU)//SendFrameNo : index base from 0
714
            break;
715
        nCalcFrames += nTotalFramesRTU;
716
        nInfoAddrStart += p_zfRtu->totalYC;
717
        nRtuNo++;
718
    }
719
    if (nRtuNo >= m_iniConfig.totalRtus || NULL == p_zfRtu)
720
    {
721
        PrintLog(LOG_ERROR, "AI?㳬?????????????ļ?????ǰRTU %d", nRtuNo+1);
722
        m_flagSendType &= 0xFD;
723
        m_nSendFrameNo = 0;
724
        return 0;
725
    }    
726
    
727
    uint32 nRtuFrameNo = m_nSendFrameNo - nCalcFrames; // get frame number which has been sent in current RTU
728
    nInfoAddrStart += MaxObjPerFrame_AI * nRtuFrameNo;
729
    uint32 nMaxPoint = MaxObjPerFrame_AI; // max DI of current frame
730
    uint32 nRtuPointStart = nMaxPoint * nRtuFrameNo; // get from which DI start
731
    
732
#ifdef LOG_WIN
733
    if (m_nSendFrameNo == 0) {
734
        m_timeBeginYC = GetTickCount();
735
    }
736
#endif
737

    
738
    // re-calculate max DI
739
    uint32 nRetPoint = p_zfRtu->totalYC - nRtuPointStart;
740
    nMaxPoint = nRetPoint < nMaxPoint ? nRetPoint : nMaxPoint;
741
  
742
    // save AI into buffer
743
    uint8 buf[1024] = {0};
744
    uint32 nCopySize = nMaxPoint * 2;
745
    uint8 * dataSrc = m_bufYC + nInfoAddrStart * 2;
746
    memcpy(buf, dataSrc, nCopySize);
747

    
748
    // DATA_HEAD
749
    DATA_HEAD dataHead;
750
    dataHead.HeadLo = 0xEB;
751
    dataHead.HeadHi = 0x90;
752
    dataHead.SysID = FixSysID_Ans;
753
    dataHead.PacketNoLo = m_nSendSeqNo % 256;
754
    dataHead.PacketNoHi = m_nSendSeqNo / 256;
755

    
756
    uint16 framelen = nMaxPoint * 2 + 8;
757
    dataHead.LenLo = framelen % 256;
758
    dataHead.LenHi = framelen / 256;
759

    
760
    bool bFinishedCycle = false;
761
//     m_logger->WriteFmtStrWithTime_L3("[procSendAI] : m_iniConfig.totalRtus = %d, nRtuNo = %d, nRtuFrameNo = %d, nTotalFramesRTU = %d",
762
//         m_iniConfig.totalRtus, nRtuNo, nRtuFrameNo, nTotalFramesRTU);
763
//     if ( (nRtuNo >= m_iniConfig.totalRtus-1) && (nRtuFrameNo >= nTotalFramesRTU-1) )
764
//         bFinishedCycle = true;
765
    if ( (nInfoAddrStart*2 + nCopySize) >= m_iniConfig.totalBytesYc)
766
        bFinishedCycle = true;
767
    if (bFinishedCycle)
768
        dataHead.FollowupFlag = 0;
769
    else
770
        dataHead.FollowupFlag = 1;
771

    
772
    dataHead.DataType = ReqTypeID_AI;
773
   
774
    //
775
    uint8 *ptr = m_sendData.databuf;
776
    m_sendData.headP = m_sendData.trailP = ptr;
777
    
778
    memcpy(ptr, (BYTE *)&dataHead, DataHeadLen);
779
    ptr += DataHeadLen;
780
    
781
    *ptr++ = nMaxPoint & 0xFF;
782
    *ptr++ = (nMaxPoint >> 8) & 0xFF;
783
    *ptr++ = (nMaxPoint >> 16) & 0xFF;
784
    
785
    *ptr++ = nInfoAddrStart & 0xFF;
786
    *ptr++ = (nInfoAddrStart >> 8) & 0xFF;
787
    *ptr++ = (nInfoAddrStart >> 16) & 0xFF;
788

    
789
    memcpy(ptr, (BYTE *)buf, nMaxPoint*2);
790
    ptr += nMaxPoint * 2;
791
    m_sendData.trailP = ptr;
792

    
793
    PrintLog(LOG_INFORMATION, "????DI??Ӧ֡");
794
    appToLink(3);
795

    
796
    m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF;
797

    
798
#ifdef LOG_WIN
799
    m_nYCFrameCount++;
800
#endif
801

    
802
    if (bFinishedCycle)
803
    {
804
        m_flagSendType &= 0xFD;
805
        m_nSendFrameNo = 0;
806
#ifdef LOG_WIN
807
        DWORD curTick = GetTickCount();
808
        DWORD spendTick = curTick - m_timeBeginYC;
809
        m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ң?? ??????ϣ???ʱ: %us(%ums), ????֡??: %d"), spendTick/1000, spendTick, m_nYCFrameCount);
810
        m_nYCFrameCount = 0;
811
        
812
        spendTick = curTick - m_timeBeginYX;
813
        m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ------>>> ???????? ??????ϣ???ʱ: %us(%ums) <<<------"), spendTick/1000, spendTick);
814
        m_timeBeginYX = m_timeBeginYC = 0;
815
#endif
816
    }
817
    else
818
        m_nSendFrameNo++;
819

    
820
    return 1;
821
}
822
*/
823

    
824
void CModbusExLnS::resetIniParam(LPIniConfig pParam)
825
{
826
	memset(pParam, 0, sizeof(IniConfig));
827
}
828

    
829
void CModbusExLnS::initBuffer()
830
{
831
	if (NULL == m_iniConfig.rtuConfArray)
832
		return;
833

    
834
	for (uint32 zfrtu_i=0; zfrtu_i<m_iniConfig.totalRtus; zfrtu_i++)
835
	{
836
		LPIniRtuParam pRtuPara = m_iniConfig.rtuConfArray + zfrtu_i;
837
//         m_logger->WriteFmtStrWithTime_L3("[initBuffer] : m_iniConfig.yxBytes 1= %d, pRtuPara->totalYxBlock = %d", m_iniConfig.yxBytes, pRtuPara->totalYxBlock);
838
		m_iniConfig.totalBytesYx += pRtuPara->totalYxBlock * 2;
839
//         m_logger->WriteFmtStrWithTime_L3("[initBuffer] : m_iniConfig.yxBytes 2= %d", m_iniConfig.yxBytes);
840
		m_iniConfig.totalBytesYc += pRtuPara->totalYC * 2;
841
	}
842

    
843
    uint32 nMaxBytesPerFrame = m_FrameObjNum_Max * 2;
844
    m_iniConfig.totalFramesYx = (m_iniConfig.totalBytesYx + nMaxBytesPerFrame - 1) / nMaxBytesPerFrame;
845
    m_iniConfig.totalFramesYc = (m_iniConfig.totalBytesYc + nMaxBytesPerFrame - 1) / nMaxBytesPerFrame;
846
}
847

    
848
sint32 CModbusExLnS::procWriteBuffer_DI()
849
{
850
    if (m_bufYX == NULL)
851
        return 0;
852
	
853
	uint32 yx_startNo_inBuff = 0;
854
	for (uint32 rtu_i=0; rtu_i<m_iniConfig.totalRtus; rtu_i++)
855
	{
856
		LPIniRtuParam pRtuPara = m_iniConfig.rtuConfArray + rtu_i;
857
		yx_startNo_inBuff += pRtuPara->totalYxBlock * 2;
858

    
859
		uint32 byteIndex, bitIndex;
860
		for (uint16 yx_i = 0; yx_i<pRtuPara->totalYX; yx_i++)
861
		{
862
			uint8 btVal = 0;
863
			PRawCtrl->GetAYx(pRtuPara->rtuNo, yx_i, &btVal);
864

    
865
			uint32 curYxNo_inBuff = yx_startNo_inBuff + yx_i;
866
			byteIndex = curYxNo_inBuff/DINumberPerBlock * 2 + curYxNo_inBuff%DINumberPerBlock / 8;
867
			bitIndex = curYxNo_inBuff % 8;
868
			if (btVal == 1) {
869
				*(m_bufYX+byteIndex) |= (1 << bitIndex);
870
			}
871
			else {
872
				*(m_bufYX+byteIndex) &= ~(1 << bitIndex);
873
			}
874
		}
875
	}
876

    
877
    return 1;
878
}
879

    
880
sint32 CModbusExLnS::procWriteBuffer_AI()
881
{
882
    if (m_bufYC == NULL)
883
        return 0;
884

    
885
	uint32 yc_startNo_inBuff = 0;
886
	for (uint32 rtu_i=0; rtu_i<m_iniConfig.totalRtus; rtu_i++)
887
	{
888
		LPIniRtuParam pRtuPara = m_iniConfig.rtuConfArray + rtu_i;
889

    
890
		uint32 byteIndex;
891
		for (uint16 yc_i=0; yc_i<pRtuPara->totalYC; yc_i++)
892
		{
893
			float32 fVal = 0.0f;
894
			PRawCtrl->GetAYc(pRtuPara->rtuNo, yc_i, &fVal);
895

    
896
			byteIndex = (yc_startNo_inBuff + yc_i) * 2;
897
			*(m_bufYC+byteIndex) = ((sint32)fVal) % 256;
898
			*(m_bufYC+byteIndex+1) = ((sint32)fVal) / 256; 
899
		}
900

    
901
        yc_startNo_inBuff += pRtuPara->totalYC;
902
	}
903
	
904
    return 1;
905
}
906

    
907
void CModbusExLnS::GetData(void * pClass)
908
{
909
    if (NULL == pClass)
910
        return;
911
    CModbusExLnS * pThis = (CModbusExLnS *)pClass;
912
	
913
    while (TRUE) {
914
        if (pThis->m_b_InitBuff == 1)
915
            break;
916
        if (pThis->m_bExitMe)
917
            return;
918
        SeSleep(1);
919
    }
920
    
921
    while (TRUE)
922
    {
923
        if (pThis->m_bExitMe)
924
            break;
925

    
926
		pThis->procWriteBuffer_DI();
927

    
928
//         pThis->m_logger->WriteFmtStrWithTime_L3("[GetData] : call procWriteBuffer_AI");
929
		pThis->procWriteBuffer_AI();
930

    
931
        if (pThis->m_bufValueHasReady == 0)
932
            pThis->m_bufValueHasReady = 1;
933
		
934
        SeSleep(1);
935
    }
936
}
937

    
938
void CModbusExLnS::setFrameProperty(uint8 bufType)
939
{
940
    if (bufType <= 0 || bufType > 6)
941
        return;
942
    
943
    uint32 nDataBuffLen = (uint32)(1 << bufType) * 1024;
944
    
945
    m_TxDataMaxLen = nDataBuffLen + sizeof(DATA_HEAD) + sizeof(DATA_BODY_HEAD) + 2;
946
    m_FrameObjNum_Max = nDataBuffLen / 2;
947
    m_FrameDINum_Max = m_FrameObjNum_Max * DINumberPerBlock;
948
}
949

    
950

    
951

    
952

    
953

    
954

    
955

    
956
////////////////////////////////////////////////////////////////
957
#if defined(WIN32)
958
		extern "C" __declspec(dllexport) 
959
#else 
960
	extern "C"
961
#endif
962
CProtocol	*CreateProtocol(char *defpara)
963
{
964
	return (CProtocol*)(new CModbusExLnS());
965
}
(1-1/3)