- prepared for 0.9 release

pull/6/head
Michael Zillgith 10 years ago
parent bc65ce46c6
commit e1a9b6a852

@ -1,3 +1,19 @@
Changes to version 0.9
----------------------
- Sampled values subscriber code
- Experimental sampled values publisher and MMS SVCB code
- server: support for VMD scope data sets (MMS named variable lists)
- .NET API: added MmsConnection.setLocalDetail and MmsConnection.getLocalDetail
- example server/sv publisher according to IEC 61850-9-2LE
- server: multi-threaded configuration now uses select instead of socket polling
- .NET API: some additional methods for MmsValue class
- server: fixed bug with nested directories in file service
- mms_utility: added read file directory feature
- SCL parser/modelviewer: show unused types in SCL file
- server: fixed some problems related to buffered reporting UCA test cases
- other bug fixes
Changes to version 0.8.7 Changes to version 0.8.7
------------------------ ------------------------
- client: added client side control service support for edition 1 and 2 APC CDCs - client: added client side control service support for edition 1 and 2 APC CDCs

@ -98,6 +98,7 @@ set(API_HEADERS
src/goose/goose_subscriber.h src/goose/goose_subscriber.h
src/goose/goose_receiver.h src/goose/goose_receiver.h
src/sampled_values/sv_subscriber.h src/sampled_values/sv_subscriber.h
src/sampled_values/sv_publisher.h
) )
IF(WIN32) IF(WIN32)

@ -17,7 +17,7 @@
#define DEBUG_COTP 0 #define DEBUG_COTP 0
#define DEBUG_ISO_SERVER 0 #define DEBUG_ISO_SERVER 0
#define DEBUG_ISO_CLIENT 0 #define DEBUG_ISO_CLIENT 0
#define DEBUG_IED_SERVER 1 #define DEBUG_IED_SERVER 0
#define DEBUG_IED_CLIENT 0 #define DEBUG_IED_CLIENT 0
#define DEBUG_MMS_CLIENT 0 #define DEBUG_MMS_CLIENT 0
#define DEBUG_MMS_SERVER 0 #define DEBUG_MMS_SERVER 0

@ -72,7 +72,7 @@
#cmakedefine01 CONFIG_INCLUDE_GOOSE_SUPPORT #cmakedefine01 CONFIG_INCLUDE_GOOSE_SUPPORT
/* Set to 1 to include Sampled Values support in the build. Otherwise set to 0 */ /* Set to 1 to include Sampled Values support in the build. Otherwise set to 0 */
#cmakedefine01 CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT #define CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT 1
#ifdef _WIN32 #ifdef _WIN32

@ -24,3 +24,6 @@ add_subdirectory(mms_client_example3)
add_subdirectory(mms_client_example4) add_subdirectory(mms_client_example4)
add_subdirectory(goose_subscriber) add_subdirectory(goose_subscriber)
add_subdirectory(sv_subscriber) add_subdirectory(sv_subscriber)
add_subdirectory(iec61850_9_2_LE_example)
add_subdirectory(iec61850_sv_client_example)
add_subdirectory(sv_publisher)

@ -27,6 +27,10 @@ EXAMPLE_DIRS += goose_subscriber
EXAMPLE_DIRS += goose_publisher EXAMPLE_DIRS += goose_publisher
EXAMPLE_DIRS += sv_subscriber EXAMPLE_DIRS += sv_subscriber
EXAMPLE_DIRS += mms_utility EXAMPLE_DIRS += mms_utility
EXAMPLE_DIRS += iec61850_9_2_LE_example
EXAMPLE_DIRS += iec61850_sv_client_example
EXAMPLE_DIRS += sv_publisher
EXAMPLE_DIRS += sv_subscriber
MODEL_DIRS += server_example1 MODEL_DIRS += server_example1
MODEL_DIRS += server_example2 MODEL_DIRS += server_example2
@ -40,6 +44,7 @@ MODEL_DIRS += server_example_complex_array
MODEL_DIRS += server_example_61400_25 MODEL_DIRS += server_example_61400_25
MODEL_DIRS += server_example_threadless MODEL_DIRS += server_example_threadless
MODEL_DIRS += server_example_setting_groups MODEL_DIRS += server_example_setting_groups
MODEL_DIRS += iec61850_9_2_LE_example
all: examples all: examples

@ -3,7 +3,7 @@ include_directories(
) )
set(sv_9_2_LE_example_SRCS set(sv_9_2_LE_example_SRCS
server_example2.c iec61850_9_2_LE_example.c
static_model.c static_model.c
) )

@ -4,7 +4,7 @@ PROJECT_BINARY_NAME = sv_9_2LE_example
PROJECT_SOURCES = iec61850_9_2_LE_example.c PROJECT_SOURCES = iec61850_9_2_LE_example.c
PROJECT_SOURCES += static_model.c PROJECT_SOURCES += static_model.c
PROJECT_ICD_FILE = complexModel.icd PROJECT_ICD_FILE = sv.icd
include $(LIBIEC_HOME)/make/target_system.mk include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk include $(LIBIEC_HOME)/make/stack_includes.mk

@ -83,7 +83,7 @@ int main(int argc, char** argv) {
while (running) { while (running) {
IedServer_lockDataModel(iedServer); IedServer_lockDataModel(iedServer);
IedServer_updateUTCTimeAttributeValue(iedServer, temperatureTimestamp, Hal_getTimeInMs()) IedServer_updateUTCTimeAttributeValue(iedServer, temperatureTimestamp, Hal_getTimeInMs());
IedServer_updateFloatAttributeValue(iedServer, temperatureValue, val); IedServer_updateFloatAttributeValue(iedServer, temperatureValue, val);
IedServer_unlockDataModel(iedServer); IedServer_unlockDataModel(iedServer);

@ -176,6 +176,7 @@ set (lib_goose_SRCS
set (lib_sv_SRCS set (lib_sv_SRCS
./sampled_values/sv_subscriber.c ./sampled_values/sv_subscriber.c
./sampled_values/sv_publisher.c
) )
set (lib_linux_SRCS set (lib_linux_SRCS

@ -660,6 +660,18 @@ MmsConnection_fileDelete(MmsConnection self, MmsError* mmsError, const char* fil
void void
MmsConnection_fileRename(MmsConnection self, MmsError* mmsError, const char* currentFileName, const char* newFileName); MmsConnection_fileRename(MmsConnection self, MmsError* mmsError, const char* currentFileName, const char* newFileName);
/**
* \brief Send an obtainFile request to the server (used to initiate file download to server)
*
* \param self MmsConnection instance to operate on
* \param mmsError user provided variable to store error code
* \param sourceFile the name of the source file (client side name)
* \param destinationFile the name of the destination file (server side name)
*/
void
MmsConnection_obtainFile(MmsConnection self, MmsError* mmsError, const char* sourceFile, const char* destinationFile);
/** /**
* \brief get the file directory of the server. * \brief get the file directory of the server.
* *

@ -236,6 +236,9 @@ mmsClient_createFileCloseRequest(uint32_t invokeId, ByteBuffer* request, int32_t
void void
mmsClient_createFileRenameRequest(uint32_t invokeId, ByteBuffer* request, const char* currentFileName, const char* newFileName); mmsClient_createFileRenameRequest(uint32_t invokeId, ByteBuffer* request, const char* currentFileName, const char* newFileName);
void
mmsClient_createObtainFileRequest(uint32_t invokeId, ByteBuffer* request, const char* sourceFile, const char* destinationFile);
void void
mmsClient_createFileDeleteRequest(uint32_t invokeId, ByteBuffer* request, const char* fileName); mmsClient_createFileDeleteRequest(uint32_t invokeId, ByteBuffer* request, const char* fileName);

@ -1794,6 +1794,29 @@ MmsConnection_fileRename(MmsConnection self, MmsError* mmsError, const char* cur
} }
void
MmsConnection_obtainFile(MmsConnection self, MmsError* mmsError, const char* sourceFile, const char* destinationFile)
{
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
*mmsError = MMS_ERROR_NONE;
uint32_t invokeId = getNextInvokeId(self);
mmsClient_createObtainFileRequest(invokeId, payload, sourceFile, destinationFile);
sendRequestAndWaitForResponse(self, invokeId, payload);
if (self->lastResponseError != MMS_ERROR_NONE)
*mmsError = self->lastResponseError;
releaseResponse(self);
if (self->associationState == MMS_STATE_CLOSED)
*mmsError = MMS_ERROR_CONNECTION_LOST;
}
void void
MmsConnection_writeVariable(MmsConnection self, MmsError* mmsError, MmsConnection_writeVariable(MmsConnection self, MmsError* mmsError,
const char* domainId, const char* itemId, const char* domainId, const char* itemId,

@ -183,7 +183,7 @@ mmsClient_createFileRenameRequest(uint32_t invokeId, ByteBuffer* request, const
{ {
uint32_t invokeIdSize = BerEncoder_UInt32determineEncodedSize(invokeId); uint32_t invokeIdSize = BerEncoder_UInt32determineEncodedSize(invokeId);
uint32_t confirmedRequestPduSize = 1 + 2 + 2 + invokeIdSize + 0; uint32_t confirmedRequestPduSize = 1 + 2 + 2 + invokeIdSize;
uint32_t parameterSize = 0; uint32_t parameterSize = 0;
@ -212,6 +212,41 @@ mmsClient_createFileRenameRequest(uint32_t invokeId, ByteBuffer* request, const
request->size = bufPos; request->size = bufPos;
} }
void
mmsClient_createObtainFileRequest(uint32_t invokeId, ByteBuffer* request, const char* sourceFile, const char* destinationFile)
{
uint32_t invokeIdSize = BerEncoder_UInt32determineEncodedSize(invokeId);
uint32_t confirmedRequestPduSize = 1 + 2 + 2 + invokeIdSize;
uint32_t parameterSize = 0;
parameterSize += encodeFileSpecification(0xa0, sourceFile, NULL, 0);
parameterSize += encodeFileSpecification(0xa1, destinationFile, NULL, 0);
confirmedRequestPduSize += parameterSize;
int bufPos = 0;
uint8_t* buffer = request->buffer;
bufPos = BerEncoder_encodeTL(0xa0, confirmedRequestPduSize, buffer, bufPos);
bufPos = BerEncoder_encodeTL(0x02, invokeIdSize, buffer, bufPos);
bufPos = BerEncoder_encodeUInt32(invokeId, buffer, bufPos);
/* Encode ObtainFile tag (context | structured ) [46 = 2eh] */
buffer[bufPos++] = 0xbf;
buffer[bufPos++] = 0x2e;
bufPos = BerEncoder_encodeLength(parameterSize, buffer, bufPos);
bufPos = encodeFileSpecification(0xa1, sourceFile, buffer, bufPos);
bufPos = encodeFileSpecification(0xa2, destinationFile, buffer, bufPos);
request->size = bufPos;
}
static bool static bool
parseFileAttributes(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* fileSize, uint64_t* lastModified) parseFileAttributes(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* fileSize, uint64_t* lastModified)
{ {

@ -264,7 +264,7 @@ encodeUtcTime(uint64_t timeval, uint8_t* buffer, int bufPos)
SampledValuesPublisher SampledValuesPublisher
SampledValuesPublisher_create(const char* interfaceId) SampledValuesPublisher_create(const char* interfaceId)
{ {
SampledValuesPublisher self = GLOBAL_CALLOC(1, sizeof(struct sSampledValuesPublisher)); SampledValuesPublisher self = (SampledValuesPublisher) GLOBAL_CALLOC(1, sizeof(struct sSampledValuesPublisher));
self->asduLIst = NULL; self->asduLIst = NULL;
@ -276,7 +276,7 @@ SampledValuesPublisher_create(const char* interfaceId)
SV_ASDU SV_ASDU
SampledValuesPublisher_addASDU(SampledValuesPublisher self, char* svID, char* datset, uint32_t confRev) SampledValuesPublisher_addASDU(SampledValuesPublisher self, char* svID, char* datset, uint32_t confRev)
{ {
SV_ASDU newAsdu = GLOBAL_CALLOC(1, sizeof(struct sSV_ASDU)); SV_ASDU newAsdu = (SV_ASDU) GLOBAL_CALLOC(1, sizeof(struct sSV_ASDU));
newAsdu->svID = svID; newAsdu->svID = svID;
newAsdu->datset = datset; newAsdu->datset = datset;

@ -566,3 +566,4 @@ EXPORTS
ClientSVControlBlock_getNoASDU ClientSVControlBlock_getNoASDU
IedServer_setSVCBHandler IedServer_setSVCBHandler
IedModel_getSVControlBlock IedModel_getSVControlBlock
Loading…
Cancel
Save