From 0af5ad4e008921e62c1c4750af4b24ceb3c22038 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sun, 10 Dec 2017 15:30:59 +0100 Subject: [PATCH] - IEC 61850/MMS: added TLS client and server examples --- examples/CMakeLists.txt | 5 + examples/tls_client_example/CMakeLists.txt | 17 + examples/tls_client_example/Makefile | 17 + examples/tls_client_example/client1-key.pem | 27 + examples/tls_client_example/client1.cer | Bin 0 -> 763 bytes examples/tls_client_example/root.cer | Bin 0 -> 785 bytes .../tls_client_example/tls_client_example.c | 151 ++ examples/tls_server_example/CMakeLists.txt | 21 + examples/tls_server_example/Makefile | 27 + examples/tls_server_example/client1.cer | Bin 0 -> 763 bytes examples/tls_server_example/client2.cer | Bin 0 -> 763 bytes examples/tls_server_example/root.cer | Bin 0 -> 785 bytes examples/tls_server_example/server-key.pem | 27 + examples/tls_server_example/server.cer | Bin 0 -> 767 bytes examples/tls_server_example/static_model.c | 2003 +++++++++++++++++ examples/tls_server_example/static_model.h | 301 +++ .../tls_server_example/tls_server_example.c | 202 ++ 17 files changed, 2798 insertions(+) create mode 100644 examples/tls_client_example/CMakeLists.txt create mode 100644 examples/tls_client_example/Makefile create mode 100644 examples/tls_client_example/client1-key.pem create mode 100644 examples/tls_client_example/client1.cer create mode 100644 examples/tls_client_example/root.cer create mode 100644 examples/tls_client_example/tls_client_example.c create mode 100644 examples/tls_server_example/CMakeLists.txt create mode 100644 examples/tls_server_example/Makefile create mode 100644 examples/tls_server_example/client1.cer create mode 100644 examples/tls_server_example/client2.cer create mode 100644 examples/tls_server_example/root.cer create mode 100644 examples/tls_server_example/server-key.pem create mode 100644 examples/tls_server_example/server.cer create mode 100644 examples/tls_server_example/static_model.c create mode 100644 examples/tls_server_example/static_model.h create mode 100644 examples/tls_server_example/tls_server_example.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 2502ff10..2d802c9b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -33,6 +33,11 @@ else() set(BUILD_SV_GOOSE_EXAMPLES ON) endif() +if(WITH_MBEDTLS) +add_subdirectory(tls_client_example) +add_subdirectory(tls_server_example) +endif(WITH_MBEDTLS) + if(${BUILD_SV_GOOSE_EXAMPLES}) add_subdirectory(server_example_goose) add_subdirectory(goose_subscriber) diff --git a/examples/tls_client_example/CMakeLists.txt b/examples/tls_client_example/CMakeLists.txt new file mode 100644 index 00000000..3a54e2d9 --- /dev/null +++ b/examples/tls_client_example/CMakeLists.txt @@ -0,0 +1,17 @@ + +set(example_SRCS + tls_client_example.c +) + +IF(WIN32) +set_source_files_properties(${example_SRCS} + PROPERTIES LANGUAGE CXX) +ENDIF(WIN32) + +add_executable(tls_client_example + ${example_SRCS} +) + +target_link_libraries(tls_client_example + iec61850 +) diff --git a/examples/tls_client_example/Makefile b/examples/tls_client_example/Makefile new file mode 100644 index 00000000..a9bce6a7 --- /dev/null +++ b/examples/tls_client_example/Makefile @@ -0,0 +1,17 @@ +LIBIEC_HOME=../.. + +PROJECT_BINARY_NAME = tls_client_example +PROJECT_SOURCES = tls_client_example.c + +include $(LIBIEC_HOME)/make/target_system.mk +include $(LIBIEC_HOME)/make/stack_includes.mk + +all: $(PROJECT_BINARY_NAME) + +include $(LIBIEC_HOME)/make/common_targets.mk + +$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME) + $(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS) + +clean: + rm -f $(PROJECT_BINARY_NAME) diff --git a/examples/tls_client_example/client1-key.pem b/examples/tls_client_example/client1-key.pem new file mode 100644 index 00000000..c39425cc --- /dev/null +++ b/examples/tls_client_example/client1-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAxAMUXdnem99n5J8Z8Wa0fdPtoMCTdkQJrOO6WJ4XePrpQgHU +HDziSmdIZDDkpJ3Ey0Byy+b+iiRDmOuIZGSCsI0ehggWaia12h2osUK0BLyThuZ/ +RQw54K0dy61eviNaYsftiBcxHYKyKmWch/wLLYxdd1qLzd0reAbSUaHDkDzrj9hO +8qr7DhKpqx7PoVh1gFhAKPKuY6b+4xqv5eZvt8QflQTWYGxaxmUIEinqCnzh1l5d +tp0rhnBsz9Y4y8dXjh0m7pbXmRNY6opMxXatqgYEqsntLy1N6x7DvWLBqtVvEmox +Tc5bbAoRW3eEToClDdFQBzLsMVcSEX8vwttk3QIDAQABAoIBABHr1ijeiqPlwTH9 ++flAUrBOeCOCd/kQL3JHP/pqOestxbXrROFwD6CN4OiIL999LUkIE3bhH9SxjByn +LElBh1FtFaVbh/EcqPPQUmQinSLxuutSl8BQZdpM+bRtnYP054awkN8of60bDf8i +WzVzrfH0K3eGJ9Iirp7CwOgFykOdpQyxsI+HG8grcwA87x1ZsAIfHhiKmQByliNl +BkbJmYBOtfVgXje5QdxTptlTNljFSbZcaCXv1P3aOqctcgJMQjg0T+E37Y8Cav80 +6SuXbpv/cdacG695MAT7Vtywue0Axh59DvxAzc+deyQT70Hzw+Mo6pgi0clFnwzU +Y5ViDWECgYEAxxhRKzpz7klnmGob5CZvrbqDfC3JUEOxKH0e342S/HmT05bTI21w +N8A0KStNjQXS1mmkAkY/OO1Zutmf6yjqsxAIEO5UMTCSEP7YLRB7qBdN7dOt3JaK +4wxErMCljdT68Vj5Qj8YzIXJkWPk871oFTvVNe2qxgrCUigE5ai2I8cCgYEA/Akv +E0L+2uXayEucEamzO3n9xVziNanjyHilnJJvduvO9gd+crBbxSKqaXSdfPnp2mSa ++e3N7elxP2b/kPrGkzZekSaMh1nPH4Upu+ISK117r1x+vmnxZHRpehrVh1QzOQ5p +Ljt+GaXa3ur3P/6uW5KMbtGGW6MEgDwLMLvpqjsCgYA5pnfyfYWOTWEbCDa1VM/n +zWc/cP6nKELHR5vF/fe+9fFxRm4zBwCElDpGZYyaNkJ75bEhG3g5Irll2phs/rcf +TJgZVvm4GKljFHhCbFByNvVQ1Ye1pT3oSugj4dDOhgp4Elxy61Rh/KeGWxez4Heg +FmhBqmVV3U2xfncUjUrYhwKBgQCKtPM3gpOIHSA/Q31tKxv9C7JiQDAuoIU/+0YJ +2X2G0VhhhtZMgErBP8bRquBRu6i8DMpN6lZ/LQ6qeiEExT8sHawF7lVA2GhpTHwf +btfZDeXYKOuIF/5F7ttt2/7QL8LRD+FLFGrd6q1+KYpRqfSDaS/ofV+YZys+98yg +0YpTqQKBgQCWJpV2ySgXcKJzAUh14VNpLTRzJOMSpsU576nwz0TLUREVjiH6rvKr +gxllDEe1bVNMEekaZ+dOqiJX+4aTnEbIrEXki5Dvz0vq8biImW9RRdPEHgYVTv/d +qBOPHiIq2JiY6abD9XNPM3VQ/z8em6/4mkC8COCJRd2mA89FOYRxOQ== +-----END RSA PRIVATE KEY----- diff --git a/examples/tls_client_example/client1.cer b/examples/tls_client_example/client1.cer new file mode 100644 index 0000000000000000000000000000000000000000..a5aa8db3e9b53f871ea99e0c9841a2d04f1ccba2 GIT binary patch literal 763 zcmXqLV)|~-#Q1mtGZP~dlfdH@FR$IGFj?*+^|Jnai5RZ|CmX9aA2X9ID}#Z!p{Ri{ z8*?ZNvoKFdYH^7|QGR}jLUN*koH(zcxq+pjfq|KUsj)$nIIpp#p^-5VnOd4!Mi~eh z3K;M~G_oh>WTxho7y_+SGT>$7)N1o+`_9YA$jHjT+{DPw02Jq9YGPz$IKnIvd-LAx z`{_^SOMXn-QhWLBf&-JwTsYS}-W4%VyyDkOC&nu>Hjlj0JyHywESY=cv_sM9XaBlX zoM*i5NJ(kh&@0!*A(o}K^_J|4jZRxw_DpVjR`1GV`CzT=>9ukDl%tZ4zwHn=lx^Ci zl{%;W54UblY|@|%-~kLdSw>pXk7Q=$JV1C#5sJ9C;nn@=a{V8>v5A z+(gv0lKXyN@I1NGT6VRM_UyU)!w>7-S9|+}iI+)YB>qPU5cKPt(zW9VQbn} hTsC#Zj>LFIwE&@-WJ%Aig!0&^YX_#hyDV(68~`yNJY@g? literal 0 HcmV?d00001 diff --git a/examples/tls_client_example/root.cer b/examples/tls_client_example/root.cer new file mode 100644 index 0000000000000000000000000000000000000000..87683444999a84b86230a7a7af3e8ae5f43de456 GIT binary patch literal 785 zcmXqLV&*kyV*I&)nTe5!Nuct==g24KTiYGuKQ`@snRCd1lZ{oIkC{o9mBB#VP}D$} zjX9KsS(v9JwYWr~C_leMAvw`NPMp`!+`!V%z`)eh!pJa6oY&aW(8w5wOf5|` z(wWYiKOLyEJDq62&(eRT@%!?cffsk(2{qzp?3i|LPg0^I z|3lW;x$){3^KEY}i!BO|$}-AMs4^C4cP!ZW=&9nDPhvj~U474^mv+d=U_zFY{BEl+ zCtTf5O|W#ZeB=Ig_opwfx_%y=H2sM%o6x!Rl+|8NL3KNVKlBQOmi@J4*c>@^bCAou zI};2iACBrQKasWOf>D}@*!o)MlEjb6PoFP&b|r4DxevR9zxKk}lIA92)4Qjqe6!Y; zcls_?@a<`Pn`P|u1?TthN?3_0?wA$wfKB2B+o7L<6$d^>%UJf;GBGnUFfNWYh&JE{ zhP$jVBjbM-Rs&`rW#9o4U}SMLux}8USd{(u$~})AH-eYjB`xX`SSX1z$eZxRFfi~L z84mxQHa%&11#VjF7vG}U-PY%L*=*YJ^S(M?MLC@M_bm_ z?CkRJ{Hieb&DO0EY#cW$EaQb*yT8AkZE?uXic68-skyfG@}|xxp~lSC#6M)USQ3{1a@a{C}tQ&+P(d!mVw;%cg~dZP1!8#g(e7899&ZS6)q4 z*UIzX+OJgGIUKt8;nQB8lWT4j40$|3PQ~ literal 0 HcmV?d00001 diff --git a/examples/tls_client_example/tls_client_example.c b/examples/tls_client_example/tls_client_example.c new file mode 100644 index 00000000..77e2b994 --- /dev/null +++ b/examples/tls_client_example/tls_client_example.c @@ -0,0 +1,151 @@ +/* + * tls_client_exmaple.c + * + * This example shows how to configure TLS + */ + +#include "iec61850_client.h" + +#include +#include + +#include "hal_thread.h" + +void +reportCallbackFunction(void* parameter, ClientReport report) +{ + MmsValue* dataSetValues = ClientReport_getDataSetValues(report); + + printf("received report for %s\n", ClientReport_getRcbReference(report)); + + int i; + for (i = 0; i < 4; i++) { + ReasonForInclusion reason = ClientReport_getReasonForInclusion(report, i); + + if (reason != IEC61850_REASON_NOT_INCLUDED) { + printf(" GGIO1.SPCSO%i.stVal: %i (included for reason %i)\n", i, + MmsValue_getBoolean(MmsValue_getElement(dataSetValues, i)), reason); + } + } +} + +int main(int argc, char** argv) { + + char* hostname; + + if (argc > 1) + hostname = argv[1]; + else + hostname = "localhost"; + + TLSConfiguration tlsConfig = TLSConfiguration_create(); + + TLSConfiguration_setChainValidation(tlsConfig, true); + TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig, false); + + if (!TLSConfiguration_setOwnKeyFromFile(tlsConfig, "client1-key.pem", NULL)) { + printf("ERROR: Failed to load private key!\n"); + return 0; + } + + if (!TLSConfiguration_setOwnCertificateFromFile(tlsConfig, "client1.cer")) { + printf("ERROR: Failed to load own certificate!\n"); + return 0; + } + + if (!TLSConfiguration_addCACertificateFromFile(tlsConfig, "root.cer")) { + printf("ERROR: Failed to load root certificate\n"); + return 0; + } + + IedClientError error; + + IedConnection con = IedConnection_createWithTlsSupport(tlsConfig); + + IedConnection_connect(con, &error, hostname, -1); + + if (error == IED_ERROR_OK) { + + IedConnection_getServerDirectory(con, &error, false); + + /* read an analog measurement value from server */ + MmsValue* value = IedConnection_readObject(con, &error, "simpleIOGenericIO/GGIO1.AnIn1.mag.f", IEC61850_FC_MX); + + if (value != NULL) { + float fval = MmsValue_toFloat(value); + printf("read float value: %f\n", fval); + MmsValue_delete(value); + } + + /* write a variable to the server */ + value = MmsValue_newVisibleString("libiec61850.com"); + IedConnection_writeObject(con, &error, "simpleIOGenericIO/GGIO1.NamPlt.vendor", IEC61850_FC_DC, value); + + if (error != IED_ERROR_OK) + printf("failed to write simpleIOGenericIO/GGIO1.NamPlt.vendor!\n"); + + MmsValue_delete(value); + + + /* read data set */ + ClientDataSet clientDataSet = IedConnection_readDataSetValues(con, &error, "simpleIOGenericIO/LLN0.Events", NULL); + + if (clientDataSet == NULL) + printf("failed to read dataset\n"); + + /* Read RCB values */ + ClientReportControlBlock rcb = + IedConnection_getRCBValues(con, &error, "simpleIOGenericIO/LLN0.RP.EventsRCB01", NULL); + + + bool rptEna = ClientReportControlBlock_getRptEna(rcb); + + printf("RptEna = %i\n", rptEna); + + /* Install handler for reports */ + IedConnection_installReportHandler(con, "simpleIOGenericIO/LLN0.RP.EventsRCB01", + ClientReportControlBlock_getRptId(rcb), reportCallbackFunction, NULL); + + /* Set trigger options and enable report */ + ClientReportControlBlock_setTrgOps(rcb, TRG_OPT_DATA_UPDATE | TRG_OPT_INTEGRITY | TRG_OPT_GI); + ClientReportControlBlock_setRptEna(rcb, true); + ClientReportControlBlock_setIntgPd(rcb, 5000); + IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_RPT_ENA | RCB_ELEMENT_TRG_OPS | RCB_ELEMENT_INTG_PD, true); + + if (error != IED_ERROR_OK) + printf("report activation failed (code: %i)\n", error); + + Thread_sleep(1000); + + /* trigger GI report */ + ClientReportControlBlock_setGI(rcb, true); + IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_GI, true); + + if (error != IED_ERROR_OK) + printf("Error triggering a GI report (code: %i)\n", error); + + Thread_sleep(60000); + + /* disable reporting */ + ClientReportControlBlock_setRptEna(rcb, false); + IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_RPT_ENA, true); + + if (error != IED_ERROR_OK) + printf("disable reporting failed (code: %i)\n", error); + + ClientDataSet_destroy(clientDataSet); + + ClientReportControlBlock_destroy(rcb); + + close_connection: + + IedConnection_close(con); + } + else { + printf("Failed to connect to %s\n", hostname); + } + + IedConnection_destroy(con); +} + + diff --git a/examples/tls_server_example/CMakeLists.txt b/examples/tls_server_example/CMakeLists.txt new file mode 100644 index 00000000..4299b8b0 --- /dev/null +++ b/examples/tls_server_example/CMakeLists.txt @@ -0,0 +1,21 @@ +include_directories( + . +) + +set(example_SRCS + tls_server_example.c + static_model.c +) + +IF(WIN32) +set_source_files_properties(${example_SRCS} + PROPERTIES LANGUAGE CXX) +ENDIF(WIN32) + +add_executable(tls_server_example + ${example_SRCS} +) + +target_link_libraries(tls_server_example + iec61850 +) diff --git a/examples/tls_server_example/Makefile b/examples/tls_server_example/Makefile new file mode 100644 index 00000000..2ddb3e43 --- /dev/null +++ b/examples/tls_server_example/Makefile @@ -0,0 +1,27 @@ +LIBIEC_HOME=../.. + +PROJECT_BINARY_NAME = tls_server_example +PROJECT_SOURCES = tls_server_example.c +PROJECT_SOURCES += static_model.c + +PROJECT_ICD_FILE = simpleIO_direct_control.icd + +include $(LIBIEC_HOME)/make/target_system.mk +include $(LIBIEC_HOME)/make/stack_includes.mk + +all: $(PROJECT_BINARY_NAME) + +include $(LIBIEC_HOME)/make/common_targets.mk + +LDLIBS += -lm + +model: $(PROJECT_ICD_FILE) + java -jar $(LIBIEC_HOME)/tools/model_generator/genmodel.jar $(PROJECT_ICD_FILE) + +$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME) + $(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS) + +clean: + rm -f $(PROJECT_BINARY_NAME) + + diff --git a/examples/tls_server_example/client1.cer b/examples/tls_server_example/client1.cer new file mode 100644 index 0000000000000000000000000000000000000000..a5aa8db3e9b53f871ea99e0c9841a2d04f1ccba2 GIT binary patch literal 763 zcmXqLV)|~-#Q1mtGZP~dlfdH@FR$IGFj?*+^|Jnai5RZ|CmX9aA2X9ID}#Z!p{Ri{ z8*?ZNvoKFdYH^7|QGR}jLUN*koH(zcxq+pjfq|KUsj)$nIIpp#p^-5VnOd4!Mi~eh z3K;M~G_oh>WTxho7y_+SGT>$7)N1o+`_9YA$jHjT+{DPw02Jq9YGPz$IKnIvd-LAx z`{_^SOMXn-QhWLBf&-JwTsYS}-W4%VyyDkOC&nu>Hjlj0JyHywESY=cv_sM9XaBlX zoM*i5NJ(kh&@0!*A(o}K^_J|4jZRxw_DpVjR`1GV`CzT=>9ukDl%tZ4zwHn=lx^Ci zl{%;W54UblY|@|%-~kLdSw>pXk7Q=$JV1C#5sJ9C;nn@=a{V8>v5A z+(gv0lKXyN@I1NGT6VRM_UyU)!w>7-S9|+}iI+)YB>qPU5cKPt(zW9VQbn} hTsC#Zj>LFIwE&@-WJ%Aig!0&^YX_#hyDV(68~`yNJY@g? literal 0 HcmV?d00001 diff --git a/examples/tls_server_example/client2.cer b/examples/tls_server_example/client2.cer new file mode 100644 index 0000000000000000000000000000000000000000..f482289bdb08962c2ba834ae910ccc35928edf62 GIT binary patch literal 763 zcmXqLV)|~-#Q1mtGZP~dlfe4(nX<}q-fe!znm!)zP>(U-WMkFlV`h?NWiSvo6g3cL zV-96u7Un5QEiO?g%Fi!RNKQ166X!KFH?TA`Ffao`gD7!cV@pFLV<0lMG_{N}5Hb`n z;DcynPtM6q%_}hiTB&5f%f_kI=F#?@mywZ?m4Ug5k)Hu5&c)Qk$jERapmE>P&9nWJ zqPAQ=!?>)%ki&knbH?f2W#t)p31u19=l2@f2#WOVHQT%V*LI2WIzKnXrMeCOvU(12 z3x(}AjdtMuR=2aH;>qhJ@8l;O_|U!fe27W$l3PFQ_g>g>z;g8^SLwj>>rW(yB&MWY z_4DN0VdE&)b?9nLUzyv-8`F7Kf2%23sc2l{b=H?hHf2VUZpZ6+lNT=Cu7N5we`?z8x7uMMnm*Sa*j{oqXX zT_S)-L4sai{@>s z%(u2X#(!+u`!eScQd|PVnvr4Qm!xe?i3`32gh(X$U;a9|XV-iG-7H>Cuew6!zI}Pg zFU>AZb>XI^@?U+oRqyI{+bk>n?pl53v_}887E3?6UY>X1%{xn$DTlVr+MvfL5aRIB z{^5~N6W(87pZua@S87n#{j!B|TNr*`V5x|IwnNgzD0%~<4R@^0?0Z@ElTPS9*IPZ8 zYw@iMt1g?*?iD)yd_lyO+~7s7e{Rn9{bRKB)Z%ORbc5|Om&?C?_lW!5b%3I*vBW-C=dQx;DWo$n5^FOZs=@oU?rDpBv2$?|d)IzFxOid3RB( j-p)A|CC9(M@0^>JZ@#JR{2s2{|` z(wWYiKOLyEJDq62&(eRT@%!?cffsk(2{qzp?3i|LPg0^I z|3lW;x$){3^KEY}i!BO|$}-AMs4^C4cP!ZW=&9nDPhvj~U474^mv+d=U_zFY{BEl+ zCtTf5O|W#ZeB=Ig_opwfx_%y=H2sM%o6x!Rl+|8NL3KNVKlBQOmi@J4*c>@^bCAou zI};2iACBrQKasWOf>D}@*!o)MlEjb6PoFP&b|r4DxevR9zxKk}lIA92)4Qjqe6!Y; zcls_?@a<`Pn`P|u1?TthN?3_0?wA$wfKB2B+o7L<6$d^>%UJf;GBGnUFfNWYh&JE{ zhP$jVBjbM-Rs&`rW#9o4U}SMLux}8USd{(u$~})AH-eYjB`xX`SSX1z$eZxRFfi~L z84mxQHa%&11#VjF7vG}U-PY%L*=*YJ^S(M?MLC@M_bm_ z?CkRJ{Hieb&DO0EY#cW$EaQb*yT8AkZE?uXic68-skyfG@}|xxp~lSC#6M)USQ3{1a@a{C}tQ&+P(d!mVw;%cg~dZP1!8#g(e7899&ZS6)q4 z*UIzX+OJgGIUKt8;nQB8lWT4j40$|3PQ~ literal 0 HcmV?d00001 diff --git a/examples/tls_server_example/server-key.pem b/examples/tls_server_example/server-key.pem new file mode 100644 index 00000000..6fe35295 --- /dev/null +++ b/examples/tls_server_example/server-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAu3Fjxb904UdyV/dDfvs8SFi6zJeNoMYjmpXm/LBcFSH3zGoK +wdcMovrUTED3Cc6Ww84AYpJ5MRMPTct7DfKJkWfSnkzOPmLldTSTv3RvzGVb4NzK +QqA5aSVDqAzPiP5RnFT6Q4KWRe69TMFxpw7zMXCJx9jDggqN1oojGGkmSgYGXnFd +Nc20Mujejh5pihgwnN4Y/bPFyxJwvIMj+D8qr9klhEmXKPTiX9UFd8oLkn9JCB6+ +SiHhNyFIo+Llossn1Q2hxCGty36fAhEWzpfBTaY510VLjie9y4q9GPTwxITDqSQd +xcX8IuvrbxX0DyEK507SMmTJmB9448eF9ZCWFQIDAQABAoIBAC80BuQtqslwrKLq +adz4d93gOmp7X/c07pJnXZwU7ZuEylp3+e2Gsm/4qq3pTkzx8ZWtsvsf19U774av +z3VbtrkfZDLpNKcRUKeLbgmw0NawT8r4zxaoMsz/zWHsl/bv1K2B2ORXZnCGBrXl +oTFo2mWA6bGiLNn6vm1grCXhlPreywyG/kFK3pi2VvkpvG3XZSI7mmZ0Dq/MD3nO +03oOZBqwwnMObfQQdhKE7646/+KgeuF/JsXaUH4bkHmtzYWyocWYMqpC0hjpNWlQ +cKuQ7t1kfmpsGD9aNW4+ND2ok9BdxIiC+rPXS9NDqZxoWLp+a8seU++uqk1l8RPq +tPE3LqECgYEAz1NmemNLiUsKvyemUvjp8+dJupzWtdV7fsnCbYhj/5gDA2UhFKCf +dP9xiHCdNe0797oAqHY7c3JhS4ug8haDy9aDIu5GG2DNYzjX/oYm4ywbCdRx+uEN +RcTw69FjSYVGkObmxWYszwsFybRasV6PYamg65qYR3FlvW2Td4Fndy8CgYEA53L/ +zHtBRQiNGJU9jfMHeX0bTtXIAt622Qn78jw0it/rhXWi2RwG2Cw5Q2aPRJ6uMt9F +yk1+GAPZcwYqwjq/nKRrl71Tn+KDWIk5rz1fNYRkaXtnMLs2MOogqoDTBshW0QBq +tnPrFNsaLKX6V92Az69wHjd2uwvLQLTvS/EuNfsCgYEAr3to/uhytAd3VirKRep3 +o0E+D5zWw1upxrwhPDK4aUuSKVp8sIfvz8iyoQiomE9vdZPTIMPKOEI1BgtuM9pI +vcyYfIVvg5bg4T3o3H9SBPB9BknyG6ZHZKl4PjGht0X+X4GBDM4Z2Tj8Mijcpsph +1AkOsrzMbZQWyEoqCnnWSHMCgYAFEHUcak4BTrCXqxxPsNOnCt/AF9lqhqkFkrxa +joqvxzqGDw7jJUPZEw6ltObJn5c8Mbp7NLrfl6X4aFgjK9npeYeJKHFd/DzXgRks +BnHA4Aa6cCLP5CjJZTYVxP/ZFCUiKZosJ9kq+ahW9cLGjWg2IyaW4qvMZ/OolMzv +onVaZQKBgQCir8u1vDsyA4JQXMytPHBJe27XaLRGULvteNydVB59Vt21a99o5gt1 +5B9gwWArZdZby3/KZiliNmzp8lMCrLJYjTL5WK6dbWdq92X5hCOofKPIjEcgHjhk +mvnAos3HeC83bJQtADXhw9jR7Vr6GJLM9HDcIgeIMzX7+BuqlMgaHA== +-----END RSA PRIVATE KEY----- diff --git a/examples/tls_server_example/server.cer b/examples/tls_server_example/server.cer new file mode 100644 index 0000000000000000000000000000000000000000..957bdc30f978d52f7ef9b5aa73375a9a21b7d6de GIT binary patch literal 767 zcmXqLV)|{+#Q1yxGZP~dlfcF$T&n{mk2X1Hu@+U&Yh7l*$;PV9$IK+l%3vUFC~6?g z#vIDREX-4qT3n(~l%HRskep~BC(dhVZeVF>U|?ooY-AoK&TDLGXk-jTrk19bQ3hg$ zA_hVbjocuOy2YtQWvN9#Yn2Rm**LY@JlekVGBPr1y6jofFe9&GR{Dm-MvMWb*!!{4=T15AK|DT40%}>b!#Ie8<1QIU&ECo2I$G z+v{_%a5>*+!-CG^Hx4&(^;34=NJB>rwbdRnMp zPqXq5d#&|1Ra-o#YkYYWf0ecT6!)ZhPY$_#UWyOR6+IR|db;Se`c>YAM-A`gOkO7k)*q=YE%rQclj0uXudC z_3MObqD;(;42+9?47?0HfT1VL$l_>V-ykrtDEse~dmcM(1TVKsTGS`7P!ea%GznB* z_#FAfd~3U7{KuxfFLMqd#V0VV85z_X5Aq+fxo*FBLA!nRf40v@?yqIdGWfc4*JM!> zt$wo&YR2=0t!-!RILa5m?eeIE+kc)37srHKV!8XST{P|D&E3atlJWDngFNGwPYwk} zae8^{g~9@oBAN~v)mHHzf7_V)qQAQ)l}FApI%hS@ysH`>QnME=GoABm@;9OB@xsUd zY|B@igY~1rOhO&iJ=7*nRRg`ByzZ^d_=> zIr44Av<_+G164WU*JW?^@5ts${Al;^-O(+cW-`V*rf3@ +#include "iec61850_model.h" + +extern IedModel iedModel; +extern LogicalDevice iedModel_GenericIO; +extern LogicalNode iedModel_GenericIO_LLN0; +extern DataObject iedModel_GenericIO_LLN0_Mod; +extern DataAttribute iedModel_GenericIO_LLN0_Mod_stVal; +extern DataAttribute iedModel_GenericIO_LLN0_Mod_q; +extern DataAttribute iedModel_GenericIO_LLN0_Mod_t; +extern DataAttribute iedModel_GenericIO_LLN0_Mod_ctlModel; +extern DataObject iedModel_GenericIO_LLN0_Beh; +extern DataAttribute iedModel_GenericIO_LLN0_Beh_stVal; +extern DataAttribute iedModel_GenericIO_LLN0_Beh_q; +extern DataAttribute iedModel_GenericIO_LLN0_Beh_t; +extern DataObject iedModel_GenericIO_LLN0_Health; +extern DataAttribute iedModel_GenericIO_LLN0_Health_stVal; +extern DataAttribute iedModel_GenericIO_LLN0_Health_q; +extern DataAttribute iedModel_GenericIO_LLN0_Health_t; +extern DataObject iedModel_GenericIO_LLN0_NamPlt; +extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_vendor; +extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_swRev; +extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_d; +extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_configRev; +extern DataAttribute iedModel_GenericIO_LLN0_NamPlt_ldNs; +extern LogicalNode iedModel_GenericIO_LPHD1; +extern DataObject iedModel_GenericIO_LPHD1_PhyNam; +extern DataAttribute iedModel_GenericIO_LPHD1_PhyNam_vendor; +extern DataObject iedModel_GenericIO_LPHD1_PhyHealth; +extern DataAttribute iedModel_GenericIO_LPHD1_PhyHealth_stVal; +extern DataAttribute iedModel_GenericIO_LPHD1_PhyHealth_q; +extern DataAttribute iedModel_GenericIO_LPHD1_PhyHealth_t; +extern DataObject iedModel_GenericIO_LPHD1_Proxy; +extern DataAttribute iedModel_GenericIO_LPHD1_Proxy_stVal; +extern DataAttribute iedModel_GenericIO_LPHD1_Proxy_q; +extern DataAttribute iedModel_GenericIO_LPHD1_Proxy_t; +extern LogicalNode iedModel_GenericIO_GGIO1; +extern DataObject iedModel_GenericIO_GGIO1_Mod; +extern DataAttribute iedModel_GenericIO_GGIO1_Mod_q; +extern DataAttribute iedModel_GenericIO_GGIO1_Mod_t; +extern DataAttribute iedModel_GenericIO_GGIO1_Mod_ctlModel; +extern DataObject iedModel_GenericIO_GGIO1_Beh; +extern DataAttribute iedModel_GenericIO_GGIO1_Beh_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_Beh_q; +extern DataAttribute iedModel_GenericIO_GGIO1_Beh_t; +extern DataObject iedModel_GenericIO_GGIO1_Health; +extern DataAttribute iedModel_GenericIO_GGIO1_Health_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_Health_q; +extern DataAttribute iedModel_GenericIO_GGIO1_Health_t; +extern DataObject iedModel_GenericIO_GGIO1_NamPlt; +extern DataAttribute iedModel_GenericIO_GGIO1_NamPlt_vendor; +extern DataAttribute iedModel_GenericIO_GGIO1_NamPlt_swRev; +extern DataAttribute iedModel_GenericIO_GGIO1_NamPlt_d; +extern DataObject iedModel_GenericIO_GGIO1_AnIn1; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn1_mag; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn1_mag_f; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn1_q; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn1_t; +extern DataObject iedModel_GenericIO_GGIO1_AnIn2; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn2_mag; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn2_mag_f; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn2_q; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn2_t; +extern DataObject iedModel_GenericIO_GGIO1_AnIn3; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn3_mag; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn3_mag_f; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn3_q; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn3_t; +extern DataObject iedModel_GenericIO_GGIO1_AnIn4; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn4_mag; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn4_mag_f; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn4_q; +extern DataAttribute iedModel_GenericIO_GGIO1_AnIn4_t; +extern DataObject iedModel_GenericIO_GGIO1_SPCSO1; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_q; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_ctlVal; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin_orCat; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin_orIdent; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_ctlNum; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_T; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_Test; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_Oper_Check; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_ctlModel; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO1_t; +extern DataObject iedModel_GenericIO_GGIO1_SPCSO2; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_q; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_ctlVal; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin_orCat; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin_orIdent; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_ctlNum; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_T; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_Test; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_Oper_Check; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_ctlModel; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO2_t; +extern DataObject iedModel_GenericIO_GGIO1_SPCSO3; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_q; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_ctlVal; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin_orCat; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin_orIdent; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_ctlNum; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_T; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_Test; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_Check; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_ctlModel; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_t; +extern DataObject iedModel_GenericIO_GGIO1_SPCSO4; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_q; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_ctlVal; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_origin; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_origin_orCat; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_origin_orIdent; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_ctlNum; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_T; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_Test; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_Check; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_ctlModel; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_t; +extern DataObject iedModel_GenericIO_GGIO1_Ind1; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind1_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind1_q; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind1_t; +extern DataObject iedModel_GenericIO_GGIO1_Ind2; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind2_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind2_q; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind2_t; +extern DataObject iedModel_GenericIO_GGIO1_Ind3; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind3_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind3_q; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind3_t; +extern DataObject iedModel_GenericIO_GGIO1_Ind4; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_stVal; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_q; +extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_t; + + + +#define IEDMODEL_GenericIO (&iedModel_GenericIO) +#define IEDMODEL_GenericIO_LLN0 (&iedModel_GenericIO_LLN0) +#define IEDMODEL_GenericIO_LLN0_Mod (&iedModel_GenericIO_LLN0_Mod) +#define IEDMODEL_GenericIO_LLN0_Mod_stVal (&iedModel_GenericIO_LLN0_Mod_stVal) +#define IEDMODEL_GenericIO_LLN0_Mod_q (&iedModel_GenericIO_LLN0_Mod_q) +#define IEDMODEL_GenericIO_LLN0_Mod_t (&iedModel_GenericIO_LLN0_Mod_t) +#define IEDMODEL_GenericIO_LLN0_Mod_ctlModel (&iedModel_GenericIO_LLN0_Mod_ctlModel) +#define IEDMODEL_GenericIO_LLN0_Beh (&iedModel_GenericIO_LLN0_Beh) +#define IEDMODEL_GenericIO_LLN0_Beh_stVal (&iedModel_GenericIO_LLN0_Beh_stVal) +#define IEDMODEL_GenericIO_LLN0_Beh_q (&iedModel_GenericIO_LLN0_Beh_q) +#define IEDMODEL_GenericIO_LLN0_Beh_t (&iedModel_GenericIO_LLN0_Beh_t) +#define IEDMODEL_GenericIO_LLN0_Health (&iedModel_GenericIO_LLN0_Health) +#define IEDMODEL_GenericIO_LLN0_Health_stVal (&iedModel_GenericIO_LLN0_Health_stVal) +#define IEDMODEL_GenericIO_LLN0_Health_q (&iedModel_GenericIO_LLN0_Health_q) +#define IEDMODEL_GenericIO_LLN0_Health_t (&iedModel_GenericIO_LLN0_Health_t) +#define IEDMODEL_GenericIO_LLN0_NamPlt (&iedModel_GenericIO_LLN0_NamPlt) +#define IEDMODEL_GenericIO_LLN0_NamPlt_vendor (&iedModel_GenericIO_LLN0_NamPlt_vendor) +#define IEDMODEL_GenericIO_LLN0_NamPlt_swRev (&iedModel_GenericIO_LLN0_NamPlt_swRev) +#define IEDMODEL_GenericIO_LLN0_NamPlt_d (&iedModel_GenericIO_LLN0_NamPlt_d) +#define IEDMODEL_GenericIO_LLN0_NamPlt_configRev (&iedModel_GenericIO_LLN0_NamPlt_configRev) +#define IEDMODEL_GenericIO_LLN0_NamPlt_ldNs (&iedModel_GenericIO_LLN0_NamPlt_ldNs) +#define IEDMODEL_GenericIO_LPHD1 (&iedModel_GenericIO_LPHD1) +#define IEDMODEL_GenericIO_LPHD1_PhyNam (&iedModel_GenericIO_LPHD1_PhyNam) +#define IEDMODEL_GenericIO_LPHD1_PhyNam_vendor (&iedModel_GenericIO_LPHD1_PhyNam_vendor) +#define IEDMODEL_GenericIO_LPHD1_PhyHealth (&iedModel_GenericIO_LPHD1_PhyHealth) +#define IEDMODEL_GenericIO_LPHD1_PhyHealth_stVal (&iedModel_GenericIO_LPHD1_PhyHealth_stVal) +#define IEDMODEL_GenericIO_LPHD1_PhyHealth_q (&iedModel_GenericIO_LPHD1_PhyHealth_q) +#define IEDMODEL_GenericIO_LPHD1_PhyHealth_t (&iedModel_GenericIO_LPHD1_PhyHealth_t) +#define IEDMODEL_GenericIO_LPHD1_Proxy (&iedModel_GenericIO_LPHD1_Proxy) +#define IEDMODEL_GenericIO_LPHD1_Proxy_stVal (&iedModel_GenericIO_LPHD1_Proxy_stVal) +#define IEDMODEL_GenericIO_LPHD1_Proxy_q (&iedModel_GenericIO_LPHD1_Proxy_q) +#define IEDMODEL_GenericIO_LPHD1_Proxy_t (&iedModel_GenericIO_LPHD1_Proxy_t) +#define IEDMODEL_GenericIO_GGIO1 (&iedModel_GenericIO_GGIO1) +#define IEDMODEL_GenericIO_GGIO1_Mod (&iedModel_GenericIO_GGIO1_Mod) +#define IEDMODEL_GenericIO_GGIO1_Mod_q (&iedModel_GenericIO_GGIO1_Mod_q) +#define IEDMODEL_GenericIO_GGIO1_Mod_t (&iedModel_GenericIO_GGIO1_Mod_t) +#define IEDMODEL_GenericIO_GGIO1_Mod_ctlModel (&iedModel_GenericIO_GGIO1_Mod_ctlModel) +#define IEDMODEL_GenericIO_GGIO1_Beh (&iedModel_GenericIO_GGIO1_Beh) +#define IEDMODEL_GenericIO_GGIO1_Beh_stVal (&iedModel_GenericIO_GGIO1_Beh_stVal) +#define IEDMODEL_GenericIO_GGIO1_Beh_q (&iedModel_GenericIO_GGIO1_Beh_q) +#define IEDMODEL_GenericIO_GGIO1_Beh_t (&iedModel_GenericIO_GGIO1_Beh_t) +#define IEDMODEL_GenericIO_GGIO1_Health (&iedModel_GenericIO_GGIO1_Health) +#define IEDMODEL_GenericIO_GGIO1_Health_stVal (&iedModel_GenericIO_GGIO1_Health_stVal) +#define IEDMODEL_GenericIO_GGIO1_Health_q (&iedModel_GenericIO_GGIO1_Health_q) +#define IEDMODEL_GenericIO_GGIO1_Health_t (&iedModel_GenericIO_GGIO1_Health_t) +#define IEDMODEL_GenericIO_GGIO1_NamPlt (&iedModel_GenericIO_GGIO1_NamPlt) +#define IEDMODEL_GenericIO_GGIO1_NamPlt_vendor (&iedModel_GenericIO_GGIO1_NamPlt_vendor) +#define IEDMODEL_GenericIO_GGIO1_NamPlt_swRev (&iedModel_GenericIO_GGIO1_NamPlt_swRev) +#define IEDMODEL_GenericIO_GGIO1_NamPlt_d (&iedModel_GenericIO_GGIO1_NamPlt_d) +#define IEDMODEL_GenericIO_GGIO1_AnIn1 (&iedModel_GenericIO_GGIO1_AnIn1) +#define IEDMODEL_GenericIO_GGIO1_AnIn1_mag (&iedModel_GenericIO_GGIO1_AnIn1_mag) +#define IEDMODEL_GenericIO_GGIO1_AnIn1_mag_f (&iedModel_GenericIO_GGIO1_AnIn1_mag_f) +#define IEDMODEL_GenericIO_GGIO1_AnIn1_q (&iedModel_GenericIO_GGIO1_AnIn1_q) +#define IEDMODEL_GenericIO_GGIO1_AnIn1_t (&iedModel_GenericIO_GGIO1_AnIn1_t) +#define IEDMODEL_GenericIO_GGIO1_AnIn2 (&iedModel_GenericIO_GGIO1_AnIn2) +#define IEDMODEL_GenericIO_GGIO1_AnIn2_mag (&iedModel_GenericIO_GGIO1_AnIn2_mag) +#define IEDMODEL_GenericIO_GGIO1_AnIn2_mag_f (&iedModel_GenericIO_GGIO1_AnIn2_mag_f) +#define IEDMODEL_GenericIO_GGIO1_AnIn2_q (&iedModel_GenericIO_GGIO1_AnIn2_q) +#define IEDMODEL_GenericIO_GGIO1_AnIn2_t (&iedModel_GenericIO_GGIO1_AnIn2_t) +#define IEDMODEL_GenericIO_GGIO1_AnIn3 (&iedModel_GenericIO_GGIO1_AnIn3) +#define IEDMODEL_GenericIO_GGIO1_AnIn3_mag (&iedModel_GenericIO_GGIO1_AnIn3_mag) +#define IEDMODEL_GenericIO_GGIO1_AnIn3_mag_f (&iedModel_GenericIO_GGIO1_AnIn3_mag_f) +#define IEDMODEL_GenericIO_GGIO1_AnIn3_q (&iedModel_GenericIO_GGIO1_AnIn3_q) +#define IEDMODEL_GenericIO_GGIO1_AnIn3_t (&iedModel_GenericIO_GGIO1_AnIn3_t) +#define IEDMODEL_GenericIO_GGIO1_AnIn4 (&iedModel_GenericIO_GGIO1_AnIn4) +#define IEDMODEL_GenericIO_GGIO1_AnIn4_mag (&iedModel_GenericIO_GGIO1_AnIn4_mag) +#define IEDMODEL_GenericIO_GGIO1_AnIn4_mag_f (&iedModel_GenericIO_GGIO1_AnIn4_mag_f) +#define IEDMODEL_GenericIO_GGIO1_AnIn4_q (&iedModel_GenericIO_GGIO1_AnIn4_q) +#define IEDMODEL_GenericIO_GGIO1_AnIn4_t (&iedModel_GenericIO_GGIO1_AnIn4_t) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1 (&iedModel_GenericIO_GGIO1_SPCSO1) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_stVal (&iedModel_GenericIO_GGIO1_SPCSO1_stVal) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_q (&iedModel_GenericIO_GGIO1_SPCSO1_q) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper (&iedModel_GenericIO_GGIO1_SPCSO1_Oper) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_ctlVal (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_ctlVal) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_origin (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_origin_orCat (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin_orCat) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_origin_orIdent (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_origin_orIdent) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_ctlNum (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_ctlNum) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_T (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_T) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_Test (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_Test) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_Oper_Check (&iedModel_GenericIO_GGIO1_SPCSO1_Oper_Check) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO1_ctlModel) +#define IEDMODEL_GenericIO_GGIO1_SPCSO1_t (&iedModel_GenericIO_GGIO1_SPCSO1_t) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2 (&iedModel_GenericIO_GGIO1_SPCSO2) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_stVal (&iedModel_GenericIO_GGIO1_SPCSO2_stVal) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_q (&iedModel_GenericIO_GGIO1_SPCSO2_q) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper (&iedModel_GenericIO_GGIO1_SPCSO2_Oper) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_ctlVal (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_ctlVal) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_origin (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_origin_orCat (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin_orCat) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_origin_orIdent (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_origin_orIdent) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_ctlNum (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_ctlNum) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_T (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_T) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_Test (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_Test) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_Oper_Check (&iedModel_GenericIO_GGIO1_SPCSO2_Oper_Check) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO2_ctlModel) +#define IEDMODEL_GenericIO_GGIO1_SPCSO2_t (&iedModel_GenericIO_GGIO1_SPCSO2_t) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3 (&iedModel_GenericIO_GGIO1_SPCSO3) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_stVal (&iedModel_GenericIO_GGIO1_SPCSO3_stVal) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_q (&iedModel_GenericIO_GGIO1_SPCSO3_q) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper (&iedModel_GenericIO_GGIO1_SPCSO3_Oper) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_ctlVal (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_ctlVal) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_origin (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_origin_orCat (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin_orCat) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_origin_orIdent (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_origin_orIdent) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_ctlNum (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_ctlNum) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_T (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_T) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_Test (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_Test) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_Oper_Check (&iedModel_GenericIO_GGIO1_SPCSO3_Oper_Check) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO3_ctlModel) +#define IEDMODEL_GenericIO_GGIO1_SPCSO3_t (&iedModel_GenericIO_GGIO1_SPCSO3_t) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4 (&iedModel_GenericIO_GGIO1_SPCSO4) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_stVal (&iedModel_GenericIO_GGIO1_SPCSO4_stVal) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_q (&iedModel_GenericIO_GGIO1_SPCSO4_q) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper (&iedModel_GenericIO_GGIO1_SPCSO4_Oper) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_ctlVal (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_ctlVal) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_origin (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_origin) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_origin_orCat (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_origin_orCat) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_origin_orIdent (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_origin_orIdent) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_ctlNum (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_ctlNum) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_T (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_T) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_Test (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_Test) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_Check (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_Check) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO4_ctlModel) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_t (&iedModel_GenericIO_GGIO1_SPCSO4_t) +#define IEDMODEL_GenericIO_GGIO1_Ind1 (&iedModel_GenericIO_GGIO1_Ind1) +#define IEDMODEL_GenericIO_GGIO1_Ind1_stVal (&iedModel_GenericIO_GGIO1_Ind1_stVal) +#define IEDMODEL_GenericIO_GGIO1_Ind1_q (&iedModel_GenericIO_GGIO1_Ind1_q) +#define IEDMODEL_GenericIO_GGIO1_Ind1_t (&iedModel_GenericIO_GGIO1_Ind1_t) +#define IEDMODEL_GenericIO_GGIO1_Ind2 (&iedModel_GenericIO_GGIO1_Ind2) +#define IEDMODEL_GenericIO_GGIO1_Ind2_stVal (&iedModel_GenericIO_GGIO1_Ind2_stVal) +#define IEDMODEL_GenericIO_GGIO1_Ind2_q (&iedModel_GenericIO_GGIO1_Ind2_q) +#define IEDMODEL_GenericIO_GGIO1_Ind2_t (&iedModel_GenericIO_GGIO1_Ind2_t) +#define IEDMODEL_GenericIO_GGIO1_Ind3 (&iedModel_GenericIO_GGIO1_Ind3) +#define IEDMODEL_GenericIO_GGIO1_Ind3_stVal (&iedModel_GenericIO_GGIO1_Ind3_stVal) +#define IEDMODEL_GenericIO_GGIO1_Ind3_q (&iedModel_GenericIO_GGIO1_Ind3_q) +#define IEDMODEL_GenericIO_GGIO1_Ind3_t (&iedModel_GenericIO_GGIO1_Ind3_t) +#define IEDMODEL_GenericIO_GGIO1_Ind4 (&iedModel_GenericIO_GGIO1_Ind4) +#define IEDMODEL_GenericIO_GGIO1_Ind4_stVal (&iedModel_GenericIO_GGIO1_Ind4_stVal) +#define IEDMODEL_GenericIO_GGIO1_Ind4_q (&iedModel_GenericIO_GGIO1_Ind4_q) +#define IEDMODEL_GenericIO_GGIO1_Ind4_t (&iedModel_GenericIO_GGIO1_Ind4_t) + +#endif /* STATIC_MODEL_H_ */ + diff --git a/examples/tls_server_example/tls_server_example.c b/examples/tls_server_example/tls_server_example.c new file mode 100644 index 00000000..5708b16a --- /dev/null +++ b/examples/tls_server_example/tls_server_example.c @@ -0,0 +1,202 @@ +/* + * tls_server_example.c + * + * How to configure a TLS server + */ + +#include "iec61850_server.h" +#include "hal_thread.h" +#include +#include +#include +#include + +#include "static_model.h" + +/* import IEC 61850 device model created from SCL-File */ +extern IedModel iedModel; + +static int running = 0; +static IedServer iedServer = NULL; + +void +sigint_handler(int signalId) +{ + running = 0; +} + +static ControlHandlerResult +controlHandlerForBinaryOutput(void* parameter, MmsValue* value, bool test) +{ + if (test) + return CONTROL_RESULT_FAILED; + + if (MmsValue_getType(value) == MMS_BOOLEAN) { + printf("received binary control command: "); + + if (MmsValue_getBoolean(value)) + printf("on\n"); + else + printf("off\n"); + } + else + return CONTROL_RESULT_FAILED; + + uint64_t timeStamp = Hal_getTimeInMs(); + + if (parameter == IEDMODEL_GenericIO_GGIO1_SPCSO1) { + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1_t, timeStamp); + IedServer_updateAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1_stVal, value); + } + + if (parameter == IEDMODEL_GenericIO_GGIO1_SPCSO2) { + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2_t, timeStamp); + IedServer_updateAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2_stVal, value); + } + + if (parameter == IEDMODEL_GenericIO_GGIO1_SPCSO3) { + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3_t, timeStamp); + IedServer_updateAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3_stVal, value); + } + + if (parameter == IEDMODEL_GenericIO_GGIO1_SPCSO4) { + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_t, timeStamp); + IedServer_updateAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_stVal, value); + } + + return CONTROL_RESULT_OK; +} + + +static void +connectionHandler (IedServer self, ClientConnection connection, bool connected, void* parameter) +{ + if (connected) + printf("Connection opened\n"); + else + printf("Connection closed\n"); +} + +int +main(int argc, char** argv) +{ + printf("Using libIEC61850 version %s\n", LibIEC61850_getVersionString()); + + TLSConfiguration tlsConfig = TLSConfiguration_create(); + + TLSConfiguration_setChainValidation(tlsConfig, false); + TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig, true); + + if (!TLSConfiguration_setOwnKeyFromFile(tlsConfig, "server-key.pem", NULL)) { + printf("Failed to load private key!\n"); + return 0; + } + + if (!TLSConfiguration_setOwnCertificateFromFile(tlsConfig, "server.cer")) { + printf("ERROR: Failed to load own certificate!\n"); + return 0; + } + + if (!TLSConfiguration_addCACertificateFromFile(tlsConfig, "root.cer")) { + printf("ERROR: Failed to load root certificate\n"); + return 0; + } + + /** + * Configure two allowed clients + */ + + if (!TLSConfiguration_addAllowedCertificateFromFile(tlsConfig, "client1.cer")) { + printf("ERROR: Failed to load allowed client certificate\n"); + return 0; + } + + if (!TLSConfiguration_addAllowedCertificateFromFile(tlsConfig, "client2.cer")) { + printf("ERROR: Failed to load allowed client certificate\n"); + return 0; + } + + iedServer = IedServer_createWithTlsSupport(&iedModel, tlsConfig); + + /* Install handler for operate command */ + IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1, + (ControlHandler) controlHandlerForBinaryOutput, + IEDMODEL_GenericIO_GGIO1_SPCSO1); + + IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2, + (ControlHandler) controlHandlerForBinaryOutput, + IEDMODEL_GenericIO_GGIO1_SPCSO2); + + IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3, + (ControlHandler) controlHandlerForBinaryOutput, + IEDMODEL_GenericIO_GGIO1_SPCSO3); + + IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4, + (ControlHandler) controlHandlerForBinaryOutput, + IEDMODEL_GenericIO_GGIO1_SPCSO4); + + IedServer_setConnectionIndicationHandler(iedServer, (IedConnectionIndicationHandler) connectionHandler, NULL); + + /* MMS server will be instructed to start listening to client connections. */ + IedServer_start(iedServer, -1); + + if (!IedServer_isRunning(iedServer)) { + printf("Starting server failed! Exit.\n"); + IedServer_destroy(iedServer); + exit(-1); + } + + running = 1; + + signal(SIGINT, sigint_handler); + + float t = 0.f; + + while (running) { + uint64_t timestamp = Hal_getTimeInMs(); + + t += 0.1f; + + float an1 = sinf(t); + float an2 = sinf(t + 1.f); + float an3 = sinf(t + 2.f); + float an4 = sinf(t + 3.f); + + IedServer_lockDataModel(iedServer); + + Timestamp iecTimestamp; + + Timestamp_clearFlags(&iecTimestamp); + Timestamp_setTimeInMilliseconds(&iecTimestamp, timestamp); + Timestamp_setLeapSecondKnown(&iecTimestamp, true); + + /* toggle clock-not-synchronized flag in timestamp */ + if (((int) t % 2) == 0) + Timestamp_setClockNotSynchronized(&iecTimestamp, true); + + IedServer_updateTimestampAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn1_t, &iecTimestamp); + IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn1_mag_f, an1); + + IedServer_updateTimestampAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn2_t, &iecTimestamp); + IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn2_mag_f, an2); + + IedServer_updateTimestampAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn3_t, &iecTimestamp); + IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn3_mag_f, an3); + + IedServer_updateTimestampAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn4_t, &iecTimestamp); + IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn4_mag_f, an4); + + IedServer_unlockDataModel(iedServer); + + Thread_sleep(100); + } + + /* stop MMS server - close TCP server socket and all client sockets */ + IedServer_stop(iedServer); + + /* Cleanup - free all resources */ + IedServer_destroy(iedServer); + + TLSConfiguration_destroy(tlsConfig); + +} /* main() */