static void addNamedVariableToResultList(MmsTypeSpecification* namedVariable, MmsDomain* domain, char* nameIdStr, LinkedList /*<MmsValue>*/ values, MmsServerConnection* connection, AlternateAccess_t* alternateAccess) { if (namedVariable != NULL) { if (DEBUG) printf("MMS read: found named variable %s with search string %s\n", namedVariable->name, nameIdStr); if (namedVariable->type == MMS_STRUCTURE) { MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr); if (value != NULL) { appendValueToResultList(value, values); } else { //TODO signal DataAccessError to client addComplexValueToResultList(namedVariable, values, connection, domain, nameIdStr); } } else if (namedVariable->type == MMS_ARRAY) { if (alternateAccess != NULL) { alternateArrayAccess(connection, alternateAccess, domain, nameIdStr, values, namedVariable); } else { //getCompleteArray MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr); appendValueToResultList(value, values); } } else { MmsValue* value = mmsServer_getValue(connection->server, domain, nameIdStr); if (value == NULL) { if (DEBUG) printf("MMS read: value of known variable is not found. Maybe illegal access to array element!\n"); appendErrorToResultList(values, 10 /* object-non-existant*/); } else appendValueToResultList(value, values); } } else appendErrorToResultList(values, 10 /* object-non-existant*/); }
static void handleReadListOfVariablesRequest( MmsServerConnection* connection, ReadRequest_t* read, uint32_t invokeId, ByteBuffer* response) { int variableCount = read->variableAccessSpecification.choice.listOfVariable.list.count; LinkedList /*<MmsValue>*/ values = LinkedList_create(); if (isSpecWithResult(read)) { /* add specification to result */ //TODO add va spec to result } MmsServer_lockModel(connection->server); int i; for (i = 0; i < variableCount; i++) { VariableSpecification_t varSpec = read->variableAccessSpecification.choice.listOfVariable.list.array[i]->variableSpecification; AlternateAccess_t* alternateAccess = read->variableAccessSpecification.choice.listOfVariable.list.array[i]->alternateAccess; if (varSpec.present == VariableSpecification_PR_name) { if (varSpec.choice.name.present == ObjectName_PR_domainspecific) { char* domainIdStr = mmsMsg_createStringFromAsnIdentifier( varSpec.choice.name.choice.domainspecific.domainId); char* nameIdStr = mmsMsg_createStringFromAsnIdentifier( varSpec.choice.name.choice.domainspecific.itemId); MmsDomain* domain = MmsDevice_getDomain(MmsServer_getDevice(connection->server), domainIdStr); if (domain == NULL) { if (DEBUG) printf("MMS read: domain %s not found!\n", domainIdStr); appendErrorToResultList(values, 10 /* object-non-existant*/); break; } MmsTypeSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameIdStr); addNamedVariableToResultList(namedVariable, domain, nameIdStr, values, connection, alternateAccess); free(domainIdStr); free(nameIdStr); } else { appendErrorToResultList(values, 10 /* object-non-existant*/); if (DEBUG) printf("MMS read: object name type not supported!\n"); } } else { //TODO should we send a ConfirmedErrorPdu here? if (DEBUG) printf("MMS read: varspec type not supported!\n"); } } encodeReadResponse(connection, invokeId, response, values, NULL); MmsServer_unlockModel(connection->server); exit: deleteValueList(values); }
static void alternateArrayAccess(MmsServerConnection* connection, AlternateAccess_t* alternateAccess, MmsDomain* domain, char* itemId, LinkedList values, MmsTypeSpecification* namedVariable) { if (mmsServer_isIndexAccess(alternateAccess)) { int lowIndex = mmsServer_getLowIndex(alternateAccess); int numberOfElements = mmsServer_getNumberOfElements(alternateAccess); if (DEBUG) printf("Alternate access index: %i elements %i\n", lowIndex, numberOfElements); int index = lowIndex; MmsValue* value = NULL; MmsValue* arrayValue = mmsServer_getValue(connection->server, domain, itemId); if (arrayValue != NULL) { if (numberOfElements == 0) if (isAccessToArrayComponent(alternateAccess)) { if (namedVariable->typeSpec.array.elementTypeSpec->type == MMS_STRUCTURE) { MmsValue* structValue = MmsValue_getElement(arrayValue, index); if (structValue != NULL) value = getComponentOfArrayElement(alternateAccess, namedVariable, structValue); } } else value = MmsValue_getElement(arrayValue, index); else { value = MmsValue_createEmtpyArray(numberOfElements); MmsValue_setDeletable(value); int resultIndex = 0; while (index < lowIndex + numberOfElements) { MmsValue* elementValue = NULL; elementValue = MmsValue_getElement(arrayValue, index); if (!MmsValue_isDeletable(elementValue)) elementValue = MmsValue_clone(elementValue); MmsValue_setElement(value, resultIndex, elementValue); index++; resultIndex++; } } appendValueToResultList(value, values); if (MmsValue_isDeletable(arrayValue)) MmsValue_delete(arrayValue); } else /* access error */ appendErrorToResultList(values, 10 /* object-non-existant*/); } else { // invalid access if (DEBUG) printf("Invalid alternate access\n"); appendErrorToResultList(values, 10 /* object-non-existant*/); } }
static void handleReadListOfVariablesRequest( MmsServerConnection connection, ReadRequest_t* read, uint32_t invokeId, ByteBuffer* response) { int variableCount = read->variableAccessSpecification.choice.listOfVariable.list.count; LinkedList /*<MmsValue>*/ values = LinkedList_create(); if (isSpecWithResult(read)) { /* add specification to result */ // ignore - not required for IEC 61850 } int i; for (i = 0; i < variableCount; i++) { VariableSpecification_t varSpec = read->variableAccessSpecification.choice.listOfVariable.list.array[i]->variableSpecification; AlternateAccess_t* alternateAccess = read->variableAccessSpecification.choice.listOfVariable.list.array[i]->alternateAccess; if (varSpec.present == VariableSpecification_PR_name) { if (varSpec.choice.name.present == ObjectName_PR_domainspecific) { char domainIdStr[65]; char nameIdStr[65]; mmsMsg_copyAsn1IdentifierToStringBuffer(varSpec.choice.name.choice.domainspecific.domainId, domainIdStr, 65); mmsMsg_copyAsn1IdentifierToStringBuffer(varSpec.choice.name.choice.domainspecific.itemId, nameIdStr, 65); MmsDomain* domain = MmsDevice_getDomain(MmsServer_getDevice(connection->server), domainIdStr); if (DEBUG_MMS_SERVER) printf("MMS_SERVER: READ domainId: (%s) nameId: (%s)\n", domainIdStr, nameIdStr); if (domain == NULL) { if (DEBUG_MMS_SERVER) printf("MMS_SERVER: READ domain %s not found!\n", domainIdStr); appendErrorToResultList(values, 10 /* object-non-existent*/); } else { MmsVariableSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameIdStr); if (namedVariable == NULL) appendErrorToResultList(values, 10 /* object-non-existent*/); else addNamedVariableToResultList(namedVariable, domain, nameIdStr, values, connection, alternateAccess); } } #if (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) else if (varSpec.choice.name.present == ObjectName_PR_vmdspecific) { char nameIdStr[65]; mmsMsg_copyAsn1IdentifierToStringBuffer(varSpec.choice.name.choice.vmdspecific, nameIdStr, 65); if (DEBUG_MMS_SERVER) printf("MMS_SERVER: READ vmd-specific nameId:%s\n", nameIdStr); MmsVariableSpecification* namedVariable = MmsDevice_getNamedVariable(MmsServer_getDevice(connection->server), nameIdStr); if (namedVariable == NULL) appendErrorToResultList(values, 10 /* object-non-existent*/); else addNamedVariableToResultList(namedVariable, (MmsDomain*) MmsServer_getDevice(connection->server), nameIdStr, values, connection, alternateAccess); } #endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */ else { appendErrorToResultList(values, 10 /* object-non-existent*/); if (DEBUG_MMS_SERVER) printf("MMS_SERVER: READ object name type not supported!\n"); } } else { if (DEBUG_MMS_SERVER) printf("MMS_SERVER: READ varspec type not supported!\n"); mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response); goto exit; } } encodeReadResponse(connection, invokeId, response, values, NULL); exit: deleteValueList(values); }