static MmsNamedVariableList
createNamedVariableList(MmsDevice* device,
                        DefineNamedVariableListRequest_t* request,
                        char* variableListName)
{
    MmsNamedVariableList namedVariableList = MmsNamedVariableList_create(variableListName, true);

    int variableCount = request->listOfVariable.list.count;

    int i;
    for (i = 0; i < variableCount; i++) {
        VariableSpecification_t* varSpec =
            &request->listOfVariable.list.array[i]->variableSpecification;

        if (varSpec->present == VariableSpecification_PR_name) {
            char* variableName = createStringFromBuffer(
                                     varSpec->choice.name.choice.domainspecific.itemId.buf,
                                     varSpec->choice.name.choice.domainspecific.itemId.size);

            char* domainId = createStringFromBuffer(
                                 varSpec->choice.name.choice.domainspecific.domainId.buf,
                                 varSpec->choice.name.choice.domainspecific.domainId.size);

            MmsDomain* domain = MmsDevice_getDomain(device, domainId);

            MmsNamedVariableListEntry variable =
                MmsNamedVariableListEntry_create(domain, variableName);

            MmsNamedVariableList_addVariable(namedVariableList, variable);

            free(domainId);
            free(variableName);
        }
        else {
            MmsNamedVariableList_destroy(namedVariableList);
            namedVariableList = NULL;
            break;
        }
    }

    return namedVariableList;
}
void
mmsServer_handleDefineNamedVariableListRequest(
		MmsServerConnection connection,
		uint8_t* buffer, int bufPos, int maxBufPos,
		uint32_t invokeId,
		ByteBuffer* response)
{
	DefineNamedVariableListRequest_t* request = 0;

	MmsPdu_t* mmsPdu = 0;

	asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, maxBufPos);

	if (rval.code != RC_OK) {
	    mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
	    goto exit_function;
	}

	request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.defineNamedVariableList);

	MmsDevice* device = MmsServer_getDevice(connection->server);

	if (request->variableListName.present == ObjectName_PR_domainspecific) {

	    char domainName[65];

	    if (request->variableListName.choice.domainspecific.domainId.size > 64) {
	        mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
	        goto exit_free_struct;
	    }

	    StringUtils_createStringFromBufferInBuffer(domainName,
	            request->variableListName.choice.domainspecific.domainId.buf,
	            request->variableListName.choice.domainspecific.domainId.size);

		MmsDomain* domain = MmsDevice_getDomain(device, domainName);

		if (domain == NULL) {
			mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
			goto exit_free_struct;
		}

		if (LinkedList_size(domain->namedVariableLists) < CONFIG_MMS_MAX_NUMBER_OF_DOMAIN_SPECIFIC_DATA_SETS) {
		    char variableListName[65];

		    if (request->variableListName.choice.domainspecific.itemId.size > 64) {
		        mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
                goto exit_free_struct;
		    }

		    StringUtils_createStringFromBufferInBuffer(variableListName,
		            request->variableListName.choice.domainspecific.itemId.buf,
                    request->variableListName.choice.domainspecific.itemId.size);

            if (MmsDomain_getNamedVariableList(domain, variableListName) != NULL) {
                mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS);
            }
            else {
                MmsError mmsError;

                MmsNamedVariableList namedVariableList = createNamedVariableList(domain, device,
                                request, variableListName, &mmsError);

                if (namedVariableList != NULL) {

                    mmsError = mmsServer_callVariableListChangedHandler(true, MMS_DOMAIN_SPECIFIC, domain, variableListName, connection);

                    if (mmsError == MMS_ERROR_NONE) {
                        MmsDomain_addNamedVariableList(domain, namedVariableList);
                        createDefineNamedVariableListResponse(invokeId, response);
                    }
                    else {
                        MmsNamedVariableList_destroy(namedVariableList);
                        mmsServer_createConfirmedErrorPdu(invokeId, response, mmsError);
                    }
                }
                else
                    mmsServer_createConfirmedErrorPdu(invokeId, response, mmsError);
            }
		}
		else
		    mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_CAPABILITY_UNAVAILABLE);


	}
	else if (request->variableListName.present == ObjectName_PR_aaspecific) {

	    if (LinkedList_size(connection->namedVariableLists) < CONFIG_MMS_MAX_NUMBER_OF_ASSOCIATION_SPECIFIC_DATA_SETS) {

	        char variableListName[65];

	        if (request->variableListName.choice.aaspecific.size > 64) {
                mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
                goto exit_free_struct;
            }

	        StringUtils_createStringFromBufferInBuffer(variableListName,
	                request->variableListName.choice.aaspecific.buf,
	                request->variableListName.choice.aaspecific.size);

            if (MmsServerConnection_getNamedVariableList(connection, variableListName) != NULL) {
                mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS);
            }
            else {
                MmsError mmsError;

                MmsNamedVariableList namedVariableList = createNamedVariableList(NULL, device,
                        request, variableListName, &mmsError);

                if (namedVariableList != NULL) {

                    if (mmsServer_callVariableListChangedHandler(true, MMS_ASSOCIATION_SPECIFIC, NULL, variableListName, connection) == MMS_ERROR_NONE) {
                        MmsServerConnection_addNamedVariableList(connection, namedVariableList);
                        createDefineNamedVariableListResponse(invokeId, response);
                    }
                    else {
                        MmsNamedVariableList_destroy(namedVariableList);
                        mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED);
                    }

                }
                else
                    mmsServer_createConfirmedErrorPdu(invokeId, response, mmsError);
            }
	    }
	    else
	        mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_CAPABILITY_UNAVAILABLE);
	}
	else
		mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_TYPE_UNSUPPORTED);

exit_free_struct:
	asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);

exit_function:
    return;
}
static MmsNamedVariableList
createNamedVariableList(MmsDomain* domain, MmsDevice* device,
		DefineNamedVariableListRequest_t* request,
		char* variableListName, MmsError* mmsError)
{
    MmsNamedVariableList namedVariableList = NULL;

	int variableCount = request->listOfVariable.list.count;

	if (variableCount > CONFIG_MMS_MAX_NUMBER_OF_DATA_SET_MEMBERS) {
	    *mmsError = MMS_ERROR_DEFINITION_OTHER;
	    goto exit_function;
	}

	namedVariableList = MmsNamedVariableList_create(domain, variableListName, true);

	int i;
	for (i = 0; i < variableCount; i++) {
		VariableSpecification_t* varSpec =
				&request->listOfVariable.list.array[i]->variableSpecification;

		long arrayIndex = -1;

		char componentNameBuf[65];
		char* componentName = NULL;

		/* Handle alternate access specification - for array element definition */
		if (request->listOfVariable.list.array[i]->alternateAccess != NULL) {

			if (request->listOfVariable.list.array[i]->alternateAccess->list.count != 1) {
				MmsNamedVariableList_destroy(namedVariableList);
				namedVariableList = NULL;
				break;
			}
			else {

				struct AlternateAccess__Member* alternateAccess =
						request->listOfVariable.list.array[i]->alternateAccess->list.array[0];

				if ((alternateAccess->present == AlternateAccess__Member_PR_unnamed)
				    &&(alternateAccess->choice.unnamed->present == AlternateAccessSelection_PR_selectAlternateAccess)
				    && (alternateAccess->choice.unnamed->choice.selectAlternateAccess.accessSelection.present ==
				               AlternateAccessSelection__selectAlternateAccess__accessSelection_PR_index))
				{
					asn_INTEGER2long(&(alternateAccess->choice.unnamed->choice.selectAlternateAccess.accessSelection.choice.index),
							&arrayIndex);

					Identifier_t componentIdentifier = alternateAccess->choice.unnamed->
                            choice.selectAlternateAccess.alternateAccess->list.array[0]->
                            choice.unnamed->choice.selectAccess.choice.component;

					componentName =
					        StringUtils_createStringFromBufferInBuffer(componentNameBuf,
					                componentIdentifier.buf, componentIdentifier.size);

				}
				else {
					MmsNamedVariableList_destroy(namedVariableList);
					namedVariableList = NULL;
					*mmsError = MMS_ERROR_DEFINITION_INVALID_ADDRESS;
					break;
				}

			}

		}

		if (varSpec->present == VariableSpecification_PR_name) {

		    char variableName[65];
		    char domainId[65];

		    StringUtils_createStringFromBufferInBuffer(variableName,
		            varSpec->choice.name.choice.domainspecific.itemId.buf,
                    varSpec->choice.name.choice.domainspecific.itemId.size);

		    StringUtils_createStringFromBufferInBuffer(domainId,
		            varSpec->choice.name.choice.domainspecific.domainId.buf,
                    varSpec->choice.name.choice.domainspecific.domainId.size);

			MmsDomain* elementDomain = MmsDevice_getDomain(device, domainId);

			MmsAccessSpecifier accessSpecifier;

			accessSpecifier.domain = elementDomain;
			accessSpecifier.variableName = variableName;
			accessSpecifier.arrayIndex = arrayIndex;
			accessSpecifier.componentName = componentName;

			// check if element exists
			if (checkIfVariableExists(device, &accessSpecifier) == true) {

                MmsNamedVariableListEntry variable =
                        MmsNamedVariableListEntry_create(accessSpecifier);

                MmsNamedVariableList_addVariable(namedVariableList, variable);
			}
			else {
			    MmsNamedVariableList_destroy(namedVariableList);
                namedVariableList = NULL;
                i = variableCount; // exit loop after freeing loop variables
                *mmsError = MMS_ERROR_DEFINITION_OBJECT_UNDEFINED;
			}
		}
		else {
			MmsNamedVariableList_destroy(namedVariableList);
			namedVariableList = NULL;
			*mmsError = MMS_ERROR_DEFINITION_INVALID_ADDRESS;
			break;
		}
	}

exit_function:

	return namedVariableList;
}