static int createVariableAccessAttributesResponse( MmsServerConnection* connection, char* domainId, char* nameId, int invokeId, ByteBuffer* response) { MmsDevice* device = MmsServer_getDevice(connection->server); MmsDomain* domain = MmsDevice_getDomain(device, domainId); if (domain == NULL) { if (DEBUG) printf("mms_server: domain %s not known\n", domainId); return -1; } MmsTypeSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameId); if (namedVariable == NULL) { if (DEBUG) printf("mms_server: named variable %s not known\n", nameId); return -1; } MmsPdu_t* mmsPdu = mmsServer_createConfirmedResponse(invokeId); mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present = ConfirmedServiceResponse_PR_getVariableAccessAttributes; GetVariableAccessAttributesResponse_t* getVarAccessAttr; getVarAccessAttr = &(mmsPdu->choice.confirmedResponsePdu. confirmedServiceResponse.choice.getVariableAccessAttributes); getVarAccessAttr->mmsDeletable = 0; createTypeSpecification(namedVariable, &getVarAccessAttr->typeSpecification); asn_enc_rval_t rval; rval = der_encode(&asn_DEF_MmsPdu, mmsPdu, mmsServer_write_out, (void*) response); if (DEBUG) xer_fprint(stdout, &asn_DEF_MmsPdu, mmsPdu); deleteVariableAccessAttributesResponse(getVarAccessAttr); asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); return 0; }
void mmsServer_handleGetNamedVariableListAttributesRequest( MmsServerConnection* connection, GetNamedVariableListAttributesRequest_t* request, int invokeId, ByteBuffer* response) { if (request->present == ObjectName_PR_domainspecific) { char* domainName = createStringFromBuffer( request->choice.domainspecific.domainId.buf, request->choice.domainspecific.domainId.size); char* itemName = createStringFromBuffer( request->choice.domainspecific.itemId.buf, request->choice.domainspecific.itemId.size); MmsDevice* mmsDevice = MmsServer_getDevice(connection->server); MmsDomain* domain = MmsDevice_getDomain(mmsDevice, domainName); if (domain != NULL) { MmsNamedVariableList variableList = MmsDomain_getNamedVariableList(domain, itemName); if (variableList != NULL) createGetNamedVariableListAttributesResponse(invokeId, response, variableList, domainName); else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_NON_EXISTENT); } else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_NON_EXISTENT); free(domainName); free(itemName); } else { mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_ACCESS_UNSUPPORTED); } }
static void handleReadNamedVariableListRequest( MmsServerConnection* connection, ReadRequest_t* read, int invokeId, ByteBuffer* response) { if (read->variableAccessSpecification.choice.variableListName.present == ObjectName_PR_domainspecific) { char* domainId = mmsMsg_createStringFromAsnIdentifier( read->variableAccessSpecification.choice.variableListName.choice.domainspecific.domainId); char* listName = mmsMsg_createStringFromAsnIdentifier( read->variableAccessSpecification.choice.variableListName.choice.domainspecific.itemId); VarAccessSpec accessSpec; accessSpec.isNamedVariableList = true; accessSpec.specific = 1; accessSpec.domainId = domainId; accessSpec.itemId = listName; MmsDomain* domain = MmsDevice_getDomain(MmsServer_getDevice(connection->server), domainId); if (domain == NULL) { if (DEBUG) printf("MMS read: domain %s not found!\n", domainId); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_NON_EXISTENT); } else { MmsNamedVariableList namedList = MmsDomain_getNamedVariableList(domain, listName); if (namedList != NULL) { createNamedVariableListResponse(connection, namedList, invokeId, response, read, &accessSpec); } else { if (DEBUG) printf("MMS read: named variable list %s not found!\n", listName); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_NON_EXISTENT); } } free(domainId); free(listName); } else if (read->variableAccessSpecification.choice.variableListName.present == ObjectName_PR_aaspecific) { char* listName = mmsMsg_createStringFromAsnIdentifier(read->variableAccessSpecification. choice.variableListName.choice.aaspecific); MmsNamedVariableList namedList = MmsServerConnection_getNamedVariableList(connection, listName); VarAccessSpec accessSpec; accessSpec.isNamedVariableList = true; accessSpec.specific = 2; accessSpec.domainId = NULL; accessSpec.itemId = listName; if (namedList == NULL) mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_NON_EXISTENT); else { createNamedVariableListResponse(connection, namedList, invokeId, response, read, &accessSpec); } free(listName); } else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_ACCESS_UNSUPPORTED); }
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); }
/********************************************************************************************** * 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; }
void mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection* connection, DeleteNamedVariableListRequest_t* request, int invokeId, ByteBuffer* response) { //TODO implement for association specific named variable lists MmsDevice* device; long scopeOfDelete; request->scopeOfDelete; asn_INTEGER2long(request->scopeOfDelete, &scopeOfDelete); device = MmsServer_getDevice(connection->server); if (scopeOfDelete == DeleteNamedVariableListRequest__scopeOfDelete_specific) { int numberMatched = 0; int numberDeleted = 0; int numberItems = request->listOfVariableListName->list.count; int i; for (i = 0; i < numberItems; i++) { if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_domainspecific) { char* domainId = mmsMsg_createStringFromAsnIdentifier( request->listOfVariableListName->list.array[i]->choice.domainspecific.domainId); MmsDomain* domain = MmsDevice_getDomain(device, domainId); char* itemId = mmsMsg_createStringFromAsnIdentifier( request->listOfVariableListName->list.array[i]->choice.domainspecific.itemId); MmsNamedVariableList variableList = MmsDomain_getNamedVariableList(domain, itemId); if (variableList != NULL) { numberMatched++; if (MmsNamedVariableList_isDeletable(variableList)) { MmsDomain_deleteNamedVariableList(domain, itemId); numberDeleted++; } } free(domainId); free(itemId); } else if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_aaspecific) { char* itemId = mmsMsg_createStringFromAsnIdentifier( request->listOfVariableListName->list.array[i]->choice.aaspecific); MmsNamedVariableList variableList = MmsServerConnection_getNamedVariableList(connection, itemId); if (variableList != NULL) { numberMatched++; numberDeleted++; MmsServerConnection_deleteNamedVariableList(connection, itemId); } free(itemId); } //TODO else send error??? } createDeleteNamedVariableListResponse(invokeId, response, numberMatched, numberDeleted); } else { mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_ACCESS_UNSUPPORTED); } }
void mmsServer_handleDefineNamedVariableListRequest( MmsServerConnection* connection, DefineNamedVariableListRequest_t* request, int invokeId, ByteBuffer* response) { MmsDevice* device = MmsServer_getDevice(connection->server); if (request->variableListName.present == ObjectName_PR_domainspecific) { MmsNamedVariableList namedVariableList; char* variableListName; char* domainName = createStringFromBuffer( request->variableListName.choice.domainspecific.domainId.buf, request->variableListName.choice.domainspecific.domainId.size); MmsDomain* domain = MmsDevice_getDomain(device, domainName); free(domainName); if (domain == NULL) { mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_NON_EXISTENT); return; } variableListName = createStringFromBuffer( request->variableListName.choice.domainspecific.itemId.buf, request->variableListName.choice.domainspecific.itemId.size); namedVariableList = createNamedVariableList(device, request, variableListName); free(variableListName); if (namedVariableList != NULL) { MmsDomain_addNamedVariableList(domain, namedVariableList); createDefineNamedVariableListResponse(invokeId, response); } else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_ACCESS_UNSUPPORTED); } else if (request->variableListName.present == ObjectName_PR_aaspecific) { char* variableListName = createStringFromBuffer( request->variableListName.choice.aaspecific.buf, request->variableListName.choice.aaspecific.size); MmsNamedVariableList namedVariableList = createNamedVariableList(device, request, variableListName); if (namedVariableList != NULL) { MmsServerConnection_addNamedVariableList(connection, namedVariableList); createDefineNamedVariableListResponse(invokeId, response); } else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_ACCESS_UNSUPPORTED); free(variableListName); } else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_TYPE_OBJECT_ACCESS_UNSUPPORTED); }
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; }
void mmsServer_handleGetNamedVariableListAttributesRequest( MmsServerConnection connection, uint8_t* buffer, int bufPos, int maxBufPos, uint32_t invokeId, ByteBuffer* response) { GetNamedVariableListAttributesRequest_t* request = 0; asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_GetNamedVariableListAttributesRequest, (void**) &request, buffer + bufPos, maxBufPos - bufPos); if (rval.code != RC_OK) { mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); return; } if (request->present == ObjectName_PR_domainspecific) { char domainName[65]; char itemName[65]; if ((request->choice.domainspecific.domainId.size > 64) || (request->choice.domainspecific.itemId.size > 64)) { mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OTHER); goto exit_function; } StringUtils_createStringFromBufferInBuffer(domainName, request->choice.domainspecific.domainId.buf, request->choice.domainspecific.domainId.size); StringUtils_createStringFromBufferInBuffer(itemName, request->choice.domainspecific.itemId.buf, request->choice.domainspecific.itemId.size); MmsDevice* mmsDevice = MmsServer_getDevice(connection->server); MmsDomain* domain = MmsDevice_getDomain(mmsDevice, domainName); if (domain != NULL) { MmsNamedVariableList variableList = MmsDomain_getNamedVariableList(domain, itemName); if (variableList != NULL) createGetNamedVariableListAttributesResponse(invokeId, response, variableList); else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); } else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); } #if (MMS_DYNAMIC_DATA_SETS == 1) else if (request->present == ObjectName_PR_aaspecific) { char listName[65]; if (request->choice.aaspecific.size > 64) { mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OTHER); goto exit_function; } StringUtils_createStringFromBufferInBuffer(listName, request->choice.aaspecific.buf, request->choice.aaspecific.size); MmsNamedVariableList varList = MmsServerConnection_getNamedVariableList(connection, listName); if (varList != NULL) createGetNamedVariableListAttributesResponse(invokeId, response, varList); else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); } #endif /* (MMS_DYNAMIC_DATA_SETS == 1) */ else { mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); } exit_function: asn_DEF_GetVariableAccessAttributesRequest.free_struct(&asn_DEF_GetNamedVariableListAttributesRequest, request, 0); }
void mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection, uint8_t* buffer, int bufPos, int maxBufPos, uint32_t invokeId, ByteBuffer* response) { DeleteNamedVariableListRequest_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.deleteNamedVariableList); long scopeOfDelete; asn_INTEGER2long(request->scopeOfDelete, &scopeOfDelete); MmsDevice* device = MmsServer_getDevice(connection->server); if (scopeOfDelete == DeleteNamedVariableListRequest__scopeOfDelete_specific) { int numberMatched = 0; int numberDeleted = 0; int numberItems = request->listOfVariableListName->list.count; int i; for (i = 0; i < numberItems; i++) { if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_domainspecific) { char domainName[65]; char listName[65]; mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.domainspecific.domainId, domainName, 65); mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.domainspecific.itemId, listName, 65); MmsDomain* domain = MmsDevice_getDomain(device, domainName); if (domain != NULL) { MmsNamedVariableList variableList = MmsDomain_getNamedVariableList(domain, listName); if (variableList != NULL) { numberMatched++; if (MmsNamedVariableList_isDeletable(variableList)) { if (mmsServer_callVariableListChangedHandler(false, MMS_DOMAIN_SPECIFIC, domain, listName, connection) == MMS_ERROR_NONE) { MmsDomain_deleteNamedVariableList(domain, listName); numberDeleted++; } } } } } else if (request->listOfVariableListName->list.array[i]->present == ObjectName_PR_aaspecific) { char listName[65]; mmsMsg_copyAsn1IdentifierToStringBuffer(request->listOfVariableListName->list.array[i]->choice.aaspecific, listName, 65); MmsNamedVariableList variableList = MmsServerConnection_getNamedVariableList(connection, listName); if (variableList != NULL) { numberMatched++; if (mmsServer_callVariableListChangedHandler(false, MMS_ASSOCIATION_SPECIFIC, NULL, listName, connection) == MMS_ERROR_NONE) { numberDeleted++; MmsServerConnection_deleteNamedVariableList(connection, listName); } } } } createDeleteNamedVariableListResponse(invokeId, response, numberMatched, numberDeleted); } else { mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); } asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); exit_function: return; }
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); }
static void createVariableAccessAttributesResponse( MmsServerConnection connection, char* domainId, char* nameId, int invokeId, ByteBuffer* response) { MmsDevice* device = MmsServer_getDevice(connection->server); MmsVariableSpecification* namedVariable = NULL; if (domainId != NULL) { MmsDomain* domain = MmsDevice_getDomain(device, domainId); if (domain == NULL) { if (DEBUG_MMS_SERVER) printf("MMS_SERVER: domain %s not known\n", domainId); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); goto exit_function; } namedVariable = MmsDomain_getNamedVariable(domain, nameId); } #if (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) else namedVariable = MmsDevice_getNamedVariable(device, nameId); #endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */ if (namedVariable == NULL) { if (DEBUG_MMS_SERVER) printf("MMS_SERVER: named variable %s not known\n", nameId); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); goto exit_function; } MmsPdu_t* mmsPdu = mmsServer_createConfirmedResponse(invokeId); mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present = ConfirmedServiceResponse_PR_getVariableAccessAttributes; GetVariableAccessAttributesResponse_t* getVarAccessAttr; getVarAccessAttr = &(mmsPdu->choice.confirmedResponsePdu. confirmedServiceResponse.choice.getVariableAccessAttributes); getVarAccessAttr->mmsDeletable = 0; createTypeSpecification(namedVariable, &getVarAccessAttr->typeSpecification); asn_enc_rval_t rval = der_encode(&asn_DEF_MmsPdu, mmsPdu, mmsServer_write_out, (void*) response); if (rval.encoded == -1) { response->size = 0; if (DEBUG_MMS_SERVER) printf("MMS getVariableAccessAttributes: message to large! send error PDU!\n"); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_SERVICE_OTHER); goto exit_function; } deleteVariableAccessAttributesResponse(getVarAccessAttr); asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); exit_function: return; }
static void handleReadNamedVariableListRequest( MmsServerConnection connection, ReadRequest_t* read, int invokeId, ByteBuffer* response) { if (read->variableAccessSpecification.choice.variableListName.present == ObjectName_PR_domainspecific) { char domainIdStr[65]; char nameIdStr[65]; mmsMsg_copyAsn1IdentifierToStringBuffer(read->variableAccessSpecification.choice.variableListName.choice.domainspecific.domainId, domainIdStr, 65); mmsMsg_copyAsn1IdentifierToStringBuffer(read->variableAccessSpecification.choice.variableListName.choice.domainspecific.itemId, nameIdStr, 65); VarAccessSpec accessSpec; accessSpec.isNamedVariableList = true; accessSpec.specific = 1; accessSpec.domainId = domainIdStr; accessSpec.itemId = nameIdStr; MmsDomain* domain = MmsDevice_getDomain(MmsServer_getDevice(connection->server), domainIdStr); if (domain == NULL) { if (DEBUG_MMS_SERVER) printf("MMS read: domain %s not found!\n", domainIdStr); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); } else { MmsNamedVariableList namedList = MmsDomain_getNamedVariableList(domain, nameIdStr); if (namedList != NULL) { createNamedVariableListResponse(connection, namedList, invokeId, response, read, &accessSpec); } else { if (DEBUG_MMS_SERVER) printf("MMS read: named variable list %s not found!\n", nameIdStr); mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); } } } #if (MMS_DYNAMIC_DATA_SETS == 1) else if (read->variableAccessSpecification.choice.variableListName.present == ObjectName_PR_aaspecific) { char listName[65]; mmsMsg_copyAsn1IdentifierToStringBuffer(read->variableAccessSpecification.choice.variableListName.choice.aaspecific, listName, 65); MmsNamedVariableList namedList = MmsServerConnection_getNamedVariableList(connection, listName); VarAccessSpec accessSpec; accessSpec.isNamedVariableList = true; accessSpec.specific = 2; accessSpec.domainId = NULL; accessSpec.itemId = listName; if (namedList == NULL) mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); else createNamedVariableListResponse(connection, namedList, invokeId, response, read, &accessSpec); } #endif /* (MMS_DYNAMIC_DATA_SETS == 1) */ else mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); }
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); }