首页 > 其他分享 >IEC60870 库扩展功能-读多个参数

IEC60870 库扩展功能-读多个参数

时间:2023-03-18 17:56:30浏览次数:34  
标签:asdu IEC60870 扩展 ASDU numOfElements int CS101 参数 taggedData

1、效果

image

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

相关文章