|
|
|
@ -3,7 +3,7 @@
|
|
|
|
|
*
|
|
|
|
|
* Implementation of the ClientReportControlBlock class
|
|
|
|
|
*
|
|
|
|
|
* Copyright 2013-2018 Michael Zillgith
|
|
|
|
|
* Copyright 2013-2022 Michael Zillgith
|
|
|
|
|
*
|
|
|
|
|
* This file is part of libIEC61850.
|
|
|
|
|
*
|
|
|
|
@ -603,8 +603,7 @@ IedConnection_getRCBValuesAsync(IedConnection self, IedClientError* error, const
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strcpy(itemId, rcbReference + strlen(domainId) + 1);
|
|
|
|
|
|
|
|
|
|
StringUtils_copyStringMax(itemId, 65, rcbReference + strlen(domainId) + 1);
|
|
|
|
|
StringUtils_replace(itemId, '.', '$');
|
|
|
|
|
|
|
|
|
|
IedConnectionOutstandingCall call = iedConnection_allocateOutstandingCall(self);
|
|
|
|
@ -653,8 +652,7 @@ IedConnection_getRCBValues(IedConnection self, IedClientError* error, const char
|
|
|
|
|
if (domainName == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
strcpy(itemId, rcbReference + strlen(domainId) + 1);
|
|
|
|
|
|
|
|
|
|
StringUtils_copyStringMax(itemId, 65, rcbReference + strlen(domainId) + 1);
|
|
|
|
|
StringUtils_replace(itemId, '.', '$');
|
|
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
@ -853,21 +851,20 @@ IedConnection_setRCBValuesAsync(IedConnection self, IedClientError* error, Clien
|
|
|
|
|
bool sendGILast = false; /* GI should be sent last when RptEna=TRUE is included */
|
|
|
|
|
|
|
|
|
|
char domainId[65];
|
|
|
|
|
char itemId[129];
|
|
|
|
|
char itemId[130];
|
|
|
|
|
|
|
|
|
|
char* rcbReference = ClientReportControlBlock_getObjectReference(rcb);
|
|
|
|
|
|
|
|
|
|
MmsMapping_getMmsDomainFromObjectReference(rcbReference, domainId);
|
|
|
|
|
|
|
|
|
|
strcpy(itemId, rcbReference + strlen(domainId) + 1);
|
|
|
|
|
|
|
|
|
|
StringUtils_copyStringMax(itemId, 130, rcbReference + strlen(domainId) + 1);
|
|
|
|
|
StringUtils_replace(itemId, '.', '$');
|
|
|
|
|
|
|
|
|
|
int itemIdLen = strlen(itemId);
|
|
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
printf("DEBUG_IED_CLIENT: setRCBValues for %s\n", rcbReference);
|
|
|
|
|
|
|
|
|
|
int itemIdLen = strlen(itemId);
|
|
|
|
|
|
|
|
|
|
/* prepare data to send -> create the list of requested itemIds references */
|
|
|
|
|
LinkedList itemIds = LinkedList_create();
|
|
|
|
|
LinkedList values = LinkedList_create();
|
|
|
|
@ -877,69 +874,87 @@ IedConnection_setRCBValuesAsync(IedConnection self, IedClientError* error, Clien
|
|
|
|
|
if (isBuffered)
|
|
|
|
|
goto error_invalid_parameter;
|
|
|
|
|
|
|
|
|
|
strcpy(itemId + itemIdLen, "$Resv");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$Resv");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->resv);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_RESV_TMS) {
|
|
|
|
|
if (!isBuffered)
|
|
|
|
|
goto error_invalid_parameter;
|
|
|
|
|
|
|
|
|
|
strcpy(itemId + itemIdLen, "$ResvTms");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$ResvTms");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->resvTms);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_RPT_ID) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$RptID");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$RptID");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->rptId);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_DATSET) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$DatSet");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$DatSet");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->datSet);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_ENTRY_ID) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$EntryID");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$EntryID");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->entryId);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_OPT_FLDS) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$OptFlds");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$OptFlds");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->optFlds);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_BUF_TM) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$BufTm");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$BufTm");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->bufTm);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_TRG_OPS) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$TrgOps");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$TrgOps");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->trgOps);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_INTG_PD) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$IntgPd");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$IntgPd");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->intgPd);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_GI) {
|
|
|
|
@ -950,10 +965,12 @@ IedConnection_setRCBValuesAsync(IedConnection self, IedClientError* error, Clien
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sendGILast == false) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$GI");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$GI");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->gi);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -961,34 +978,42 @@ IedConnection_setRCBValuesAsync(IedConnection self, IedClientError* error, Clien
|
|
|
|
|
if (!isBuffered)
|
|
|
|
|
goto error_invalid_parameter;
|
|
|
|
|
|
|
|
|
|
strcpy(itemId + itemIdLen, "$PurgeBuf");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$PurgeBuf");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->purgeBuf);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_TIME_OF_ENTRY) {
|
|
|
|
|
if (!isBuffered)
|
|
|
|
|
goto error_invalid_parameter;
|
|
|
|
|
|
|
|
|
|
strcpy(itemId + itemIdLen, "$TimeofEntry");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$TimeofEntry");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->timeOfEntry);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_RPT_ENA) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$RptEna");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$RptEna");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->rptEna);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sendGILast) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$GI");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$GI");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->gi);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IedConnectionOutstandingCall call = iedConnection_allocateOutstandingCall(self);
|
|
|
|
@ -1075,21 +1100,20 @@ IedConnection_setRCBValues(IedConnection self, IedClientError* error, ClientRepo
|
|
|
|
|
bool sendGILast = false; /* GI should be sent last when RptEna=TRUE is included */
|
|
|
|
|
|
|
|
|
|
char domainId[65];
|
|
|
|
|
char itemId[129];
|
|
|
|
|
char itemId[130];
|
|
|
|
|
|
|
|
|
|
char* rcbReference = ClientReportControlBlock_getObjectReference(rcb);
|
|
|
|
|
|
|
|
|
|
MmsMapping_getMmsDomainFromObjectReference(rcbReference, domainId);
|
|
|
|
|
|
|
|
|
|
strcpy(itemId, rcbReference + strlen(domainId) + 1);
|
|
|
|
|
|
|
|
|
|
StringUtils_copyStringMax(itemId, 130, rcbReference + strlen(domainId) + 1);
|
|
|
|
|
StringUtils_replace(itemId, '.', '$');
|
|
|
|
|
|
|
|
|
|
int itemIdLen = strlen(itemId);
|
|
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
printf("DEBUG_IED_CLIENT: setRCBValues for %s\n", rcbReference);
|
|
|
|
|
|
|
|
|
|
int itemIdLen = strlen(itemId);
|
|
|
|
|
|
|
|
|
|
/* create the list of requested itemIds references */
|
|
|
|
|
LinkedList itemIds = LinkedList_create();
|
|
|
|
|
LinkedList values = LinkedList_create();
|
|
|
|
@ -1097,10 +1121,12 @@ IedConnection_setRCBValues(IedConnection self, IedClientError* error, ClientRepo
|
|
|
|
|
/* add rptEna = false as first element */
|
|
|
|
|
if (ClientReportControlBlock_getRptEna(rcb) == false) {
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_RPT_ENA) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$RptEna");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$RptEna");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->rptEna);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1109,69 +1135,87 @@ IedConnection_setRCBValues(IedConnection self, IedClientError* error, ClientRepo
|
|
|
|
|
if (isBuffered)
|
|
|
|
|
goto error_invalid_parameter;
|
|
|
|
|
|
|
|
|
|
strcpy(itemId + itemIdLen, "$Resv");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$Resv");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->resv);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_RESV_TMS) {
|
|
|
|
|
if (!isBuffered)
|
|
|
|
|
goto error_invalid_parameter;
|
|
|
|
|
|
|
|
|
|
strcpy(itemId + itemIdLen, "$ResvTms");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$ResvTms");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->resvTms);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_RPT_ID) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$RptID");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$RptID");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->rptId);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_DATSET) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$DatSet");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$DatSet");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->datSet);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_ENTRY_ID) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$EntryID");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$EntryID");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->entryId);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_OPT_FLDS) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$OptFlds");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$OptFlds");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->optFlds);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_BUF_TM) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$BufTm");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$BufTm");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->bufTm);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_TRG_OPS) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$TrgOps");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$TrgOps");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->trgOps);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_INTG_PD) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$IntgPd");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$IntgPd");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->intgPd);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_GI) {
|
|
|
|
@ -1182,10 +1226,12 @@ IedConnection_setRCBValues(IedConnection self, IedClientError* error, ClientRepo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sendGILast == false) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$GI");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$GI");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->gi);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1193,36 +1239,44 @@ IedConnection_setRCBValues(IedConnection self, IedClientError* error, ClientRepo
|
|
|
|
|
if (!isBuffered)
|
|
|
|
|
goto error_invalid_parameter;
|
|
|
|
|
|
|
|
|
|
strcpy(itemId + itemIdLen, "$PurgeBuf");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$PurgeBuf");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->purgeBuf);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_TIME_OF_ENTRY) {
|
|
|
|
|
if (!isBuffered)
|
|
|
|
|
goto error_invalid_parameter;
|
|
|
|
|
|
|
|
|
|
strcpy(itemId + itemIdLen, "$TimeofEntry");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$TimeofEntry");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->timeOfEntry);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ClientReportControlBlock_getRptEna(rcb) == true) {
|
|
|
|
|
if (parametersMask & RCB_ELEMENT_RPT_ENA) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$RptEna");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$RptEna");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->rptEna);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sendGILast) {
|
|
|
|
|
strcpy(itemId + itemIdLen, "$GI");
|
|
|
|
|
StringUtils_appendString(itemId, 130, "$GI");
|
|
|
|
|
|
|
|
|
|
LinkedList_add(itemIds, StringUtils_copyString(itemId));
|
|
|
|
|
LinkedList_add(values, rcb->gi);
|
|
|
|
|
|
|
|
|
|
itemId[itemIdLen] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (singleRequest) {
|
|
|
|
|