- added support for sorted getNameList reponse (can be switched off by setting CONFIG_MMS_SORT_NAME_LIST to 0)

pull/6/head
Michael Zillgith 10 years ago
parent 23d7092a5c
commit 9896742d12

@ -188,6 +188,10 @@
/* VMD scope named variables are not used by IEC 61850 (one application is ICCP) */
#define CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES 0
/* Sort getNameList response according to the MMS specified collation order - this is required by the standard
* Set to 0 only for performance reasons and when no certification is required! */
#define CONFIG_MMS_SORT_NAME_LIST 1
#define CONFIG_INCLUDE_PLATFORM_SPECIFIC_HEADERS 0
/* use short FC defines as in old API */

@ -300,69 +300,64 @@ StringUtils_compareStrings(const char* a, const char* b)
void
StringUtils_sortList(LinkedList list)
{
LinkedList firstElement = list->next;
LinkedList prevElement = NULL;
LinkedList selectedElement = list->next;
while (true) {
if (selectedElement == NULL) /* list is empty */
return;
/* Check for end of list */
if (firstElement->next) {
list->next = selectedElement->next;
selectedElement->next = NULL;
char* str1 = (char*) LinkedList_getData(firstElement);
char* str2 = (char*) LinkedList_getData(firstElement->next);
struct sLinkedList sortedListData;
/* Compare first element with next element */
if (StringUtils_compareStrings(str1, str2) > 0) {
LinkedList removedElement = firstElement;
LinkedList sortedList = &sortedListData;
if (firstElement == list->next)
list->next = firstElement->next;
else
prevElement->next = firstElement->next;
sortedList->next = selectedElement;
firstElement = firstElement->next;
selectedElement = list->next;
/* search for place to insert */
LinkedList compareElement = removedElement->next->next;
LinkedList prevCompareElement = removedElement->next;
while (selectedElement != NULL) {
while (true) {
str2 = (char*) LinkedList_getData(compareElement);
list->next = selectedElement->next;
selectedElement->next = NULL;
if (StringUtils_compareStrings(str1, str2) < 0) {
/* insert element before */
prevCompareElement->next = removedElement;
removedElement->next = compareElement;
char* str1 = (char*) LinkedList_getData(selectedElement);
break;
}
LinkedList prevElement = sortedList;
prevCompareElement = compareElement;
compareElement = compareElement->next;
while (true) {
/* Are we at the end of the list? */
if (compareElement == NULL) {
/* Insert removed element at end of list */
prevCompareElement->next = removedElement;
removedElement->next = NULL;
break;
}
if (prevElement->next == NULL) {
prevElement->next = selectedElement;
break;
}
char* str2 = (char*) LinkedList_getData(prevElement->next);
if (StringUtils_compareStrings(str1, str2) < 0) {
/* insert "nextElement" before */
if (sortedList == prevElement) {
selectedElement->next = sortedList->next;
sortedList->next = selectedElement;
}
else {
selectedElement->next = prevElement->next;
prevElement->next = selectedElement;
}
break;
}
else {
prevElement = firstElement;
firstElement = firstElement->next;
}
prevElement = prevElement->next;
}
selectedElement = list->next;
}
else
if (selectedElement == NULL)
break;
}
}
list->next = sortedList->next;
}

@ -32,6 +32,10 @@
* MMS GetNameList Service
*********************************************************************************************/
#ifndef CONFIG_MMS_SORT_NAME_LIST
#define CONFIG_MMS_SORT_NAME_LIST 1
#endif
#define OBJECT_CLASS_NAMED_VARIABLE 0
#define OBJECT_CLASS_NAMED_VARIABLE_LIST 2
#define OBJECT_CLASS_JOURNAL 8
@ -160,84 +164,6 @@ getNameListDomainSpecific(MmsServerConnection connection, char* domainName)
}
#if 0
typedef struct sGetNextListElementDomainSpecificState {
const char* continueAfter;
MmsVariableSpecification** variables;
int variablesCount;
} GetNextListElementDomainSpecificState;
static bool
getNextListElement_DomainSpecific_init(MmsServerConnection connection, char* domainName,
GetNextListElementDomainSpecificState* state, const char* continueAfter)
{
MmsDevice* device = MmsServer_getDevice(connection->server);
MmsDomain* domain = MmsDevice_getDomain(device, domainName);
state->continueAfter = continueAfter;
if (domain != NULL) {
state->variables = domain->namedVariables;
state->variablesCount = domain->namedVariablesCount;
}
}
static LinkedList
TEMP_addSubNamedVaribleNamesToList(LinkedList nameList, char* prefix, MmsVariableSpecification* variable)
{
LinkedList listElement = nameList;
if (variable->type == MMS_STRUCTURE) {
int i;
MmsVariableSpecification** variables = variable->typeSpec.structure.elements;
for (i = 0; i < variable->typeSpec.structure.elementCount; i++) {
char* variableName = appendMmsSubVariable(prefix, variables[i]->name);
listElement = LinkedList_insertAfter(listElement, variableName);
listElement = addSubNamedVaribleNamesToList(listElement, variableName, variables[i]);
}
}
return listElement;
}
// return NULL if no more elements are left
static char*
getNextListElement_DomainSpecific(void* stateParameter)
{
GetNextListElementDomainSpecificState* state = (GetNextListElementDomainSpecificState*) stateParameter;
= NULL;
int i;
LinkedList element = nameList;
for (i = 0; i < state->variablesCount; i++) {
element = LinkedList_insertAfter(element, copyString(state->variables[i]->name));
#if (CONFIG_MMS_SUPPORT_FLATTED_NAME_SPACE == 1)
char* prefix = state->variables[i]->name;
element = TEMP_addSubNamedVaribleNamesToList(element, prefix, state->variables[i]);
#endif
}
return nameList;
}
#endif
#if (MMS_DATA_SET_SERVICE == 1)
static LinkedList
@ -409,122 +335,6 @@ createNameListResponse(
printf("MMS_SERVER: getNameList: encoded %i bytes\n", response->size);
}
#if 0
static void
NEW_createNameListResponse(
MmsServerConnection connection,
int invokeId,
LinkedList nameList,
ByteBuffer* response,
char* continueAfter)
{
#if 0
//TODO move continueAfter handling in variable name generation code!
LinkedList startElement = NULL;
if (continueAfter != NULL) {
LinkedList element = nameList;
while ((element = LinkedList_getNext(element)) != NULL) {
if (strcmp((char*) (element->data), continueAfter) == 0) {
startElement = element;
break;
}
}
if (startElement == NULL) {
mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED);
return;
}
}
/* determine number of identifiers to include in response */
if (startElement == NULL)
startElement = nameList;
#endif
int nameCount = 0;
int estimatedMmsPduLength = 27; /* estimated overhead size of PDU encoding */
int maxPduSize = connection->maxPduSize;
bool moreFollows = false;
LinkedList element = startElement;
uint32_t identifierListSize = 0;
while ((element = LinkedList_getNext(element)) != NULL) {
int elementLength;
elementLength = BerEncoder_determineEncodedStringSize((char*) element->data);
if ((estimatedMmsPduLength + elementLength) > maxPduSize) {
moreFollows = true;
break;
}
else {
estimatedMmsPduLength += elementLength;
identifierListSize += elementLength;
nameCount++;
}
}
uint32_t listOfIdentifierSize = 1 + BerEncoder_determineLengthSize(identifierListSize) + identifierListSize;
uint32_t getNameListSize = listOfIdentifierSize;
if (moreFollows == false)
getNameListSize += 3;
uint32_t confirmedServiceResponseSize = 1 + BerEncoder_determineLengthSize(getNameListSize) + getNameListSize;
uint32_t invokeIdSize = BerEncoder_UInt32determineEncodedSize((uint32_t) invokeId) + 2;
uint32_t confirmedResponsePDUSize = confirmedServiceResponseSize + invokeIdSize;
/* encode response */
element = startElement;
uint8_t* buffer = response->buffer;
int bufPos = 0;
bufPos = BerEncoder_encodeTL(0xa1, confirmedResponsePDUSize, buffer, bufPos);
bufPos = BerEncoder_encodeTL(0x02, invokeIdSize - 2, buffer, bufPos);
bufPos = BerEncoder_encodeUInt32((uint32_t) invokeId, buffer, bufPos);
bufPos = BerEncoder_encodeTL(0xa1, getNameListSize, buffer, bufPos);
bufPos = BerEncoder_encodeTL(0xa0, identifierListSize, buffer, bufPos);
int i = 0;
while ((element = LinkedList_getNext(element)) != NULL) {
bufPos = BerEncoder_encodeStringWithTag(0x1a, (char*) element->data, buffer, bufPos);
i++;
if (i == nameCount)
break;
}
if (moreFollows == false)
bufPos = BerEncoder_encodeBoolean(0x81, moreFollows, buffer, bufPos);
response->size = bufPos;
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: getNameList: encoded %i bytes\n", response->size);
}
#endif
void
mmsServer_handleGetNameListRequest(
MmsServerConnection connection,
@ -626,14 +436,9 @@ mmsServer_handleGetNameListRequest(
mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
else {
printf("\n-------------\n");
LinkedList_printStringList(nameList);
#if (CONFIG_MMS_SORT_NAME_LIST == 1)
StringUtils_sortList(nameList);
printf("\n-------------\n");
LinkedList_printStringList(nameList);
printf("\n-------------\n");
#endif
createNameListResponse(connection, invokeId, nameList, response, continueAfterId);
LinkedList_destroy(nameList);
@ -646,7 +451,10 @@ mmsServer_handleGetNameListRequest(
if (nameList == NULL)
mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
else {
#if (CONFIG_MMS_SORT_NAME_LIST == 1)
StringUtils_sortList(nameList);
#endif
createNameListResponse(connection, invokeId, nameList, response, continueAfter);
LinkedList_destroy(nameList);
@ -667,7 +475,9 @@ mmsServer_handleGetNameListRequest(
LinkedList nameList = getDomainNames(connection);
#if (CONFIG_MMS_SORT_NAME_LIST == 1)
StringUtils_sortList(nameList);
#endif
createNameListResponse(connection, invokeId, nameList, response, continueAfter);
@ -688,7 +498,9 @@ mmsServer_handleGetNameListRequest(
else if (objectClass == OBJECT_CLASS_NAMED_VARIABLE_LIST) {
LinkedList nameList = getnamedVariableListsVMDSpecific(connection);
#if (CONFIG_MMS_SORT_NAME_LIST == 1)
StringUtils_sortList(nameList);
#endif
createNameListResponse(connection, invokeId, nameList, response, continueAfter);
@ -699,7 +511,9 @@ mmsServer_handleGetNameListRequest(
else if (objectClass == OBJECT_CLASS_JOURNAL) {
LinkedList nameList = LinkedList_create();
// StringUtils_sortList(nameList);
#if (CONFIG_MMS_SORT_NAME_LIST == 1)
StringUtils_sortList(nameList);
#endif
createNameListResponse(connection, invokeId, nameList, response, continueAfter);
@ -720,7 +534,9 @@ mmsServer_handleGetNameListRequest(
if (objectClass == OBJECT_CLASS_NAMED_VARIABLE_LIST) {
LinkedList nameList = getNamedVariableListAssociationSpecific(connection);
#if (CONFIG_MMS_SORT_NAME_LIST == 1)
StringUtils_sortList(nameList);
#endif
createNameListResponse(connection, invokeId, nameList, response, continueAfter);

Loading…
Cancel
Save