Exemple #1
0
void
IsoServer_destroy(IsoServer self)
{

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    if (self->state == ISO_SVR_STATE_RUNNING)
        IsoServer_stopListening(self);
#endif

#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1)

#if (CONFIG_MMS_SINGLE_THREADED == 1)
    if (self->openClientConnections != NULL)
        LinkedList_destroy(self->openClientConnections);
#else
    if (self->openClientConnections != NULL)
        LinkedList_destroyStatic(self->openClientConnections);
#endif /* (CONFIG_MMS_SINGLE_THREADED == 1) */

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    lockClientConnections(self);
    Semaphore_destroy(self->openClientConnectionsMutex);
#endif

#else
    GLOBAL_FREEMEM(self->openClientConnections);
#endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    Semaphore_destroy(self->connectionCounterMutex);
#endif

    GLOBAL_FREEMEM(self);
}
static void
freeInitiateRequestPdu(InitiateRequestPdu_t request)
{
    GLOBAL_FREEMEM(request.localDetailCalling);
    GLOBAL_FREEMEM(request.proposedDataStructureNestingLevel);
    GLOBAL_FREEMEM(request.mmsInitRequestDetail.proposedParameterCBB.buf);
}
Exemple #3
0
void
GooseReceiver_destroy(GooseReceiver self)
{
    LinkedList_destroyDeep(self->subscriberList,
            (LinkedListValueDeleteFunction) GooseSubscriber_destroy);

    GLOBAL_FREEMEM(self->buffer);
    GLOBAL_FREEMEM(self);
}
Exemple #4
0
void Ethernet_destroySocket(EthernetSocket self)
{
    // Close the BPF device.
    close(self->bpf);

    // Free all dynamic resources used by the ethernet socket.
    GLOBAL_FREEMEM(self->bpfBuffer);
    GLOBAL_FREEMEM(self->bpfProgram.bf_insns);
    GLOBAL_FREEMEM(self);
}
Exemple #5
0
/**
 * Request a single value
 */
int
mmsClient_createReadRequest(uint32_t invokeId, const char* domainId, const char* itemId, ByteBuffer* writeBuffer)
{
	MmsPdu_t* mmsPdu = mmsClient_createConfirmedRequestPdu(invokeId);

	ReadRequest_t* readRequest = createReadRequest(mmsPdu);

	readRequest->specificationWithResult = NULL;

	readRequest->variableAccessSpecification.present = VariableAccessSpecification_PR_listOfVariable;

	readRequest->variableAccessSpecification.choice.listOfVariable.list.array = 
			(ListOfVariableSeq_t**) GLOBAL_CALLOC(1, sizeof(ListOfVariableSeq_t*));
	readRequest->variableAccessSpecification.choice.listOfVariable.list.count = 1;

	ListOfVariableSeq_t* listOfVars = (ListOfVariableSeq_t*) GLOBAL_CALLOC(1, sizeof(ListOfVariableSeq_t));

	readRequest->variableAccessSpecification.choice.listOfVariable.list.array[0] = listOfVars;

	listOfVars->alternateAccess = NULL;
	listOfVars->variableSpecification.present = VariableSpecification_PR_name;

	if (domainId != NULL) {
        listOfVars->variableSpecification.choice.name.present = ObjectName_PR_domainspecific;
        listOfVars->variableSpecification.choice.name.choice.domainspecific.domainId.buf = (uint8_t*) domainId;
        listOfVars->variableSpecification.choice.name.choice.domainspecific.domainId.size = strlen(domainId);
        listOfVars->variableSpecification.choice.name.choice.domainspecific.itemId.buf = (uint8_t*) itemId;
        listOfVars->variableSpecification.choice.name.choice.domainspecific.itemId.size = strlen(itemId);
	}
	else {
	    listOfVars->variableSpecification.choice.name.present = ObjectName_PR_vmdspecific;
	    listOfVars->variableSpecification.choice.name.choice.vmdspecific.buf = (uint8_t*) itemId;
	    listOfVars->variableSpecification.choice.name.choice.vmdspecific.size = strlen(itemId);
	}

	asn_enc_rval_t rval;

	rval = der_encode(&asn_DEF_MmsPdu, mmsPdu,
	            (asn_app_consume_bytes_f*) mmsClient_write_out, (void*) writeBuffer);

	/* clean up data structures */
	GLOBAL_FREEMEM(listOfVars);
	GLOBAL_FREEMEM(readRequest->variableAccessSpecification.choice.listOfVariable.list.array);
	readRequest->variableAccessSpecification.choice.listOfVariable.list.array = NULL;
	readRequest->variableAccessSpecification.choice.listOfVariable.list.count = 0;
	asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);

	return rval.encoded;
}
Exemple #6
0
int
mmsClient_createWriteRequest(uint32_t invokeId, const char* domainId, const char* itemId, MmsValue* value,
		ByteBuffer* writeBuffer)
{
	MmsPdu_t* mmsPdu = mmsClient_createConfirmedRequestPdu(invokeId);

	mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.present =
			ConfirmedServiceRequest_PR_write;
	WriteRequest_t* request =
			&(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.write);

	/* Create list of variable specifications */
	request->variableAccessSpecification.present = VariableAccessSpecification_PR_listOfVariable;
	request->variableAccessSpecification.choice.listOfVariable.list.count = 1;
	request->variableAccessSpecification.choice.listOfVariable.list.size = 1;
	request->variableAccessSpecification.choice.listOfVariable.list.array =
			(ListOfVariableSeq_t**) GLOBAL_CALLOC(1, sizeof(ListOfVariableSeq_t*));
	request->variableAccessSpecification.choice.listOfVariable.list.array[0] = (ListOfVariableSeq_t*)
			createNewDomainVariableSpecification(domainId, itemId);

	/* Create list of typed data values */
	request->listOfData.list.count = 1;
	request->listOfData.list.size = 1;
	request->listOfData.list.array = (Data_t**) GLOBAL_CALLOC(1, sizeof(struct Data*));
	request->listOfData.list.array[0] = mmsMsg_createBasicDataElement(value);

	asn_enc_rval_t rval;

	rval = der_encode(&asn_DEF_MmsPdu, mmsPdu,
			(asn_app_consume_bytes_f*) mmsClient_write_out, (void*) writeBuffer);

	/* Free ASN structure */
	request->variableAccessSpecification.choice.listOfVariable.list.count = 0;

	GLOBAL_FREEMEM(request->variableAccessSpecification.choice.listOfVariable.list.array[0]);
	GLOBAL_FREEMEM(request->variableAccessSpecification.choice.listOfVariable.list.array);
	request->variableAccessSpecification.choice.listOfVariable.list.array = 0;

	request->listOfData.list.count = 0;

	deleteDataElement(request->listOfData.list.array[0]);

	GLOBAL_FREEMEM(request->listOfData.list.array);
	request->listOfData.list.array = 0;

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

	return rval.encoded;
}
Exemple #7
0
MmsValue*
MmsValueCache_lookupValue(MmsValueCache self, char* itemId)
{
	// get value for first matching key substring!
	// Then iterate the value for the exact value.

	MmsValue* value = NULL;

	MmsValueCacheEntry* cacheEntry;

	cacheEntry = (MmsValueCacheEntry*) Map_getEntry(self->map, itemId);

	if (cacheEntry == NULL) {
		char* itemIdCopy = copyString(itemId);
		char* parentItemId = getParentSubString(itemIdCopy);

		if (parentItemId != NULL) {
			value = searchCacheForValue(self, itemId, parentItemId);
		}

		GLOBAL_FREEMEM(itemIdCopy);
	}

	if (cacheEntry != NULL)
		return cacheEntry->value;
	else
		return value;
}
Exemple #8
0
void
GooseReceiver_setInterfaceId(GooseReceiver self, const char* interfaceId)
{
    if (self->interfaceId != NULL)
        GLOBAL_FREEMEM(self->interfaceId);

    self->interfaceId = copyString(interfaceId);
}
Exemple #9
0
static void
cacheEntryDelete(MmsValueCacheEntry* entry)
{
	if (entry != NULL) {
		MmsValue_delete(entry->value);
		GLOBAL_FREEMEM(entry);
	}
}
void
ClientGooseControlBlock_destroy(ClientGooseControlBlock self)
{
    GLOBAL_FREEMEM(self->objectReference);

    MmsValue_deleteIfNotNull(self->goEna);
    MmsValue_deleteIfNotNull(self->goID);
    MmsValue_deleteIfNotNull(self->datSet);
    MmsValue_deleteIfNotNull(self->confRev);
    MmsValue_deleteIfNotNull(self->ndsCom);
    MmsValue_deleteIfNotNull(self->dstAddress);
    MmsValue_deleteIfNotNull(self->minTime);
    MmsValue_deleteIfNotNull(self->maxTime);
    MmsValue_deleteIfNotNull(self->fixedOffs);

    GLOBAL_FREEMEM(self);
}
static void
deleteVariableAccessAttributesResponse(
		GetVariableAccessAttributesResponse_t* getVarAccessAttr)
{
	if (getVarAccessAttr->typeSpecification.present	== TypeSpecification_PR_structure) {
		int count =	getVarAccessAttr->typeSpecification.choice.structure.components.list.count;

		int i;
		for (i = 0; i < count; i++) {
		    GLOBAL_FREEMEM(getVarAccessAttr->typeSpecification.choice.structure.components.list.array[i]->componentName->buf);
			GLOBAL_FREEMEM(getVarAccessAttr->typeSpecification.choice.structure.components.list.array[i]->componentName);
			TypeSpecification_t* typeSpec =
					getVarAccessAttr->typeSpecification.choice.structure.components.list.array[i]->componentType;
			freeTypeSpecRecursive(typeSpec);
			GLOBAL_FREEMEM(typeSpec);
			GLOBAL_FREEMEM(getVarAccessAttr->typeSpecification.choice.structure.components.list.array[i]);
		}

		GLOBAL_FREEMEM(getVarAccessAttr->typeSpecification.choice.structure.components.list.array);

		getVarAccessAttr->typeSpecification.choice.structure.components.list.array = NULL;
		getVarAccessAttr->typeSpecification.choice.structure.components.list.count = 0;
		getVarAccessAttr->typeSpecification.choice.structure.components.list.size =	0;
	} else if (getVarAccessAttr->typeSpecification.present == TypeSpecification_PR_array) {
		GLOBAL_FREEMEM(getVarAccessAttr->typeSpecification.choice.array.numberOfElements.buf);
		getVarAccessAttr->typeSpecification.choice.array.numberOfElements.buf = NULL;
		getVarAccessAttr->typeSpecification.choice.array.numberOfElements.size = 0;
		freeTypeSpecRecursive(getVarAccessAttr->typeSpecification.choice.array.elementType);

		GLOBAL_FREEMEM(getVarAccessAttr->typeSpecification.choice.array.elementType);

		getVarAccessAttr->typeSpecification.choice.array.elementType = NULL;
	}
}
Exemple #12
0
void
ControlObjectClient_setOrigin(ControlObjectClient self, const char* orIdent, int orCat)
{
    if (self->orIdent != NULL)
        GLOBAL_FREEMEM(self->orIdent);

    self->orIdent = copyString(orIdent);
    self->orCat = orCat;
}
Exemple #13
0
void
ControlObjectClient_destroy(ControlObjectClient self)
{
    if (self != NULL)
    {
        GLOBAL_FREEMEM(self->objectReference);

        private_IedConnection_removeControlClient(self->connection, self);

        if (self->ctlVal != NULL)
            MmsValue_delete(self->ctlVal);

        if (self->orIdent != NULL)
            GLOBAL_FREEMEM(self->orIdent);

        GLOBAL_FREEMEM(self);
    }
}
Exemple #14
0
/**
 * Request multiple values of a single domain
 */
int
mmsClient_createReadRequestMultipleValues(uint32_t invokeId, const char* domainId, LinkedList items,
		ByteBuffer* writeBuffer)
{
	MmsPdu_t* mmsPdu = mmsClient_createConfirmedRequestPdu(invokeId);

	ReadRequest_t* readRequest = createReadRequest(mmsPdu);

	readRequest->specificationWithResult = NULL;

	int valuesCount = LinkedList_size(items);

	ListOfVariableSeq_t** listOfVars = createListOfVariables(readRequest, valuesCount);

	LinkedList item = items;

	int i = 0;

	while ((item = LinkedList_getNext(item)) != NULL) {
		listOfVars[i] = createVariableIdentifier(domainId, (char*) (item->data));
		i++;
	}

	asn_enc_rval_t rval;

	rval = der_encode(&asn_DEF_MmsPdu, mmsPdu,
		(asn_app_consume_bytes_f*) mmsClient_write_out, (void*) writeBuffer);

	for (i = 0; i < valuesCount; i++) {
		GLOBAL_FREEMEM(listOfVars[i]);
	}
	GLOBAL_FREEMEM(listOfVars);

	readRequest->variableAccessSpecification.choice.listOfVariable.list.count = 0;
	readRequest->variableAccessSpecification.choice.listOfVariable.list.size = 0;
	readRequest->variableAccessSpecification.choice.listOfVariable.list.array = NULL;


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

	return rval.encoded;
}
Exemple #15
0
void
BufferChain_destroy(BufferChain self)
{
    BufferChain currentChainElement = self;

    while (currentChainElement != NULL) {
        BufferChain nextChainElement = currentChainElement->nextPart;
        GLOBAL_FREEMEM(currentChainElement);
        currentChainElement = nextChainElement;
    }
}
Exemple #16
0
static void
handleClientConnections(IsoServer self)
{
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1)

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    lockClientConnections(self);
#endif

    LinkedList openConnection = LinkedList_getNext(self->openClientConnections);
    LinkedList lastConnection = self->openClientConnections;

    while (openConnection != NULL) {
        IsoConnection isoConnection = (IsoConnection) openConnection->data;

        if (IsoConnection_isRunning(isoConnection))
            IsoConnection_handleTcpConnection(isoConnection);
        else {
            IsoConnection_destroy(isoConnection);

            lastConnection->next = openConnection->next;

            GLOBAL_FREEMEM(openConnection);
        }

        openConnection = LinkedList_getNext(openConnection);
    }

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    unlockClientConnections(self);
#endif

#else


    int i;

    for (i = 0; i < CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS; i++) {
        if (self->openClientConnections[i] != NULL) {
            if (IsoConnection_isRunning(self->openClientConnections[i])) {

                IsoConnection_handleTcpConnection(self->openClientConnections[i]);
            }
            else {
                IsoConnection_destroy(self->openClientConnections[i]);

                self->openClientConnections[i] = NULL;
            }

        }
    }
#endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */
}
Exemple #17
0
void
ControlObject_destroy(ControlObject* self)
{
    if (self->mmsValue != NULL)
        MmsValue_delete(self->mmsValue);

    if (self->sbo != NULL)
        MmsValue_delete(self->sbo);

    if (self->emptyString != NULL)
        MmsValue_delete(self->emptyString);

    if (self->ctlObjectName != NULL)
        GLOBAL_FREEMEM(self->ctlObjectName);

    if (self->error != NULL)
        MmsValue_delete(self->error);

    if (self->addCause != NULL)
        MmsValue_delete(self->addCause);

    if (self->ctlVal != NULL)
        MmsValue_delete(self->ctlVal);

    if (self->ctlNum != NULL)
        MmsValue_delete(self->ctlNum);

    if (self->origin != NULL)
        MmsValue_delete(self->origin);

    if (self->name != NULL)
        GLOBAL_FREEMEM(self->name);

#if (CONFIG_MMS_THREADLESS_STACK != 1)
    if (self->stateLock != NULL)
        Semaphore_destroy(self->stateLock);
#endif

    GLOBAL_FREEMEM(self);
}
Exemple #18
0
void
mmsMsg_deleteAccessResultList(AccessResult_t** accessResult, int variableCount)
{
    int i;

    for (i = 0; i < variableCount; i++) {

        if (accessResult[i]->present == AccessResult_PR_structure) {
            int elementCount = accessResult[i]->choice.structure.list.count;

            int j;

            for (j = 0; j < elementCount; j++) {
                deleteDataElement(accessResult[i]->choice.structure.list.array[j]);
            }

            GLOBAL_FREEMEM(accessResult[i]->choice.structure.list.array);
        }
        else if (accessResult[i]->present == AccessResult_PR_array) {
            int elementCount = accessResult[i]->choice.array.list.count;

            int j;

            for (j = 0; j < elementCount; j++) {
                deleteDataElement(accessResult[i]->choice.array.list.array[j]);
            }

            GLOBAL_FREEMEM(accessResult[i]->choice.array.list.array);
        }
        else if (accessResult[i]->present == AccessResult_PR_integer)
            GLOBAL_FREEMEM(accessResult[i]->choice.integer.buf);
        else if (accessResult[i]->present == AccessResult_PR_unsigned)
            GLOBAL_FREEMEM(accessResult[i]->choice.Unsigned.buf);
        else if (accessResult[i]->present == AccessResult_PR_floatingpoint)
            GLOBAL_FREEMEM(accessResult[i]->choice.floatingpoint.buf);
        else if (accessResult[i]->present == AccessResult_PR_utctime)
            GLOBAL_FREEMEM(accessResult[i]->choice.utctime.buf);
        else if (accessResult[i]->present == AccessResult_PR_failure)
            GLOBAL_FREEMEM(accessResult[i]->choice.failure.buf);

        GLOBAL_FREEMEM(accessResult[i]);
    }

    GLOBAL_FREEMEM(accessResult);
}
Exemple #19
0
void
Socket_destroy(Socket self)
{
    int fd = self->fd;

    self->fd = -1;

    closeAndShutdownSocket(fd);

    Thread_sleep(10);

    GLOBAL_FREEMEM(self);
}
int
mmsClient_createInitiateRequest(MmsConnection self, ByteBuffer* message)
{
    MmsPdu_t* mmsPdu = (MmsPdu_t*) GLOBAL_CALLOC(1, sizeof(MmsPdu_t));

    mmsPdu->present = MmsPdu_PR_initiateRequestPdu;

    mmsPdu->choice.initiateRequestPdu = createInitiateRequestPdu(self);

    asn_enc_rval_t rval = der_encode(&asn_DEF_MmsPdu, mmsPdu,
            (asn_app_consume_bytes_f*) mmsClient_write_out, (void*) message);

    freeInitiateRequestPdu(mmsPdu->choice.initiateRequestPdu);
    GLOBAL_FREEMEM(mmsPdu);

    return rval.encoded;
}
Exemple #21
0
static void
deleteDataElement(Data_t* dataElement)
{
    if (dataElement == NULL ) {
        printf("deleteDataElement NULL argument\n");
        return;
    }

    if (dataElement->present == Data_PR_structure) {
        int elementCount = dataElement->choice.structure->list.count;

        int i;
        for (i = 0; i < elementCount; i++) {
            deleteDataElement(dataElement->choice.structure->list.array[i]);
        }

        GLOBAL_FREEMEM(dataElement->choice.structure->list.array);
        GLOBAL_FREEMEM(dataElement->choice.structure);
    }
    else if (dataElement->present == Data_PR_array) {
        int elementCount = dataElement->choice.array->list.count;

        int i;
        for (i = 0; i < elementCount; i++) {
            deleteDataElement(dataElement->choice.array->list.array[i]);
        }

        GLOBAL_FREEMEM(dataElement->choice.array->list.array);
        GLOBAL_FREEMEM(dataElement->choice.array);
    }
    else if (dataElement->present == Data_PR_floatingpoint) {
        GLOBAL_FREEMEM(dataElement->choice.floatingpoint.buf);
    }
    else if (dataElement->present == Data_PR_utctime) {
        GLOBAL_FREEMEM(dataElement->choice.utctime.buf);
    }

    GLOBAL_FREEMEM(dataElement);
}
static void
freeTypeSpecRecursive(TypeSpecification_t* typeSpec) {
	if (typeSpec->present == TypeSpecification_PR_structure) {
		int elementCount =
				typeSpec->choice.structure.components.list.count;

		int i;

		for (i = 0; i < elementCount; i++) {
		    GLOBAL_FREEMEM(typeSpec->choice.structure.components.list.array[i]->componentName->buf);
			GLOBAL_FREEMEM(typeSpec->choice.structure.components.list.array[i]->componentName);
			freeTypeSpecRecursive(typeSpec->choice.structure.components.list.array[i]->componentType);
			GLOBAL_FREEMEM(typeSpec->choice.structure.components.list.array[i]->componentType);
			GLOBAL_FREEMEM(typeSpec->choice.structure.components.list.array[i]);
		}

		GLOBAL_FREEMEM(typeSpec->choice.structure.components.list.array);
	}
	else if (typeSpec->present == TypeSpecification_PR_array) {
		GLOBAL_FREEMEM(typeSpec->choice.array.numberOfElements.buf);
		freeTypeSpecRecursive(typeSpec->choice.array.elementType);
		GLOBAL_FREEMEM(typeSpec->choice.array.elementType);
	}
}
void
FileSystem_closeDirectory(DirectoryHandle directory)
{
    closedir(directory->handle);
    GLOBAL_FREEMEM(directory);
}
Exemple #24
0
void
MmsValueCache_destroy(MmsValueCache self)
{
	Map_deleteDeep(self->map, true, (void (*) (void*)) cacheEntryDelete);
	GLOBAL_FREEMEM(self);
}
Exemple #25
0
static int
parseAllData(uint8_t* buffer, int allDataLength, MmsValue* dataSetValues)
{
    int bufPos = 0;
    int elementLength = 0;

    int elementIndex = 0;

    int maxIndex = MmsValue_getArraySize(dataSetValues) - 1;

    while (bufPos < allDataLength) {
        uint8_t tag = buffer[bufPos++];

        if (elementIndex > maxIndex) {
            if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: too much elements!\n");
            return 0;
        }

        MmsValue* value = MmsValue_getElement(dataSetValues, elementIndex);

        bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, allDataLength);

        if (bufPos + elementLength > allDataLength) {
            if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: sub element is too large!\n");
            return 0;
        }

        switch (tag) {
        case 0x80: /* reserved for access result */
            printf("GOOSE_SUBSCRIBER:    found reserved value (tag 0x80)!\n");
            break;
        case 0xa1: /* array */
            if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER:    found array\n");
            if (MmsValue_getType(value) == MMS_ARRAY) {
                if (!parseAllData(buffer + bufPos, elementLength, value))
                    return -1;
            }
            break;
        case 0xa2: /* structure */
            if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER:    found structure\n");
            if (MmsValue_getType(value) == MMS_STRUCTURE) {
                if (!parseAllData(buffer + bufPos, elementLength, value))
                    return -1;
            }
            break;
        case 0x83: /* boolean */
            if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER:    found boolean\n");

            if (MmsValue_getType(value) == MMS_BOOLEAN) {
                MmsValue_setBoolean(value, BerDecoder_decodeBoolean(buffer, bufPos));
            }
            else
                if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER:      message contains value of wrong type!\n");

            break;

        case 0x84: /* BIT STRING */
            if (MmsValue_getType(value) == MMS_BIT_STRING) {
                int padding = buffer[bufPos];
                int bitStringLength = (8 * (elementLength - 1)) - padding;
                if (bitStringLength == value->value.bitString.size) {
                    memcpy(value->value.bitString.buf, buffer + bufPos + 1,
                            elementLength - 1);
                }
                else
                    if (DEBUG_GOOSE_SUBSCRIBER)
                        printf("bit-string is of wrong size");
            }
            break;
        case 0x85: /* integer */
            if (MmsValue_getType(value) == MMS_INTEGER) {
                if (elementLength <= value->value.integer->maxSize) {
                    value->value.integer->size = elementLength;
                    memcpy(value->value.integer->octets, buffer + bufPos, elementLength);
                }
            }
            break;
        case 0x86: /* unsigned integer */
            if (MmsValue_getType(value) == MMS_UNSIGNED) {
                if (elementLength <= value->value.integer->maxSize) {
                    value->value.integer->size = elementLength;
                    memcpy(value->value.integer->octets, buffer + bufPos, elementLength);
                }
            }
            break;
        case 0x87: /* Float */
            if (MmsValue_getType(value) == MMS_FLOAT) {
                if (elementLength == 9) {
                    MmsValue_setDouble(value, BerDecoder_decodeDouble(buffer, bufPos));
                }
                else if (elementLength == 5) {
                    MmsValue_setFloat(value, BerDecoder_decodeFloat(buffer, bufPos));
                }
            }
            break;

        case 0x89: /* octet string */
            if (MmsValue_getType(value) == MMS_OCTET_STRING) {
                if (elementLength <= value->value.octetString.maxSize) {
                    value->value.octetString.size = elementLength;
                    memcpy(value->value.octetString.buf, buffer + bufPos, elementLength);
                }
            }
            break;
        case 0x8a: /* visible string */
            if (MmsValue_getType(value) == MMS_VISIBLE_STRING) {

                if (value->value.visibleString.buf != NULL) {
                    if ((int32_t) value->value.visibleString.size >= elementLength) {
                        memcpy(value->value.visibleString.buf, buffer + bufPos, elementLength);
                        value->value.visibleString.buf[elementLength] = 0;
                    }
                    else {
                        GLOBAL_FREEMEM(value->value.visibleString.buf);

                        createNewStringFromBufferElement(value, buffer + bufPos, elementLength);
                    }
                }
                else
                    createNewStringFromBufferElement(value, buffer + bufPos, elementLength);

            }
            break;
        case 0x8c: /* binary time */
            if (MmsValue_getType(value) == MMS_BINARY_TIME) {
                if ((elementLength == 4) || (elementLength == 6)) {
                    memcpy(value->value.binaryTime.buf, buffer + bufPos, elementLength);
                }
            }
            break;
        case 0x91: /* Utctime */
            if (elementLength == 8) {
                if (MmsValue_getType(value) == MMS_UTC_TIME) {
                    MmsValue_setUtcTimeByBuffer(value, buffer + bufPos);
                }
                else
                    if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER:      message contains value of wrong type!\n");
            }
            else
                if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER:      UTCTime element is of wrong size!\n");
            break;
        default:
            if (DEBUG_GOOSE_SUBSCRIBER)
                printf("GOOSE_SUBSCRIBER:    found unkown tag %02x\n", tag);
            break;
        }

        bufPos += elementLength;

        elementIndex++;
    }

    return 1;
}
Exemple #26
0
static void
initialize(ControlObject* self)
{
    if (!(self->initialized)) {

        MmsServer mmsServer = IedServer_getMmsServer(self->iedServer);

        self->emptyString = MmsValue_newVisibleString(NULL);

        char* ctlModelName = createString(4, self->lnName, "$CF$", self->name, "$ctlModel");

        if (DEBUG_IED_SERVER)
            printf("initialize control for %s\n", ctlModelName);

        MmsValue* ctlModel = MmsServer_getValueFromCache(mmsServer,
                self->mmsDomain, ctlModelName);

        if (ctlModel == NULL) {
            if (DEBUG_IED_SERVER)
                printf("No control model found for variable %s\n", ctlModelName);
        }

        GLOBAL_FREEMEM(ctlModelName);

        char* sboClassName = createString(4, self->lnName, "$CF$", self->name, "$sboClass");

        self->sboClass = MmsServer_getValueFromCache(mmsServer, self->mmsDomain, sboClassName);

        GLOBAL_FREEMEM(sboClassName);

        self->ctlObjectName = (char*) GLOBAL_MALLOC(130);

        StringUtils_createStringInBuffer(self->ctlObjectName, 5, MmsDomain_getName(self->mmsDomain), "/",
                self->lnName, "$CO$", self->name);

        self->error = MmsValue_newIntegerFromInt32(0);
        self->addCause = MmsValue_newIntegerFromInt32(0);

        if (ctlModel != NULL) {
            uint32_t ctlModelVal = MmsValue_toInt32(ctlModel);

            self->ctlModel = ctlModelVal;

            if (DEBUG_IED_SERVER)
                printf("  ctlModel: %i\n", ctlModelVal);

            if ((ctlModelVal == 2) || (ctlModelVal == 4)) { /* SBO */
                char* sboTimeoutName = createString(4, self->lnName, "$CF$", self->name, "$sboTimeout");

                char* controlObjectReference = createString(6, self->mmsDomain->domainName, "/", self->lnName, "$",
                        self->name, "$SBO");

                self->sbo = MmsValue_newVisibleString(controlObjectReference);

                self->sboTimeout = MmsServer_getValueFromCache(mmsServer,
                        self->mmsDomain, sboTimeoutName);

                updateSboTimeoutValue(self);

                setState(self, STATE_UNSELECTED);

                if (DEBUG_IED_SERVER)
                    printf("timeout for %s is %i\n", sboTimeoutName, self->selectTimeout);

                GLOBAL_FREEMEM(controlObjectReference);
                GLOBAL_FREEMEM(sboTimeoutName);
            }
            else {
                self->sbo = MmsValue_newVisibleString(NULL);

                setState(self, STATE_READY);
            }
        }

        self->initialized = true;
    }
}
int
mmsServer_handleGetVariableAccessAttributesRequest(
		MmsServerConnection connection,
		uint8_t* buffer, int bufPos, int maxBufPos,
		uint32_t invokeId,
		ByteBuffer* response)
{
	int retVal = 0;

	GetVariableAccessAttributesRequest_t* request = 0;

	asn_dec_rval_t rval; /* Decoder return value  */

	rval = ber_decode(NULL, &asn_DEF_GetVariableAccessAttributesRequest,
				(void**) &request, buffer + bufPos, maxBufPos - bufPos);

	if (rval.code == RC_OK) {
		if (request->present == GetVariableAccessAttributesRequest_PR_name) {
			if (request->choice.name.present == ObjectName_PR_domainspecific) {
				Identifier_t domainId = request->choice.name.choice.domainspecific.domainId;
				Identifier_t nameId = request->choice.name.choice.domainspecific.itemId;

				char* domainIdStr = createStringFromBuffer(domainId.buf, domainId.size);
				char* nameIdStr = createStringFromBuffer(nameId.buf, nameId.size);

				if (DEBUG_MMS_SERVER)
				    printf("MMS_SERVER: getVariableAccessAttributes domainId: %s nameId: %s\n", domainIdStr, nameIdStr);

				createVariableAccessAttributesResponse(connection, domainIdStr, nameIdStr, invokeId, response);

				GLOBAL_FREEMEM(domainIdStr);
				GLOBAL_FREEMEM(nameIdStr);
			}
#if (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1)
			else if (request->choice.name.present == ObjectName_PR_vmdspecific) {
			    Identifier_t nameId = request->choice.name.choice.vmdspecific;

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

			    if (DEBUG_MMS_SERVER) printf("MMS_SERVER: getVariableAccessAttributes (VMD specific) nameId: %s\n", nameIdStr);

			    createVariableAccessAttributesResponse(connection, NULL, nameIdStr, invokeId, response);

			    GLOBAL_FREEMEM(nameIdStr);
			}
#endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */
			else {
				if (DEBUG_MMS_SERVER) printf("GetVariableAccessAttributesRequest with name other than domainspecific is not supported!\n");
				retVal = -1;
			}
		}
		else {
			if (DEBUG_MMS_SERVER) printf("GetVariableAccessAttributesRequest with address not supported!\n");
			retVal = -1;
		}
	}
	else {
		if (DEBUG_MMS_SERVER) printf("GetVariableAccessAttributesRequest parsing request failed!\n");
		retVal = -1;
	}

	asn_DEF_GetVariableAccessAttributesRequest.free_struct(&asn_DEF_GetVariableAccessAttributesRequest, request, 0);

	return retVal;
}
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;
        }

        MmsVariableSpecification* variable;

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

        MmsDomain* domain = NULL;

        char* nameIdStr;

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

            domain = MmsDevice_getDomain(device, domainIdStr);

            GLOBAL_FREEMEM(domainIdStr);

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

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

            variable = MmsDomain_getNamedVariable(domain, nameIdStr);
        }

#if (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1)
        else if (varSpec->variableSpecification.choice.name.present == ObjectName_PR_vmdspecific) {

            Identifier_t nameId = varSpec->variableSpecification.choice.name.choice.vmdspecific;
            nameIdStr = createStringFromBuffer(nameId.buf, nameId.size);

            variable = MmsDevice_getNamedVariable(device, nameIdStr);
        }
#endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */

        else {
            accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED;
            continue;
        }

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

        AlternateAccess_t* alternateAccess = varSpec->alternateAccess;

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

            if (!mmsServer_isIndexAccess(alternateAccess)) {
                GLOBAL_FREEMEM(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) {
            GLOBAL_FREEMEM(nameIdStr);
            accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
            continue;
        }

        /* Check for correct type */
        if (MmsValue_getType(value) != MmsVariableSpecification_getType(variable)) {
            GLOBAL_FREEMEM(nameIdStr);
            MmsValue_delete(value);
            accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT;
            continue;
        }

        if (alternateAccess != NULL) {

            if (domain != NULL)
                domain = (MmsDomain*) device;

            MmsValue* cachedArray = MmsServer_getValueFromCache(connection->server, domain, nameIdStr);

            if (cachedArray == NULL) {
                GLOBAL_FREEMEM(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) {
                GLOBAL_FREEMEM(nameIdStr);
                MmsValue_delete(value);
                accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT;
                continue;
            }

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

            GLOBAL_FREEMEM(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);

        GLOBAL_FREEMEM(nameIdStr);
	}

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

	asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
}
Exemple #29
0
int
IsoServer_waitReady(IsoServer self, unsigned int timeoutMs)
{
   int result;

   if (self->state == ISO_SVR_STATE_RUNNING) {
       HandleSet handles;

       handles = Handleset_new();
       if (handles != NULL) {
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1)

#if (CONFIG_MMS_THREADLESS_STACK != 1)
           lockClientConnections(self);
#endif

           LinkedList openConnection = LinkedList_getNext(self->openClientConnections);
           LinkedList lastConnection = self->openClientConnections;

           while (openConnection != NULL) {
               IsoConnection isoConnection = (IsoConnection) openConnection->data;

               if (IsoConnection_isRunning(isoConnection)) {
                   IsoConnection_addHandleSet(isoConnection, handles);
                   openConnection = LinkedList_getNext(openConnection);
               } else {
                   IsoConnection_destroy(isoConnection);
                   lastConnection->next = openConnection->next;
                   GLOBAL_FREEMEM(openConnection);
                   openConnection = lastConnection->next;
               }

               lastConnection = lastConnection->next;
           }

#if (CONFIG_MMS_THREADLESS_STACK != 1)
           unlockClientConnections(self);
#endif

#else
           int i;

           for (i = 0; i < CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS; i++) {
               if (self->openClientConnections[i] != NULL) {
                   if (IsoConnection_isRunning(self->openClientConnections[i])) {
                       IsoConnection_addHandleSet(self->openClientConnections[i], handles);
                   } else {
                       IsoConnection_destroy(self->openClientConnections[i]);
                       self->openClientConnections[i] = NULL;
                   }
               }
           }
#endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */
           Handleset_addSocket(handles, self->serverSocket);
           result = Handleset_waitReady(handles, timeoutMs);
           Handleset_destroy(handles);
       } else {
           result = -1;
       }
   } else {
       result = -1;
   }

   return result;
}
Exemple #30
0
EthernetSocket
Ethernet_createSocket(const char* interfaceId, uint8_t* destAddress)
{
    char bpfFileStringBuffer[11] = { 0 };
    int i;
    struct ifreq ifr;
    int optval;
    struct bpf_insn destAddrFiltCode[] =
    {
        // Load 0 into accumulator. Change to 1 to enable ethernet address filter.
        {0x00, 0, 0, 0x00000000},   // A0:  ld #0
        {0x15, 4, 0, 0x00000000},   //      jeq #0, P0, A1

        // Load 4 bytes starting at offest 2 into the accu and compare it with 4 bytes of the destination address.
        {0x20, 0, 0, 0x00000002},   // A1:  ld [2]
        {0x15, 0, 7, 0x00000000},   //      jeq #0, A2, KO

        // Load 2 bytes starting at offest 0 into the accu and compare it with 2 bytes of the destination address.
        {0x28, 0, 0, 0x00000000},   // A2:  ldh [0]
        {0x15, 0, 5, 0x00000000},   //      jeq #0, P0, KO

        // Load 0 into accumulator. Change to 1 to enable ethernet protocol filter.
        {0x00, 0, 0, 0x00000000},   // P0:  ld #0
        {0x15, 2, 0, 0x00000000},   //      jeq #0, OK, P1

        // Load 2 bytes starting at offset 12 into the accu and compare it with the given ethertype.
        {0x28, 0, 0, 0x0000000c},   // P1:  ldh [12]
        {0x15, 0, 1, 0x00000000},   //      jeq #0, OK, KO

        // Accept packet.
        {0x6, 0, 0, 0x0000ffff},    // OK:  ret #65535

        // Drop packet.
        {0x6, 0, 0, 0x00000000}     // KO:  ret #0

        /* The whole BPF VM assembler program compiled with bpfc into the machine code above:
         *
         * A0: ld #0
         *     jeq #0, P0, A1
         * A1: ld [2]
         *     jeq #0, A2, KO
         * A2: ldh [0]
         *     jeq #0, P0, KO
         * P0: ld #0
         *     jeq #0, OK, P1
         * P1: ldh [12]
         *     jeq #0, OK, KO
         * OK: ret #65535
         * KO: ret #0
         */
    };

    EthernetSocket self = GLOBAL_CALLOC(1, sizeof(struct sEthernetSocket));
    if (!self)
    {
        printf("Could not allocate socket descriptor!\n");
        return NULL;
    }

    // Copy default BPF filter program into descriptor.
    self->bpfProgram.bf_insns = GLOBAL_CALLOC(1, sizeof(destAddrFiltCode));
    if (!self->bpfProgram.bf_insns)
    {
        printf("Could not allocate memory for BPF filter program!\n");
        return NULL;
    }
    memcpy(self->bpfProgram.bf_insns, &destAddrFiltCode, sizeof(destAddrFiltCode));
    self->bpfProgram.bf_len = 12;

    // Find the first unused BPF device node.
    self->bpf = -1;
    for (i = 0; i < 99; ++i)
    {
        sprintf(bpfFileStringBuffer, "/dev/bpf%i", i);
        self->bpf = open(bpfFileStringBuffer, O_RDWR);

        if (self->bpf != -1) break;
    }

    // Did not found any unused, fail.
    if (self->bpf == -1)
    {
        printf("Error opening BPF file handle!\n");
        GLOBAL_FREEMEM(self->bpfProgram.bf_insns);
        GLOBAL_FREEMEM(self);
        return NULL;
    }

    // Activate non-blocking operation.
    optval = ioctl(self->bpf, F_GETFL);
    optval |= O_NONBLOCK;
    if (fcntl(self->bpf, F_SETFL, &optval) == -1)
    {
        printf("Unable to change to non-blocking mode!\n");
        GLOBAL_FREEMEM(self->bpfProgram.bf_insns);
        GLOBAL_FREEMEM(self);
        return NULL;
    }

    // Select the network interface for the BPF.
    strncpy(ifr.ifr_name, interfaceId, IFNAMSIZ);
    if (ioctl(self->bpf, BIOCSETIF, &ifr))
    {
        printf("Unable to select interface %s!\n", interfaceId);
        GLOBAL_FREEMEM(self->bpfProgram.bf_insns);
        GLOBAL_FREEMEM(self);
        return NULL;
    }

    // Activate immediate mode.
    if (ioctl(self->bpf, BIOCIMMEDIATE, &self->bpfBufferSize) == -1)
    {
        printf("Unable to activate immediate mode!\n");
        GLOBAL_FREEMEM(self->bpfProgram.bf_insns);
        GLOBAL_FREEMEM(self);
        return NULL;
    }

    // Get the buffer length from the BPF handle.
    if (ioctl(self->bpf, BIOCGBLEN, &self->bpfBufferSize) == -1)
    {
        printf("Unable to get BPF buffer lenght!\n");
        GLOBAL_FREEMEM(self->bpfProgram.bf_insns);
        GLOBAL_FREEMEM(self);
        return NULL;
    }

    // Allocate a buffer for the message reception.
    self->bpfBuffer = GLOBAL_CALLOC(1, self->bpfBufferSize);
    if (!self->bpfBuffer)
    {
        printf("Unable to allocate BPF RX buffer!\n");
        GLOBAL_FREEMEM(self->bpfProgram.bf_insns);
        GLOBAL_FREEMEM(self);
        return NULL;
    }
    self->bpfPositon = self->bpfBuffer;
    self->bpfEnd = self->bpfBuffer;

    // Set BPF into promiscous mode.
    optval = 1;
    if (ioctl(self->bpf, BIOCPROMISC, &optval) == -1)
    {
        printf("Unable to activate promiscous mode!\n");
        GLOBAL_FREEMEM(self->bpfProgram.bf_insns);
        GLOBAL_FREEMEM(self->bpfBuffer);
        GLOBAL_FREEMEM(self);
        return NULL;
    }

    return self;
}