Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging latest updates. #444

Open
wants to merge 5 commits into
base: v1.5
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions pyiec61850/iec61850.i
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,45 @@ void CommParameters_setDstAddress(CommParameters *gooseCommParameters,
#include "servicePythonWrapper.hpp"
%}
%include "servicePythonWrapper.hpp"

/* SV Subscriber section */
%{
struct sSVSubscriber;
typedef struct sSVSubscriber* SVSubscriber;
struct sSVSubscriber_ASDU {

char* svId;
char* datSet;

uint8_t* smpCnt;
uint8_t* confRev;
uint8_t* refrTm;
uint8_t* smpSynch;
uint8_t* smpMod;
uint8_t* smpRate;

int dataBufferLength;
uint8_t* dataBuffer;
};
typedef struct sSVSubscriber_ASDU* SVSubscriber_ASDU;
#include "sv_subscriber.h"
#include "sv_publisher.h"
%}
%include "sv_publisher.h"
%include "sv_subscriber.h"
struct sSVSubscriber_ASDU {

char* svId;
char* datSet;

uint8_t* smpCnt;
uint8_t* confRev;
uint8_t* refrTm;
uint8_t* smpSynch;
uint8_t* smpMod;
uint8_t* smpRate;

int dataBufferLength;
uint8_t* dataBuffer;
};
typedef struct sSVSubscriber_ASDU* SVSubscriber_ASDU;
99 changes: 99 additions & 0 deletions src/iec61850/client/client_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,59 @@ createCancelParameters(ControlObjectClient self)
return cancelParameters;
}

static MmsValue*
createCancelwParameters(ControlObjectClient self, MmsValue* ctlVal)
{
MmsValue* cancelParameters;

if (self->hasTimeActivatedMode)
cancelParameters = MmsValue_createEmptyStructure(6);
else
cancelParameters = MmsValue_createEmptyStructure(5);

MmsValue_setElement(cancelParameters, 0, ctlVal);

int index = 1;

if (self->hasTimeActivatedMode) {
MmsValue* operTm = MmsValue_newUtcTimeByMsTime(self->opertime);
MmsValue_setElement(cancelParameters, index++, operTm);
}

MmsValue* origin = createOriginValue(self);

MmsValue_setElement(cancelParameters, index++, origin);

MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->ctlNum);
MmsValue_setElement(cancelParameters, index++, ctlNum);

uint64_t timestamp;

if (self->useConstantT)
timestamp = self->constantT;
else
timestamp = Hal_getTimeInMs();

MmsValue* ctlTime;

if (self->edition == 2) {
ctlTime = MmsValue_newUtcTimeByMsTime(timestamp);

if (self->connection)
MmsValue_setUtcTimeQuality(ctlTime, self->connection->timeQuality);
}
else {
ctlTime = MmsValue_newBinaryTime(false);
MmsValue_setBinaryTime(ctlTime, timestamp);
}
MmsValue_setElement(cancelParameters, index++, ctlTime);

MmsValue* ctlTest = MmsValue_newBoolean(self->test);
MmsValue_setElement(cancelParameters, index++, ctlTest);

return cancelParameters;
}

bool
ControlObjectClient_cancel(ControlObjectClient self)
{
Expand Down Expand Up @@ -1154,6 +1207,52 @@ ControlObjectClient_cancel(ControlObjectClient self)
return true;
}

bool
ControlObjectClient_cancelWithValue(ControlObjectClient self, MmsValue* ctlVal)
{
resetLastApplError(self);

MmsValue* cancelParameters = createCancelwParameters(self, ctlVal);

char domainId[65];
char itemId[65];

MmsMapping_getMmsDomainFromObjectReference(self->objectReference, domainId);

convertToMmsAndInsertFC(itemId, self->objectReference + strlen(domainId) + 1, "CO");

strncat(itemId, "$Cancel", 64);

if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: cancel: %s/%s\n", domainId, itemId);

MmsError mmsError;

MmsDataAccessError writeResult = MmsConnection_writeVariable(IedConnection_getMmsConnection(self->connection),
&mmsError, domainId, itemId, cancelParameters);

self->lastMmsError = mmsError;
self->lastAccessError = writeResult;

MmsValue_setElement(cancelParameters, 0, NULL);
MmsValue_delete(cancelParameters);

if (mmsError != MMS_ERROR_NONE) {
if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: cancel failed!\n");
return false;
}
else {
if (writeResult != DATA_ACCESS_ERROR_SUCCESS) {
if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: cancel failed!\n");
return false;
}
}

return true;
}

static void
internalCancelHandler(uint32_t invokeId, void* parameter, MmsError err, MmsDataAccessError accessError)
{
Expand Down
13 changes: 13 additions & 0 deletions src/iec61850/inc/iec61850_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -2201,6 +2201,19 @@ ControlObjectClient_selectWithValue(ControlObjectClient self, MmsValue* ctlVal);
LIB61850_API bool
ControlObjectClient_cancel(ControlObjectClient self);

/**
* \brief Send a cancel command to the server
*
* The cancel command can be used to stop an ongoing operation (when the server and application
* support this) and to cancel a former select command.
*
* \param self the control object instance to use
* \param ctlVal the control value (for APC the value may be either AnalogueValue (MMS_STRUCT) or MMS_FLOAT/MMS_INTEGER
*
* \return true if operation has been successful, false otherwise.
*/
LIB61850_API bool
ControlObjectClient_cancelWithValue(ControlObjectClient self, MmsValue* ctlVal);

/**
* \brief Send an operate command to the server - async version
Expand Down