1、效果
2、扩展后调用代码
case C_RS_NA_1: // 读取参数
// 获取请求的地址
printf("ReadParam:%d,datasize:%d\n", CS101_ASDU_getTypeID(asdu), CS101_ASDU_getPayloadSize(asdu));
uint16_t payload_size = CS101_ASDU_getPayloadSize(asdu);
uint8_t *pPayLoad = CS101_ASDU_getPayload(asdu);
int sn = ReadParamCommand_getSN(asdu);//获取sn
int numOfElements = CS101_ASDU_getNumberOfElements(asdu); // 0读全部,1指定
bool isSequment = CS101_ASDU_isSequence(asdu); // 是否是顺序
printf("numOfElements:%d\n", numOfElements);
int arrayNum[256];
if (numOfElements > 0) // 指定数据单元
{
if (!isSequment) // 离散
{
for (int i = 0; i < numOfElements; i++)
{
printf("i:%ld\n", i);
InformationObject io = CS101_ASDU_getElement(asdu, i); // 必须先执行getElement初始化,需要自己实现对应逻辑。
int n = InformationObject_getObjectAddress(io);
arrayNum[i] = n;
}
}
else // 顺序
{
InformationObject io = CS101_ASDU_getElement(asdu, 0); // 必须先执行getElement初始化,需要自己实现对应逻辑。
int n = InformationObject_getObjectAddress(io);
for (int i = 0; i < numOfElements; i++)
{
arrayNum[i] = n++;
}
}
}
else // 全部数据单元
{
numOfElements = 20; // 从配置文件读取个数
for (int i = 0; i < numOfElements; i++) // 假定配置了20个参数
{
arrayNum[i] = 0x8000 + i;
}
}
// 组装报文
CS101_AppLayerParameters alParams = IMasterConnection_getApplicationLayerParameters(connection);
InformationObject io = NULL;
int haveNextFrame = 0; // 是否有下一帧
CS101_ASDU newAsdu=NULL;
for (int i = 0; i < numOfElements; i++) // 按照要读取元素分包发送返回数据
{
if (i == 0 || haveNextFrame) // 第一包或者分包后的一包
{
haveNextFrame = 0;
newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_ACTIVATION_CON,
0, 1, false, false);
}
int address = arrayNum[i];
printf("address:%ld,%02X\n", address, address);
// todo: 实现GetDataByAddress,这里数据根据address从配置项读取
TaggedData taggedData; // 共用体用于转换数据
///////////////////////不同数据类型示例//////////////////////
taggedData.tag = FLOAT_TAG;
taggedData.value.floatValue = 120.45;
taggedData.len = GetTLVLen(taggedData);
taggedData.tag = STRING_TAG;
sprintf(taggedData.value.stringValue, "Ver1.0");
taggedData.len = GetTLVLen(taggedData);
taggedData.tag = BOOLEAN_TAG;
taggedData.value.booleanValue = true;
taggedData.len = GetTLVLen(taggedData);
taggedData.tag = LONG_TAG;
taggedData.value.longValue = 1888;
taggedData.len = GetTLVLen(taggedData);
///////////////////////不同数据类型示例//////////////////////
bool bAddOk = false;
if (io == NULL)
bAddOk = CS101_ASDU_addInformationObject(newAsdu, io = (InformationObject)ReadParamCommand_create(NULL, address, taggedData));
else
bAddOk = CS101_ASDU_addInformationObject(newAsdu, (InformationObject)ReadParamCommand_create((ReadParamCommand)io, address, taggedData));
if (!bAddOk) // 本包超出限制,分组并将本包数据放到下一包发送
{
haveNextFrame = 1;
i--;
}
if ((i == numOfElements - 1) || (haveNextFrame)) // 最后一包或者分包
{
InformationObject_destroy(io);
IMasterConnection_sendASDU(connection, newAsdu);
CS101_ASDU_destroy(newAsdu);
}
}
return true;
break;
标签:asdu,IEC60870,扩展,ASDU,numOfElements,int,CS101,参数,taggedData
From: https://www.cnblogs.com/zhaogaojian/p/17231341.html