Skip to content

Commit

Permalink
fix(bacnet): implement BACnetUnconfirmedServiceRequestIAm
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Nov 30, 2021
1 parent f19d8f7 commit 6563eb9
Showing 4 changed files with 50 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -576,9 +576,9 @@ public String getReservedValue(ReservedField reservedField) {
}

/**
* @param field this generally only is needed in order to access field attributes such as encoding etc.
* @param resultType the type the resulting expression should have
* @param term the term representing the expression
* @param field this generally only is needed in order to access field attributes such as encoding etc.
* @param resultType the type the resulting expression should have
* @param term the term representing the expression
* @param parserArguments any parser arguments, which could be referenced in expressions (Needed for getting the type)
* @return Java code which does the things defined in 'term'
*/
@@ -588,9 +588,9 @@ public String toParseExpression(Field field, TypeReference resultType, Term term
}

/**
* @param field this generally only is needed in order to access field attributes such as encoding etc.
* @param resultType the type the resulting expression should have
* @param term the term representing the expression
* @param field this generally only is needed in order to access field attributes such as encoding etc.
* @param resultType the type the resulting expression should have
* @param term the term representing the expression
* @param serializerArguments any serializer arguments, which could be referenced in expressions (Needed for getting the type)
* @return Java code which does the things defined in 'term'
*/
@@ -628,18 +628,18 @@ private String toLiteralTermExpression(Field field, TypeReference resultType, Li
} else if (literal instanceof NumericLiteral) {
tracer = tracer.dive("numeric literal instanceOf");
final String numberString = ((NumericLiteral) literal).getNumber().toString();
if(resultType.isIntegerTypeReference()) {
if (resultType.isIntegerTypeReference()) {
final IntegerTypeReference integerTypeReference = resultType.asIntegerTypeReference().orElseThrow(RuntimeException::new);
if(integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
tracer = tracer.dive("uint >= 32bit");
return tracer + numberString + "L";
} else if(integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
} else if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
tracer = tracer.dive("int > 32bit");
return tracer + numberString + "L";
}
} else if(resultType.isFloatTypeReference()) {
} else if (resultType.isFloatTypeReference()) {
final FloatTypeReference floatTypeReference = resultType.asFloatTypeReference().orElseThrow(RuntimeException::new);
if(floatTypeReference.getSizeInBits() <= 32) {
if (floatTypeReference.getSizeInBits() <= 32) {
tracer = tracer.dive("float < 32bit");
return tracer + numberString + "F";
}
@@ -648,12 +648,12 @@ private String toLiteralTermExpression(Field field, TypeReference resultType, Li
} else if (literal instanceof HexadecimalLiteral) {
tracer = tracer.dive("hexadecimal literal instanceOf");
final String hexString = ((HexadecimalLiteral) literal).getHexString();
if(resultType.isIntegerTypeReference()) {
if (resultType.isIntegerTypeReference()) {
final IntegerTypeReference integerTypeReference = resultType.asIntegerTypeReference().orElseThrow(RuntimeException::new);
if(integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
tracer = tracer.dive("uint >= 32bit");
return tracer + hexString + "L";
} else if(integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
} else if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
tracer = tracer.dive("int > 32bit");
return tracer + hexString + "L";
}
@@ -689,13 +689,13 @@ private String toUnaryTermExpression(Field field, TypeReference resultType, Unar
switch (unaryTerm.getOperation()) {
case "!":
tracer = tracer.dive("case !");
if((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
throw new IllegalArgumentException("'!(...)' expression requires boolean type");
}
return tracer + "!(" + toExpression(field, resultType, a, variableExpressionGenerator) + ")";
case "-":
tracer = tracer.dive("case -");
if((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
throw new IllegalArgumentException("'-(...)' expression requires integer or floating-point type");
}
return tracer + "-(" + toExpression(field, resultType, a, variableExpressionGenerator) + ")";
@@ -715,7 +715,7 @@ private String toBinaryTermExpression(Field field, TypeReference resultType, Bin
switch (operation) {
case "^": {
tracer = tracer.dive(operation);
if((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
throw new IllegalArgumentException("'A^B' expression requires numeric result type");
}
return tracer + "Math.pow((" + toExpression(field, resultType, a, variableExpressionGenerator) + "), (" + toExpression(field, resultType, b, variableExpressionGenerator) + "))";
@@ -726,7 +726,7 @@ private String toBinaryTermExpression(Field field, TypeReference resultType, Bin
case "+":
case "-": {
tracer = tracer.dive(operation);
if((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
throw new IllegalArgumentException("'A" + operation + "B' expression requires numeric result type");
}
return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, resultType, b, variableExpressionGenerator) + ")";
@@ -742,15 +742,15 @@ private String toBinaryTermExpression(Field field, TypeReference resultType, Bin
case "<":
case "==":
case "!=": {
if((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
throw new IllegalArgumentException("'A" + operation + "B' expression requires boolean result type");
}
// TODO: Try to infer the types of the arguments in this case
return tracer + "(" + toExpression(field, ANY_TYPE_REFERENCE, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, ANY_TYPE_REFERENCE, b, variableExpressionGenerator) + ")";
}
case "&&":
case "||": {
if((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
throw new IllegalArgumentException("'A" + operation + "B' expression requires boolean result type");
}
return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, resultType, b, variableExpressionGenerator) + ")";
@@ -771,7 +771,12 @@ private String toTernaryTermExpression(Field field, TypeReference resultType, Te
Term a = ternaryTerm.getA();
Term b = ternaryTerm.getB();
Term c = ternaryTerm.getC();
return tracer + "((" + toExpression(field, BOOL_TYPE_REFERENCE, a, variableExpressionGenerator) + ") ? " + toExpression(field, resultType, b, variableExpressionGenerator) + " : " + toExpression(field, resultType, c, variableExpressionGenerator) + ")";
return tracer +
"(" +
"(" + toExpression(field, BOOL_TYPE_REFERENCE, a, variableExpressionGenerator) + ") ? " +
toExpression(field, resultType, b, variableExpressionGenerator) + " : " +
toExpression(field, resultType, c, variableExpressionGenerator) + "" +
")";
} else {
throw new IllegalArgumentException("Unsupported ternary operation type " + ternaryTerm.getOperation());
}
Original file line number Diff line number Diff line change
@@ -153,6 +153,8 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
public <#if field.loopType?? && field.type.isByteBased()>byte[]<#elseif field.loopType??>List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}><#else>${helper.getLanguageTypeNameForField(field)}</#if> get${field.name?cap_first}() {
<#if helper.getLanguageTypeNameForField(field) = 'String'>
return ${helper.getLanguageTypeNameForField(field)}.valueOf(${helper.toSerializationExpression(field, field.type, field.valueExpression, parserArguments)});
<#elseif helper.getLanguageTypeNameForField(field) = 'BigInteger'>
return BigInteger.valueOf(${helper.toSerializationExpression(field, field.type, field.valueExpression, parserArguments)});
<#else>
return (${helper.getLanguageTypeNameForField(field)}) (${helper.toSerializationExpression(field, field.type, field.valueExpression, parserArguments)});
</#if>
Original file line number Diff line number Diff line change
@@ -25,6 +25,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigInteger;

public class FieldReaderVirtual<T> implements FieldCommons {

@SuppressWarnings({"unused", "unchecked"})
@@ -73,6 +75,10 @@ public T readVirtualField(Class<T> type, Object valueExpression, WithReaderArgs.
if (type == String.class) {
return type.cast(String.valueOf(valueExpression));
}
if (type == BigInteger.class) {
long longValue = valueExpression instanceof Long ? (Long) valueExpression : (long) valueExpression;
return (T) BigInteger.valueOf(longValue);
}
return type.cast(valueExpression);
}

Original file line number Diff line number Diff line change
@@ -271,16 +271,10 @@
[discriminator uint 8 serviceChoice]
[typeSwitch serviceChoice
['0x00' BACnetUnconfirmedServiceRequestIAm
[const uint 8 objectIdentifierHeader 0xC4]
[simple uint 10 objectType]
[simple uint 22 objectInstanceNumber]
[const uint 5 maximumApduLengthAcceptedHeader 0x04]
[simple uint 3 maximumApduLengthAcceptedLength]
[array int 8 maximumApduLengthAccepted count 'maximumApduLengthAcceptedLength']
[const uint 8 segmentationSupportedHeader 0x91]
[simple uint 8 segmentationSupported]
[const uint 8 vendorIdHeader 0x21]
[simple uint 8 vendorId]
[simple BACnetTagApplicationObjectIdentifier deviceIdentifier ]
[simple BACnetTagApplicationUnsignedInteger maximumApduLengthAcceptedLength ]
[simple BACnetTagApplicationEnumerated segmentationSupported ]
[simple BACnetTagApplicationUnsignedInteger vendorId ]
]
['0x01' BACnetUnconfirmedServiceRequestIHave
[simple BACnetTagApplicationObjectIdentifier deviceIdentifier ]
@@ -510,8 +504,13 @@
[optional uint 16 valueUint16 'isUint16' ]
[virtual bit isUint32 'actualLength == 3' ]
[optional uint 32 valueUint32 'isUint32' ]
// TODO: we only go up to uint32 till we have the BigInteger stuff in java solved
[virtual uint 32 actualValue 'isUint8?valueUint8:(isUint16?valueUint16:(isUint32?valueUint32:0))']
/*
[virtual bit isUint64 'actualLength == 4' ]
[optional uint 64 valueUint64 'isUint64' ]
[virtual uint 64 actualValue 'isUint8?valueUint8:(isUint16?valueUint16:(isUint32?valueUint32:(isUint64?valueUint64:0)))']
*/
]
['APPLICATION_TAGS','0x3' BACnetTagApplicationSignedInteger(uint 32 actualLength)
[virtual bit isInt8 'actualLength == 1' ]
@@ -522,6 +521,7 @@
[optional int 32 valueInt32 'isInt32' ]
[virtual bit isInt64 'actualLength == 4' ]
[optional int 64 valueInt64 'isInt64' ]
[virtual uint 64 actualValue 'isInt8?valueInt8:(isInt16?valueInt16:(isInt64?valueInt64:0))']
]
['APPLICATION_TAGS','0x4' BACnetTagApplicationReal
[simple float 32 value]
@@ -609,8 +609,13 @@
[optional uint 16 valueUint16 'isUint16' ]
[virtual bit isUint32 'actualLength == 3' ]
[optional uint 32 valueUint32 'isUint32' ]
// TODO: we only go up to uint32 till we have the BigInteger stuff in java solved
[virtual uint 32 actualValue 'isUint8?valueUint8:(isUint16?valueUint16:(isUint32?valueUint32:0))']
/*
[virtual bit isUint64 'actualLength == 4' ]
[optional uint 64 valueUint64 'isUint64' ]
[virtual uint 64 actualValue 'isUint8?valueUint8:(isUint16?valueUint16:(isUint32?valueUint32:(isUint64?valueUint64:0)))']
*/
]
['SIGNED_INTEGER' BACnetComplexTagSignedInteger(uint 32 actualLength)
[virtual bit isInt8 'actualLength == 1' ]
@@ -621,6 +626,7 @@
[optional int 32 valueInt32 'isInt32' ]
[virtual bit isInt64 'actualLength == 4' ]
[optional int 64 valueInt64 'isInt64' ]
[virtual uint 64 actualValue 'isInt8?valueInt8:(isInt16?valueInt16:(isInt64?valueInt64:0))']
]
['REAL' BACnetComplexTagReal(uint 32 actualLength)
[simple float 32 value]

0 comments on commit 6563eb9

Please sign in to comment.