Пример #1
0
static MmsValue*
parseAllDataUnknownValue(GooseSubscriber self, uint8_t* buffer, int allDataLength, bool isStructure)
{
    int bufPos = 0;
    int elementLength = 0;

    int elementIndex = 0;

    MmsValue* dataSetValues = NULL;

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

        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");
            goto exit_with_error;
        }

        switch (tag) {
        case 0x80: /* reserved for access result */
            break;
        case 0xa1: /* array */
            break;
        case 0xa2: /* structure */
            break;
        case 0x83: /* boolean */
            break;
        case 0x84: /* BIT STRING */
            break;
        case 0x85: /* integer */
            break;
        case 0x86: /* unsigned integer */
            break;
        case 0x87: /* Float */
            break;
        case 0x89: /* octet string */
            break;
        case 0x8a: /* visible string */
            break;
        case 0x8c: /* binary time */
            break;
        case 0x91: /* Utctime */
            break;
        default:
            if (DEBUG_GOOSE_SUBSCRIBER)
                printf("GOOSE_SUBSCRIBER:    found unknown tag %02x\n", tag);
            goto exit_with_error;
        }

        bufPos += elementLength;

        elementIndex++;
    }

    if (isStructure)
        dataSetValues = MmsValue_createEmptyStructure(elementIndex);
    else
        dataSetValues = MmsValue_createEmptyArray(elementIndex);

    elementIndex = 0;
    bufPos = 0;

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

        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");
            goto exit_with_error;
        }

        MmsValue* value = NULL;

        switch (tag) {
        case 0xa1: /* array */
            if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER:    found array\n");

            value = parseAllDataUnknownValue(self, buffer + bufPos, elementLength, false);

            if (value == NULL)
                goto exit_with_error;

            break;
        case 0xa2: /* structure */
            if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER:    found structure\n");

            value = parseAllDataUnknownValue(self, buffer + bufPos, elementLength, true);

            if (value == NULL)
                goto exit_with_error;

            break;
        case 0x83: /* boolean */
            if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER:    found boolean\n");
            value = MmsValue_newBoolean(BerDecoder_decodeBoolean(buffer, bufPos));

            break;

        case 0x84: /* BIT STRING */
            {
                int padding = buffer[bufPos];
                int bitStringLength = (8 * (elementLength - 1)) - padding;
                value = MmsValue_newBitString(bitStringLength);
                memcpy(value->value.bitString.buf, buffer + bufPos + 1, elementLength - 1);

            }
            break;
        case 0x85: /* integer */
            value = MmsValue_newInteger(elementLength * 8);
            memcpy(value->value.integer->octets, buffer + bufPos, elementLength);
            value->value.integer->size = elementLength;
            break;
        case 0x86: /* unsigned integer */
            value = MmsValue_newUnsigned(elementLength * 8);
            memcpy(value->value.integer->octets, buffer + bufPos, elementLength);
            value->value.integer->size = elementLength;
            break;
        case 0x87: /* Float */
                if (elementLength == 9)
                    value = MmsValue_newDouble(BerDecoder_decodeDouble(buffer, bufPos));
                else if (elementLength == 5)
                    value = MmsValue_newFloat(BerDecoder_decodeFloat(buffer, bufPos));
            break;

        case 0x89: /* octet string */
            value = MmsValue_newOctetString(elementLength, elementLength);
            memcpy(value->value.octetString.buf, buffer + bufPos, elementLength);
            break;
        case 0x8a: /* visible string */
            value = MmsValue_newVisibleStringFromByteArray(buffer + bufPos, elementLength);
            break;
        case 0x8c: /* binary time */
            if (elementLength == 4)
                value = MmsValue_newBinaryTime(true);
            else if (elementLength == 6)
                value = MmsValue_newBinaryTime(false);

            if ((elementLength == 4) || (elementLength == 6))
                memcpy(value->value.binaryTime.buf, buffer + bufPos, elementLength);

            break;
        case 0x91: /* Utctime */
            if (elementLength == 8) {
                value = MmsValue_newUtcTime(0);
                MmsValue_setUtcTimeByBuffer(value, buffer + bufPos);
            }
            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);
            goto exit_with_error;
        }

        bufPos += elementLength;

        if (value != NULL) {
            MmsValue_setElement(dataSetValues, elementIndex, value);
            elementIndex++;
        }
    }

    self->dataSetValuesSelfAllocated = true;

    return dataSetValues;

exit_with_error:

    if (dataSetValues != NULL)
        MmsValue_delete(dataSetValues);

    return NULL;
}
Пример #2
0
MmsValue*
mmsClient_parseListOfAccessResults(AccessResult_t** accessResultList, int listSize, bool createArray)
{
    MmsValue* valueList = NULL;
    MmsValue* value = NULL;

    int elementCount = listSize;

    if ((elementCount > 1) || createArray)
        valueList = MmsValue_createEmptyArray(elementCount);

    int i = 0;

    for (i = 0; i < elementCount; i++) {
        AccessResult_PR presentType = accessResultList[i]->present;

        if (presentType == AccessResult_PR_failure) {
            if (DEBUG_MMS_CLIENT) printf("access error!\n");

            if (accessResultList[i]->choice.failure.size > 0) {
                int errorCode = (int) accessResultList[i]->choice.failure.buf[0];

                MmsDataAccessError dataAccessError = DATA_ACCESS_ERROR_UNKNOWN;

                if ((errorCode >= 0) && (errorCode < 12))
                    dataAccessError = (MmsDataAccessError) errorCode;

                value = MmsValue_newDataAccessError(dataAccessError);
            }
            else
                value = MmsValue_newDataAccessError(DATA_ACCESS_ERROR_UNKNOWN);
        }
        else if (presentType == AccessResult_PR_array) {
            value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
            value->type = MMS_ARRAY;

            int arrayElementCount =
                    accessResultList[i]->choice.array.list.count;

            value->value.structure.size = arrayElementCount;
            value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(arrayElementCount, sizeof(MmsValue*));

            int j;

            for (j = 0; j < arrayElementCount; j++) {
                value->value.structure.components[j] = mmsMsg_parseDataElement(
                        accessResultList[i]->choice.array.list.array[j]);
            }
        }
        else if (presentType == AccessResult_PR_structure) {
            value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
            value->type = MMS_STRUCTURE;

            int componentCount =
                    accessResultList[i]->choice.structure.list.count;

            value->value.structure.size = componentCount;
            value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));

            int j;
            for (j = 0; j < componentCount; j++) {
                value->value.structure.components[j] = mmsMsg_parseDataElement(
                        accessResultList[i]->choice.structure.list.array[j]);
            }
        }
        else if (presentType == AccessResult_PR_bitstring) {
            value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
            value->type = MMS_BIT_STRING;
            int size = accessResultList[i]->choice.bitstring.size;

            value->value.bitString.size = (size * 8)
               - accessResultList[i]->choice.bitstring.bits_unused;

            value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
            memcpy(value->value.bitString.buf,
                    accessResultList[i]->choice.bitstring.buf, size);

        }
        else if (presentType == AccessResult_PR_integer) {
            Asn1PrimitiveValue* berInteger =
                    BerInteger_createFromBuffer(accessResultList[i]->choice.integer.buf,
                                                accessResultList[i]->choice.integer.size);

            value = MmsValue_newIntegerFromBerInteger(berInteger);
        }
        else if (presentType == AccessResult_PR_unsigned) {
            Asn1PrimitiveValue* berInteger =
                    BerInteger_createFromBuffer(accessResultList[i]->choice.Unsigned.buf,
                                                                    accessResultList[i]->choice.Unsigned.size);

            value = MmsValue_newUnsignedFromBerInteger(berInteger);
        }
        else if (presentType == AccessResult_PR_floatingpoint) {
            int size = accessResultList[i]->choice.floatingpoint.size;

            value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
            value->type = MMS_FLOAT;

            if (size == 5) { /* FLOAT32 */
                value->value.floatingPoint.formatWidth = 32;
                value->value.floatingPoint.exponentWidth = accessResultList[i]->choice.floatingpoint.buf[0];

                uint8_t* floatBuf = (accessResultList[i]->choice.floatingpoint.buf + 1);

                value->value.floatingPoint.buf = (uint8_t*) GLOBAL_MALLOC(4);

#if (ORDER_LITTLE_ENDIAN == 1)
                    memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4);
#else
                    memcpy(value->value.floatingPoint.buf, floatBuf, 4);
#endif

            }

            if (size == 9) { /* FLOAT64 */
                value->value.floatingPoint.formatWidth = 64;
                value->value.floatingPoint.exponentWidth = accessResultList[i]->choice.floatingpoint.buf[0];

                uint8_t* floatBuf = (accessResultList[i]->choice.floatingpoint.buf + 1);

                value->value.floatingPoint.buf = (uint8_t*) GLOBAL_MALLOC(8);

#if (ORDER_LITTLE_ENDIAN == 1)
                memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8);
#else
                memcpy(value->value.floatingPoint.buf, floatBuf, 8);
#endif
            }

        }
        else if (presentType == AccessResult_PR_visiblestring) {
            value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));

            value->type = MMS_VISIBLE_STRING;

            int strSize = accessResultList[i]->choice.visiblestring.size;

            value->value.visibleString.buf = (char*) GLOBAL_MALLOC(strSize + 1);
            value->value.visibleString.size = strSize;

            memcpy(value->value.visibleString.buf,
                    accessResultList[i]->choice.visiblestring.buf,
                    strSize);

            value->value.visibleString.buf[strSize] = 0;
        }
        else if (presentType == AccessResult_PR_mMSString) {
        	value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));

        	value->type = MMS_STRING;

        	int strSize = accessResultList[i]->choice.mMSString.size;

        	value->value.visibleString.buf = (char*) GLOBAL_MALLOC(strSize + 1);
        	value->value.visibleString.size = strSize;

        	memcpy(value->value.visibleString.buf,
        			accessResultList[i]->choice.mMSString.buf, strSize);

        	value->value.visibleString.buf[strSize] = 0;

        }
        else if (presentType == AccessResult_PR_utctime) {
            value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));

            value->type = MMS_UTC_TIME;
            memcpy(value->value.utcTime,
                    accessResultList[i]->choice.utctime.buf, 8);
        }
        else if (presentType == AccessResult_PR_boolean) {
            value = MmsValue_newBoolean(accessResultList[i]->choice.boolean);
        }
        else if (presentType == AccessResult_PR_binarytime) {
            int size = accessResultList[i]->choice.binarytime.size;

            if (size <= 6) {
                value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
                value->type = MMS_BINARY_TIME;
                value->value.binaryTime.size = size;
                memcpy(value->value.binaryTime.buf, accessResultList[i]->choice.binarytime.buf, size);
            }
        }
        else if (presentType == AccessResult_PR_octetstring) {
        	int size = accessResultList[i]->choice.octetstring.size;

        	value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
        	value->type = MMS_OCTET_STRING;
        	value->value.octetString.maxSize = size;
        	value->value.octetString.size = size;
        	value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
        	memcpy(value->value.octetString.buf, accessResultList[i]->choice.octetstring.buf, size);
        }
        else {
            printf("unknown type %i\n", presentType);
            value = MmsValue_newDataAccessError(DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID);
        }

        if ((elementCount > 1) || createArray)
            MmsValue_setElement(valueList, i, value);
    }

    if (valueList == NULL)
        valueList = value;

    return valueList;
}
Пример #3
0
static void
alternateArrayAccess(MmsServerConnection connection,
		AlternateAccess_t* alternateAccess, MmsDomain* domain,
		char* itemId, LinkedList values,
		MmsVariableSpecification* namedVariable)
{
	if (mmsServer_isIndexAccess(alternateAccess))
	{
		int lowIndex = mmsServer_getLowIndex(alternateAccess);
		int numberOfElements = mmsServer_getNumberOfElements(alternateAccess);

		if (DEBUG_MMS_SERVER) printf("Alternate access index: %i elements %i\n",
				lowIndex, numberOfElements);

		int index = lowIndex;

		MmsValue* arrayValue = mmsServer_getValue(connection->server, domain, itemId, connection);

		if (arrayValue != NULL) {

	        MmsValue* value = NULL;

			if (numberOfElements == 0)
			    if (isAccessToArrayComponent(alternateAccess)) {
			        if (namedVariable->typeSpec.array.elementTypeSpec->type == MMS_STRUCTURE) {
			            MmsValue* structValue = MmsValue_getElement(arrayValue, index);

			            if (structValue != NULL)
			                value = getComponentOfArrayElement(alternateAccess,
			                        namedVariable, structValue);
			        }
			    }
			    else
			        value = MmsValue_getElement(arrayValue, index);
			else {
				value = MmsValue_createEmptyArray(numberOfElements);

				MmsValue_setDeletable(value);

				int resultIndex = 0;
				while (index < lowIndex + numberOfElements) {
					MmsValue* elementValue = NULL;

					elementValue = MmsValue_getElement(arrayValue, index);

					if (!MmsValue_isDeletable(elementValue)) {
						elementValue = MmsValue_clone(elementValue);
						elementValue->deleteValue = 1;
					}

					MmsValue_setElement(value, resultIndex, elementValue);

					index++;
					resultIndex++;
				}
			}

			appendValueToResultList(value, values);

		}
		else  /* access error */
			appendErrorToResultList(values, 10 /* object-non-existant*/);

	}
	else { // invalid access
		if (DEBUG_MMS_SERVER) printf("Invalid alternate access\n");

        appendErrorToResultList(values, 10 /* object-non-existant*/);
	}
}