天天看點

lib60870-IEC 60870-5-101 / 104 C源代碼庫使用者指南-版本2.3.0 -第二部分

Slave從站(server伺服器)端程式設計

CS104(TCP / IP)伺服器配置和設定

要配置和設定IEC 60870-5-104伺服器/從屬伺服器,需要CS104_Slave資料類型的執行個體。

CS104_Slave slave = CS104_Slave_create(100,100);
           

建立伺服器執行個體後,可以對其進行配置

CS104伺服器模式

伺服器提供了三種有關備援連接配接支援和事件隊列處理的模式:

預設模式(CS104_MODE_SINGLE_REDUNDANCY_GROUP)僅允許單個活動用戶端連接配接。活動用戶端連接配接是發送ASDU(應用程式資料單元)的連接配接。所有其他連接配接隻是不發送應用程式層資料的備用連接配接。事件隻有一個隊列。當沒有用戶端連接配接或沒有連接配接處于活動狀态時,也會存儲事件。

第二種模式(CS104_MODE_CONNECTION_IS_REDUNDANCY_GROUP)允許多個活動用戶端連接配接。每個連接配接都有其自己的事件隊列。關閉用戶端連接配接後,事件隊列将被删除。當多個用戶端必須通路應用程式資料時,可以使用此模式。此模式易于使用。但是此模式的缺點是,當沒有用戶端連接配接時事件會丢失。

第三種模式(CS104_MODE_MULTIPLE_REDUNDANCY_GROUPS)允許多個活動用戶端連接配接,同時保留未連接配接任何用戶端時的事件。在這種模式下,可以将用戶端配置設定給特定的備援組。配置設定基于用戶端的IP位址。備援組可以有多個同時連接配接,但是這些連接配接中隻有一個可以處于活動狀态。激活的連接配接數受備援組數的限制。每個備援組都有一個專用的事件隊列。

可以使用CS104_Slave_setServerMode函數設定伺服器模式:

CS104_Slave_setServerMode(從站,CS104_MODE_MULTIPLE_REDUNDANCY_GROUPS);
           

CS104:定義多個備援組

僅當使用伺服器模式CS104_MODE_MULTIPLE_REDUNDANCY_GROUPS時,才需要顯式建立備援組。您可以将多個IP位址配置設定給備援組。然後,來自這些IP位址之一的傳入連接配接将自動配置設定給該特定的備援組。

當備援組沒有配置設定的IP位址時,它将用作“全部捕獲”組。這意味着所有未配置設定給其他組之一的傳入連接配接都将落入該組。

示例如何定義多重備援組  

CS104_Slave_setServerMode(slave, CS104_MODE_MULTIPLE_REDUNDANCY_GROUPS);

CS104_RedundancyGroup redGroup1 = CS104_RedundancyGroup_create("red-group-1");
CS104_RedundancyGroup_addAllowedClient(redGroup1, "192.168.2.9");

CS104_RedundancyGroup redGroup2 = CS104_RedundancyGroup_create("red-group-2");
CS104_RedundancyGroup_addAllowedClient(redGroup2, "192.168.2.223");
CS104_RedundancyGroup_addAllowedClient(redGroup2, "192.168.2.222");

CS104_RedundancyGroup redGroup3 = CS104_RedundancyGroup_create("catch-all");

CS104_Slave_addRedundancyGroup(slave, redGroup1);
CS104_Slave_addRedundancyGroup(slave, redGroup2);
CS104_Slave_addRedundancyGroup(slave, redGroup3);
           

CS101(串行)slave從站配置和設定

與主側相似,CS101從側也可以配置為兩種鍊路層模式之一(平衡或不平衡)。CS101從站由CS101_SLave對象表示。

一個前CS101_Slave對象可以建立的SerialPort是必需的對象。所述的SerialPort對象表示串行接口和它的配置。

SerialPort port = SerialPort_create(serialPort, 9600, 8, 'E', 1);
           

CS101_Slave_create函數需要建立的SerialPort對象:

CS101_Slave slave = CS101_Slave_create(port,NULL,NULL,IEC60870_LINK_LAYER_UNBALANCED);
           

此功能具有以下簽名:

CS101_Slave
CS101_Slave_create(SerialPort serialPort, LinkLayerParameters llParameters, CS101_AppLayerParameters alParameters, IEC60870_LinkLayerMode linkLayerMode)
           

可選地,可以指定鍊路層參數和應用程式層參數。如果應使用預設值,則可以跳過這些參數(設定為NULL)。最後一個參數指定使用平衡還是不平衡模式。

對于串行從站,還需要設定一個鍊路層位址:

CS101_Slave_setLinkLayerAddress(slave,1);
           

設定回調處理函數 callback handler functions

在啟動或運作伺服器之前,建議設定回調函數以處理從屬事件。可以使用以下回調處理程式類型(有關功能簽名的詳細資訊,請參閱API參考手冊)。其中一些僅可用于CS 104伺服器,而某些僅可用于CS101從伺服器。

表2.從站側回調處理程式類型Slave side callback handler types

回調類型 事件 第101章 第104章
CS101_InterrogationHandler 詢問請求 + +
CS101_CounterInterrogationHandler 反詢問請求 + +
CS101_ReadHandler 讀取單個資訊對象的請求 + +
CS101_ClockSynchronizationHandler 收到時鐘同步消息 + +
CS101_ResetProcessHandler 收到重置流程請求 + +
CS101_DelayAcquisitionHandler 收到延遲擷取請求 + --
CS101_ASDUHandler ASDU已收到但未由其他回調處理程式之一處理 + +
CS101_ResetCUHandler 收到類型為複位CU(通信單元)的鍊路層消息 + --
CS104_ConnectionRequestHandler 一個新的TCP / IP用戶端嘗試連接配接 -- +
/* set the callback handler for the clock synchronization command */
CS101_Slave_setClockSyncHandler(slave, clockSyncHandler, NULL);

/* set the callback handler for the interrogation command */
CS101_Slave_setInterrogationHandler(slave, interrogationHandler, NULL);

/* set handler for other message types */
CS101_Slave_setASDUHandler(slave, asduHandler, NULL);

/* set handler for reset CU (reset communication unit) message */
CS101_Slave_setResetCUHandler(slave, resetCUHandler, (void*) slave);
           

CS104啟動/停止伺服器

配置伺服器後,可以使用CS104_Slave_start函數啟動它。此函數啟動一個新的背景線程,該線程正在偵聽傳入的用戶端連接配接。

CS104_Slave_start(slave);
           

要停用IEC 60870-5-104服務,可以使用CS104_Slave_stop功能停止伺服器。

CS104_Slave_stop(slave);
           

自動或定期發送消息

為了在server/slave  伺服器/從站上 自動或定期地進行消息傳輸,使用者必須配置設定代表單個ASDU的CS101_ASDU對象,将資訊對象添加到ASDU,最後将ASDU放入傳輸隊列中。傳輸隊列是FIFO(先進先出)清單。如果隊列已滿,則最早的消息将被删除,并由新添加的消息代替。僅當存在活動的用戶端連接配接或有效的鍊路層連接配接時,才發送消息。否則,消息将保留在隊列中,直到激活連接配接為止。

CS 104:在CS 104從站中,隊列大小由CS104_Slave_create函數的maxLowPrioQueueSize參數确定。如果将maxLowPrioQueueSize參數設定為零,則隊列将始終具有CONFIG_SLAVE_MESSAGE_QUEUE_SIZE定義的大小。第二個參數maxHighPrioQueueSize确定高優先級資料隊列的大小。放入此隊列的消息會繞過低優先級隊列的消息。高優先級隊列用于庫回調處理程式中的請求響應。

要發送自發或定期消息,必須執行以下步驟:

  1. 建立一個新的CS101_ASDU執行個體(使用CS101_COT_PERIODIC定期資料和CS101_COT_SPONTANEOUS自發資料)
    CS101_ASDU newAsdu = CS101_ASDU_create(alParameters,false,CS101_COT_PERIODIC,0,1,false,false);
               
  2. 建立一個包含要發送資料的新資訊對象執行個體
    InformationObject io =(InformationObject)MeasuredValueScaled_create(NULL,110,scaledValue,IEC60870_QUALITY_GOOD);
               
  3. 将新的資訊對象添加到ASDU
    CS101_ASDU_addInformationObject(newAsdu,io);
               
  4. 釋放資訊對象記憶體
    InformationObject_destroy(io);
               
  5. 将ASDU放入2類資料隊列中進行傳輸
    CS101_Slave_enqueueUserDataClass2(slave,newAsdu);
               
  6. 釋放ASDU記憶體
    CS101_ASDU_destroy(newAsdu);
               

注意:對于CS 104,您必須在步驟5中使用CS104_Slave_enqueueASDU函數:

CS104_Slave_enqueueASDU(slave,newAsdu);
           

處理查詢請求

在伺服器端,您應該使用InterrogationHandler回調函數來處理Interrogation請求。根據QOI(詢問限定符)的值,您可以傳回不同的資訊對象。對于一個簡單的系統,僅處理 總查詢 請求就足夠了(QOI = 20)。QOI值21-36用于詢問組(1-16)。由從屬實施者将資訊對象配置設定給詢問組。

根據規範,伺服器必須用ACT_CON響應響應來自用戶端的ACTIVATION請求,然後是ASDU,其中ASDU包含代表站質詢或COT的資訊對象,其中CS101_COT_INTERROGATED_BY_STATION代表相應的質詢組(例如,質詢組1的CS101_COT_INTERROGATED_BY_GROUP_1)。發送完所有資訊對象後,伺服器必須發送初始查詢指令消息,其中COT = CS101_COT_ACTIVATION_TERMINATION,以訓示查詢資料的傳輸已完成。

示例如何實作詢問處理程式  

static bool
interrogationHandler(void* parameter, IMasterConnection connection, CS101_ASDU asdu, uint8_t qoi)
{
    if (qoi == 20) { /* only handle station interrogation */

        CS101_AppLayerParameters alParams = IMasterConnection_getApplicationLayerParameters(connection);

        IMasterConnection_sendACT_CON(connection, asdu, false);

        CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_INTERROGATED_BY_STATION,
                0, 1, false, false);

        InformationObject io = (InformationObject) MeasuredValueScaled_create(NULL, 100, -1, IEC60870_QUALITY_GOOD);

        CS101_ASDU_addInformationObject(newAsdu, io);

        CS101_ASDU_addInformationObject(newAsdu, (InformationObject)
            MeasuredValueScaled_create((MeasuredValueScaled) io, 101, 23, IEC60870_QUALITY_GOOD));

        CS101_ASDU_addInformationObject(newAsdu, (InformationObject)
            MeasuredValueScaled_create((MeasuredValueScaled) io, 102, 2300, IEC60870_QUALITY_GOOD));

        InformationObject_destroy(io);

        IMasterConnection_sendASDU(connection, newAsdu);

        CS101_ASDU_destroy(newAsdu);

        IMasterConnection_sendACT_TERM(connection, asdu);
    }
    else {
        IMasterConnection_sendACT_CON(connection, asdu, true);
    }

    return true;
}
           

在詢問處理程式内部,可以使用IMasterConnection接口将詢問的資料發送回用戶端/主機。在查詢處理程式内部建立的 CS101_ASDU和 InformationObject執行個體由使用者負責,并且在之前動态配置設定它們之前,必須使用适當的功能( CS101_ASDU_destroy和 InformationObject_destroy)來釋放它們。                                          

繼續閱讀