- implemented GET_PARAMETER event for IedServer_RCBEventHandler

- implemented additional access functions for ReportControlBlock to allow access to runtime values
pull/374/head
Michael Zillgith 4 years ago
parent d036b09712
commit b27681f408

@ -1311,6 +1311,28 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern string ReportControlBlock_getName(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ReportControlBlock_getRptEna(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ReportControlBlock_getRptID(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ReportControlBlock_getDataSet(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ReportControlBlock_getTrgOps(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ReportControlBlock_getIntgPd(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ReportControlBlock_getOwner(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Memory_free(IntPtr self);
public IntPtr self = IntPtr.Zero;
private string name = null;
@ -1360,6 +1382,57 @@ namespace IEC61850
}
}
public bool RptEna
{
get
{
return ReportControlBlock_getRptEna(self);
}
}
public string RptID
{
get
{
IntPtr rptIdPtr = ReportControlBlock_getRptID(self);
string rptId = Marshal.PtrToStringAnsi(rptIdPtr);
Memory_free(rptIdPtr);
return rptId;
}
}
public string DataSet
{
get
{
IntPtr dataSetPtr = ReportControlBlock_getDataSet(self);
string dataSet = Marshal.PtrToStringAnsi(dataSetPtr);
Memory_free(dataSetPtr);
return dataSet;
}
}
public TriggerOptions TrgOps
{
get
{
return (TriggerOptions)ReportControlBlock_getTrgOps(self);
}
}
public UInt32 IntgPd
{
get
{
return ReportControlBlock_getIntgPd(self);
}
}
}
/// <summary>

@ -71,7 +71,14 @@ namespace server1
{
Console.WriteLine("RCB: " + rcb.Parent.GetObjectReference() + "." + rcb.Name + " event: " + eventType.ToString());
if (eventType == RCBEventType.SET_PARAMETER)
if (eventType == RCBEventType.ENABLED)
{
//Console.WriteLine(" RptID: " + rcb.RptID);
//Console.WriteLine(" DatSet: " + rcb.DataSet);
Console.WriteLine(" TrgOps: " + rcb.TrgOps.ToString());
}
if ((eventType == RCBEventType.SET_PARAMETER) || (eventType == RCBEventType.GET_PARAMETER))
{
Console.WriteLine(" param: " + parameterName);
Console.WriteLine(" result: " + serviceError.ToString());

@ -79,6 +79,27 @@ connectionHandler (IedServer self, ClientConnection connection, bool connected,
printf("Connection closed\n");
}
static void
rcbEventHandler(void* parameter, ReportControlBlock* rcb, ClientConnection connection, IedServer_RCBEventType event, const char* parameterName, MmsDataAccessError serviceError)
{
printf("RCB: %s event: %i\n", ReportControlBlock_getName(rcb), event);
if ((event == RCB_EVENT_SET_PARAMETER) || (event == RCB_EVENT_GET_PARAMETER)) {
printf(" param: %s\n", parameterName);
printf(" result: %i\n", serviceError);
}
if (event == RCB_EVENT_ENABLE) {
char* rptId = ReportControlBlock_getRptID(rcb);
printf(" rptID: %s\n", rptId);
char* dataSet = ReportControlBlock_getDataSet(rcb);
printf(" datSet: %s\n", dataSet);
free(rptId);
free(dataSet);
}
}
int
main(int argc, char** argv)
{
@ -136,6 +157,8 @@ main(int argc, char** argv)
IedServer_setConnectionIndicationHandler(iedServer, (IedConnectionIndicationHandler) connectionHandler, NULL);
IedServer_setRCBEventHandler(iedServer, rcbEventHandler, NULL);
/* By default access to variables with FC=DC and FC=CF is not allowed.
* This allow to write to simpleIOGenericIO/GGIO1.NamPlt.vendor variable used
* by iec61850_client_example1.

@ -243,6 +243,24 @@ ReportControlBlock_isBuffered(ReportControlBlock* self);
LIB61850_API LogicalNode*
ReportControlBlock_getParent(ReportControlBlock* self);
LIB61850_API int
ReportControlBlock_getRptEna(ReportControlBlock* self);
LIB61850_API char*
ReportControlBlock_getRptID(ReportControlBlock* self);
LIB61850_API char*
ReportControlBlock_getDataSet(ReportControlBlock* self);
LIB61850_API int
ReportControlBlock_getTrgOps(ReportControlBlock* self);
LIB61850_API uint32_t
ReportControlBlock_getIntgPd(ReportControlBlock* self);
LIB61850_API MmsValue*
ReportControlBlock_getOwner(ReportControlBlock* self);
/**
* \brief create a new log control block (LCB)
*

@ -269,7 +269,9 @@ struct sReportControlBlock {
type can be one of (0 - no reservation, 4 - IPv4 client, 6 - IPv6 client) */
uint8_t clientReservation[17];
ReportControlBlock* sibling; /* next control block in list or NULL if this is the last entry */
ReportControlBlock* sibling; /* next control block in list or NULL if this is the last entry
* at runtime reuse as pointer to ReportControl instance!
**/
};
struct sLogControlBlock {

@ -107,6 +107,7 @@ typedef struct {
MmsValue* timeOfEntry;
ReportControlBlock* rcb;
ReportControlBlock* sibling; /* backup sibling field of original ReportControlBlock */
IedServer server;
} ReportControl;
@ -136,7 +137,7 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
MmsServerConnection connection);
LIB61850_INTERNAL void
ReportControl_readAccess(ReportControl* rc, MmsMapping* mmsMapping, char* elementName);
ReportControl_readAccess(ReportControl* rc, MmsMapping* mmsMapping, MmsServerConnection connection, char* elementName);
LIB61850_INTERNAL void
Reporting_activateBufferedReports(MmsMapping* self);

@ -2034,6 +2034,24 @@ MmsMapping_create(IedModel* model, IedServer iedServer)
MmsMapping_destroy(self);
self = NULL;
}
else {
LinkedList rcElem = LinkedList_getNext(self->reportControls);
while (rcElem) {
ReportControl* rc = (ReportControl*)LinkedList_getData(rcElem);
/* backup original sibling of ReportControlBlock */;
rc->sibling = rc->rcb->sibling;
/* reuse ReportControlBlock.sibling as reference to runtime information (ReportControl) */
rc->rcb->sibling = (ReportControlBlock*)rc;
/* set runtime mode flag (indicate that sibling field contains now runtime information reference!) */
rc->rcb->trgOps |= 64;
rcElem = LinkedList_getNext(rcElem);
}
}
return self;
}
@ -3075,7 +3093,7 @@ mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerCo
char* elementName = MmsMapping_getNextNameElement(reportName);
ReportControl_readAccess(rc, self, elementName);
ReportControl_readAccess(rc, self, connection, elementName);
MmsValue* value = NULL;

@ -226,6 +226,10 @@ ReportControl_destroy(ReportControl* self)
}
}
/* restore original sibling of ReportControlBlock */
self->rcb->sibling = self->sibling;
self->rcb->trgOps &= ~(64); /* clear runtime mode flag */
ReportBuffer_destroy(self->reportBuffer);
#if (CONFIG_MMS_THREADLESS_STACK != 1)
@ -1603,16 +1607,20 @@ checkReservationTimeout(MmsMapping* self, ReportControl* rc)
}
void
ReportControl_readAccess(ReportControl* rc, MmsMapping* mmsMapping, char* elementName)
ReportControl_readAccess(ReportControl* rc, MmsMapping* mmsMapping, MmsServerConnection connection, char* elementName)
{
(void)elementName;
/* TODO add log message */
/* check reservation timeout */
if (rc->buffered) {
checkReservationTimeout(mmsMapping, rc);
}
if (mmsMapping->rcbEventHandler) {
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(mmsMapping->iedServer, connection);
mmsMapping->rcbEventHandler(mmsMapping->rcbEventHandlerParameter, rc->rcb, clientConnection, RCB_EVENT_GET_PARAMETER, elementName, DATA_ACCESS_ERROR_SUCCESS);
}
}
static bool
@ -3642,4 +3650,92 @@ ReportControl_valueUpdated(ReportControl* self, int dataSetEntryIndex, int flag,
ReportControl_unlockNotify(self);
}
int
ReportControlBlock_getRptEna(ReportControlBlock* self)
{
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
return rc->enabled;
}
else {
return false;
}
}
char*
ReportControlBlock_getRptID(ReportControlBlock* self)
{
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
MmsValue* rptIdValue = ReportControl_getRCBValue(rc, "RptID");
return strdup(MmsValue_toString(rptIdValue));
}
else {
return self->rptId;
}
}
char*
ReportControlBlock_getDataSet(ReportControlBlock* self)
{
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
MmsValue* dataSetValue = ReportControl_getRCBValue(rc, "DatSet");
return strdup(MmsValue_toString(dataSetValue));
}
else {
return self->dataSetName;
}
}
int
ReportControlBlock_getTrgOps(ReportControlBlock* self)
{
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
return rc->triggerOps;
}
else {
return (int)(self->trgOps);
}
}
uint32_t
ReportControlBlock_getIntgPd(ReportControlBlock* self)
{
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
return rc->intgPd;
}
else {
return self->intPeriod;
}
}
MmsValue*
ReportControlBlock_getOwner(ReportControlBlock* self)
{
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
if (rc->hasOwner) {
return ReportControl_getRCBValue(rc, "Owner");
}
else
return NULL;
}
else {
return NULL;
}
}
#endif /* (CONFIG_IEC61850_REPORT_SERVICE == 1) */

Loading…
Cancel
Save