- updated code format

pull/521/head
Michael Zillgith 1 year ago
parent f5af7c07c7
commit be15bfc393

@ -101,4 +101,3 @@ MmsServer_getRevision(MmsServer self)
} }
#endif /* MMS_IDENTIFY_SERVICE == 1 */ #endif /* MMS_IDENTIFY_SERVICE == 1 */

@ -50,7 +50,8 @@ MmsServerConnection_sendInformationReportSingleVariableVMDSpecific(MmsServerConn
uint32_t completeMessageSize = 1 + informationReportSize + BerEncoder_determineLengthSize(informationReportSize); uint32_t completeMessageSize = 1 + informationReportSize + BerEncoder_determineLengthSize(informationReportSize);
if (completeMessageSize > self->maxPduSize) { if (completeMessageSize > self->maxPduSize)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: report message too large %u (max = %u) -> skip message!\n", completeMessageSize, self->maxPduSize); printf("MMS_SERVER: report message too large %u (max = %u) -> skip message!\n", completeMessageSize, self->maxPduSize);
@ -113,12 +114,13 @@ MmsServerConnection_sendInformationReportListOfVariables(
LinkedList specElement = LinkedList_getNext(variableAccessDeclarations); LinkedList specElement = LinkedList_getNext(variableAccessDeclarations);
while (specElement != NULL) { while (specElement)
{
MmsVariableAccessSpecification* spec = (MmsVariableAccessSpecification*) specElement->data; MmsVariableAccessSpecification* spec = (MmsVariableAccessSpecification*) specElement->data;
uint32_t varSpecSize = BerEncoder_determineEncodedStringSize(spec->itemId); uint32_t varSpecSize = BerEncoder_determineEncodedStringSize(spec->itemId);
if (spec->domainId != NULL) if (spec->domainId)
varSpecSize += BerEncoder_determineEncodedStringSize(spec->domainId); varSpecSize += BerEncoder_determineEncodedStringSize(spec->domainId);
uint32_t sequenceSize = (varSpecSize + 1 + BerEncoder_determineLengthSize(varSpecSize)); uint32_t sequenceSize = (varSpecSize + 1 + BerEncoder_determineLengthSize(varSpecSize));
@ -131,12 +133,12 @@ MmsServerConnection_sendInformationReportListOfVariables(
uint32_t listOfVariableSize = 1 + BerEncoder_determineLengthSize(listOfVarSpecSize) + listOfVarSpecSize; uint32_t listOfVariableSize = 1 + BerEncoder_determineLengthSize(listOfVarSpecSize) + listOfVarSpecSize;
uint32_t accessResultSize = 0; uint32_t accessResultSize = 0;
LinkedList valueElement = LinkedList_getNext(values); LinkedList valueElement = LinkedList_getNext(values);
while (valueElement != NULL) { while (valueElement)
{
MmsValue* value = (MmsValue*) valueElement->data; MmsValue* value = (MmsValue*) valueElement->data;
accessResultSize += MmsValue_encodeMmsData(value, NULL, 0, false); accessResultSize += MmsValue_encodeMmsData(value, NULL, 0, false);
@ -155,7 +157,8 @@ MmsServerConnection_sendInformationReportListOfVariables(
uint32_t completeMessageSize = 1 + informationReportSize + BerEncoder_determineLengthSize(informationReportSize); uint32_t completeMessageSize = 1 + informationReportSize + BerEncoder_determineLengthSize(informationReportSize);
if (completeMessageSize > self->maxPduSize) { if (completeMessageSize > self->maxPduSize)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: report message too large %u (max = %u) -> skip message!\n", completeMessageSize, self->maxPduSize); printf("MMS_SERVER: report message too large %u (max = %u) -> skip message!\n", completeMessageSize, self->maxPduSize);
@ -183,13 +186,14 @@ MmsServerConnection_sendInformationReportListOfVariables(
specElement = LinkedList_getNext(variableAccessDeclarations); specElement = LinkedList_getNext(variableAccessDeclarations);
i = 0; i = 0;
while (specElement != NULL) { while (specElement)
{
MmsVariableAccessSpecification* spec = (MmsVariableAccessSpecification*) specElement->data; MmsVariableAccessSpecification* spec = (MmsVariableAccessSpecification*) specElement->data;
uint32_t varSpecSize = BerEncoder_determineEncodedStringSize(spec->itemId); uint32_t varSpecSize = BerEncoder_determineEncodedStringSize(spec->itemId);
if (spec->domainId != NULL) { if (spec->domainId)
{
varSpecSize += BerEncoder_determineEncodedStringSize(spec->domainId); varSpecSize += BerEncoder_determineEncodedStringSize(spec->domainId);
uint32_t varSpecSizeComplete = varSpecSize + BerEncoder_determineLengthSize(varSpecSize) + 1; uint32_t varSpecSizeComplete = varSpecSize + BerEncoder_determineLengthSize(varSpecSize) + 1;
uint32_t sequenceSize = varSpecSizeComplete + BerEncoder_determineLengthSize(varSpecSizeComplete) + 1; uint32_t sequenceSize = varSpecSizeComplete + BerEncoder_determineLengthSize(varSpecSizeComplete) + 1;
@ -200,14 +204,14 @@ MmsServerConnection_sendInformationReportListOfVariables(
bufPos = BerEncoder_encodeStringWithTag(0x1a, spec->domainId, buffer, bufPos); bufPos = BerEncoder_encodeStringWithTag(0x1a, spec->domainId, buffer, bufPos);
bufPos = BerEncoder_encodeStringWithTag(0x1a, spec->itemId, buffer, bufPos); bufPos = BerEncoder_encodeStringWithTag(0x1a, spec->itemId, buffer, bufPos);
} }
else { else
{
uint32_t sequenceSize = varSpecSize + BerEncoder_determineLengthSize(varSpecSize) + 1; uint32_t sequenceSize = varSpecSize + BerEncoder_determineLengthSize(varSpecSize) + 1;
bufPos = BerEncoder_encodeTL(0x30, sequenceSize, buffer, bufPos); bufPos = BerEncoder_encodeTL(0x30, sequenceSize, buffer, bufPos);
bufPos = BerEncoder_encodeTL(0xa0, varSpecSize, buffer, bufPos); /* vmd-specific */ bufPos = BerEncoder_encodeTL(0xa0, varSpecSize, buffer, bufPos); /* vmd-specific */
bufPos = BerEncoder_encodeStringWithTag(0x80, spec->itemId, buffer, bufPos); bufPos = BerEncoder_encodeStringWithTag(0x80, spec->itemId, buffer, bufPos);
} }
i++; i++;
specElement = LinkedList_getNext(specElement); specElement = LinkedList_getNext(specElement);
} }
@ -217,7 +221,8 @@ MmsServerConnection_sendInformationReportListOfVariables(
valueElement = LinkedList_getNext(values); valueElement = LinkedList_getNext(values);
while (valueElement != NULL) { while (valueElement)
{
MmsValue* value = (MmsValue*) valueElement->data; MmsValue* value = (MmsValue*) valueElement->data;
bufPos = MmsValue_encodeMmsData(value, buffer, bufPos, true); bufPos = MmsValue_encodeMmsData(value, buffer, bufPos, true);
@ -232,7 +237,8 @@ MmsServerConnection_sendInformationReportListOfVariables(
MmsServer_releaseTransmitBuffer(self->server); MmsServer_releaseTransmitBuffer(self->server);
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
if (handlerMode == false) { if (handlerMode == false)
{
IsoConnection_unlock(self->isoConnection); IsoConnection_unlock(self->isoConnection);
} }
#endif #endif
@ -260,8 +266,8 @@ MmsServerConnection_sendInformationReportVMDSpecific(MmsServerConnection self, c
/* iterate values list and add values to the accessResultList */ /* iterate values list and add values to the accessResultList */
LinkedList value = LinkedList_getNext(values); LinkedList value = LinkedList_getNext(values);
while (value != NULL) { while (value)
{
MmsValue* data = (MmsValue*) value->data; MmsValue* data = (MmsValue*) value->data;
accessResultSize += MmsValue_encodeMmsData(data, NULL, 0, false); accessResultSize += MmsValue_encodeMmsData(data, NULL, 0, false);
@ -279,7 +285,8 @@ MmsServerConnection_sendInformationReportVMDSpecific(MmsServerConnection self, c
uint32_t completeMessageSize = 1 + informationReportSize + BerEncoder_determineLengthSize(informationReportSize); uint32_t completeMessageSize = 1 + informationReportSize + BerEncoder_determineLengthSize(informationReportSize);
if (completeMessageSize > self->maxPduSize) { if (completeMessageSize > self->maxPduSize)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: report message too large %u (max = %u) -> skip message!\n", completeMessageSize, self->maxPduSize); printf("MMS_SERVER: report message too large %u (max = %u) -> skip message!\n", completeMessageSize, self->maxPduSize);
@ -296,7 +303,6 @@ MmsServerConnection_sendInformationReportVMDSpecific(MmsServerConnection self, c
uint8_t* buffer = reportBuffer->buffer; uint8_t* buffer = reportBuffer->buffer;
int bufPos = 0; int bufPos = 0;
/* encode */ /* encode */
bufPos = BerEncoder_encodeTL(0xa3, informationReportSize, buffer, bufPos); bufPos = BerEncoder_encodeTL(0xa3, informationReportSize, buffer, bufPos);
bufPos = BerEncoder_encodeTL(0xa0, informationReportContentSize, buffer, bufPos); bufPos = BerEncoder_encodeTL(0xa0, informationReportContentSize, buffer, bufPos);
@ -308,8 +314,8 @@ MmsServerConnection_sendInformationReportVMDSpecific(MmsServerConnection self, c
value = LinkedList_getNext(values); value = LinkedList_getNext(values);
while (value != NULL) { while (value)
{
MmsValue* data = (MmsValue*) value->data; MmsValue* data = (MmsValue*) value->data;
bufPos = MmsValue_encodeMmsData(data, buffer, bufPos, true); bufPos = MmsValue_encodeMmsData(data, buffer, bufPos, true);
@ -331,6 +337,3 @@ MmsServerConnection_sendInformationReportVMDSpecific(MmsServerConnection self, c
exit_function: exit_function:
return; return;
} }

@ -1,7 +1,7 @@
/* /*
* mms_journal.c * mms_journal.c
* *
* Copyright 2016 Michael Zillgith * Copyright 2016-2024 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -33,7 +33,11 @@ MmsJournal_create(const char* name)
MmsJournal self = (MmsJournal) GLOBAL_MALLOC(sizeof(struct sMmsJournal)); MmsJournal self = (MmsJournal) GLOBAL_MALLOC(sizeof(struct sMmsJournal));
if (self)
{
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->logStorage = NULL;
}
return self; return self;
} }
@ -41,6 +45,9 @@ MmsJournal_create(const char* name)
void void
MmsJournal_destroy(MmsJournal self) MmsJournal_destroy(MmsJournal self)
{ {
if (self)
{
GLOBAL_FREEMEM(self->name); GLOBAL_FREEMEM(self->name);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }

@ -57,8 +57,8 @@ entryCallback(void* parameter, uint64_t timestamp, uint64_t entryID, bool moreFo
{ {
JournalEncoder encoder = (JournalEncoder) parameter; JournalEncoder encoder = (JournalEncoder) parameter;
if (moreFollow) { if (moreFollow)
{
if (encoder->moreFollows) if (encoder->moreFollows)
return false; return false;
@ -84,7 +84,8 @@ entryDataCallback (void* parameter, const char* dataRef, uint8_t* data, int data
/* TODO check if entry is too long for buffer! */ /* TODO check if entry is too long for buffer! */
if (moreFollow) { if (moreFollow)
{
int bufPos = encoder->bufPos; int bufPos = encoder->bufPos;
uint32_t dataRefStrLen = strlen(dataRef); uint32_t dataRefStrLen = strlen(dataRef);
@ -112,7 +113,8 @@ entryDataCallback (void* parameter, const char* dataRef, uint8_t* data, int data
uint32_t totalLen = firstVariableLen + secondVariableLen; uint32_t totalLen = firstVariableLen + secondVariableLen;
if ((int) (bufPos + totalLen) > encoder->maxSize) { if ((int) (bufPos + totalLen) > encoder->maxSize)
{
encoder->moreFollows = true; encoder->moreFollows = true;
encoder->bufPos = encoder->currentEntryBufPos; /* remove last entry */ encoder->bufPos = encoder->currentEntryBufPos; /* remove last entry */
return false; return false;
@ -137,7 +139,8 @@ entryDataCallback (void* parameter, const char* dataRef, uint8_t* data, int data
encoder->bufPos = bufPos; encoder->bufPos = bufPos;
} }
else { else
{
int dataContentLen = encoder->bufPos - (encoder->currentEntryBufPos + 48); int dataContentLen = encoder->bufPos - (encoder->currentEntryBufPos + 48);
int journalVariablesLen = 1 + BerEncoder_determineLengthSize(dataContentLen) + dataContentLen; int journalVariablesLen = 1 + BerEncoder_determineLengthSize(dataContentLen) + dataContentLen;
@ -191,19 +194,22 @@ parseStringWithMaxLength(char* filename, int maxLength, uint8_t* buffer, int* bu
uint8_t tag = buffer[(*bufPos)++]; uint8_t tag = buffer[(*bufPos)++];
int length; int length;
if (tag != 0x1a) { if (tag != 0x1a)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return false; return false;
} }
*bufPos = BerDecoder_decodeLength(buffer, &length, *bufPos, maxBufPos); *bufPos = BerDecoder_decodeLength(buffer, &length, *bufPos, maxBufPos);
if (*bufPos < 0) { if (*bufPos < 0)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return false; return false;
} }
if (length > maxLength) { if (length > maxLength)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
return false; return false;
} }
@ -243,30 +249,34 @@ mmsServer_handleReadJournalRequest(
bool hasTimeSpec = false; bool hasTimeSpec = false;
bool hasEntrySpec = false; bool hasEntrySpec = false;
while (bufPos < maxBufPos) { while (bufPos < maxBufPos)
{
uint8_t tag = requestBuffer[bufPos++]; uint8_t tag = requestBuffer[bufPos++];
int length; int length;
bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos); bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
if (bufPos < 0) { if (bufPos < 0)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return; return;
} }
switch (tag) { switch (tag)
{
case 0xa0: /* journalName */ case 0xa0: /* journalName */
{ {
uint8_t objectIdTag = requestBuffer[bufPos++]; uint8_t objectIdTag = requestBuffer[bufPos++];
bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos); bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
if (bufPos < 0) { if (bufPos < 0)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return; return;
} }
switch (objectIdTag) { switch (objectIdTag)
{
case 0xa1: /* domain-specific */ case 0xa1: /* domain-specific */
if (!parseStringWithMaxLength(domainId, 64, requestBuffer, &bufPos, bufPos + length, invokeId, response)) { if (!parseStringWithMaxLength(domainId, 64, requestBuffer, &bufPos, bufPos + length, invokeId, response)) {
@ -294,20 +304,22 @@ mmsServer_handleReadJournalRequest(
{ {
uint8_t subTag = requestBuffer[bufPos++]; uint8_t subTag = requestBuffer[bufPos++];
if (subTag != 0x80) { if (subTag != 0x80)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response);
return; return;
} }
bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos); bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
if (bufPos < 0) { if (bufPos < 0)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return; return;
} }
if ((length == 4) || (length == 6)) { if ((length == 4) || (length == 6))
{
rangeStart.type = MMS_BINARY_TIME; rangeStart.type = MMS_BINARY_TIME;
rangeStart.value.binaryTime.size = length; rangeStart.value.binaryTime.size = length;
@ -315,7 +327,8 @@ mmsServer_handleReadJournalRequest(
hasRangeStartSpec = true; hasRangeStartSpec = true;
} }
else { else
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
return; /* forward request to implementation class */ return; /* forward request to implementation class */
} }
@ -329,19 +342,22 @@ mmsServer_handleReadJournalRequest(
{ {
uint8_t subTag = requestBuffer[bufPos++]; uint8_t subTag = requestBuffer[bufPos++];
if (subTag != 0x80) { if (subTag != 0x80)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER, response);
return; return;
} }
bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos); bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
if (bufPos < 0) { if (bufPos < 0)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return; return;
} }
if ((length == 4) || (length == 6)) { if ((length == 4) || (length == 6))
{
rangeStop.type = MMS_BINARY_TIME; rangeStop.type = MMS_BINARY_TIME;
rangeStop.value.binaryTime.size = length; rangeStop.value.binaryTime.size = length;
@ -349,9 +365,10 @@ mmsServer_handleReadJournalRequest(
hasRangeStopSpec = true; hasRangeStopSpec = true;
} }
else { else
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
return; /* forward request to implementation class */ return;
} }
bufPos += length; bufPos += length;
@ -363,20 +380,24 @@ mmsServer_handleReadJournalRequest(
{ {
int maxSubBufPos = bufPos + length; int maxSubBufPos = bufPos + length;
while (bufPos < maxSubBufPos) { while (bufPos < maxSubBufPos)
{
uint8_t subTag = requestBuffer[bufPos++]; uint8_t subTag = requestBuffer[bufPos++];
bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos); bufPos = BerDecoder_decodeLength(requestBuffer, &length, bufPos, maxBufPos);
if (bufPos < 0) { if (bufPos < 0)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return; return;
} }
switch (subTag) { switch (subTag)
{
case 0x80: /* timeSpecification */ case 0x80: /* timeSpecification */
if ((length == 4) || (length == 6)) { if ((length == 4) || (length == 6))
{
rangeStart.type = MMS_BINARY_TIME; rangeStart.type = MMS_BINARY_TIME;
rangeStart.value.binaryTime.size = length; rangeStart.value.binaryTime.size = length;
@ -384,7 +405,8 @@ mmsServer_handleReadJournalRequest(
hasTimeSpec = true; hasTimeSpec = true;
} }
else { else
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
return; return;
} }
@ -393,13 +415,15 @@ mmsServer_handleReadJournalRequest(
case 0x81: /* entrySpecification */ case 0x81: /* entrySpecification */
if (length <= entrySpec.value.octetString.maxSize) { if (length <= entrySpec.value.octetString.maxSize)
{
memcpy(entrySpec.value.octetString.buf, requestBuffer + bufPos, length); memcpy(entrySpec.value.octetString.buf, requestBuffer + bufPos, length);
entrySpec.value.octetString.size = length; entrySpec.value.octetString.size = length;
hasEntrySpec = true; hasEntrySpec = true;
} }
else { else
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
return; return;
} }
@ -424,7 +448,8 @@ mmsServer_handleReadJournalRequest(
} }
/* check if required fields are present */ /* check if required fields are present */
if (hasNames == false) { if (hasNames == false)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: readJournal missing journal name\n"); printf("MMS_SERVER: readJournal missing journal name\n");
@ -439,7 +464,8 @@ mmsServer_handleReadJournalRequest(
MmsDomain* mmsDomain = MmsDevice_getDomain(mmsDevice, domainId); MmsDomain* mmsDomain = MmsDevice_getDomain(mmsDevice, domainId);
if (mmsDomain == NULL) { if (mmsDomain == NULL)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: readJournal domain %s not found\n", domainId); printf("MMS_SERVER: readJournal domain %s not found\n", domainId);
@ -450,7 +476,8 @@ mmsServer_handleReadJournalRequest(
MmsJournal mmsJournal = MmsDomain_getJournal(mmsDomain, logName); MmsJournal mmsJournal = MmsDomain_getJournal(mmsDomain, logName);
if (mmsJournal == NULL) { if (mmsJournal == NULL)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: readJournal journal %s not found\n", logName); printf("MMS_SERVER: readJournal journal %s not found\n", logName);
@ -485,17 +512,20 @@ mmsServer_handleReadJournalRequest(
LogStorage logStorage = mmsJournal->logStorage; LogStorage logStorage = mmsJournal->logStorage;
if (logStorage != NULL) { if (logStorage)
{
if (hasRangeStartSpec && hasRangeStopSpec) { if (hasRangeStartSpec && hasRangeStopSpec)
{
LogStorage_getEntries(logStorage, MmsValue_getBinaryTimeAsUtcMs(&rangeStart), MmsValue_getBinaryTimeAsUtcMs(&rangeStop), LogStorage_getEntries(logStorage, MmsValue_getBinaryTimeAsUtcMs(&rangeStart), MmsValue_getBinaryTimeAsUtcMs(&rangeStop),
entryCallback, entryDataCallback, &encoder); entryCallback, entryDataCallback, &encoder);
} }
else if (hasEntrySpec && hasTimeSpec) { else if (hasEntrySpec && hasTimeSpec)
{
LogStorage_getEntriesAfter(logStorage, MmsValue_getBinaryTimeAsUtcMs(&rangeStart), *((uint64_t*) entryIdBuf), LogStorage_getEntriesAfter(logStorage, MmsValue_getBinaryTimeAsUtcMs(&rangeStart), *((uint64_t*) entryIdBuf),
entryCallback, entryDataCallback, &encoder); entryCallback, entryDataCallback, &encoder);
} }
else { else
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: readJournal missing valid argument combination\n"); printf("MMS_SERVER: readJournal missing valid argument combination\n");
@ -503,7 +533,6 @@ mmsServer_handleReadJournalRequest(
return; return;
} }
} }
/* actual encoding will happen in callback handler. When getEntries returns the data is /* actual encoding will happen in callback handler. When getEntries returns the data is
* already encoded in the buffer. * already encoded in the buffer.

@ -28,27 +28,35 @@
MmsNamedVariableListEntry MmsNamedVariableListEntry
MmsNamedVariableListEntry_create(MmsAccessSpecifier accessSpecifier) MmsNamedVariableListEntry_create(MmsAccessSpecifier accessSpecifier)
{ {
MmsNamedVariableListEntry listEntry = (MmsNamedVariableListEntry) GLOBAL_MALLOC(sizeof(MmsAccessSpecifier)); MmsNamedVariableListEntry self = (MmsNamedVariableListEntry) GLOBAL_MALLOC(sizeof(MmsAccessSpecifier));
listEntry->domain = accessSpecifier.domain; if (self)
listEntry->variableName = StringUtils_copyString(accessSpecifier.variableName); {
listEntry->arrayIndex = accessSpecifier.arrayIndex; self->domain = accessSpecifier.domain;
self->variableName = StringUtils_copyString(accessSpecifier.variableName);
self->arrayIndex = accessSpecifier.arrayIndex;
if (accessSpecifier.componentName != NULL) if (accessSpecifier.componentName)
listEntry->componentName = StringUtils_copyString(accessSpecifier.componentName); self->componentName = StringUtils_copyString(accessSpecifier.componentName);
else else
listEntry->componentName = NULL; self->componentName = NULL;
}
return listEntry; return self;
} }
void void
MmsNamedVariableListEntry_destroy(MmsNamedVariableListEntry self) MmsNamedVariableListEntry_destroy(MmsNamedVariableListEntry self)
{ {
if (self)
{
GLOBAL_FREEMEM(self->variableName); GLOBAL_FREEMEM(self->variableName);
if (self->componentName) if (self->componentName)
GLOBAL_FREEMEM(self->componentName); GLOBAL_FREEMEM(self->componentName);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
MmsDomain* MmsDomain*
@ -58,7 +66,8 @@ MmsNamedVariableListEntry_getDomain(MmsNamedVariableListEntry self)
} }
char* char*
MmsNamedVariableListEntry_getVariableName(MmsNamedVariableListEntry self) { MmsNamedVariableListEntry_getVariableName(MmsNamedVariableListEntry self)
{
return self->variableName; return self->variableName;
} }
@ -67,10 +76,13 @@ MmsNamedVariableList_create(MmsDomain* domain, char* name, bool deletable)
{ {
MmsNamedVariableList self = (MmsNamedVariableList) GLOBAL_MALLOC(sizeof(struct sMmsNamedVariableList)); MmsNamedVariableList self = (MmsNamedVariableList) GLOBAL_MALLOC(sizeof(struct sMmsNamedVariableList));
if (self)
{
self->deletable = deletable; self->deletable = deletable;
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->listOfVariables = LinkedList_create(); self->listOfVariables = LinkedList_create();
self->domain = domain; self->domain = domain;
}
return self; return self;
} }
@ -115,7 +127,10 @@ deleteVariableListEntry(void* listEntry)
void void
MmsNamedVariableList_destroy(MmsNamedVariableList self) MmsNamedVariableList_destroy(MmsNamedVariableList self)
{ {
if (self)
{
LinkedList_destroyDeep(self->listOfVariables, deleteVariableListEntry); LinkedList_destroyDeep(self->listOfVariables, deleteVariableListEntry);
GLOBAL_FREEMEM(self->name); GLOBAL_FREEMEM(self->name);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }

@ -1,7 +1,7 @@
/* /*
* mms_named_variable_list_service.c * mms_named_variable_list_service.c
* *
* Copyright 2013-2023 Michael Zillgith * Copyright 2013-2024 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -54,7 +54,8 @@ mmsServer_callVariableListChangedHandler(MmsVariableListAccessType accessType, M
{ {
MmsServer self = connection->server; MmsServer self = connection->server;
if (self->variableListAccessHandler != NULL) { if (self->variableListAccessHandler)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: call MmsNamedVariableListAccessHandler for new list %s\n", listName); printf("MMS_SERVER: call MmsNamedVariableListAccessHandler for new list %s\n", listName);
@ -125,7 +126,8 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, maxBufPos); asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, maxBufPos);
if (rval.code != RC_OK) { if (rval.code != RC_OK)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_function; goto exit_function;
} }
@ -136,7 +138,8 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
{ {
request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.deleteNamedVariableList); request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.deleteNamedVariableList);
} }
else { else
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_function; goto exit_function;
} }
@ -154,7 +157,8 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
MmsDevice* device = MmsServer_getDevice(connection->server); MmsDevice* device = MmsServer_getDevice(connection->server);
if (scopeOfDelete == DeleteNamedVariableListRequest__scopeOfDelete_specific) { if (scopeOfDelete == DeleteNamedVariableListRequest__scopeOfDelete_specific)
{
MmsError serviceError = MMS_ERROR_NONE; MmsError serviceError = MMS_ERROR_NONE;
int numberMatched = 0; int numberMatched = 0;
@ -164,8 +168,10 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
int i; int i;
for (i = 0; i < numberItems; i++) { for (i = 0; i < numberItems; i++)
if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_domainspecific) { {
if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_domainspecific)
{
char domainName[65]; char domainName[65];
char listName[65]; char listName[65];
@ -177,18 +183,20 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
MmsDomain* domain = MmsDevice_getDomain(device, domainName); MmsDomain* domain = MmsDevice_getDomain(device, domainName);
if (domain != NULL) { if (domain)
{
MmsNamedVariableList variableList = MmsDomain_getNamedVariableList(domain, listName); MmsNamedVariableList variableList = MmsDomain_getNamedVariableList(domain, listName);
if (variableList != NULL) { if (variableList)
{
numberMatched++; numberMatched++;
if (MmsNamedVariableList_isDeletable(variableList)) { if (MmsNamedVariableList_isDeletable(variableList))
{
MmsError deleteError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_DOMAIN_SPECIFIC, domain, listName, connection); MmsError deleteError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_DOMAIN_SPECIFIC, domain, listName, connection);
if (deleteError == MMS_ERROR_NONE) { if (deleteError == MMS_ERROR_NONE)
{
MmsDomain_deleteNamedVariableList(domain, listName); MmsDomain_deleteNamedVariableList(domain, listName);
numberDeleted++; numberDeleted++;
} }
@ -198,7 +206,8 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
} }
} }
} }
else if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_aaspecific) { else if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_aaspecific)
{
char listName[65]; char listName[65];
mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.aaspecific, mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.aaspecific,
@ -206,12 +215,14 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
MmsNamedVariableList variableList = MmsServerConnection_getNamedVariableList(connection, listName); MmsNamedVariableList variableList = MmsServerConnection_getNamedVariableList(connection, listName);
if (variableList != NULL) { if (variableList)
{
numberMatched++; numberMatched++;
MmsError deleteError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_ASSOCIATION_SPECIFIC, NULL, listName, connection); MmsError deleteError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_ASSOCIATION_SPECIFIC, NULL, listName, connection);
if (deleteError == MMS_ERROR_NONE) { if (deleteError == MMS_ERROR_NONE)
{
numberDeleted++; numberDeleted++;
MmsServerConnection_deleteNamedVariableList(connection, listName); MmsServerConnection_deleteNamedVariableList(connection, listName);
} }
@ -219,7 +230,8 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
serviceError = deleteError; serviceError = deleteError;
} }
} }
else if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_vmdspecific) { else if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_vmdspecific)
{
char listName[65]; char listName[65];
mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.vmdspecific, mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.vmdspecific,
@ -227,12 +239,14 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
MmsNamedVariableList variableList = mmsServer_getNamedVariableListWithName(device->namedVariableLists, listName); MmsNamedVariableList variableList = mmsServer_getNamedVariableListWithName(device->namedVariableLists, listName);
if (variableList != NULL) { if (variableList)
{
numberMatched++; numberMatched++;
MmsError deleteError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_VMD_SPECIFIC, NULL, listName, connection); MmsError deleteError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_VMD_SPECIFIC, NULL, listName, connection);
if (deleteError == MMS_ERROR_NONE) { if (deleteError == MMS_ERROR_NONE)
{
numberDeleted++; numberDeleted++;
mmsServer_deleteVariableList(device->namedVariableLists, listName); mmsServer_deleteVariableList(device->namedVariableLists, listName);
} }
@ -247,7 +261,8 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
else else
createServiceErrorDeleteVariableLists(invokeId, response, serviceError, numberDeleted); createServiceErrorDeleteVariableLists(invokeId, response, serviceError, numberDeleted);
} }
else { else
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED);
} }
@ -292,14 +307,16 @@ checkIfVariableExists(MmsDevice* device, MmsAccessSpecifier* accessSpecifier)
if (variableSpec == NULL) if (variableSpec == NULL)
return false; return false;
if (accessSpecifier->arrayIndex != -1) { if (accessSpecifier->arrayIndex != -1)
{
if (variableSpec->type != MMS_ARRAY) if (variableSpec->type != MMS_ARRAY)
return false; return false;
if (accessSpecifier->arrayIndex >= variableSpec->typeSpec.array.elementCount) if (accessSpecifier->arrayIndex >= variableSpec->typeSpec.array.elementCount)
return false; return false;
if (accessSpecifier->componentName != NULL) { if (accessSpecifier->componentName)
{
variableSpec = variableSpec->typeSpec.array.elementTypeSpec; variableSpec = variableSpec->typeSpec.array.elementTypeSpec;
if (MmsVariableSpecification_getNamedVariableRecursive(variableSpec, accessSpecifier->componentName) == NULL) if (MmsVariableSpecification_getNamedVariableRecursive(variableSpec, accessSpecifier->componentName) == NULL)
@ -323,9 +340,11 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
printf("MMS_SERVER: create-named-variable-list (%i variable(s) | max=%i)\n", variableCount, server->maxDataSetEntries); printf("MMS_SERVER: create-named-variable-list (%i variable(s) | max=%i)\n", variableCount, server->maxDataSetEntries);
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
if ((variableCount == 0 ) || (variableCount > server->maxDataSetEntries)) { if ((variableCount == 0 ) || (variableCount > server->maxDataSetEntries))
{
#else #else
if ((variableCount == 0 ) || (variableCount > CONFIG_MMS_MAX_NUMBER_OF_DATA_SET_MEMBERS)) { if ((variableCount == 0 ) || (variableCount > CONFIG_MMS_MAX_NUMBER_OF_DATA_SET_MEMBERS))
{
#endif #endif
*mmsError = MMS_ERROR_DEFINITION_OTHER; *mmsError = MMS_ERROR_DEFINITION_OTHER;
goto exit_function; goto exit_function;
@ -334,7 +353,8 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
namedVariableList = MmsNamedVariableList_create(domain, variableListName, true); namedVariableList = MmsNamedVariableList_create(domain, variableListName, true);
int i; int i;
for (i = 0; i < variableCount; i++) { for (i = 0; i < variableCount; i++)
{
VariableSpecification_t* varSpec = VariableSpecification_t* varSpec =
&request->listOfVariable.list.array[i]->variableSpecification; &request->listOfVariable.list.array[i]->variableSpecification;
@ -344,10 +364,10 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
char* componentName = NULL; char* componentName = NULL;
/* Handle alternate access specification - for array element definition */ /* Handle alternate access specification - for array element definition */
if (request->listOfVariable.list.array[i]->alternateAccess != NULL) { if (request->listOfVariable.list.array[i]->alternateAccess)
{
if (request->listOfVariable.list.array[i]->alternateAccess->list.count != 1) { if (request->listOfVariable.list.array[i]->alternateAccess->list.count != 1)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: create-named-variable list - only one alternate access specification allowed!\n"); printf("MMS_SERVER: create-named-variable list - only one alternate access specification allowed!\n");
@ -355,8 +375,8 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
namedVariableList = NULL; namedVariableList = NULL;
break; break;
} }
else { else
{
struct AlternateAccess__Member* alternateAccess = struct AlternateAccess__Member* alternateAccess =
request->listOfVariable.list.array[i]->alternateAccess->list.array[0]; request->listOfVariable.list.array[i]->alternateAccess->list.array[0];
@ -368,14 +388,16 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
asn_INTEGER2long(&(alternateAccess->choice.unnamed->choice.selectAlternateAccess.accessSelection.choice.index), asn_INTEGER2long(&(alternateAccess->choice.unnamed->choice.selectAlternateAccess.accessSelection.choice.index),
&arrayIndex); &arrayIndex);
if (alternateAccess->choice.unnamed->choice.selectAlternateAccess.alternateAccess) { if (alternateAccess->choice.unnamed->choice.selectAlternateAccess.alternateAccess)
{
componentNameBuf[0] = 0; componentNameBuf[0] = 0;
componentName = mmsMsg_getComponentNameFromAlternateAccess( componentName = mmsMsg_getComponentNameFromAlternateAccess(
alternateAccess->choice.unnamed->choice.selectAlternateAccess.alternateAccess, alternateAccess->choice.unnamed->choice.selectAlternateAccess.alternateAccess,
componentNameBuf, 0); componentNameBuf, 0);
} }
else { else
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: create-named-variable-list - component specification is missing!\n"); printf("MMS_SERVER: create-named-variable-list - component specification is missing!\n");
} }
@ -387,7 +409,8 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
{ {
asn_INTEGER2long(&(alternateAccess->choice.unnamed->choice.selectAccess.choice.index), &arrayIndex); asn_INTEGER2long(&(alternateAccess->choice.unnamed->choice.selectAccess.choice.index), &arrayIndex);
} }
else { else
{
MmsNamedVariableList_destroy(namedVariableList); MmsNamedVariableList_destroy(namedVariableList);
namedVariableList = NULL; namedVariableList = NULL;
*mmsError = MMS_ERROR_DEFINITION_INVALID_ADDRESS; *mmsError = MMS_ERROR_DEFINITION_INVALID_ADDRESS;
@ -396,8 +419,8 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
} }
} }
if (varSpec->present == VariableSpecification_PR_name) { if (varSpec->present == VariableSpecification_PR_name)
{
char variableName[65]; char variableName[65];
char domainId[65]; char domainId[65];
@ -422,14 +445,15 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
printf("MMS SERVER: add named variable list entry: %s/%s(%li)%s\n", MmsDomain_getName(elementDomain), variableName, arrayIndex, componentName); printf("MMS SERVER: add named variable list entry: %s/%s(%li)%s\n", MmsDomain_getName(elementDomain), variableName, arrayIndex, componentName);
/* check if element exists */ /* check if element exists */
if (checkIfVariableExists(device, &accessSpecifier) == true) { if (checkIfVariableExists(device, &accessSpecifier) == true)
{
MmsNamedVariableListEntry variable = MmsNamedVariableListEntry variable =
MmsNamedVariableListEntry_create(accessSpecifier); MmsNamedVariableListEntry_create(accessSpecifier);
MmsNamedVariableList_addVariable(namedVariableList, variable); MmsNamedVariableList_addVariable(namedVariableList, variable);
} }
else { else
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: failed - variable does not exist!\n"); printf("MMS_SERVER: failed - variable does not exist!\n");
@ -439,7 +463,8 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device,
*mmsError = MMS_ERROR_DEFINITION_OBJECT_UNDEFINED; *mmsError = MMS_ERROR_DEFINITION_OBJECT_UNDEFINED;
} }
} }
else { else
{
MmsNamedVariableList_destroy(namedVariableList); MmsNamedVariableList_destroy(namedVariableList);
namedVariableList = NULL; namedVariableList = NULL;
*mmsError = MMS_ERROR_DEFINITION_INVALID_ADDRESS; *mmsError = MMS_ERROR_DEFINITION_INVALID_ADDRESS;
@ -467,7 +492,8 @@ mmsServer_handleDefineNamedVariableListRequest(
asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, maxBufPos); asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, maxBufPos);
if (rval.code != RC_OK) { if (rval.code != RC_OK)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_free_struct; goto exit_free_struct;
} }
@ -478,18 +504,20 @@ mmsServer_handleDefineNamedVariableListRequest(
{ {
request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.defineNamedVariableList); request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.defineNamedVariableList);
} }
else { else
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_free_struct; goto exit_free_struct;
} }
MmsDevice* device = MmsServer_getDevice(connection->server); MmsDevice* device = MmsServer_getDevice(connection->server);
if (request->variableListName.present == ObjectName_PR_domainspecific) { if (request->variableListName.present == ObjectName_PR_domainspecific)
{
char domainName[65]; char domainName[65];
if (request->variableListName.choice.domainspecific.domainId.size > 64) { if (request->variableListName.choice.domainspecific.domainId.size > 64)
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
goto exit_free_struct; goto exit_free_struct;
} }
@ -500,19 +528,23 @@ mmsServer_handleDefineNamedVariableListRequest(
MmsDomain* domain = MmsDevice_getDomain(device, domainName); MmsDomain* domain = MmsDevice_getDomain(device, domainName);
if (domain == NULL) { if (domain == NULL)
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
goto exit_free_struct; goto exit_free_struct;
} }
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
if (LinkedList_size(domain->namedVariableLists) < connection->server->maxDomainSpecificDataSets) { if (LinkedList_size(domain->namedVariableLists) < connection->server->maxDomainSpecificDataSets)
{
#else #else
if (LinkedList_size(domain->namedVariableLists) < CONFIG_MMS_MAX_NUMBER_OF_DOMAIN_SPECIFIC_DATA_SETS) { if (LinkedList_size(domain->namedVariableLists) < CONFIG_MMS_MAX_NUMBER_OF_DOMAIN_SPECIFIC_DATA_SETS)
{
#endif #endif
char variableListName[65]; char variableListName[65];
if (request->variableListName.choice.domainspecific.itemId.size > 64) { if (request->variableListName.choice.domainspecific.itemId.size > 64)
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
goto exit_free_struct; goto exit_free_struct;
} }
@ -521,24 +553,28 @@ mmsServer_handleDefineNamedVariableListRequest(
request->variableListName.choice.domainspecific.itemId.buf, request->variableListName.choice.domainspecific.itemId.buf,
request->variableListName.choice.domainspecific.itemId.size, sizeof(variableListName)); request->variableListName.choice.domainspecific.itemId.size, sizeof(variableListName));
if (MmsDomain_getNamedVariableList(domain, variableListName) != NULL) { if (MmsDomain_getNamedVariableList(domain, variableListName))
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS);
} }
else { else
{
MmsError mmsError; MmsError mmsError;
MmsNamedVariableList namedVariableList = createNamedVariableList(connection->server, domain, device, MmsNamedVariableList namedVariableList = createNamedVariableList(connection->server, domain, device,
request, variableListName, &mmsError); request, variableListName, &mmsError);
if (namedVariableList != NULL) { if (namedVariableList)
{
mmsError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_CREATE, MMS_DOMAIN_SPECIFIC, domain, variableListName, connection); mmsError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_CREATE, MMS_DOMAIN_SPECIFIC, domain, variableListName, connection);
if (mmsError == MMS_ERROR_NONE) { if (mmsError == MMS_ERROR_NONE)
{
MmsDomain_addNamedVariableList(domain, namedVariableList); MmsDomain_addNamedVariableList(domain, namedVariableList);
createDefineNamedVariableListResponse(invokeId, response); createDefineNamedVariableListResponse(invokeId, response);
} }
else { else
{
MmsNamedVariableList_destroy(namedVariableList); MmsNamedVariableList_destroy(namedVariableList);
mmsMsg_createServiceErrorPdu(invokeId, response, mmsError); mmsMsg_createServiceErrorPdu(invokeId, response, mmsError);
} }
@ -549,20 +585,21 @@ mmsServer_handleDefineNamedVariableListRequest(
} }
else else
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_CAPABILITY_UNAVAILABLE); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_CAPABILITY_UNAVAILABLE);
} }
else if (request->variableListName.present == ObjectName_PR_aaspecific) { else if (request->variableListName.present == ObjectName_PR_aaspecific)
{
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
if (LinkedList_size(connection->namedVariableLists) < connection->server->maxAssociationSpecificDataSets) { if (LinkedList_size(connection->namedVariableLists) < connection->server->maxAssociationSpecificDataSets)
{
#else #else
if (LinkedList_size(connection->namedVariableLists) < CONFIG_MMS_MAX_NUMBER_OF_ASSOCIATION_SPECIFIC_DATA_SETS) { if (LinkedList_size(connection->namedVariableLists) < CONFIG_MMS_MAX_NUMBER_OF_ASSOCIATION_SPECIFIC_DATA_SETS)
{
#endif #endif
char variableListName[65]; char variableListName[65];
if (request->variableListName.choice.aaspecific.size > 64) { if (request->variableListName.choice.aaspecific.size > 64)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
goto exit_free_struct; goto exit_free_struct;
} }
@ -571,26 +608,29 @@ mmsServer_handleDefineNamedVariableListRequest(
request->variableListName.choice.aaspecific.buf, request->variableListName.choice.aaspecific.buf,
request->variableListName.choice.aaspecific.size, sizeof(variableListName)); request->variableListName.choice.aaspecific.size, sizeof(variableListName));
if (MmsServerConnection_getNamedVariableList(connection, variableListName) != NULL) { if (MmsServerConnection_getNamedVariableList(connection, variableListName))
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS);
} }
else { else
{
MmsError mmsError; MmsError mmsError;
MmsNamedVariableList namedVariableList = createNamedVariableList(connection->server, NULL, device, MmsNamedVariableList namedVariableList = createNamedVariableList(connection->server, NULL, device,
request, variableListName, &mmsError); request, variableListName, &mmsError);
if (namedVariableList != NULL) { if (namedVariableList)
{
if (mmsServer_callVariableListChangedHandler(MMS_VARLIST_CREATE, MMS_ASSOCIATION_SPECIFIC, NULL, variableListName, connection) == MMS_ERROR_NONE) { if (mmsServer_callVariableListChangedHandler(MMS_VARLIST_CREATE, MMS_ASSOCIATION_SPECIFIC, NULL, variableListName, connection) == MMS_ERROR_NONE)
{
MmsServerConnection_addNamedVariableList(connection, namedVariableList); MmsServerConnection_addNamedVariableList(connection, namedVariableList);
createDefineNamedVariableListResponse(invokeId, response); createDefineNamedVariableListResponse(invokeId, response);
} }
else { else
{
MmsNamedVariableList_destroy(namedVariableList); MmsNamedVariableList_destroy(namedVariableList);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED);
} }
} }
else else
mmsMsg_createServiceErrorPdu(invokeId, response, mmsError); mmsMsg_createServiceErrorPdu(invokeId, response, mmsError);
@ -599,14 +639,16 @@ mmsServer_handleDefineNamedVariableListRequest(
else else
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_CAPABILITY_UNAVAILABLE); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_CAPABILITY_UNAVAILABLE);
} }
else if (request->variableListName.present == ObjectName_PR_vmdspecific) { else if (request->variableListName.present == ObjectName_PR_vmdspecific)
{
LinkedList vmdScopeNVLs = MmsDevice_getNamedVariableLists(connection->server->device); LinkedList vmdScopeNVLs = MmsDevice_getNamedVariableLists(connection->server->device);
if (LinkedList_size(vmdScopeNVLs) < CONFIG_MMS_MAX_NUMBER_OF_VMD_SPECIFIC_DATA_SETS) { if (LinkedList_size(vmdScopeNVLs) < CONFIG_MMS_MAX_NUMBER_OF_VMD_SPECIFIC_DATA_SETS)
{
char variableListName[65]; char variableListName[65];
if (request->variableListName.choice.vmdspecific.size > 64) { if (request->variableListName.choice.vmdspecific.size > 64)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
goto exit_free_struct; goto exit_free_struct;
} }
@ -615,27 +657,31 @@ mmsServer_handleDefineNamedVariableListRequest(
request->variableListName.choice.vmdspecific.buf, request->variableListName.choice.vmdspecific.buf,
request->variableListName.choice.vmdspecific.size, sizeof(variableListName)); request->variableListName.choice.vmdspecific.size, sizeof(variableListName));
if (mmsServer_getNamedVariableListWithName(MmsDevice_getNamedVariableLists(connection->server->device), variableListName) != NULL) { if (mmsServer_getNamedVariableListWithName(MmsDevice_getNamedVariableLists(connection->server->device), variableListName))
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS);
} }
else { else
{
MmsError mmsError; MmsError mmsError;
MmsNamedVariableList namedVariableList = createNamedVariableList(connection->server, NULL, device, MmsNamedVariableList namedVariableList = createNamedVariableList(connection->server, NULL, device,
request, variableListName, &mmsError); request, variableListName, &mmsError);
if (namedVariableList != NULL) { if (namedVariableList)
{
if (mmsServer_callVariableListChangedHandler(MMS_VARLIST_CREATE, MMS_VMD_SPECIFIC, NULL, variableListName, connection) if (mmsServer_callVariableListChangedHandler(MMS_VARLIST_CREATE, MMS_VMD_SPECIFIC, NULL, variableListName, connection)
== MMS_ERROR_NONE) { == MMS_ERROR_NONE)
{
LinkedList_add(vmdScopeNVLs, (void*) namedVariableList); LinkedList_add(vmdScopeNVLs, (void*) namedVariableList);
createDefineNamedVariableListResponse(invokeId, response); createDefineNamedVariableListResponse(invokeId, response);
} }
else { else
{
MmsNamedVariableList_destroy(namedVariableList); MmsNamedVariableList_destroy(namedVariableList);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED);
} }
} }
} }
} }
@ -708,11 +754,13 @@ createGetNamedVariableListAttributesResponse(int invokeId, ByteBuffer* response,
varListResponse->listOfVariable.list.array[i]->variableSpecification.choice.name.choice. varListResponse->listOfVariable.list.array[i]->variableSpecification.choice.name.choice.
domainspecific.itemId.size = strlen(variableEntry->variableName); domainspecific.itemId.size = strlen(variableEntry->variableName);
if (variableEntry->arrayIndex != -1) { if (variableEntry->arrayIndex != -1)
{
varListResponse->listOfVariable.list.array[i]->alternateAccess = varListResponse->listOfVariable.list.array[i]->alternateAccess =
mmsClient_createAlternateAccessIndexComponent(variableEntry->arrayIndex, variableEntry->componentName); mmsClient_createAlternateAccessIndexComponent(variableEntry->arrayIndex, variableEntry->componentName);
} }
else if (variableEntry->componentName) { else if (variableEntry->componentName)
{
varListResponse->listOfVariable.list.array[i]->alternateAccess = varListResponse->listOfVariable.list.array[i]->alternateAccess =
mmsClient_createAlternateAccessComponent(variableEntry->componentName); mmsClient_createAlternateAccessComponent(variableEntry->componentName);
} }
@ -742,7 +790,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_GetNamedVariableListAttributesRequest, asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_GetNamedVariableListAttributesRequest,
(void**) &request, buffer + bufPos, maxBufPos - bufPos); (void**) &request, buffer + bufPos, maxBufPos - bufPos);
if (rval.code != RC_OK) { if (rval.code != RC_OK)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_function; goto exit_function;
} }
@ -753,7 +802,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
char itemName[65]; char itemName[65];
if ((request->choice.domainspecific.domainId.size > 64) || if ((request->choice.domainspecific.domainId.size > 64) ||
(request->choice.domainspecific.itemId.size > 64)) { (request->choice.domainspecific.itemId.size > 64))
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OTHER); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OTHER);
goto exit_function; goto exit_function;
} }
@ -776,35 +826,36 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
{ {
MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_GET_DIRECTORY, MMS_DOMAIN_SPECIFIC, domain, varList->name, connection); MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_GET_DIRECTORY, MMS_DOMAIN_SPECIFIC, domain, varList->name, connection);
if (accessError == MMS_ERROR_NONE) { if (accessError == MMS_ERROR_NONE)
if (createGetNamedVariableListAttributesResponse(invokeId, response, varList) == false) { {
if (createGetNamedVariableListAttributesResponse(invokeId, response, varList) == false)
{
/* encoding failed - probably because buffer size is too small for message */ /* encoding failed - probably because buffer size is too small for message */
ByteBuffer_setSize(response, 0); ByteBuffer_setSize(response, 0);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_OTHER); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_OTHER);
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS get named variable list attributes: variable list %s access error: %i\n", varList->name, accessError); if (DEBUG_MMS_SERVER) printf("MMS get named variable list attributes: variable list %s access error: %i\n", varList->name, accessError);
mmsMsg_createServiceErrorPdu(invokeId, response, accessError); mmsMsg_createServiceErrorPdu(invokeId, response, accessError);
} }
} }
else else
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
} }
else else
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
} }
#if (MMS_DYNAMIC_DATA_SETS == 1) #if (MMS_DYNAMIC_DATA_SETS == 1)
else if (request->present == ObjectName_PR_aaspecific) else if (request->present == ObjectName_PR_aaspecific)
{ {
char listName[65]; char listName[65];
if (request->choice.aaspecific.size > 64) { if (request->choice.aaspecific.size > 64)
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OTHER); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OTHER);
goto exit_function; goto exit_function;
} }
@ -820,15 +871,16 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
if (accessError == MMS_ERROR_NONE) if (accessError == MMS_ERROR_NONE)
{ {
if (createGetNamedVariableListAttributesResponse(invokeId, response, varList) == false) { if (createGetNamedVariableListAttributesResponse(invokeId, response, varList) == false)
{
/* encoding failed - probably because buffer size is too small for message */ /* encoding failed - probably because buffer size is too small for message */
ByteBuffer_setSize(response, 0); ByteBuffer_setSize(response, 0);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_OTHER); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_OTHER);
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS get named variable list attributes: variable list %s access error: %i\n", varList->name, accessError); if (DEBUG_MMS_SERVER) printf("MMS get named variable list attributes: variable list %s access error: %i\n", varList->name, accessError);
mmsMsg_createServiceErrorPdu(invokeId, response, accessError); mmsMsg_createServiceErrorPdu(invokeId, response, accessError);
@ -842,7 +894,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
{ {
char listName[65]; char listName[65];
if (request->choice.vmdspecific.size > 64) { if (request->choice.vmdspecific.size > 64)
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OTHER); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OTHER);
goto exit_function; goto exit_function;
} }
@ -860,15 +913,16 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
if (accessError == MMS_ERROR_NONE) if (accessError == MMS_ERROR_NONE)
{ {
if (createGetNamedVariableListAttributesResponse(invokeId, response, varList) == false) { if (createGetNamedVariableListAttributesResponse(invokeId, response, varList) == false)
{
/* encoding failed - probably because buffer size is too small for message */ /* encoding failed - probably because buffer size is too small for message */
ByteBuffer_setSize(response, 0); ByteBuffer_setSize(response, 0);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_OTHER); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_OTHER);
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS get named variable list attributes: variable list %s access error: %i\n", varList->name, accessError); if (DEBUG_MMS_SERVER) printf("MMS get named variable list attributes: variable list %s access error: %i\n", varList->name, accessError);
mmsMsg_createServiceErrorPdu(invokeId, response, accessError); mmsMsg_createServiceErrorPdu(invokeId, response, accessError);
@ -877,7 +931,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
else else
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
} }
else { else
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED);
} }

@ -49,14 +49,14 @@ addNamedVariableValue(MmsVariableSpecification* namedVariable, MmsServerConnecti
{ {
MmsValue* value = NULL; MmsValue* value = NULL;
if (namedVariable->type == MMS_STRUCTURE) { if (namedVariable->type == MMS_STRUCTURE)
{
value = mmsServer_getValue(connection->server, domain, itemId, connection, false); value = mmsServer_getValue(connection->server, domain, itemId, connection, false);
if (value != NULL) if (value)
goto exit_function; goto exit_function;
else { else
{
int componentCount = namedVariable->typeSpec.structure.elementCount; int componentCount = namedVariable->typeSpec.structure.elementCount;
value = MmsValue_createEmptyStructure(componentCount); value = MmsValue_createEmptyStructure(componentCount);
@ -65,7 +65,8 @@ addNamedVariableValue(MmsVariableSpecification* namedVariable, MmsServerConnecti
int i; int i;
for (i = 0; i < componentCount; i++) { for (i = 0; i < componentCount; i++)
{
char newNameIdStr[65]; char newNameIdStr[65];
StringUtils_createStringInBuffer(newNameIdStr, 65, 3, itemId, "$", StringUtils_createStringInBuffer(newNameIdStr, 65, 3, itemId, "$",
@ -75,7 +76,8 @@ addNamedVariableValue(MmsVariableSpecification* namedVariable, MmsServerConnecti
addNamedVariableValue(namedVariable->typeSpec.structure.elements[i], addNamedVariableValue(namedVariable->typeSpec.structure.elements[i],
connection, domain, newNameIdStr); connection, domain, newNameIdStr);
if (element == NULL) { if (element == NULL)
{
MmsValue_delete(value); MmsValue_delete(value);
value = NULL; value = NULL;
break; break;
@ -85,7 +87,8 @@ addNamedVariableValue(MmsVariableSpecification* namedVariable, MmsServerConnecti
} }
} }
} }
else { else
{
value = mmsServer_getValue(connection->server, domain, itemId, connection, false); value = mmsServer_getValue(connection->server, domain, itemId, connection, false);
} }
@ -104,7 +107,6 @@ addComplexValueToResultList(MmsVariableSpecification* namedVariable,
LinkedList_add(typedValues, value); LinkedList_add(typedValues, value);
} }
static void static void
appendValueToResultList(MmsValue* value, LinkedList values) appendValueToResultList(MmsValue* value, LinkedList values)
{ {
@ -113,7 +115,8 @@ appendValueToResultList(MmsValue* value, LinkedList values)
} }
static void static void
appendErrorToResultList(LinkedList values, MmsDataAccessError errorType) { appendErrorToResultList(LinkedList values, MmsDataAccessError errorType)
{
MmsValue* value = MmsValue_newDataAccessError(errorType); MmsValue* value = MmsValue_newDataAccessError(errorType);
MmsValue_setDeletable(value); MmsValue_setDeletable(value);
appendValueToResultList(value, values); appendValueToResultList(value, values);
@ -124,7 +127,8 @@ deleteValueList(LinkedList values)
{ {
LinkedList value = LinkedList_getNext(values); LinkedList value = LinkedList_getNext(values);
while (value) { while (value)
{
MmsValue* typedValue = (MmsValue*) (value->data); MmsValue* typedValue = (MmsValue*) (value->data);
MmsValue_deleteConditional(typedValue); MmsValue_deleteConditional(typedValue);
@ -140,40 +144,43 @@ getComponent(MmsServerConnection connection, MmsDomain* domain, AlternateAccess_
{ {
MmsValue* retValue = NULL; MmsValue* retValue = NULL;
if (mmsServer_isComponentAccess(alternateAccess)) { if (mmsServer_isComponentAccess(alternateAccess))
{
Identifier_t component = Identifier_t component =
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.component; alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.component;
if (component.size > 129) if (component.size > 129)
goto exit_function; goto exit_function;
if (namedVariable->type == MMS_STRUCTURE) { if (namedVariable->type == MMS_STRUCTURE)
{
int i; int i;
for (i = 0; i < namedVariable->typeSpec.structure.elementCount; i++) { for (i = 0; i < namedVariable->typeSpec.structure.elementCount; i++)
{
if ((int) strlen(namedVariable->typeSpec.structure.elements[i]->name) if ((int) strlen(namedVariable->typeSpec.structure.elements[i]->name)
== component.size) { == component.size)
{
if (!strncmp(namedVariable->typeSpec.structure.elements[i]->name, if (!strncmp(namedVariable->typeSpec.structure.elements[i]->name,
(char*) component.buf, component.size)) (char*) component.buf, component.size))
{ {
if (strlen(variableName) + component.size < 199) { if (strlen(variableName) + component.size < 199)
{
StringUtils_appendString(variableName, 200, "$"); StringUtils_appendString(variableName, 200, "$");
/* here we need strncat because component.buf is not null terminated! */ /* here we need strncat because component.buf is not null terminated! */
strncat(variableName, (const char*)component.buf, (size_t)component.size); strncat(variableName, (const char*)component.buf, (size_t)component.size);
if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess)
!= NULL) { {
retValue = retValue =
getComponent(connection, domain, getComponent(connection, domain,
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess, alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess,
namedVariable->typeSpec.structure.elements[i], namedVariable->typeSpec.structure.elements[i],
variableName); variableName);
} }
else { else
{
retValue = mmsServer_getValue(connection->server, domain, variableName, connection, false); retValue = mmsServer_getValue(connection->server, domain, variableName, connection, false);
} }
} }
@ -210,7 +217,8 @@ alternateArrayAccess(MmsServerConnection connection,
{ {
if (mmsServer_isAccessToArrayComponent(alternateAccess)) if (mmsServer_isAccessToArrayComponent(alternateAccess))
{ {
if (namedVariable->typeSpec.array.elementTypeSpec->type == MMS_STRUCTURE) { if (namedVariable->typeSpec.array.elementTypeSpec->type == MMS_STRUCTURE)
{
MmsValue* structValue = MmsValue_getElement(arrayValue, index); MmsValue* structValue = MmsValue_getElement(arrayValue, index);
if (structValue != NULL) if (structValue != NULL)
@ -218,7 +226,8 @@ alternateArrayAccess(MmsServerConnection connection,
namedVariable, structValue, NULL); namedVariable, structValue, NULL);
} }
} }
else { else
{
value = MmsValue_getElement(arrayValue, index); value = MmsValue_getElement(arrayValue, index);
} }
} }
@ -235,7 +244,8 @@ alternateArrayAccess(MmsServerConnection connection,
elementValue = MmsValue_getElement(arrayValue, index); elementValue = MmsValue_getElement(arrayValue, index);
if (!MmsValue_isDeletable(elementValue)) { if (!MmsValue_isDeletable(elementValue))
{
elementValue = MmsValue_clone(elementValue); elementValue = MmsValue_clone(elementValue);
elementValue->deleteValue = 1; elementValue->deleteValue = 1;
} }
@ -256,7 +266,9 @@ alternateArrayAccess(MmsServerConnection connection,
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT); appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
} }
else { /* invalid access */ else
{
/* invalid access */
if (DEBUG_MMS_SERVER) printf("Invalid alternate access\n"); if (DEBUG_MMS_SERVER) printf("Invalid alternate access\n");
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT); appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
@ -267,8 +279,8 @@ static void
addNamedVariableToResultList(MmsVariableSpecification* namedVariable, MmsDomain* domain, char* nameIdStr, addNamedVariableToResultList(MmsVariableSpecification* namedVariable, MmsDomain* domain, char* nameIdStr,
LinkedList /*<MmsValue>*/ values, MmsServerConnection connection, AlternateAccess_t* alternateAccess, bool isAccessToSingleVariable) LinkedList /*<MmsValue>*/ values, MmsServerConnection connection, AlternateAccess_t* alternateAccess, bool isAccessToSingleVariable)
{ {
if (namedVariable) { if (namedVariable)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS read: found named variable %s with search string %s\n", printf("MMS read: found named variable %s with search string %s\n",
namedVariable->name, nameIdStr); namedVariable->name, nameIdStr);
@ -283,45 +295,56 @@ addNamedVariableToResultList(MmsVariableSpecification* namedVariable, MmsDomain*
MmsValue* value = getComponent(connection, domain, alternateAccess, namedVariable, variableName); MmsValue* value = getComponent(connection, domain, alternateAccess, namedVariable, variableName);
if (value) { if (value)
{
appendValueToResultList(value, values); appendValueToResultList(value, values);
} }
else { else
{
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT); appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
} }
} }
else { else
{
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, isAccessToSingleVariable); MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, isAccessToSingleVariable);
if (value) { if (value)
{
appendValueToResultList(value, values); appendValueToResultList(value, values);
} }
else { else
{
addComplexValueToResultList(namedVariable, addComplexValueToResultList(namedVariable,
values, connection, domain, nameIdStr); values, connection, domain, nameIdStr);
} }
} }
} }
else if (namedVariable->type == MMS_ARRAY) { else if (namedVariable->type == MMS_ARRAY)
{
if (alternateAccess) { if (alternateAccess)
{
alternateArrayAccess(connection, alternateAccess, domain, alternateArrayAccess(connection, alternateAccess, domain,
nameIdStr, values, namedVariable); nameIdStr, values, namedVariable);
} }
else { /* return complete array */ else
{
/* return complete array */
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, isAccessToSingleVariable); MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, isAccessToSingleVariable);
appendValueToResultList(value, values); appendValueToResultList(value, values);
} }
} }
else { else
{
if (alternateAccess) { if (alternateAccess)
{
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT); appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
} }
else { else
{
MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, isAccessToSingleVariable); MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr, connection, isAccessToSingleVariable);
if (value == NULL) { if (value == NULL)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS read: value of known variable is not found. Maybe illegal access to array element!\n"); printf("MMS read: value of known variable is not found. Maybe illegal access to array element!\n");
@ -336,7 +359,6 @@ addNamedVariableToResultList(MmsVariableSpecification* namedVariable, MmsDomain*
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT); appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
} }
static bool static bool
isSpecWithResult(ReadRequest_t* read) isSpecWithResult(ReadRequest_t* read)
{ {
@ -394,13 +416,11 @@ encodeVariableAccessSpecification(VarAccessSpec* accessSpec, uint8_t* buffer, in
} }
else if (accessSpec->specific == 1) { /* domain-specific */ else if (accessSpec->specific == 1) { /* domain-specific */
bufPos = BerEncoder_encodeTL(0xa1, specificityLength, buffer, bufPos); bufPos = BerEncoder_encodeTL(0xa1, specificityLength, buffer, bufPos);
} }
else { /* association-specific */ else { /* association-specific */
bufPos = BerEncoder_encodeTL(0xa2, specificityLength, buffer, bufPos); bufPos = BerEncoder_encodeTL(0xa2, specificityLength, buffer, bufPos);
} }
if (accessSpec->domainId != NULL) if (accessSpec->domainId != NULL)
bufPos = BerEncoder_encodeStringWithTag(0x1a, accessSpec->domainId, buffer, bufPos); bufPos = BerEncoder_encodeStringWithTag(0x1a, accessSpec->domainId, buffer, bufPos);
@ -422,9 +442,8 @@ encodeReadResponse(MmsServerConnection connection,
uint32_t varAccessSpecSize = 0; uint32_t varAccessSpecSize = 0;
if (accessSpec != NULL) { if (accessSpec)
varAccessSpecSize = encodeVariableAccessSpecification(accessSpec, NULL, 0, false); varAccessSpecSize = encodeVariableAccessSpecification(accessSpec, NULL, 0, false);
}
/* determine BER encoded message sizes */ /* determine BER encoded message sizes */
uint32_t accessResultSize = 0; uint32_t accessResultSize = 0;
@ -564,13 +583,15 @@ handleReadListOfVariablesRequest(
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: READ domainId: (%s) nameId: (%s)\n", domainIdStr, nameIdStr); printf("MMS_SERVER: READ domainId: (%s) nameId: (%s)\n", domainIdStr, nameIdStr);
if (domain == NULL) { if (domain == NULL)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: READ domain %s not found!\n", domainIdStr); printf("MMS_SERVER: READ domain %s not found!\n", domainIdStr);
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT); appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
} }
else { else
{
MmsVariableSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameIdStr); MmsVariableSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameIdStr);
if (namedVariable == NULL) if (namedVariable == NULL)
@ -602,13 +623,15 @@ handleReadListOfVariablesRequest(
} }
#endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */ #endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */
else { else
{
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT); appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
if (DEBUG_MMS_SERVER) printf("MMS_SERVER: READ object name type not supported!\n"); if (DEBUG_MMS_SERVER) printf("MMS_SERVER: READ object name type not supported!\n");
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS_SERVER: READ varspec type not supported!\n"); if (DEBUG_MMS_SERVER) printf("MMS_SERVER: READ varspec type not supported!\n");
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
goto exit; goto exit;
@ -625,8 +648,10 @@ handleReadListOfVariablesRequest(
if (value) if (value)
{ {
if (MmsValue_getType(value) == MMS_DATA_ACCESS_ERROR) { if (MmsValue_getType(value) == MMS_DATA_ACCESS_ERROR)
if (MmsValue_getDataAccessError(value) == DATA_ACCESS_ERROR_NO_RESPONSE) { {
if (MmsValue_getDataAccessError(value) == DATA_ACCESS_ERROR_NO_RESPONSE)
{
sendResponse = false; sendResponse = false;
break; break;
} }
@ -672,10 +697,12 @@ addNamedVariableToNamedVariableListResultList(MmsVariableSpecification* namedVar
MmsValue* subElementValue = MmsVariableSpecification_getChildValue(elementType, elementValue, listEntry->componentName); MmsValue* subElementValue = MmsVariableSpecification_getChildValue(elementType, elementValue, listEntry->componentName);
if (subElementValue) { if (subElementValue)
{
appendValueToResultList(subElementValue, values); appendValueToResultList(subElementValue, values);
} }
else { else
{
if (DEBUG_IED_SERVER) if (DEBUG_IED_SERVER)
printf("IED_SERVER: ERROR - component %s of array element not found\n", listEntry->componentName); printf("IED_SERVER: ERROR - component %s of array element not found\n", listEntry->componentName);
} }
@ -683,7 +710,6 @@ addNamedVariableToNamedVariableListResultList(MmsVariableSpecification* namedVar
else { else {
appendValueToResultList(elementValue, values); appendValueToResultList(elementValue, values);
} }
} }
else else
{ {
@ -693,11 +719,13 @@ addNamedVariableToNamedVariableListResultList(MmsVariableSpecification* namedVar
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT); appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
} }
} }
else { else
{
appendValueToResultList(value, values); appendValueToResultList(value, values);
} }
} }
else { else
{
appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT); appendErrorToResultList(values, DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT);
} }
} }
@ -785,21 +813,22 @@ handleReadNamedVariableListRequest(
if (namedList) if (namedList)
{ {
MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_READ, MMS_DOMAIN_SPECIFIC, domain, namedList->name, connection); MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_READ, MMS_DOMAIN_SPECIFIC, domain, namedList->name, connection);
if (accessError == MMS_ERROR_NONE) { if (accessError == MMS_ERROR_NONE)
{
createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read),
&accessSpec); &accessSpec);
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS read: named variable list %s access error: %i\n", nameIdStr, accessError); if (DEBUG_MMS_SERVER) printf("MMS read: named variable list %s access error: %i\n", nameIdStr, accessError);
mmsMsg_createServiceErrorPdu(invokeId, response, accessError); mmsMsg_createServiceErrorPdu(invokeId, response, accessError);
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS read: named variable list %s not found!\n", nameIdStr); if (DEBUG_MMS_SERVER) printf("MMS read: named variable list %s not found!\n", nameIdStr);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
} }
@ -833,7 +862,8 @@ handleReadNamedVariableListRequest(
createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec); createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec);
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS read: VMD specific named variable list %s access error: %i\n", listName, accessError); if (DEBUG_MMS_SERVER) printf("MMS read: VMD specific named variable list %s access error: %i\n", listName, accessError);
mmsMsg_createServiceErrorPdu(invokeId, response, accessError); mmsMsg_createServiceErrorPdu(invokeId, response, accessError);
@ -870,7 +900,8 @@ handleReadNamedVariableListRequest(
createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec); createNamedVariableListResponse(connection, namedList, invokeId, response, isSpecWithResult(read), &accessSpec);
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS read: association specific named variable list %s access error: %i\n", listName, accessError); if (DEBUG_MMS_SERVER) printf("MMS read: association specific named variable list %s access error: %i\n", listName, accessError);
mmsMsg_createServiceErrorPdu(invokeId, response, accessError); mmsMsg_createServiceErrorPdu(invokeId, response, accessError);
@ -898,7 +929,8 @@ mmsServer_handleReadRequest(
asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, maxBufPos); asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, maxBufPos);
if (rval.code != RC_OK) { if (rval.code != RC_OK)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_function; goto exit_function;
} }
@ -909,7 +941,8 @@ mmsServer_handleReadRequest(
{ {
request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.read); request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.read);
} }
else { else
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_function; goto exit_function;
} }
@ -932,7 +965,8 @@ mmsServer_handleReadRequest(
MmsServer_unlockModel(connection->server); MmsServer_unlockModel(connection->server);
} }
#endif #endif
else { else
{
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED);
} }
@ -965,4 +999,3 @@ MmsServerConnection_sendReadResponse(MmsServerConnection self, uint32_t invokeId
if (handlerMode == false) if (handlerMode == false)
IsoConnection_unlock(self->isoConnection); IsoConnection_unlock(self->isoConnection);
} }

@ -1,7 +1,7 @@
/* /*
* mms_server_common.c * mms_server_common.c
* *
* Copyright 2013-2020 Michael Zillgith * Copyright 2013-2024 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -32,7 +32,8 @@ mmsServer_write_out(const void *buffer, size_t size, void *app_key)
int appendedBytes = ByteBuffer_append(writeBuffer, (uint8_t*) buffer, size); int appendedBytes = ByteBuffer_append(writeBuffer, (uint8_t*) buffer, size);
if (appendedBytes == -1) { if (appendedBytes == -1)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: message exceeds maximum PDU size!\n"); printf("MMS_SERVER: message exceeds maximum PDU size!\n");
} }
@ -156,9 +157,7 @@ mapErrorTypeToErrorClass(MmsError errorType, uint8_t* tag, uint8_t* value)
*tag = 0x8c; /* others */ *tag = 0x8c; /* others */
*value = 0; *value = 0;
break; break;
} }
} }
void void
@ -240,7 +239,8 @@ mmsMsg_createInitiateErrorPdu(ByteBuffer* response, uint8_t initiateErrorCode)
bool bool
mmsServer_isIndexAccess(AlternateAccess_t* alternateAccess) mmsServer_isIndexAccess(AlternateAccess_t* alternateAccess)
{ {
if (alternateAccess->list.array[0]->present == AlternateAccess__Member_PR_unnamed) { if (alternateAccess->list.array[0]->present == AlternateAccess__Member_PR_unnamed)
{
if ((alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present if ((alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present
== AlternateAccessSelection__selectAccess_PR_index) || == AlternateAccessSelection__selectAccess_PR_index) ||
(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present (alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present
@ -256,10 +256,11 @@ mmsServer_isIndexAccess(AlternateAccess_t* alternateAccess)
bool bool
mmsServer_isComponentAccess(AlternateAccess_t* alternateAccess) mmsServer_isComponentAccess(AlternateAccess_t* alternateAccess)
{ {
if (alternateAccess->list.array[0]->present if (alternateAccess->list.array[0]->present == AlternateAccess__Member_PR_unnamed)
== AlternateAccess__Member_PR_unnamed) { {
if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present
== AlternateAccessSelection__selectAccess_PR_component) { == AlternateAccessSelection__selectAccess_PR_component)
{
return true; return true;
} }
} }
@ -410,10 +411,12 @@ mmsServer_getNamedVariableListWithName(LinkedList namedVariableLists, const char
LinkedList element = LinkedList_getNext(namedVariableLists); LinkedList element = LinkedList_getNext(namedVariableLists);
while (element) { while (element)
{
MmsNamedVariableList varList = (MmsNamedVariableList) element->data; MmsNamedVariableList varList = (MmsNamedVariableList) element->data;
if (strcmp(MmsNamedVariableList_getName(varList), variableListName) == 0) { if (strcmp(MmsNamedVariableList_getName(varList), variableListName) == 0)
{
variableList = varList; variableList = varList;
break; break;
} }
@ -430,11 +433,12 @@ mmsServer_deleteVariableList(LinkedList namedVariableLists, char* variableListNa
LinkedList previousElement = namedVariableLists; LinkedList previousElement = namedVariableLists;
LinkedList element = LinkedList_getNext(namedVariableLists); LinkedList element = LinkedList_getNext(namedVariableLists);
while (element) { while (element)
{
MmsNamedVariableList varList = (MmsNamedVariableList) element->data; MmsNamedVariableList varList = (MmsNamedVariableList) element->data;
if (strcmp(MmsNamedVariableList_getName(varList), variableListName) if (strcmp(MmsNamedVariableList_getName(varList), variableListName) == 0)
== 0) { {
previousElement->next = element->next; previousElement->next = element->next;
GLOBAL_FREEMEM(element); GLOBAL_FREEMEM(element);
MmsNamedVariableList_destroy(varList); MmsNamedVariableList_destroy(varList);

@ -73,7 +73,8 @@ mmsMsg_encodeMmsRejectPdu(uint32_t* invokeId, int rejectType, int rejectReason,
uint32_t rejectPduLength = 3; uint32_t rejectPduLength = 3;
if (invokeId != NULL) { if (invokeId)
{
invokeIdLength = BerEncoder_UInt32determineEncodedSize(*invokeId); invokeIdLength = BerEncoder_UInt32determineEncodedSize(*invokeId);
rejectPduLength += 2 + invokeIdLength; rejectPduLength += 2 + invokeIdLength;
} }
@ -81,7 +82,8 @@ mmsMsg_encodeMmsRejectPdu(uint32_t* invokeId, int rejectType, int rejectReason,
/* Encode reject PDU */ /* Encode reject PDU */
bufPos = BerEncoder_encodeTL(0xa4, rejectPduLength, buffer, bufPos); bufPos = BerEncoder_encodeTL(0xa4, rejectPduLength, buffer, bufPos);
if (invokeId != NULL) { if (invokeId)
{
/* original invokeId */ /* original invokeId */
bufPos = BerEncoder_encodeTL(0x80, invokeIdLength, buffer, bufPos); bufPos = BerEncoder_encodeTL(0x80, invokeIdLength, buffer, bufPos);
bufPos = BerEncoder_encodeUInt32(*invokeId, buffer, bufPos); bufPos = BerEncoder_encodeUInt32(*invokeId, buffer, bufPos);
@ -143,31 +145,34 @@ handleConfirmedRequestPdu(
{ {
uint32_t invokeId = 0; uint32_t invokeId = 0;
while (bufPos < maxBufPos) { while (bufPos < maxBufPos)
{
uint8_t tag = buffer[bufPos++]; uint8_t tag = buffer[bufPos++];
int length; int length;
bool extendedTag = false; bool extendedTag = false;
if ((tag & 0x1f) == 0x1f) { if ((tag & 0x1f) == 0x1f)
{
extendedTag = true; extendedTag = true;
tag = buffer[bufPos++]; tag = buffer[bufPos++];
} }
bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos); bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos);
if (bufPos < 0) { if (bufPos < 0)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
return; return;
} }
if (extendedTag) { if (extendedTag)
{
switch (tag) switch (tag)
{ {
#if (MMS_OBTAIN_FILE_SERVICE == 1) #if (MMS_OBTAIN_FILE_SERVICE == 1)
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
case 0x2e: /* obtain-file */ case 0x2e: /* obtain-file */
if (self->server->fileServiceEnabled) if (self->server->fileServiceEnabled)
@ -300,7 +305,8 @@ handleConfirmedRequestPdu(
break; break;
} }
} }
else { else
{
switch (tag) switch (tag)
{ {
case 0x02: /* invoke Id */ case 0x02: /* invoke Id */
@ -424,24 +430,25 @@ handleConfirmedErrorPdu(
bool hasInvokeId = false; bool hasInvokeId = false;
MmsServiceError serviceError; MmsServiceError serviceError;
if (mmsMsg_parseConfirmedErrorPDU(buffer, bufPos, maxBufPos, &invokeId, &hasInvokeId, &serviceError)) { if (mmsMsg_parseConfirmedErrorPDU(buffer, bufPos, maxBufPos, &invokeId, &hasInvokeId, &serviceError))
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: Handle confirmed error PDU: invokeID: %u\n", invokeId); printf("MMS_SERVER: Handle confirmed error PDU: invokeID: %u\n", invokeId);
if (hasInvokeId) { if (hasInvokeId)
{
/* check if message is related to an existing file upload task */ /* check if message is related to an existing file upload task */
int i; int i;
for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++) { for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++)
{
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_wait(self->server->fileUploadTasks[i].taskLock); Semaphore_wait(self->server->fileUploadTasks[i].taskLock);
#endif #endif
if (self->server->fileUploadTasks[i].state != MMS_FILE_UPLOAD_STATE_NOT_USED) { if (self->server->fileUploadTasks[i].state != MMS_FILE_UPLOAD_STATE_NOT_USED)
{
if (self->server->fileUploadTasks[i].lastRequestInvokeId == invokeId) { if (self->server->fileUploadTasks[i].lastRequestInvokeId == invokeId)
{
self->server->fileUploadTasks[i].state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE; self->server->fileUploadTasks[i].state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE;
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
@ -449,7 +456,6 @@ handleConfirmedErrorPdu(
#endif #endif
return; return;
} }
} }
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
@ -457,9 +463,9 @@ handleConfirmedErrorPdu(
#endif #endif
} }
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: error parsing confirmed error PDU\n"); printf("MMS_SERVER: error parsing confirmed error PDU\n");
} }
@ -469,7 +475,8 @@ static MmsObtainFileTask
getUploadTaskByInvokeId(MmsServer mmsServer, uint32_t invokeId) getUploadTaskByInvokeId(MmsServer mmsServer, uint32_t invokeId)
{ {
int i; int i;
for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++) { for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++)
{
if ((mmsServer->fileUploadTasks[i].state != 0) && (mmsServer->fileUploadTasks[i].lastRequestInvokeId == invokeId)) if ((mmsServer->fileUploadTasks[i].state != 0) && (mmsServer->fileUploadTasks[i].lastRequestInvokeId == invokeId))
return &(mmsServer->fileUploadTasks[i]); return &(mmsServer->fileUploadTasks[i]);
} }
@ -486,19 +493,23 @@ mmsFileReadHandler(uint32_t invokeId, void* parameter, MmsError mmsError, int32_
MmsObtainFileTask task = (MmsObtainFileTask) parameter; MmsObtainFileTask task = (MmsObtainFileTask) parameter;
if (mmsError == MMS_ERROR_NONE) { if (mmsError == MMS_ERROR_NONE)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: file %i received %u bytes\n", task->frmsId, bytesReceived); printf("MMS_SERVER: file %i received %u bytes\n", task->frmsId, bytesReceived);
if(task->fileHandle){ if(task->fileHandle)
{
FileSystem_writeFile(task->fileHandle, buffer, bytesReceived); FileSystem_writeFile(task->fileHandle, buffer, bytesReceived);
} }
else{ else
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: problem reading file %i file already closed\n", task->frmsId); printf("MMS_SERVER: problem reading file %i file already closed\n", task->frmsId);
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: problem reading file %i (error code: %i)\n", task->frmsId, mmsError); printf("MMS_SERVER: problem reading file %i (error code: %i)\n", task->frmsId, mmsError);
} }
@ -512,7 +523,8 @@ handleConfirmedResponsePdu(
{ {
uint32_t invokeId = 0; uint32_t invokeId = 0;
while (bufPos < maxBufPos) { while (bufPos < maxBufPos)
{
int startBufPos = bufPos; int startBufPos = bufPos;
uint8_t tag = buffer[bufPos++]; uint8_t tag = buffer[bufPos++];
@ -520,19 +532,22 @@ handleConfirmedResponsePdu(
bool extendedTag = false; bool extendedTag = false;
if ((tag & 0x1f) == 0x1f) { if ((tag & 0x1f) == 0x1f)
{
extendedTag = true; extendedTag = true;
tag = buffer[bufPos++]; tag = buffer[bufPos++];
} }
bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos); bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos);
if (bufPos < 0) { if (bufPos < 0)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response);
return; return;
} }
if (extendedTag) { if (extendedTag)
{
switch (tag) switch (tag)
{ {
@ -545,15 +560,17 @@ handleConfirmedResponsePdu(
{ {
MmsObtainFileTask fileTask = getUploadTaskByInvokeId(self->server, invokeId); MmsObtainFileTask fileTask = getUploadTaskByInvokeId(self->server, invokeId);
if (fileTask != NULL) { if (fileTask)
{
int32_t frmsId; int32_t frmsId;
if (mmsMsg_parseFileOpenResponse(buffer, startBufPos, maxBufPos, &frmsId, NULL, NULL)) { if (mmsMsg_parseFileOpenResponse(buffer, startBufPos, maxBufPos, &frmsId, NULL, NULL))
{
fileTask->frmsId = frmsId; fileTask->frmsId = frmsId;
fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_READ; fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_READ;
} }
else { else
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: error parsing file-open-response\n"); printf("MMS_SERVER: error parsing file-open-response\n");
fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE; fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE;
@ -576,24 +593,29 @@ handleConfirmedResponsePdu(
MmsObtainFileTask fileTask = getUploadTaskByInvokeId(self->server, invokeId); MmsObtainFileTask fileTask = getUploadTaskByInvokeId(self->server, invokeId);
if (fileTask != NULL) { if (fileTask)
{
bool moreFollows; bool moreFollows;
if(fileTask->fileHandle == NULL){ if(fileTask->fileHandle == NULL)
{
fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_DESTINATION; fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_DESTINATION;
} }
else{ else
if (mmsMsg_parseFileReadResponse(buffer, startBufPos, maxBufPos, invokeId, fileTask->frmsId, &moreFollows, mmsFileReadHandler, (void*) fileTask)) { {
if (mmsMsg_parseFileReadResponse(buffer, startBufPos, maxBufPos, invokeId, fileTask->frmsId, &moreFollows, mmsFileReadHandler, (void*) fileTask))
if (moreFollows) { {
if (moreFollows)
{
fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_READ; fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_READ;
} }
else { else
{
fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_CLOSE; fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_CLOSE;
} }
} }
else { else
{
fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE; fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE;
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
@ -601,7 +623,8 @@ handleConfirmedResponsePdu(
} }
} }
} }
else { else
{
/* ignore */ /* ignore */
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
@ -618,13 +641,17 @@ handleConfirmedResponsePdu(
MmsObtainFileTask fileTask = getUploadTaskByInvokeId(self->server, invokeId); MmsObtainFileTask fileTask = getUploadTaskByInvokeId(self->server, invokeId);
if (fileTask != NULL) { if (fileTask)
if(fileTask->fileHandle){ {
if(fileTask->fileHandle)
{
FileSystem_closeFile(fileTask->fileHandle); FileSystem_closeFile(fileTask->fileHandle);
} }
fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_RESPONSE; fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_RESPONSE;
} }
else { else
{
/* ignore */ /* ignore */
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
@ -640,7 +667,8 @@ handleConfirmedResponsePdu(
break; break;
} }
} }
else { else
{
switch (tag) switch (tag)
{ {
case 0x02: /* invoke Id */ case 0x02: /* invoke Id */
@ -762,6 +790,8 @@ MmsServerConnection_init(MmsServerConnection connection, MmsServer server, IsoCo
else else
self = connection; self = connection;
if (self)
{
self->maxServOutstandingCalled = 0; self->maxServOutstandingCalled = 0;
self->maxServOutstandingCalling = 0; self->maxServOutstandingCalling = 0;
self->maxPduSize = CONFIG_MMS_MAXIMUM_PDU_SIZE; self->maxPduSize = CONFIG_MMS_MAXIMUM_PDU_SIZE;
@ -780,6 +810,7 @@ MmsServerConnection_init(MmsServerConnection connection, MmsServer server, IsoCo
IsoConnection_installListener(isoCon, messageReceived, IsoConnection_installListener(isoCon, messageReceived,
(UserLayerTickHandler) connectionTickHandler, (UserLayerTickHandler) connectionTickHandler,
(void*) self); (void*) self);
}
return self; return self;
} }
@ -894,6 +925,3 @@ MmsServerConnection_getFilesystemBasepath(MmsServerConnection self)
return CONFIG_VIRTUAL_FILESTORE_BASEPATH; return CONFIG_VIRTUAL_FILESTORE_BASEPATH;
#endif #endif
} }

@ -41,9 +41,12 @@ MmsValueCache_create(MmsDomain* domain)
{ {
MmsValueCache self = (MmsValueCache) GLOBAL_CALLOC(1, sizeof(struct sMmsValueCache)); MmsValueCache self = (MmsValueCache) GLOBAL_CALLOC(1, sizeof(struct sMmsValueCache));
if (self)
{
self->domain = domain; self->domain = domain;
self->map = StringMap_create(); self->map = StringMap_create();
}
return self; return self;
} }
@ -53,7 +56,8 @@ MmsValueCache_insertValue(MmsValueCache self, char* itemId, MmsValue* value)
{ {
MmsVariableSpecification* typeSpec = MmsDomain_getNamedVariable(self->domain, itemId); MmsVariableSpecification* typeSpec = MmsDomain_getNamedVariable(self->domain, itemId);
if (typeSpec != NULL) { if (typeSpec)
{
MmsValueCacheEntry* cacheEntry = (MmsValueCacheEntry*) GLOBAL_MALLOC(sizeof(MmsValueCacheEntry)); MmsValueCacheEntry* cacheEntry = (MmsValueCacheEntry*) GLOBAL_MALLOC(sizeof(MmsValueCacheEntry));
cacheEntry->value = value; cacheEntry->value = value;
@ -73,8 +77,10 @@ getParentSubString(char* itemId)
char* strPos = itemId + len; char* strPos = itemId + len;
while (--strPos > itemId) { while (--strPos > itemId)
if (*strPos == '$') { {
if (*strPos == '$')
{
*strPos = 0; *strPos = 0;
return itemId; return itemId;
} }
@ -97,24 +103,24 @@ searchCacheForValue(MmsValueCache self, const char* itemId, char* parentId, MmsV
cacheEntry = (MmsValueCacheEntry*) Map_getEntry(self->map, (void*) parentId); cacheEntry = (MmsValueCacheEntry*) Map_getEntry(self->map, (void*) parentId);
if (cacheEntry == NULL) { if (cacheEntry == NULL)
{
char* parentItemId = getParentSubString(parentId); char* parentItemId = getParentSubString(parentId);
if (parentItemId != NULL) { if (parentItemId)
value = searchCacheForValue(self, itemId, parentItemId, outSpec); value = searchCacheForValue(self, itemId, parentItemId, outSpec);
} }
} else
else { {
const char* childId = getChildSubString(itemId, parentId); const char* childId = getChildSubString(itemId, parentId);
MmsVariableSpecification* typeSpec = MmsDomain_getNamedVariable(self->domain, parentId); MmsVariableSpecification* typeSpec = MmsDomain_getNamedVariable(self->domain, parentId);
value = MmsVariableSpecification_getChildValue(typeSpec, cacheEntry->value, childId); value = MmsVariableSpecification_getChildValue(typeSpec, cacheEntry->value, childId);
if (outSpec) { if (outSpec)
{
*outSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId); *outSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId);
} }
} }
return value; return value;
@ -131,24 +137,23 @@ MmsValueCache_lookupValue(MmsValueCache self, const char* itemId, MmsVariableSpe
MmsValueCacheEntry* cacheEntry = (MmsValueCacheEntry*) Map_getEntry(self->map, (void*) itemId); MmsValueCacheEntry* cacheEntry = (MmsValueCacheEntry*) Map_getEntry(self->map, (void*) itemId);
if (cacheEntry) { if (cacheEntry)
{
if (outSpec) { if (outSpec)
*outSpec = cacheEntry->typeSpec; *outSpec = cacheEntry->typeSpec;
}
return cacheEntry->value; return cacheEntry->value;
} }
else { else
{
char itemIdCopy[65]; char itemIdCopy[65];
StringUtils_copyStringToBuffer(itemId, itemIdCopy); StringUtils_copyStringToBuffer(itemId, itemIdCopy);
char* parentItemId = getParentSubString(itemIdCopy); char* parentItemId = getParentSubString(itemIdCopy);
if (parentItemId != NULL) { if (parentItemId)
value = searchCacheForValue(self, itemId, parentItemId, outSpec); value = searchCacheForValue(self, itemId, parentItemId, outSpec);
} }
}
return value; return value;
} }
@ -161,46 +166,54 @@ searchCacheForValueEx(MmsValueCache self, const char* itemId, char* parentId, in
cacheEntry = (MmsValueCacheEntry*) Map_getEntry(self->map, (void*) parentId); cacheEntry = (MmsValueCacheEntry*) Map_getEntry(self->map, (void*) parentId);
if (cacheEntry == NULL) { if (cacheEntry == NULL)
{
char* parentItemId = getParentSubString(parentId); char* parentItemId = getParentSubString(parentId);
if (parentItemId) { if (parentItemId)
{
value = searchCacheForValueEx(self, itemId, parentItemId, idx, componentId, outSpec); value = searchCacheForValueEx(self, itemId, parentItemId, idx, componentId, outSpec);
} }
} }
else { else
{
const char* childId = getChildSubString(itemId, parentId); const char* childId = getChildSubString(itemId, parentId);
if (childId) { if (childId)
{
MmsVariableSpecification* typeSpec = MmsDomain_getNamedVariable(self->domain, parentId); MmsVariableSpecification* typeSpec = MmsDomain_getNamedVariable(self->domain, parentId);
value = MmsVariableSpecification_getChildValue(typeSpec, cacheEntry->value, childId); value = MmsVariableSpecification_getChildValue(typeSpec, cacheEntry->value, childId);
if (value) { if (value)
{
if (idx != -1) { if (idx != -1)
if (MmsValue_getType(value) == MMS_ARRAY) { {
if (MmsValue_getType(value) == MMS_ARRAY)
{
MmsValue* elementValue = MmsValue_getElement(value, idx); MmsValue* elementValue = MmsValue_getElement(value, idx);
if (elementValue) { if (elementValue)
if ((componentId != NULL) && (componentId[0] != 0)) { {
if ((componentId != NULL) && (componentId[0] != 0))
{
MmsVariableSpecification* childSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId); MmsVariableSpecification* childSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId);
if (childSpec) { if (childSpec)
{
MmsVariableSpecification* elementSpec = childSpec->typeSpec.array.elementTypeSpec; MmsVariableSpecification* elementSpec = childSpec->typeSpec.array.elementTypeSpec;
if (elementSpec) { if (elementSpec)
{
MmsValue* componentValue = MmsVariableSpecification_getChildValue(elementSpec, elementValue, componentId); MmsValue* componentValue = MmsVariableSpecification_getChildValue(elementSpec, elementValue, componentId);
if (componentValue) { if (componentValue)
value = componentValue; value = componentValue;
} }
} }
} }
} else
else { {
value = elementValue; value = elementValue;
} }
} }
@ -208,11 +221,10 @@ searchCacheForValueEx(MmsValueCache self, const char* itemId, char* parentId, in
} }
} }
if (outSpec) { if (outSpec)
*outSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId); *outSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId);
} }
} }
}
return value; return value;
} }
@ -224,14 +236,15 @@ MmsValueCache_lookupValueEx(MmsValueCache self, const char* itemId, int idx, con
MmsValueCacheEntry* cacheEntry = (MmsValueCacheEntry*) Map_getEntry(self->map, (void*) itemId); MmsValueCacheEntry* cacheEntry = (MmsValueCacheEntry*) Map_getEntry(self->map, (void*) itemId);
if (cacheEntry) { if (cacheEntry)
if (outSpec) { {
if (outSpec)
*outSpec = cacheEntry->typeSpec; *outSpec = cacheEntry->typeSpec;
}
return cacheEntry->value; return cacheEntry->value;
} }
else { else
{
char itemIdCopy[65]; char itemIdCopy[65];
char componentIdCopyBuf[65]; char componentIdCopyBuf[65];
@ -239,16 +252,14 @@ MmsValueCache_lookupValueEx(MmsValueCache self, const char* itemId, int idx, con
char* componentIdCopy = NULL; char* componentIdCopy = NULL;
if (componentId) { if (componentId)
componentIdCopy = StringUtils_copyStringMax(componentIdCopyBuf, 65, componentId); componentIdCopy = StringUtils_copyStringMax(componentIdCopyBuf, 65, componentId);
}
char* parentItemId = getParentSubString(itemIdCopy); char* parentItemId = getParentSubString(itemIdCopy);
if (parentItemId != NULL) { if (parentItemId)
value = searchCacheForValueEx(self, itemId, parentItemId, idx, componentIdCopy, outSpec); value = searchCacheForValueEx(self, itemId, parentItemId, idx, componentIdCopy, outSpec);
} }
}
return value; return value;
} }
@ -256,7 +267,8 @@ MmsValueCache_lookupValueEx(MmsValueCache self, const char* itemId, int idx, con
static void static void
cacheEntryDelete(MmsValueCacheEntry* entry) cacheEntryDelete(MmsValueCacheEntry* entry)
{ {
if (entry != NULL) { if (entry)
{
MmsValue_delete(entry->value); MmsValue_delete(entry->value);
GLOBAL_FREEMEM(entry); GLOBAL_FREEMEM(entry);
} }
@ -265,6 +277,9 @@ cacheEntryDelete(MmsValueCacheEntry* entry)
void void
MmsValueCache_destroy(MmsValueCache self) MmsValueCache_destroy(MmsValueCache self)
{ {
if (self)
{
Map_deleteDeep(self->map, true, (void (*) (void*)) cacheEntryDelete); Map_deleteDeep(self->map, true, (void (*) (void*)) cacheEntryDelete);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }

@ -46,7 +46,8 @@ mmsServer_createMmsWriteResponse(MmsServerConnection connection,
uint32_t accessResultsLength = 0; uint32_t accessResultsLength = 0;
int i; int i;
for (i = 0; i < numberOfItems; i++) { for (i = 0; i < numberOfItems; i++)
{
if (accessResults[i] < 0) if (accessResults[i] < 0)
accessResultsLength += 2; accessResultsLength += 2;
else else
@ -57,7 +58,8 @@ mmsServer_createMmsWriteResponse(MmsServerConnection connection,
+ 1 + BerEncoder_determineLengthSize(accessResultsLength) + 1 + BerEncoder_determineLengthSize(accessResultsLength)
+ accessResultsLength; + accessResultsLength;
if ((int)(writeResponseLength + 1) > response->maxSize) { if ((int)(writeResponseLength + 1) > response->maxSize)
{
/* TODO add log message */ /* TODO add log message */
response->size = 0; response->size = 0;
@ -74,12 +76,15 @@ mmsServer_createMmsWriteResponse(MmsServerConnection connection,
bufPos = BerEncoder_encodeTL(0xa5, accessResultsLength, buffer, bufPos); bufPos = BerEncoder_encodeTL(0xa5, accessResultsLength, buffer, bufPos);
for (i = 0; i < numberOfItems; i++) { for (i = 0; i < numberOfItems; i++)
if (accessResults[i] < 0) { {
if (accessResults[i] < 0)
{
buffer[bufPos++] = 0x81; buffer[bufPos++] = 0x81;
buffer[bufPos++] = 0x00; buffer[bufPos++] = 0x00;
} }
else { else
{
buffer[bufPos++] = 0x80; buffer[bufPos++] = 0x80;
buffer[bufPos++] = 0x01; buffer[bufPos++] = 0x01;
buffer[bufPos++] = (uint8_t) accessResults[i]; buffer[bufPos++] = (uint8_t) accessResults[i];
@ -349,7 +354,8 @@ createWriteNamedVariableListResponse(
int numberOfWriteItems = LinkedList_size(variables); int numberOfWriteItems = LinkedList_size(variables);
if (numberOfWriteItems > CONFIG_MMS_WRITE_SERVICE_MAX_NUMBER_OF_WRITE_ITEMS) { if (numberOfWriteItems > CONFIG_MMS_WRITE_SERVICE_MAX_NUMBER_OF_WRITE_ITEMS)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_OTHER, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_OTHER, response);
return; return;
} }
@ -362,7 +368,8 @@ createWriteNamedVariableListResponse(
int i = 0; int i = 0;
for (element = LinkedList_getNext(variables); element != NULL; element = LinkedList_getNext(element)) { for (element = LinkedList_getNext(variables); element != NULL; element = LinkedList_getNext(element))
{
MmsNamedVariableListEntry variableListEntry = (MmsNamedVariableListEntry) LinkedList_getData(element); MmsNamedVariableListEntry variableListEntry = (MmsNamedVariableListEntry) LinkedList_getData(element);
MmsDomain* variableDomain = MmsNamedVariableListEntry_getDomain(variableListEntry); MmsDomain* variableDomain = MmsNamedVariableListEntry_getDomain(variableListEntry);
@ -374,14 +381,17 @@ createWriteNamedVariableListResponse(
MmsValue* newValue = mmsMsg_parseDataElement(dataElement); MmsValue* newValue = mmsMsg_parseDataElement(dataElement);
if (newValue == NULL) { if (newValue == NULL)
{
accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT; accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
} }
else if (MmsValue_equalTypes(oldValue, newValue) == false) { else if (MmsValue_equalTypes(oldValue, newValue) == false)
{
MmsValue_delete(newValue); MmsValue_delete(newValue);
accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT; accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT;
} }
else { else
{
MmsDataAccessError valueIndication = MmsDataAccessError valueIndication =
mmsServer_setValue(connection->server, variableDomain, variableName, newValue, connection); mmsServer_setValue(connection->server, variableDomain, variableName, newValue, connection);
@ -420,38 +430,42 @@ handleWriteNamedVariableListRequest(
MmsDomain* domain = MmsDevice_getDomain(MmsServer_getDevice(connection->server), domainIdStr); MmsDomain* domain = MmsDevice_getDomain(MmsServer_getDevice(connection->server), domainIdStr);
if (domain == NULL) { if (domain == NULL)
{
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS write: domain %s not found!\n", domainIdStr); printf("MMS write: domain %s not found!\n", domainIdStr);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
return; return;
} }
else { else
{
MmsNamedVariableList namedList = MmsDomain_getNamedVariableList(domain, nameIdStr); MmsNamedVariableList namedList = MmsDomain_getNamedVariableList(domain, nameIdStr);
if (namedList) { if (namedList)
{
MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_WRITE, MMS_DOMAIN_SPECIFIC, domain, namedList->name, connection); MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_WRITE, MMS_DOMAIN_SPECIFIC, domain, namedList->name, connection);
if (accessError == MMS_ERROR_NONE) { if (accessError == MMS_ERROR_NONE)
{
createWriteNamedVariableListResponse(connection, writeRequest, invokeId, namedList, response); createWriteNamedVariableListResponse(connection, writeRequest, invokeId, namedList, response);
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS write: named variable list %s access error: %i\n", nameIdStr, accessError); if (DEBUG_MMS_SERVER) printf("MMS write: named variable list %s access error: %i\n", nameIdStr, accessError);
mmsMsg_createServiceErrorPdu(invokeId, response, accessError); mmsMsg_createServiceErrorPdu(invokeId, response, accessError);
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS write: named variable list %s not found!\n", nameIdStr); if (DEBUG_MMS_SERVER) printf("MMS write: named variable list %s not found!\n", nameIdStr);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
} }
} }
} }
else if (writeRequest->variableAccessSpecification.choice.variableListName.present == ObjectName_PR_vmdspecific) { else if (writeRequest->variableAccessSpecification.choice.variableListName.present == ObjectName_PR_vmdspecific)
{
char listName[65]; char listName[65];
mmsMsg_copyAsn1IdentifierToStringBuffer(writeRequest->variableAccessSpecification.choice.variableListName.choice.vmdspecific, mmsMsg_copyAsn1IdentifierToStringBuffer(writeRequest->variableAccessSpecification.choice.variableListName.choice.vmdspecific,
@ -459,27 +473,31 @@ handleWriteNamedVariableListRequest(
MmsNamedVariableList namedList = mmsServer_getNamedVariableListWithName(connection->server->device->namedVariableLists, listName); MmsNamedVariableList namedList = mmsServer_getNamedVariableListWithName(connection->server->device->namedVariableLists, listName);
if (namedList) { if (namedList)
{
MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_WRITE, MMS_VMD_SPECIFIC, NULL, namedList->name, connection); MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_WRITE, MMS_VMD_SPECIFIC, NULL, namedList->name, connection);
if (accessError == MMS_ERROR_NONE) { if (accessError == MMS_ERROR_NONE)
{
createWriteNamedVariableListResponse(connection, writeRequest, invokeId, namedList, response); createWriteNamedVariableListResponse(connection, writeRequest, invokeId, namedList, response);
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS write: vmd specific named variable list %s access error: %i\n", namedList->name, accessError); if (DEBUG_MMS_SERVER) printf("MMS write: vmd specific named variable list %s access error: %i\n", namedList->name, accessError);
mmsMsg_createServiceErrorPdu(invokeId, response, accessError); mmsMsg_createServiceErrorPdu(invokeId, response, accessError);
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS write: vmd specific named variable list %s not found!\n", listName); if (DEBUG_MMS_SERVER) printf("MMS write: vmd specific named variable list %s not found!\n", listName);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
} }
} }
#if (MMS_DYNAMIC_DATA_SETS == 1) #if (MMS_DYNAMIC_DATA_SETS == 1)
else if (writeRequest->variableAccessSpecification.choice.variableListName.present == ObjectName_PR_aaspecific) { else if (writeRequest->variableAccessSpecification.choice.variableListName.present == ObjectName_PR_aaspecific)
{
char listName[65]; char listName[65];
mmsMsg_copyAsn1IdentifierToStringBuffer(writeRequest->variableAccessSpecification.choice.variableListName.choice.aaspecific, mmsMsg_copyAsn1IdentifierToStringBuffer(writeRequest->variableAccessSpecification.choice.variableListName.choice.aaspecific,
@ -487,21 +505,23 @@ handleWriteNamedVariableListRequest(
MmsNamedVariableList namedList = MmsServerConnection_getNamedVariableList(connection, listName); MmsNamedVariableList namedList = MmsServerConnection_getNamedVariableList(connection, listName);
if (namedList) { if (namedList)
{
MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_WRITE, MMS_ASSOCIATION_SPECIFIC, NULL, namedList->name, connection); MmsError accessError = mmsServer_callVariableListChangedHandler(MMS_VARLIST_WRITE, MMS_ASSOCIATION_SPECIFIC, NULL, namedList->name, connection);
if (accessError == MMS_ERROR_NONE) { if (accessError == MMS_ERROR_NONE)
{
createWriteNamedVariableListResponse(connection, writeRequest, invokeId, namedList, response); createWriteNamedVariableListResponse(connection, writeRequest, invokeId, namedList, response);
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS write: association specific named variable list %s access error: %i\n", namedList->name, accessError); if (DEBUG_MMS_SERVER) printf("MMS write: association specific named variable list %s access error: %i\n", namedList->name, accessError);
mmsMsg_createServiceErrorPdu(invokeId, response, accessError); mmsMsg_createServiceErrorPdu(invokeId, response, accessError);
} }
} }
else { else
{
if (DEBUG_MMS_SERVER) printf("MMS write: association specific named variable list %s not found!\n", listName); if (DEBUG_MMS_SERVER) printf("MMS write: association specific named variable list %s not found!\n", listName);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
} }
@ -583,7 +603,8 @@ mmsServer_handleWriteRequest(
rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, maxBufPos); rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, maxBufPos);
if (rval.code != RC_OK) { if (rval.code != RC_OK)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_function; goto exit_function;
} }
@ -610,17 +631,20 @@ mmsServer_handleWriteRequest(
{ {
int numberOfWriteItems = writeRequest->variableAccessSpecification.choice.listOfVariable.list.count; int numberOfWriteItems = writeRequest->variableAccessSpecification.choice.listOfVariable.list.count;
if (numberOfWriteItems < 1) { if (numberOfWriteItems < 1)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
goto exit_function; goto exit_function;
} }
if (numberOfWriteItems > CONFIG_MMS_WRITE_SERVICE_MAX_NUMBER_OF_WRITE_ITEMS) { if (numberOfWriteItems > CONFIG_MMS_WRITE_SERVICE_MAX_NUMBER_OF_WRITE_ITEMS)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_OTHER, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_OTHER, response);
goto exit_function; goto exit_function;
} }
if (writeRequest->listOfData.list.count != numberOfWriteItems) { if (writeRequest->listOfData.list.count != numberOfWriteItems)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
goto exit_function; goto exit_function;
} }
@ -636,7 +660,8 @@ mmsServer_handleWriteRequest(
ListOfVariableSeq_t* varSpec = ListOfVariableSeq_t* varSpec =
writeRequest->variableAccessSpecification.choice.listOfVariable.list.array[i]; writeRequest->variableAccessSpecification.choice.listOfVariable.list.array[i];
if (varSpec->variableSpecification.present != VariableSpecification_PR_name) { if (varSpec->variableSpecification.present != VariableSpecification_PR_name)
{
accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED; accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED;
continue; continue;
} }
@ -659,7 +684,8 @@ mmsServer_handleWriteRequest(
domain = MmsDevice_getDomain(device, domainIdStr); domain = MmsDevice_getDomain(device, domainIdStr);
if (domain == NULL) { if (domain == NULL)
{
accessResults[i] = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT; accessResults[i] = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT;
continue; continue;
} }
@ -672,7 +698,8 @@ mmsServer_handleWriteRequest(
} }
#if (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) #if (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1)
else if (varSpec->variableSpecification.choice.name.present == ObjectName_PR_vmdspecific) { else if (varSpec->variableSpecification.choice.name.present == ObjectName_PR_vmdspecific)
{
Identifier_t nameId = varSpec->variableSpecification.choice.name.choice.vmdspecific; Identifier_t nameId = varSpec->variableSpecification.choice.name.choice.vmdspecific;
mmsMsg_copyAsn1IdentifierToStringBuffer(nameId, nameIdStr, 65); mmsMsg_copyAsn1IdentifierToStringBuffer(nameId, nameIdStr, 65);
@ -681,12 +708,14 @@ mmsServer_handleWriteRequest(
} }
#endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */ #endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */
else { else
{
accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED; accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED;
continue; continue;
} }
if (variable == NULL) { if (variable == NULL)
{
accessResults[i] = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT; accessResults[i] = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT;
continue; continue;
} }
@ -715,7 +744,8 @@ mmsServer_handleWriteRequest(
MmsValue* value = mmsMsg_parseDataElement(dataElement); MmsValue* value = mmsMsg_parseDataElement(dataElement);
if (value == NULL) { if (value == NULL)
{
accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT; accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
continue; continue;
} }
@ -729,7 +759,8 @@ mmsServer_handleWriteRequest(
{ {
MmsValue* cachedArray = MmsServer_getValueFromCache(connection->server, domain, nameIdStr); MmsValue* cachedArray = MmsServer_getValueFromCache(connection->server, domain, nameIdStr);
if (cachedArray == NULL) { if (cachedArray == NULL)
{
accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT; accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
goto end_of_main_loop; goto end_of_main_loop;
} }
@ -788,12 +819,14 @@ mmsServer_handleWriteRequest(
MmsValue* newElement = MmsValue_getElement(value, elementNo); MmsValue* newElement = MmsValue_getElement(value, elementNo);
MmsValue* elementValue = MmsValue_getElement(cachedArray, index++); MmsValue* elementValue = MmsValue_getElement(cachedArray, index++);
if ((elementValue == NULL) || (newElement == NULL) ) { if ((elementValue == NULL) || (newElement == NULL) )
{
accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT; accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT;
goto end_of_main_loop; goto end_of_main_loop;
} }
if (MmsValue_update(elementValue, newElement) == false) { if (MmsValue_update(elementValue, newElement) == false)
{
accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT; accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT;
goto end_of_main_loop; goto end_of_main_loop;
} }
@ -840,7 +873,9 @@ mmsServer_handleWriteRequest(
if (sendResponse) if (sendResponse)
mmsServer_createMmsWriteResponse(connection, invokeId, response, numberOfWriteItems, accessResults); mmsServer_createMmsWriteResponse(connection, invokeId, response, numberOfWriteItems, accessResults);
} }
else { /* unknown request type */ else
{
/* unknown request type */
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
goto exit_function; goto exit_function;
} }

Loading…
Cancel
Save