📄 msghdler.cpp
字号:
case 2: // analog input
SetRtuCmdStep(sendInfo->pRtu, 0);
pF3Rsp = (F3RSP *)p_buf;
if (crc != *(USHORT *)&p_buf[len - 2]) {
SetPioRecvStatus(pPio, PIO__BAD_CHECKSUM);
}
else {
gix = AINORMSLOT;
for (i = 0; i < (len - 6) / 2; i++) {
shtval = byte_swap(pF3Rsp->reg[i]);
if (shtval & 0x8000) { // negative
shtval -= (short)0x8000; // for bipolar
}
else {
shtval += 0x8000;
}
pix = i % PNTGRPMAX;
value = shtval;
UpdRtuRawData(sendInfo->pRtu, gix, pix, value);
if ((i % PNTGRPMAX) == (PNTGRPMAX - 1)) {
gix++;
}
}
}
// clear polling flag for next polling
ClrRtuPollSts(sendInfo->pRtu);
break;
}
break;
case DIGI_COMD: // digital output command
pF5Rsp = (F5RSP *)p_buf;
if (crc != *(USHORT *)&p_buf[len - 2]) {
SetPioRecvStatus(pPio, PIO__BAD_CHECKSUM);
}
if (sendInfo->rGrpIdx == DOPARMSLOT) { // to read control word
// send additional polling command
sendInfo->FuncCode = RELY_COMD;
sendInfo->cmdIdx = RLY_CONSET;
// add a high priority refresh poll
AddMorePollCmd(sendInfo, TRUE);
}
break;
case ANAL_COMD: // register output command
pF5Rsp = (F5RSP *)p_buf;
if (crc != *(USHORT *)&p_buf[len - 2]) {
SetPioRecvStatus(pPio, PIO__BAD_CHECKSUM);
}
break;
case RELY_COMD: // relay control command
switch (sendInfo->cmdIdx) {
case RLY_VALQRY: // 定值查询
pF3Rsp = (F3RSP *)p_buf;
startidx = 0;
cpuidx = sendInfo->rGrpIdx; // cpu number
setnum = sendInfo->rPntIdx; // set number
setval = GetSetFuncNum(sendInfo->pRtu, cpuidx);
for (i = 0; i < setval; i++) {
shtval = byte_swap(pF3Rsp->reg[i]);
if (!GetSetUpdData(sendInfo->pRtu, cpuidx, startidx, &valtyp, data)) {
valtyp = 0;
}
switch (valtyp) {
case 1:
shtval = (shtval == ENGIVALUE) ? 1 : 0;
break;
case 2:
if (shtval == SP9600VAL) {
shtval = 3;
}
else if (shtval == SP4800VAL) {
shtval = 2;
}
else if (shtval == SP2400VAL) {
shtval = 1;
}
else {
shtval = 0;
}
break;
}
if ((setidx = PutRlySetValue(sendInfo->pRtu, cpuidx, setnum,
startidx, (BYTE *)&shtval)) < 0)
break;
startidx = setidx;
}
// set successful flag, where the last param is type
// type = 0 for query, type = 1 for value setup
SetRlySucFlag(sendInfo->pRtu, setnum, 0);
if (setnum != 0) { // query working set, replace display
PutRlySetToActDev(sendInfo->pRtu, cpuidx, setnum);
}
// transfer set value to standby cpu
RelayValueXfr(sendInfo->pRtu, 1);
break;
case RLY_CONSET: // 控制字召唤
pF3Rsp = (F3RSP *)p_buf;
gix = DIPROTSLOT;
pSts = (BYTE *)pF3Rsp->reg;
shtval = byte_swap(pF3Rsp->num);
for (i = 0; i < shtval; i++) {
if (*pSts >= CTLWORDON) {
value = (*pSts == CTLWORDON) ? 1 : 0;
UpdRtuRawData(sendInfo->pRtu, gix, i, value, 1);
}
else {
if (GetDioInpInfo(sendInfo->pRtu, gix, i, &inpcnt)) {
if (inpcnt > 2) {
switch (*pSts) {
case 0:
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 3);
break;
case 1:
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 3);
break;
case 2:
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 3);
break;
case 3:
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 3);
break;
case 4:
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 3);
break;
case 5:
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 3);
break;
case 6:
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 3);
break;
case 7:
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 3);
break;
}
}
else {
switch (*pSts) {
case 0:
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
break;
case 1:
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
break;
case 2:
UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
break;
case 3:
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
break;
}
}
}
}
pSts++;
}
UpdRtuPntSts(sendInfo->pRtu, 1);
break;
case RLY_VALSET: // 定值设置
// inform client value setup finished
SetRlySucFlag(sendInfo->pRtu, 100, 1);
break;
}
break;
}
}
else {
// write data to debug buffer if rtu in debug mode
SetPioRtuDbgInMsg(pPio, sendInfo->pRtu);
// clear polling flag for next polling
ClrRtuPollSts(sendInfo->pRtu);
}
ClrPioRtuStream(ioStream);
}
static UINT SendCommand(CPio *pPio, REQUEST_MSGS *pMsg, int *respnum)
{
int value, setitm, nextitm, item;
int grp, pix, ctlcnt;
UINT len = 0;
USHORT setval, cpuidx;
BYTE valtyp, *data, *p_buf = GetPioWrtBuf(pPio);
float fvalue;
F3CMD *pF3Cmd;
F5CMD *pF5Cmd;
F6CMD *pF6Cmd;
F16CMD *pF16Cmd;
SYSTEMTIME sTime;
switch (pMsg->FuncCode) {
// digital/analog control types
case DIGI_COMD: // digital output command
// form frame section
if (pMsg->rGrpIdx < DORESTSLOT) { // normal do control
pF5Cmd = (F5CMD *)p_buf;
pF5Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
pF5Cmd->func = FUNC_5;
pF5Cmd->coil = byte_swap(pMsg->rPntIdx + pMsg->cmdIdx);
pF5Cmd->num = byte_swap(1);
pF5Cmd->value = DOONVALUE;
pF5Cmd->crc = mod_crc(p_buf, (MODBUS_F5_SIZ - 2 ) );
len = MODBUS_F5_SIZ;
*respnum = MODBUS_F5_REPLY_SIZ;
}
#if 0
else if (pMsg->rGrpIdx < DOPARMSLOT) { // reset control
pF6Cmd = (F6CMD *)p_buf;
pF6Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
pF6Cmd->func = FUNC_6;
pF6Cmd->reg = byte_swap(pMsg->rPntIdx);
pF6Cmd->len = byte_swap(1);
pF6Cmd->val[0] = 0;
pF6Cmd->crc = mod_crc(p_buf, (MODBUS_F6_SIZ - 2 ) );
len = MODBUS_F6_SIZ;
*respnum = MODBUS_F6_REPLY_SIZ;
}
#endif
else { // control word, normal
pF6Cmd = (F6CMD *)p_buf;
pF6Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
pF6Cmd->func = FUNC_6;
if (GetDioCtlInfo(pMsg->pntIdx, &grp, &pix, &ctlcnt)) {
setval = CTLWORDORG + pix - 1;
pF6Cmd->reg = byte_swap(setval);
pF6Cmd->len = byte_swap(1);
if (ctlcnt <= 2) { // 压板控制字
pF6Cmd->val[0] = (pMsg->cmdIdx % 2) ? CTLWORDON : CTLWORDOFF;
}
else { // 特殊控制字
pF6Cmd->val[0] = pMsg->cmdIdx - 1;
}
pF6Cmd->crc = mod_crc(p_buf, (MODBUS_F6_SIZ - 2 ) );
len = MODBUS_F6_SIZ;
*respnum = MODBUS_F6_REPLY_SIZ;
}
}
break;
case ANAL_COMD: // register output command
// to be develop
*respnum = 0;
break;
case RELY_COMD: // relay control command
switch (pMsg->cmdIdx) {
case RLY_VALQRY: // 定值和参数查询
pF3Cmd = (F3CMD *)p_buf;
pF3Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
pF3Cmd->func = FUNC_3;
cpuidx = pMsg->rGrpIdx; // cpu number
if (cpuidx <= 1) { // 定值查询
pF3Cmd->reg = byte_swap(SETWORDORG);
}
else { // 参数查询
pF3Cmd->reg = byte_swap(PRMWORDORG);
}
setval = GetSetFuncNum(pMsg->pRtu, (BYTE)cpuidx) * 2;
pF3Cmd->num = byte_swap(setval);
pF3Cmd->crc = mod_crc(p_buf, (MODBUS_F3_SIZ - 2 ) );
len = MODBUS_F3_SIZ;
*respnum = MODBUS_F3_SIZ + setval - 2;
break;
case RLY_VALSET: // 定值和参数设置
pF6Cmd = (F6CMD *)p_buf;
pF6Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
pF6Cmd->func = FUNC_6;
cpuidx = pMsg->rGrpIdx; // cpu number
if (cpuidx <= 1) { // 定值设置
pF6Cmd->reg = byte_swap(SETWORDORG);
}
else { // 参数设置
pF6Cmd->reg = byte_swap(PRMWORDORG);
}
// read modification data from relay device database
setitm = nextitm = 0;
data = (BYTE *)pF6Cmd->val;
while (item = GetSetUpdData(pMsg->pRtu, (BYTE)cpuidx, nextitm, &valtyp, (BYTE *)&value)) {
// revert set value to 2 bytes data
switch (valtyp) {
case 1:
setval = value;
if (setval == 1) {
setval = ENGIVALUE;
}
else {
setval = CHINVALUE;
}
setval = byte_swap(setval);
break;
case 2:
setval = value;
if (setval == 1) {
setval = SP2400VAL;
}
else if (setval == 2) {
setval = SP4800VAL;
}
else if (setval == 3) {
setval = SP9600VAL;
}
else {
setval = SP2400VAL;
}
setval = byte_swap(setval);
break;
default:
fvalue = *(float *)&value;
setval = byte_swap((USHORT)fvalue);
break;
}
*(USHORT *)data = setval;
nextitm = item; // go to get next set value
setitm++;
data += 2;
}
setval = setitm * 2;
pF6Cmd->len = byte_swap(setval);
len = setval + 8;
*(USHORT *)data = mod_crc(p_buf, len - 2 );
*respnum = MODBUS_F6_REPLY_SIZ;
break;
case RLY_DEVRST: // 装置复位
pF6Cmd = (F6CMD *)p_buf;
pF6Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
pF6Cmd->func = FUNC_6;
pF6Cmd->reg = 0;
pF6Cmd->len = byte_swap(1);
pF6Cmd->val[0] = 0;
pF6Cmd->crc = mod_crc(p_buf, (MODBUS_F6_SIZ - 2 ) );
len = MODBUS_F6_SIZ;
*respnum = MODBUS_F6_REPLY_SIZ;
break;
case RLY_CONSET: // 控制字召唤
pF3Cmd = (F3CMD *)p_buf;
pF3Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
pF3Cmd->func = FUNC_3;
setval = CTLWORDORG;
pF3Cmd->reg = byte_swap(setval);
setval = GetActGrpPnt(pMsg->pRtu, DIPROTSLOT);
pF3Cmd->num = byte_swap(setval);
pF3Cmd->crc = mod_crc(p_buf, (MODBUS_F3_SIZ - 2 ) );
len = MODBUS_F3_SIZ;
*respnum = MODBUS_F3_SIZ + setval - 2;
break;
}
break;
case TIME_SYNC: // time sync command
// form time message section
GetLocalTime(&sTime);
pF16Cmd = (F16CMD *)p_buf;
pF16Cmd->addr = *respnum;
pF16Cmd->func = FUNC_16;
pF16Cmd->reg = 0;
pF16Cmd->len = byte_swap(6);
pF16Cmd->tim[0] = (BYTE)SET_BCD(sTime.wSecond);
pF16Cmd->tim[1] = (BYTE)SET_BCD(sTime.wMinute);
pF16Cmd->tim[2] = (BYTE)SET_BCD(sTime.wHour);
pF16Cmd->tim[3] = (BYTE)SET_BCD(sTime.wDay);
pF16Cmd->tim[4] = (BYTE)SET_BCD(sTime.wMonth);
pF16Cmd->tim[5] = (BYTE)SET_BCD(sTime.wYear % 100);
pF16Cmd->crc = mod_crc(p_buf, (MODBUS_F16_SIZ - 2 ) );
len = MODBUS_F16_SIZ;
*respnum = 0;
break;
}
return len;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -