|
|
@ -347,6 +347,13 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
MmsValue* rptIdValue = MmsValue_getElement(value, 0);
|
|
|
|
MmsValue* rptIdValue = MmsValue_getElement(value, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((rptIdValue == NULL) || (MmsValue_getType(rptIdValue) != MMS_VISIBLE_STRING)) {
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: received malformed report (RptId)\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LinkedList element = LinkedList_getNext(self->enabledReports);
|
|
|
|
LinkedList element = LinkedList_getNext(self->enabledReports);
|
|
|
|
ClientReport matchingReport = NULL;
|
|
|
|
ClientReport matchingReport = NULL;
|
|
|
|
|
|
|
|
|
|
|
@ -378,10 +385,17 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
matchingReport->hasBufOverflow = false;
|
|
|
|
matchingReport->hasBufOverflow = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
printf("DEBUG_IED_CLIENT: received report with ID %s\n", MmsValue_toString(rptIdValue));
|
|
|
|
printf("IED_CLIENT: received report with ID %s\n", MmsValue_toString(rptIdValue));
|
|
|
|
|
|
|
|
|
|
|
|
MmsValue* optFlds = MmsValue_getElement(value, 1);
|
|
|
|
MmsValue* optFlds = MmsValue_getElement(value, 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((optFlds == NULL) || (MmsValue_getType(optFlds) != MMS_BIT_STRING)) {
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: received malformed report (OptFlds)\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int inclusionIndex = 2;
|
|
|
|
int inclusionIndex = 2;
|
|
|
|
|
|
|
|
|
|
|
|
/* has sequence-number */
|
|
|
|
/* has sequence-number */
|
|
|
@ -389,11 +403,16 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
|
|
|
|
|
|
|
|
MmsValue* seqNum = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
MmsValue* seqNum = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
|
|
|
|
|
|
|
|
if (MmsValue_getType(seqNum) == MMS_UNSIGNED) {
|
|
|
|
if ((seqNum == NULL) || (MmsValue_getType(seqNum) != MMS_UNSIGNED)) {
|
|
|
|
matchingReport->seqNum = (uint16_t) MmsValue_toUint32(seqNum);
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
matchingReport->hasSequenceNumber = true;
|
|
|
|
printf("IED_CLIENT: received malformed report (seqNum)\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
matchingReport->seqNum = (uint16_t) MmsValue_toUint32(seqNum);
|
|
|
|
|
|
|
|
matchingReport->hasSequenceNumber = true;
|
|
|
|
|
|
|
|
|
|
|
|
inclusionIndex++;
|
|
|
|
inclusionIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -402,14 +421,19 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
|
|
|
|
|
|
|
|
MmsValue* timeStampValue = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
MmsValue* timeStampValue = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
|
|
|
|
|
|
|
|
if (MmsValue_getType(timeStampValue) == MMS_BINARY_TIME) {
|
|
|
|
if ((timeStampValue == NULL) || (MmsValue_getType(timeStampValue) != MMS_BINARY_TIME)) {
|
|
|
|
matchingReport->hasTimestamp = true;
|
|
|
|
|
|
|
|
matchingReport->timestamp = MmsValue_getBinaryTimeAsUtcMs(timeStampValue);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
printf("DEBUG_IED_CLIENT: report has timestamp %" PRIu64 "\n", matchingReport->timestamp);
|
|
|
|
printf("IED_CLIENT: received malformed report (timeStamp)\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
matchingReport->hasTimestamp = true;
|
|
|
|
|
|
|
|
matchingReport->timestamp = MmsValue_getBinaryTimeAsUtcMs(timeStampValue);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: report has timestamp %" PRIu64 "\n", matchingReport->timestamp);
|
|
|
|
|
|
|
|
|
|
|
|
inclusionIndex++;
|
|
|
|
inclusionIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -419,6 +443,13 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
|
|
|
|
|
|
|
|
MmsValue* dataSetName = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
MmsValue* dataSetName = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((dataSetName == NULL) || (MmsValue_getType(dataSetName) != MMS_VISIBLE_STRING)) {
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: received malformed report (DatSet)\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char* dataSetNameStr = MmsValue_toString(dataSetName);
|
|
|
|
const char* dataSetNameStr = MmsValue_toString(dataSetName);
|
|
|
|
|
|
|
|
|
|
|
|
if (matchingReport->dataSetName == NULL) {
|
|
|
|
if (matchingReport->dataSetName == NULL) {
|
|
|
@ -440,12 +471,19 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
printf("DEBUG_IED_CLIENT: Found enabled report!\n");
|
|
|
|
printf("IED_CLIENT: Found enabled report!\n");
|
|
|
|
|
|
|
|
|
|
|
|
/* check bufOvfl */
|
|
|
|
/* check bufOvfl */
|
|
|
|
if (MmsValue_getBitStringBit(optFlds, 6) == true) {
|
|
|
|
if (MmsValue_getBitStringBit(optFlds, 6) == true) {
|
|
|
|
MmsValue* bufOverflow = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
MmsValue* bufOverflow = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((bufOverflow == NULL) || (MmsValue_getType(bufOverflow) != MMS_BOOLEAN)) {
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: received malformed report (BufOvfl)\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
matchingReport->hasBufOverflow = true;
|
|
|
|
matchingReport->hasBufOverflow = true;
|
|
|
|
matchingReport->bufOverflow = MmsValue_getBoolean(bufOverflow);
|
|
|
|
matchingReport->bufOverflow = MmsValue_getBoolean(bufOverflow);
|
|
|
|
|
|
|
|
|
|
|
@ -456,6 +494,13 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
if (MmsValue_getBitStringBit(optFlds, 7) == true) {
|
|
|
|
if (MmsValue_getBitStringBit(optFlds, 7) == true) {
|
|
|
|
MmsValue* entryId = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
MmsValue* entryId = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((entryId == NULL) || (MmsValue_getType(entryId) != MMS_OCTET_STRING)) {
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: received malformed report (entryID)\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (matchingReport->entryId != NULL) {
|
|
|
|
if (matchingReport->entryId != NULL) {
|
|
|
|
|
|
|
|
|
|
|
|
if (!MmsValue_update(matchingReport->entryId, entryId)) {
|
|
|
|
if (!MmsValue_update(matchingReport->entryId, entryId)) {
|
|
|
@ -474,11 +519,16 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
if (MmsValue_getBitStringBit(optFlds, 8) == true) {
|
|
|
|
if (MmsValue_getBitStringBit(optFlds, 8) == true) {
|
|
|
|
MmsValue* confRev = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
MmsValue* confRev = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
|
|
|
|
|
|
|
|
if (MmsValue_getType(confRev) == MMS_UNSIGNED) {
|
|
|
|
if ((confRev == NULL) || (MmsValue_getType(confRev) != MMS_UNSIGNED)) {
|
|
|
|
matchingReport->confRev = MmsValue_toUint32(confRev);
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
matchingReport->hasConfRev = true;
|
|
|
|
printf("IED_CLIENT: received malformed report (confRev)\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
matchingReport->confRev = MmsValue_toUint32(confRev);
|
|
|
|
|
|
|
|
matchingReport->hasConfRev = true;
|
|
|
|
|
|
|
|
|
|
|
|
inclusionIndex++;
|
|
|
|
inclusionIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -489,12 +539,19 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
|
|
|
|
|
|
|
|
MmsValue* inclusion = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
MmsValue* inclusion = MmsValue_getElement(value, inclusionIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((inclusion == NULL) || (MmsValue_getType(inclusion) != MMS_BIT_STRING)) {
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: received malformed report (inclusion)\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int dataSetSize = MmsValue_getBitStringSize(inclusion);
|
|
|
|
int dataSetSize = MmsValue_getBitStringSize(inclusion);
|
|
|
|
|
|
|
|
|
|
|
|
int includedElements = MmsValue_getNumberOfSetBits(inclusion);
|
|
|
|
int includedElements = MmsValue_getNumberOfSetBits(inclusion);
|
|
|
|
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
printf("DEBUG_IED_CLIENT: Report includes %i data set elements of %i\n", includedElements,
|
|
|
|
printf("IED_CLIENT: Report includes %i data set elements of %i\n", includedElements,
|
|
|
|
dataSetSize);
|
|
|
|
dataSetSize);
|
|
|
|
|
|
|
|
|
|
|
|
int valueIndex = inclusionIndex + 1;
|
|
|
|
int valueIndex = inclusionIndex + 1;
|
|
|
@ -514,16 +571,23 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
MmsValue* dataSetElement = MmsValue_getElement(matchingReport->dataReferences, elementIndex);
|
|
|
|
MmsValue* dataSetElement = MmsValue_getElement(matchingReport->dataReferences, elementIndex);
|
|
|
|
|
|
|
|
|
|
|
|
if (dataSetElement == NULL) {
|
|
|
|
if (dataSetElement == NULL) {
|
|
|
|
dataSetElement = MmsValue_clone(MmsValue_getElement(value, valueIndex));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MmsValue_setElement(matchingReport->dataReferences, elementIndex, dataSetElement);
|
|
|
|
MmsValue* dataRefValue = MmsValue_getElement(value, valueIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((dataRefValue == NULL) || (MmsValue_getType(dataRefValue) != MMS_VISIBLE_STRING)) {
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: report contains invalid data reference\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
dataSetElement = MmsValue_clone(dataRefValue);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MmsValue_setElement(matchingReport->dataReferences, elementIndex, dataSetElement);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
valueIndex += 1;
|
|
|
|
valueIndex += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// valueIndex += includedElements;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
int i;
|
|
|
@ -556,19 +620,33 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
|
|
|
|
|
|
|
|
|
|
|
|
MmsValue* newElementValue = MmsValue_getElement(value, valueIndex);
|
|
|
|
MmsValue* newElementValue = MmsValue_getElement(value, valueIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (newElementValue == NULL) {
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: report is missing expected element value\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (dataSetElement == NULL)
|
|
|
|
if (dataSetElement == NULL)
|
|
|
|
MmsValue_setElement(dataSetValues, i, MmsValue_clone(newElementValue));
|
|
|
|
MmsValue_setElement(dataSetValues, i, MmsValue_clone(newElementValue));
|
|
|
|
else
|
|
|
|
else
|
|
|
|
MmsValue_update(dataSetElement, newElementValue);
|
|
|
|
MmsValue_update(dataSetElement, newElementValue);
|
|
|
|
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
printf("DEBUG_IED_CLIENT: update element value type: %i\n", MmsValue_getType(newElementValue));
|
|
|
|
printf("IED_CLIENT: update element value type: %i\n", MmsValue_getType(newElementValue));
|
|
|
|
|
|
|
|
|
|
|
|
valueIndex++;
|
|
|
|
valueIndex++;
|
|
|
|
|
|
|
|
|
|
|
|
if (hasReasonForInclusion) {
|
|
|
|
if (hasReasonForInclusion) {
|
|
|
|
MmsValue* reasonForInclusion = MmsValue_getElement(value, reasonForInclusionIndex);
|
|
|
|
MmsValue* reasonForInclusion = MmsValue_getElement(value, reasonForInclusionIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((reasonForInclusion == NULL) || (MmsValue_getType(reasonForInclusion) != MMS_BIT_STRING)) {
|
|
|
|
|
|
|
|
if (DEBUG_IED_CLIENT)
|
|
|
|
|
|
|
|
printf("IED_CLIENT: report contains invalid reason-for-inclusion\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto exit_function;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (MmsValue_getBitStringBit(reasonForInclusion, 1) == true)
|
|
|
|
if (MmsValue_getBitStringBit(reasonForInclusion, 1) == true)
|
|
|
|
matchingReport->reasonForInclusion[i] = IEC61850_REASON_DATA_CHANGE;
|
|
|
|
matchingReport->reasonForInclusion[i] = IEC61850_REASON_DATA_CHANGE;
|
|
|
|
else if (MmsValue_getBitStringBit(reasonForInclusion, 2) == true)
|
|
|
|
else if (MmsValue_getBitStringBit(reasonForInclusion, 2) == true)
|
|
|
|