/**********************************************************************************************
 * mmsServer_handleWriteRequest
 * возвращает MmsServiceError
 *********************************************************************************************/
int mmsServer_handleWriteRequest( MmsServerConnection* connection,	WriteRequest_t* writeRequest,	int invokeId, ByteBuffer* response)
{
    ListOfVariableSeq_t* varSpec;
    Identifier_t domainId;
    char* domainIdStr;
    MmsDevice* device;
    MmsDomain* domain;
    Identifier_t nameId;
    char* nameIdStr;
    MmsTypeSpecification* variable;
    AlternateAccess_t* alternateAccess;
    Data_t* dataElement;
    MmsValue* value;
    MmsValueIndication valueIndication;

	if (writeRequest->variableAccessSpecification.choice.listOfVariable.list.count != 1)
		return -1;

	varSpec = writeRequest->variableAccessSpecification.choice.listOfVariable.list.array[0];

	if (varSpec->variableSpecification.present != VariableSpecification_PR_name) {
		createMmsWriteResponse(connection, invokeId, response, MMS_VALUE_ACCESS_DENIED);
		return 0;
	}

	if (varSpec->variableSpecification.choice.name.present != ObjectName_PR_domainspecific) {
		createMmsWriteResponse(connection, invokeId, response, MMS_VALUE_ACCESS_DENIED);
		return 0;
	}

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

	device = MmsServer_getDevice(connection->server);

	domain = MmsDevice_getDomain(device, domainIdStr);

	free(domainIdStr);

	if (domain == NULL) {
		createMmsWriteResponse(connection, invokeId, response, MMS_VALUE_ACCESS_DENIED);
		return 0;
	}

	nameId = varSpec->variableSpecification.choice.name.choice.domainspecific.itemId;

    nameIdStr = createStringFromBuffer(nameId.buf, nameId.size);

	variable = MmsDomain_getNamedVariable(domain, nameIdStr);

	if (variable == NULL)
		goto return_access_denied;

	if (writeRequest->listOfData.list.count != 1)
		goto return_access_denied;

	alternateAccess = varSpec->alternateAccess;

	if (alternateAccess != NULL) {
		if (variable->type != MMS_ARRAY)
			goto return_access_denied;

		if (!mmsServer_isIndexAccess(alternateAccess))
			goto return_access_denied;
	}

	dataElement = writeRequest->listOfData.list.array[0];

	value = mmsMsg_parseDataElement(dataElement);

	if (value == NULL)
		goto return_access_denied;

	if (alternateAccess != NULL) {
		MmsValue* cachedArray = MmsServer_getValueFromCache(connection->server, domain, nameIdStr);
        int index;
        MmsValue* elementValue;

		if (cachedArray == NULL) {
			MmsValue_delete(value);
			goto return_access_denied;
		}

		index = mmsServer_getLowIndex(alternateAccess);

		elementValue = MmsValue_getElement(cachedArray, index);

		if (elementValue == NULL) {
			MmsValue_delete(value);
			goto return_access_denied;
		}

		if (MmsValue_update(elementValue, value) == false) {
			MmsValue_delete(value);
			goto return_access_denied;
		}
	}

	MmsServer_lockModel(connection->server);

	valueIndication =	mmsServer_setValue(connection->server, domain, nameIdStr, value, connection);

	MmsServer_unlockModel(connection->server);

	createMmsWriteResponse(connection, invokeId, response, valueIndication);

	MmsValue_delete(value);

	free(nameIdStr);
	return 0;

return_access_denied:
	createMmsWriteResponse(connection, invokeId, response, MMS_VALUE_ACCESS_DENIED);
	free(nameIdStr);
	return 0;
}
Example #2
0
void
mmsServer_handleWriteRequest(
		MmsServerConnection* connection,
		uint8_t* buffer, int bufPos, int maxBufPos,
		uint32_t invokeId,
		ByteBuffer* response)
{
	WriteRequest_t* writeRequest = 0;

	MmsPdu_t* mmsPdu = 0;

	asn_dec_rval_t rval; /* Decoder return value  */

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

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

	writeRequest = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.write);

	int numberOfWriteItems = writeRequest->variableAccessSpecification.choice.listOfVariable.list.count;

	if (numberOfWriteItems < 1) {
        mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
        return;
	}

	if (numberOfWriteItems > CONFIG_MMS_WRITE_SERVICE_MAX_NUMBER_OF_WRITE_ITEMS) {
	    mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_OTHER, response);
	    return;
	}

    if (writeRequest->listOfData.list.count != numberOfWriteItems) {
        mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT, response);
        return;
    }

    MmsDataAccessError accessResults[CONFIG_MMS_WRITE_SERVICE_MAX_NUMBER_OF_WRITE_ITEMS * sizeof(MmsDataAccessError)];

	bool sendResponse = true;

	int i;

	for (i = 0; i < numberOfWriteItems; i++) {
	    ListOfVariableSeq_t* varSpec =
                writeRequest->variableAccessSpecification.choice.listOfVariable.list.array[i];

        if (varSpec->variableSpecification.present != VariableSpecification_PR_name) {
            accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED;
            continue;
        }

        if (varSpec->variableSpecification.choice.name.present != ObjectName_PR_domainspecific) {
            accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED;
            continue;
        }

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

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

        MmsDomain* domain = MmsDevice_getDomain(device, domainIdStr);

        free(domainIdStr);

        if (domain == NULL) {
            accessResults[i] = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT;
            continue;
        }

        Identifier_t nameId = varSpec->variableSpecification.choice.name.choice.domainspecific.itemId;
        char* nameIdStr = createStringFromBuffer(nameId.buf, nameId.size);

        MmsVariableSpecification* variable = MmsDomain_getNamedVariable(domain, nameIdStr);

        if (variable == NULL) {
            free(nameIdStr);
            accessResults[i] = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT;
            continue;
        }

        AlternateAccess_t* alternateAccess = varSpec->alternateAccess;

        if (alternateAccess != NULL) {
            if (variable->type != MMS_ARRAY) {
                free(nameIdStr);
                accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
                continue;
            }

            if (!mmsServer_isIndexAccess(alternateAccess)) {
                free(nameIdStr);
                accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED;
                continue;
            }
        }

        Data_t* dataElement = writeRequest->listOfData.list.array[i];

        MmsValue* value = mmsMsg_parseDataElement(dataElement);

        if (value == NULL) {
            free(nameIdStr);
            accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
            continue;
        }

        if (alternateAccess != NULL) {
            MmsValue* cachedArray = MmsServer_getValueFromCache(connection->server, domain, nameIdStr);

            if (cachedArray == NULL) {
                free(nameIdStr);
                MmsValue_delete(value);
                accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
                continue;
            }

            int index = mmsServer_getLowIndex(alternateAccess);

            MmsValue* elementValue = MmsValue_getElement(cachedArray, index);

            if (elementValue == NULL) {
                free(nameIdStr);
                MmsValue_delete(value);
                accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
                continue;
            }

            if (MmsValue_update(elementValue, value) == false) {
                free(nameIdStr);
                MmsValue_delete(value);
                accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT;
                continue;
            }

            free(nameIdStr);
            MmsValue_delete(value);
            accessResults[i] = DATA_ACCESS_ERROR_SUCCESS;
            continue;

        }

        MmsDataAccessError valueIndication =
                mmsServer_setValue(connection->server, domain, nameIdStr, value, connection);

        if (valueIndication == DATA_ACCESS_ERROR_NO_RESPONSE)
            sendResponse = false;

        accessResults[i] = valueIndication;

        MmsValue_delete(value);

        free(nameIdStr);
	}

	if (sendResponse) {
	    mmsServer_createMmsWriteResponse(connection, invokeId, response, numberOfWriteItems, accessResults);
	}

	asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
}