664 lines
21 KiB
C++
664 lines
21 KiB
C++
#include "host_sacnet103.h"
|
||
|
||
CHostSacNet103Item::CHostSacNet103Item()
|
||
{
|
||
m_scn = 0;
|
||
apdu_t0_max = 30;
|
||
apdu_t1_max = 15;
|
||
apdu_t2_max = 600;
|
||
}
|
||
|
||
CHostSacNet103Item::~CHostSacNet103Item()
|
||
{
|
||
m_scn = 0;
|
||
apdu_t0_max = 30;
|
||
apdu_t1_max = 15;
|
||
apdu_t2_max = 600;
|
||
}
|
||
|
||
void CHostSacNet103Item::Attach(int uid, int sock, DWORD peer_addr, WORD peer_port)
|
||
{
|
||
CNetProcessItem::Attach(uid, sock, peer_addr, peer_port);
|
||
m_scn = 0;
|
||
apdu_t0_begin = 1;
|
||
apdu_t1_begin = 1;
|
||
apdu_t2_begin = 1;
|
||
}
|
||
|
||
void CHostSacNet103Item::Release(void)
|
||
{
|
||
m_scn = 0;
|
||
apdu_t0_max = 30;
|
||
apdu_t1_max = 15;
|
||
apdu_t2_max = 600;
|
||
CNetProcessItem::Release();
|
||
}
|
||
|
||
CHostSacNet103Process::CHostSacNet103Process()
|
||
{
|
||
}
|
||
|
||
CHostSacNet103Process::~CHostSacNet103Process()
|
||
{
|
||
}
|
||
|
||
CNetProcessItem *CHostSacNet103Process::CreateItem(int ord)
|
||
{
|
||
return dynamic_cast<CNetProcessItem *>(new CHostSacNet103Item);
|
||
}
|
||
|
||
void CHostSacNet103Process::DestroyItem(int ord, BOOLEAN bDeleted /* = FALSE */)
|
||
{
|
||
CHostSacNet103Item *pItem = (CHostSacNet103Item *)GetItem(ord);
|
||
if (pItem != NULL && !bDeleted)
|
||
{
|
||
delete pItem;
|
||
return CNetProcess::DestroyItem(ord, TRUE);
|
||
}
|
||
|
||
return CNetProcess::DestroyItem(ord, bDeleted);
|
||
}
|
||
|
||
BOOLEAN CHostSacNet103Process::UDPSend(BOOLEAN set_time, BOOLEAN broadcast, DWORD addr)
|
||
{
|
||
int sock;
|
||
struct sockaddr_in broadcast_addr;
|
||
|
||
memset(&broadcast_addr, 0,sizeof(broadcast_addr));
|
||
broadcast_addr.sin_family = AF_INET;
|
||
broadcast_addr.sin_port = htons(m_option.net.target_port);
|
||
if (broadcast)
|
||
{
|
||
broadcast_addr.sin_addr.s_addr = m_option.net.target_addr;
|
||
}
|
||
else if (addr != 0)
|
||
{
|
||
broadcast_addr.sin_addr.s_addr = addr;
|
||
}
|
||
|
||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||
optval_t opt = 1;
|
||
if (broadcast)
|
||
{
|
||
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) < 0)
|
||
{
|
||
vLog(LOG_ERROR, "UDP socket set broadcast error(%d,%s).\r\n", errno, strerror(errno));
|
||
close(sock);
|
||
sock = -1;
|
||
return FALSE;
|
||
}
|
||
}
|
||
BYTE buffer[48];
|
||
memset(buffer, 0x00, sizeof(buffer));
|
||
buffer[0] = 0xff;
|
||
buffer[9] = 'S'; buffer[10] = 'P';
|
||
buffer[11] = 'i'; buffer[12] = 's';
|
||
buffer[13] = 'o'; buffer[14] = 'f';
|
||
buffer[15] = 't'; buffer[16] = '-';
|
||
buffer[17] = 'C'; buffer[18] = 'M';
|
||
buffer[19] = 'G';
|
||
if (set_time)
|
||
{
|
||
unionCP56Time st;
|
||
memset(&st, 0, sizeof(st));
|
||
memcpy(&st, &system32.now, sizeof(st));
|
||
get_system_time(&st);
|
||
if ((st.millisecond % 1000) < 900)
|
||
{
|
||
buffer[1] = 1;
|
||
buffer[2] = st.millisecond & 0xff;
|
||
buffer[3] = (st.millisecond >> 8) & 0xff;
|
||
buffer[4] = st.minute;
|
||
buffer[5] = st.hour;
|
||
buffer[6] = st.dayofmonth|st.dayofweek;
|
||
buffer[7] = st.month;
|
||
buffer[8] = st.year;
|
||
}
|
||
}
|
||
if (sendto(sock, (const char *)buffer, 41, 0, (sockaddr *)&broadcast_addr, sizeof(broadcast_addr)) < 0)
|
||
{
|
||
vLog(LOG_ERROR, "udp socket send error(%d,%s).\r\n", errno, strerror(errno));
|
||
close(sock);
|
||
sock = -1;
|
||
return FALSE;
|
||
}
|
||
DisplayTxData(buffer, 41, TRUE);
|
||
close(sock);
|
||
sock = -1;
|
||
return TRUE;
|
||
}
|
||
|
||
BOOLEAN CHostSacNet103Process::OnPreCreate(int id)
|
||
{
|
||
int i, j, uid;
|
||
CHostSacNet103Item *pItem;
|
||
if (!CNetProcess::OnPreCreate(id)) return FALSE;
|
||
|
||
if (!GetOption(&m_option, sizeof(m_option))) return FALSE;
|
||
|
||
for (i = 0; i < PROCESS_UNIT_NUM; i++)
|
||
{
|
||
pItem = (CHostSacNet103Item *)GetItem(i);
|
||
if (NULL == pItem) continue;
|
||
uid = GetUnitID(i);
|
||
if (uid < 0 || uid >= UNIT_NUM) continue;
|
||
if (!GetUnitAddr(uid, (BYTE *)&pItem->m_addr, 4))
|
||
{ //<2F><>ȡ<EFBFBD><C8A1>Ԫ<EFBFBD><D4AA>ַ<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>ԭ<EFBFBD><D4AD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ԪΪ<D4AA><CEAA>Ч<EFBFBD><D0A7>ַ<EFBFBD><D6B7>
|
||
pItem->m_addr = 0; //<2F><><EFBFBD>õ<EFBFBD>ַ
|
||
}
|
||
#if 0
|
||
//<2F><>ȡ<EFBFBD><C8A1>ԪCPU id
|
||
if (!GetUnitOption(uid, &pItem->m_option, sizeof(pItem->m_option)))
|
||
{ //δ<><CEB4>ȡ<EFBFBD><C8A1><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
vLog(LOG_ERROR, "Unit(%d) get unit configured error!\n", uid);
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
if (pItem->m_option.cpu_count <= 0)
|
||
{ //û<><C3BB>cpu
|
||
vLog(LOG_ERROR, "Unit(%d) not configured cpu ids!\n", uid);
|
||
continue;
|
||
}
|
||
}
|
||
#endif
|
||
pItem->apdu_t0_max = m_option.reconnect_interval;
|
||
pItem->apdu_t1_max = m_option.udp_send_interval;
|
||
pItem->apdu_t2_max = m_option.interrogation_interval;
|
||
pItem->Attach(uid, -1, 0, 0);
|
||
}
|
||
//upd<70>㲥<EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD>
|
||
//UDPSend(TRUE);
|
||
return TRUE;
|
||
}
|
||
|
||
int CHostSacNet103Process::GetAsdu10Length(BYTE* pData, int nLength)
|
||
{
|
||
BYTE i;
|
||
int nRet = ASDUHEAD_DAT + 2;
|
||
if ( nLength < nRet ) return 0;
|
||
BYTE btTotal = pData[ASDUHEAD_DAT + 1] & 0xFF;
|
||
for (i = 0; i < btTotal; i++)
|
||
{
|
||
if (nLength < nRet + GIN_LEN + KOD_LEN + GDD_LEN) return 0;
|
||
int nDataLen = pData[nRet + GIN_LEN + KOD_LEN + 1] * (pData[nRet + GIN_LEN + KOD_LEN + 2] & 0x7F);
|
||
nRet += GIN_LEN + KOD_LEN + GDD_LEN + nDataLen;
|
||
}
|
||
if (nLength < (nRet - 1)) return 0;
|
||
return nRet;
|
||
}
|
||
|
||
int CHostSacNet103Process::GetAsdu23Length(BYTE* pData, int nLength)
|
||
{
|
||
int nRet = ASDUHEAD_DAT + (pData[ASDUHEAD_VSQ] & 0x7F) * 10;
|
||
if (nLength < nRet) return 0;
|
||
return nRet;
|
||
}
|
||
|
||
int CHostSacNet103Process::GetAsdu29Length(BYTE* pData, int nLength)
|
||
{
|
||
int nRet = ASDUHEAD_DAT + 3 + pData[ASDUHEAD_DAT + 2] * 5;
|
||
if (nLength < nRet) return 0;
|
||
return nRet;
|
||
}
|
||
|
||
int CHostSacNet103Process::GetAsdu30Length(BYTE* pData, int nLength)
|
||
{
|
||
int nRet = ASDUHEAD_DAT + 9 + MAKEWORD(pData[ASDUHEAD_DAT + 5], pData[ASDUHEAD_DAT + 6]) * 2;
|
||
if (nLength < nRet) return 0;
|
||
return nRet;
|
||
}
|
||
|
||
BOOLEAN CHostSacNet103Process::Run(void)
|
||
{
|
||
if (!CNetProcess::Run()) return FALSE;
|
||
|
||
FeedDog();
|
||
return TRUE;
|
||
}
|
||
|
||
BOOLEAN CHostSacNet103Process::OnTimer(void)
|
||
{
|
||
int uid;
|
||
int i, j;
|
||
int time_gap;
|
||
|
||
CHostSacNet103Item *pItem;
|
||
BOOLEAN sec_changed = FALSE;
|
||
BOOLEAN bSetTime = FALSE;
|
||
|
||
if (!CNetProcess::OnTimer()) return FALSE;
|
||
|
||
if (last_sec != (time_t)system32.timers)
|
||
{
|
||
last_sec = system32.timers;
|
||
sec_changed = TRUE;
|
||
}
|
||
time_gap = GetSetTimeGap();
|
||
if (time_gap != 0 &&(system32.timers % time_gap) == 0 && sec_changed)
|
||
{
|
||
bSetTime = TRUE;
|
||
}
|
||
for (i = 0; i < PROCESS_UNIT_NUM; i++)
|
||
{
|
||
pItem = (CHostSacNet103Item *)GetItem(i);
|
||
if (NULL == pItem) continue;
|
||
uid = pItem->GetUnitID();
|
||
if (uid < 0 || uid >= UNIT_NUM) continue;
|
||
//<2F><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (pItem->GetSock() < 0)
|
||
{
|
||
if (pItem->apdu_t0_begin > 0 && system32.timers > (pItem->apdu_t0_begin + pItem->apdu_t0_max))
|
||
{
|
||
pItem->apdu_t0_begin = system32.timers;
|
||
UDPSend(bSetTime, FALSE, pItem->m_addr);
|
||
}
|
||
continue;
|
||
}
|
||
//TCP<43><50><EFBFBD>Ӿͱ<D3BE>ʾ<EFBFBD>õ<EFBFBD>ԪͨѶ<CDA8><D1B6><EFBFBD><EFBFBD>
|
||
UnitFeedDog(uid);
|
||
//ң<>ر<EFBFBD><D8B1><EFBFBD>
|
||
if (GetYKFrame(pItem, i)) continue;
|
||
if (sec_changed)
|
||
{
|
||
if (pItem->apdu_t1_begin > 0 && system32.timers > (pItem->apdu_t1_begin + pItem->apdu_t1_max))
|
||
{
|
||
pItem->apdu_t1_begin = system32.timers;
|
||
UDPSend(bSetTime, FALSE, pItem->m_addr);
|
||
}
|
||
if (pItem->apdu_t2_begin > 0 && system32.timers > (pItem->apdu_t2_begin + pItem->apdu_t2_max))
|
||
{
|
||
pItem->apdu_t2_begin = system32.timers;
|
||
if (!orgAsdu7(pItem, 0xff, i))
|
||
{
|
||
vLog(LOG_ERROR, "Unit(%d) send IGI error.\n", uid);
|
||
}
|
||
#if 0
|
||
for (j = 0; j < pItem->m_option.cpu_count; j++)
|
||
{
|
||
if (!orgAsdu7(pItem, pItem->m_option.comm_addr[j], i))
|
||
{
|
||
vLog(LOG_ERROR, "Unit(%d) send IGI error.\n", uid);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
int CHostSacNet103Process::OnPackageReceived(BYTE* pBuf, int count, int ord)
|
||
{
|
||
int uid;
|
||
int len = 0;
|
||
CHostSacNet103Item* pItem;
|
||
pItem = (CHostSacNet103Item *)GetItem(ord);
|
||
if (NULL == pItem) return -1;
|
||
uid = pItem->GetUnitID();
|
||
if (uid < 0 || uid >= UNIT_NUM) return -1;
|
||
if (count < 5) return 0;
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5>ı<EFBFBD><C4B1><EFBFBD>
|
||
switch (pBuf[0])
|
||
{
|
||
case M_IRC_NA_3:
|
||
len = ASDU_5_SIZE;
|
||
break;
|
||
case M_GD_NA_3:
|
||
len = GetAsdu10Length(pBuf, count);
|
||
break;
|
||
case M_LRD_TA_3: //<2F><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>Ŷ<EFBFBD><C5B6><EFBFBD>ASDU23
|
||
len = GetAsdu23Length(pBuf, count);
|
||
break;
|
||
case M_RTD_TA_3: //<2F>Ŷ<EFBFBD><C5B6><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ASDU26
|
||
len = ASDU_26_SIZE;
|
||
break;
|
||
case M_RTC_NA_3: //<2F><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ASDU27
|
||
len = ASDU_27_SIZE;
|
||
break;
|
||
case M_RTT_NA_3: //<2F><><EFBFBD><EFBFBD>־<EFBFBD><D6BE>״̬<D7B4><CCAC>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ASDU28
|
||
len = ASDU_28_SIZE;
|
||
break;
|
||
case M_TDT_TA_3: // <20><><EFBFBD>ʹ<EFBFBD><CDB4><EFBFBD>־<EFBFBD><D6BE>״̬<D7B4><CCAC>λASDU29
|
||
len = GetAsdu29Length(pBuf, count);
|
||
break;
|
||
case M_TDN_NA_3: // <20><><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>ֵASDU30
|
||
len = GetAsdu30Length(pBuf, count);
|
||
break;
|
||
case M_EOT_NA_3: //<2F><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>ASDU31
|
||
len = ASDU_31_SIZE;
|
||
break;
|
||
default:
|
||
//<2F><><EFBFBD><EFBFBD>ASDU<44><55><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
|
||
return count;
|
||
}
|
||
if (len <= 0 || count < len)
|
||
{ //<2F><><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD>
|
||
vLog(LOG_DEBUG, "Unit(%d) recv(%02x %02x %02x) buffer is not enough(%d,%d)!\n", uid, pBuf[0], pBuf[1], pBuf[2], len, count);
|
||
return 0;
|
||
}
|
||
SacNet103AsduProc(pItem, pBuf, ord);
|
||
DisplayRxData(pBuf, len, TRUE, uid);
|
||
UnitFeedDog(uid);
|
||
return (len);
|
||
}
|
||
|
||
void CHostSacNet103Process::SacNet103AsduProc(CHostSacNet103Item* pItem, BYTE* buffer, int ord)
|
||
{
|
||
BYTE COT, INF, fun1, inf1, prop;
|
||
BYTE Datalen, state;
|
||
BYTE NGD1,Datalen1;
|
||
BYTE comm_addr;
|
||
BYTE param[4];
|
||
WORD pp;
|
||
short YcValue = 0;
|
||
int yxno, ycno, ykno;
|
||
int i;
|
||
DWORD dwValue = 0;
|
||
float fValue = 0.0f;
|
||
unionCP56Time st;
|
||
|
||
if (NULL == pItem) return;
|
||
int uid = pItem->GetUnitID();
|
||
if (uid < 0) return;
|
||
|
||
memcpy(&st, &system32.now, sizeof(st));
|
||
|
||
COT = buffer[2];
|
||
comm_addr = buffer[3];
|
||
NGD1 = buffer[7];
|
||
param[0] = comm_addr;
|
||
switch (buffer[0])
|
||
{//w1
|
||
case M_GD_NA_3://ͨ<>÷<EFBFBD><C3B7><EFBFBD>
|
||
pp = 7;
|
||
for (i = 0; i < NGD1; i++)
|
||
{//w2
|
||
fun1 = buffer[pp + 1];
|
||
param[1] = fun1;
|
||
switch (fun1) //GIN
|
||
{
|
||
case 0x00:
|
||
break;
|
||
case 0x01:
|
||
break;//printf("system process\n");
|
||
case 0x03://<2F><>ֵ
|
||
break;
|
||
case 0x04://<2F><><EFBFBD><EFBFBD>
|
||
case 0x05://<2F>澯
|
||
{
|
||
inf1 = buffer[pp + 2];
|
||
Datalen = buffer[pp + 5];
|
||
param[2] = inf1;
|
||
yxno = GetUnitYXPointByParam(uid, param, 3);
|
||
if ((buffer[pp + 7] & 0x03) == DPI_ON) state = SPI_ON;
|
||
else state = SPI_OFF;
|
||
if (yxno >= 0)
|
||
{
|
||
if ((COT == IEC103_COT_SPONT) || (COT == IEC103_COT_LOOP))
|
||
{
|
||
st.millisecond = (buffer[pp + 8] + (buffer[pp + 9] << 8));
|
||
st.minute = buffer[pp + 10] & 0x7f;
|
||
st.hour = buffer[pp + 11] & 0x1f;
|
||
SetUnitSOE(uid, yxno, state, st);
|
||
SetUnitYX(uid, yxno, state);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 0x08://<2F><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ң<EFBFBD><D2A3><EFBFBD>ࣨ<EFBFBD>絶բ<E7B5B6><D5A2><EFBFBD><EFBFBD><EFBFBD>ء<EFBFBD><D8A1>źš<C5BA>״̬<D7B4>ȣ<EFBFBD>soe
|
||
case 0x18:
|
||
case 0x0e:
|
||
if (COT == IEC103_COT_SPONT) //<2F><><EFBFBD><EFBFBD>ң<EFBFBD><D2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
|
||
{
|
||
inf1 = buffer[pp + 2];
|
||
Datalen = buffer[pp + 5];
|
||
if (fun1 == 0x18) param[1] = param[1] - 0x10;
|
||
param[2] = inf1;
|
||
yxno = GetUnitYXPointByParam(uid, param, 3);
|
||
if ((buffer[pp + 7] & 0x03) == DPI_ON) state = SPI_ON;
|
||
else state = SPI_OFF;
|
||
if (yxno >= 0)
|
||
{
|
||
if (fun1 == 0x18) //ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ң<EFBFBD>ű<EFBFBD><C5B1><EFBFBD>
|
||
{
|
||
st.millisecond = (buffer[pp + 8] + (buffer[pp + 9] << 8));
|
||
st.minute = buffer[pp + 10] & 0x7f;
|
||
st.hour = buffer[pp + 11] & 0x1f;
|
||
SetUnitSOE(uid, yxno, state, st);
|
||
SetUnitYX(uid, yxno, state);
|
||
}
|
||
else
|
||
{
|
||
SetUnitYX(uid, yxno, state);
|
||
}
|
||
}
|
||
}
|
||
if ((COT == IEC103_COT_LOOP) || (COT == IEC103_COT_IGI)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٻ<EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD>ݵı<DDB5><C4B1><EFBFBD>
|
||
{
|
||
inf1 = buffer[pp + 2];
|
||
Datalen = buffer[pp + 5];
|
||
param[2] = inf1;
|
||
if ((fun1 == 0x08) || (fun1 == 0x0e)) //ң<>ż<EFBFBD><C5BC><EFBFBD>ѹ<EFBFBD><D1B9>
|
||
{
|
||
yxno = GetUnitYXPointByParam(uid, param, 3);
|
||
if ((buffer[pp + 7] & 0x03) == DPI_ON) state = SPI_ON;
|
||
else state = SPI_OFF;
|
||
if (yxno >= 0)
|
||
{
|
||
SetUnitYX(uid, yxno, state);
|
||
}
|
||
}
|
||
if (fun1 == 0x07) //ң<><D2A3>
|
||
{
|
||
vLog(LOG_ERROR, "never be here.\n");
|
||
ycno = GetUnitYCPointByParam(uid, param, 3);
|
||
if (ycno >= 0)
|
||
{
|
||
if (Datalen == 4)
|
||
{
|
||
dwValue = (DWORD)((buffer[pp + 10] << 24) | (buffer[pp + 9] << 16) | (buffer[pp + 8] << 8) | buffer[pp + 7]);
|
||
memcpy(&fValue, &dwValue, Datalen);
|
||
SetUnitYC(uid, ycno, fValue);
|
||
}
|
||
if (Datalen == 2)
|
||
{
|
||
YcValue = (buffer[pp + 7] + (buffer[pp + 8] << 8));
|
||
if (YcValue & 0x1000)
|
||
{
|
||
YcValue = (((~YcValue & 0xffff) | 0x1000) + 1);
|
||
}
|
||
if (YcValue > 16380) YcValue = 0;
|
||
SetUnitYC(uid, ycno, (LONG)YcValue);
|
||
}
|
||
if (Datalen == 1)
|
||
{
|
||
YcValue = buffer[pp + 7];
|
||
SetUnitYC(uid, ycno, (LONG)YcValue);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 0x06: //ң<><D2A3><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ)
|
||
break;
|
||
case 0x07: //ң<><D2A3><EFBFBD>ࣨ<EFBFBD><E0A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD>ʡ<EFBFBD>Ƶ<EFBFBD>ʡ<EFBFBD>ˮλ<CBAE><CEBB><EFBFBD>¶ȵȣ<C8B5>
|
||
inf1 = buffer[pp + 2];
|
||
Datalen = buffer[pp + 5];
|
||
param[2] = inf1;
|
||
ycno = GetUnitYCPointByParam(uid, param, 3);
|
||
if (ycno >= 0)
|
||
{
|
||
if (Datalen == 4)
|
||
{
|
||
dwValue = (DWORD)((buffer[pp + 10] << 24) | (buffer[pp + 9] << 16) | (buffer[pp + 8] << 8) | buffer[pp + 7]);
|
||
memcpy(&fValue, &dwValue, Datalen);
|
||
SetUnitYC(uid, ycno, fValue);
|
||
}
|
||
if (Datalen == 2)
|
||
{
|
||
YcValue = (buffer[pp + 7] + (buffer[pp + 8] << 8));
|
||
if (YcValue & 0x1000)
|
||
{
|
||
YcValue = (((~YcValue & 0xffff) | 0x1000) + 1);
|
||
}
|
||
if (YcValue > 16380) YcValue = 0;
|
||
SetUnitYC(uid, ycno, (LONG)YcValue);
|
||
}
|
||
if (Datalen == 1)
|
||
{
|
||
YcValue = buffer[pp + 7];
|
||
SetUnitYC(uid, ycno, (LONG)YcValue);
|
||
}
|
||
}
|
||
break;
|
||
case 0x09://ң<><D2A3><EFBFBD><EFBFBD>
|
||
break;
|
||
case 0x0a:
|
||
break; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
case 0x0b: /*ң<>ز<EFBFBD><D8B2><EFBFBD>*/
|
||
INF = buffer[5];
|
||
inf1 = buffer[9]; //<2F><>Ŀ<EFBFBD><C4BF>
|
||
prop = buffer[14]; //<2F><><EFBFBD>ݣ<EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD> 2<><32><EFBFBD>ϣ<EFBFBD>
|
||
param[2] = inf1;
|
||
ykno = GetUnitYKPointByParam(uid, param, 3);
|
||
if (ykno >= 0)
|
||
{
|
||
switch (INF)
|
||
{
|
||
case 249:/*ң<><D2A3>ѡ<EFBFBD><D1A1>*/
|
||
{
|
||
BOOLEAN value = (prop == 0x02) ? TRUE : FALSE;
|
||
SetUnitYK(uid, ykno, value, YKS_SELED, YKR_SUCC);
|
||
vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC.\r\n", uid, ykno, (value ? "CLOSE" : "TRIP"));
|
||
}
|
||
break;
|
||
case 250:/*ң<><D2A3>ִ<EFBFBD><D6B4>*/
|
||
{
|
||
BOOLEAN value = (prop == 0x02) ? TRUE : FALSE;
|
||
SetUnitYK(uid, ykno, value, YKS_EXEED, YKR_SUCC);
|
||
vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_EXEED result is YKR_SUCC.\r\n", uid, ykno, (value ? "CLOSE" : "TRIP"));
|
||
}
|
||
break;
|
||
case 251:/*ң<>س<EFBFBD><D8B3><EFBFBD>*/
|
||
{
|
||
BOOLEAN value = (prop == 0x02) ? TRUE : FALSE;
|
||
SetUnitYK(uid, ykno, value, YKS_ABRED, YKR_SUCC);
|
||
vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC.\r\n", uid, ykno, (value ? "CLOSE" : "TRIP"));
|
||
}
|
||
break;
|
||
default: break;
|
||
}
|
||
}
|
||
break;
|
||
case 0x0d:
|
||
break;//ң<>ط<EFBFBD>ͷ<EFBFBD>ࣨ<EFBFBD><E0A3A8>/<2F><><EFBFBD><EFBFBD>
|
||
default:
|
||
break;
|
||
}
|
||
Datalen1 = buffer[pp + 5];
|
||
pp = pp + Datalen1 + 6;
|
||
}//w2
|
||
break;
|
||
/*<2A>Ŷ<EFBFBD><C5B6><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>asdu23<32><33>asdu26<32><36>asdu27<32><37>asdu28<32><38>asdu29<32><39>asdu30<33><30>asdu31*/
|
||
case M_LRD_TA_3: //<2F><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>Ŷ<EFBFBD><C5B6><EFBFBD>ASDU23
|
||
break;
|
||
case M_RTD_TA_3: //<2F>Ŷ<EFBFBD><C5B6><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ASDU26
|
||
break;
|
||
case M_RTC_NA_3: //<2F><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ASDU27
|
||
break;
|
||
case M_RTT_NA_3: //<2F><><EFBFBD><EFBFBD>־<EFBFBD><D6BE>״̬<D7B4><CCAC>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ASDU28
|
||
break;
|
||
case M_TDT_TA_3: // <20><><EFBFBD>ʹ<EFBFBD><CDB4><EFBFBD>־<EFBFBD><D6BE>״̬<D7B4><CCAC>λASDU29
|
||
break;
|
||
case M_TDN_NA_3: // <20><><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>ֵASDU30
|
||
break;
|
||
case M_EOT_NA_3: //<2F><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>ASDU31
|
||
break;
|
||
default: break;
|
||
}//w1
|
||
}
|
||
|
||
BOOLEAN CHostSacNet103Process::GetYKFrame(CHostSacNet103Item* pItem, int ord)
|
||
{
|
||
int uid, order;
|
||
BYTE value, state, result;
|
||
BYTE buffer[64];
|
||
|
||
if (NULL == pItem) return FALSE;
|
||
memset(buffer, 0, sizeof(buffer));
|
||
uid = pItem->GetUnitID();
|
||
if (uid < 0 || uid >= UNIT_NUM) return FALSE;
|
||
if (!GetUnitYK(uid, order, value, state, result)) return FALSE;
|
||
|
||
vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is %s result is %s.\r\n", uid, order, (value ? "CLOSE" : "TRIP"), val_to_str( state, yk_state, "STATE= %d" ), val_to_str( result, yk_result, "RESULT= %d"));
|
||
//<2F><>ȡң<C8A1><D2A3><EFBFBD><EFBFBD>Ϣ
|
||
BYTE* pParam = GetUnitYKParamByPoint(uid, order);
|
||
if (NULL == pParam) return FALSE;
|
||
BYTE comm_addr;
|
||
BYTE groupno, itemno, prop, inf = 0;
|
||
comm_addr = pParam[0];
|
||
groupno = pParam[1];
|
||
itemno = pParam[2];
|
||
if (value) prop = 2;
|
||
else prop = 1;
|
||
if (YKS_SELREQ == state)
|
||
{
|
||
inf = 249;
|
||
}
|
||
else if (YKS_EXEREQ == state)
|
||
{
|
||
inf = 250;
|
||
}
|
||
else if ((YKS_ABRREQ == state) || ((YKS_SELING == state || YKS_SELED == state) && YKR_OVER == result))
|
||
{
|
||
inf = 251;
|
||
}
|
||
buffer[0] = 0x0a;
|
||
buffer[1] = 0x81;
|
||
buffer[2] = 40;
|
||
buffer[3] = comm_addr;
|
||
buffer[4] = 254;
|
||
buffer[5] = inf;
|
||
buffer[6] = 0;
|
||
buffer[7] = 1;
|
||
buffer[8] = groupno;
|
||
buffer[9] = itemno;
|
||
buffer[10] = 1;
|
||
buffer[11] = 9;
|
||
buffer[12] = 1;
|
||
buffer[13] = 1;
|
||
buffer[14] = prop;
|
||
return sendToSacDev(pItem, buffer, 15, ord);
|
||
}
|
||
|
||
|
||
BOOLEAN CHostSacNet103Process::orgAsdu7(CHostSacNet103Item* pItem, BYTE comm_addr, int ord)
|
||
{
|
||
BYTE buffer[8];
|
||
|
||
if (NULL == pItem) return FALSE;
|
||
memset(buffer, 0, sizeof(buffer));
|
||
buffer[0] = 0x07; //TYP
|
||
buffer[1] = 0x81; //
|
||
buffer[2] = 0x09;
|
||
buffer[3] = comm_addr;
|
||
buffer[4] = 0xff; //FUN
|
||
buffer[5] = 0x00;
|
||
buffer[6] = pItem->m_scn++;
|
||
return sendToSacDev(pItem, buffer, 7, ord);
|
||
}
|
||
|
||
BOOLEAN CHostSacNet103Process::sendToSacDev(CHostSacNet103Item* pItem, BYTE* pBuf, int len, int ord)
|
||
{
|
||
if (NULL == pItem) return FALSE;
|
||
|
||
if (!WriteData(pBuf, len, ord))
|
||
{
|
||
vLog(LOG_ERROR, "Unit(%d) Send Frame Write Data Error.\r\n", pItem->GetUnitID());
|
||
return FALSE;
|
||
}
|
||
DisplayTxData(pBuf, len, TRUE);
|
||
return TRUE;
|
||
}
|