def create_array_message() -> Message: length_type = ModularInteger("Arrays.Length", Pow(Number(2), Number(8))) modular_type = ModularInteger("Arrays.Modular_Integer", Pow(Number(2), Number(16))) modular_vector_type = Array("Arrays.Modular_Vector", modular_type) range_type = RangeInteger("Arrays.Range_Integer", Number(1), Number(100), Number(8)) range_vector_type = Array("Arrays.Range_Vector", range_type) enum_type = Enumeration( "Arrays.Enumeration", { "ZERO": Number(0), "ONE": Number(1), "TWO": Number(2) }, Number(8), False, ) enum_vector_type = Array("Arrays.Enumeration_Vector", enum_type) av_enum_type = Enumeration( "Arrays.AV_Enumeration", { "AV_ZERO": Number(0), "AV_ONE": Number(1), "AV_TWO": Number(2) }, Number(8), True, ) av_enum_vector_type = Array("Arrays.AV_Enumeration_Vector", av_enum_type) structure = [ Link(INITIAL, Field("Length")), Link(Field("Length"), Field("Modular_Vector"), length=Mul(Variable("Length"), Number(8))), Link(Field("Modular_Vector"), Field("Range_Vector"), length=Number(16)), Link(Field("Range_Vector"), Field("Enumeration_Vector"), length=Number(16)), Link(Field("Enumeration_Vector"), Field("AV_Enumeration_Vector"), length=Number(16)), Link(Field("AV_Enumeration_Vector"), FINAL), ] types = { Field("Length"): length_type, Field("Modular_Vector"): modular_vector_type, Field("Range_Vector"): range_vector_type, Field("Enumeration_Vector"): enum_vector_type, Field("AV_Enumeration_Vector"): av_enum_vector_type, } return Message("Arrays.Message", structure, types)
def test_array_assign_incorrect_values( tlv: MessageValue, frame: MessageValue, array_type_foo: MessageValue, enum_value: EnumValue ) -> None: # pylint: disable=protected-access type_array = ArrayValue(Array("Test.Array", ModularInteger("Test.Mod_Int", Number(256)))) msg_array = ArrayValue(Array("Test.MsgArray", tlv._type)) intval = IntegerValue(ModularInteger("Test.Int", Number(256))) enum_value.assign("One") with pytest.raises(ValueError, match="cannot assign EnumValue to an array of ModularInteger"): type_array.assign([enum_value]) tlv.set("Tag", "Msg_Data") with pytest.raises( ValueError, match='cannot assign message "Message" to array of messages: all messages must be valid', ): msg_array.assign([tlv]) with pytest.raises(ValueError, match="cannot assign EnumValue to an array of Message"): msg_array.assign([enum_value]) tlv.set("Tag", "Msg_Data") tlv.set("Length", 4) tlv.set("Value", b"\x00\x00\x00\x00") frame.set("Destination", 0) frame.set("Source", 0) frame.set("Type_Length_TPID", 47) frame.set("Type_Length", 1537) frame.set("Payload", bytes(46)) with pytest.raises(ValueError, match='cannot assign "Frame" to an array of "Message"'): msg_array.assign([tlv, frame]) with pytest.raises( ValueError, match="cannot parse nested messages in array of type TLV.Message: Error while setting " "value for field Tag: 'Number 0 is not a valid enum value'", ): msg_array.parse(Bitstring("0001111")) tlv.set("Tag", "Msg_Data") tlv._fields["Length"].typeval.assign(111111111111111, False) with pytest.raises( ValueError, match='cannot assign message "Message" to array of messages: all messages must be valid', ): msg_array.assign([tlv]) assert msg_array.value == [] intval.assign(5) array_type_foo.set("Length", 42) with pytest.raises( ValueError, match="invalid data length: input length is 8 while expected input length is 336", ): array_type_foo.set("Bytes", [intval])
def test_array_unsupported_element_type() -> None: assert_type_error( Array( "P.A", ModularInteger("P.B", Pow(Number(2), Number(4)), Location((3, 4))), Location((5, 4)), ), r'^<stdin>:5:4: model: error: unsupported element type size of array "A"\n' r'<stdin>:3:4: model: info: type "B" has size 4, must be multiple of 8$', ) assert_type_error( Array("P.A", BOOLEAN, Location((5, 4))), r'^<stdin>:5:4: model: error: unsupported element type size of array "A"\n' r'__BUILTINS__:0:0: model: info: type "Boolean" has size 1, must be multiple of 8$', )
def test_array_aggregate_invalid_element_type() -> None: inner = Message( "P.I", [Link(INITIAL, Field("F")), Link(Field("F"), FINAL)], {Field("F"): MODULAR_INTEGER}, ) array_type = Array("P.Array", inner) f = Field("F") with pytest.raises( RecordFluxError, match=r"^<stdin>:90:10: model: error: invalid array element type" ' "P.I" for aggregate comparison$', ): Message( "P.M", [ Link(INITIAL, f, length=Number(18)), Link( f, FINAL, condition=Equal( Variable("F"), Aggregate(Number(1), Number(2), Number(64)), Location((90, 10)), ), ), ], {Field("F"): array_type}, )
def test_array_aggregate_out_of_range() -> None: array_type = Array("P.Array", ModularInteger("P.Element", Number(64))) f = Field("F") with pytest.raises( RecordFluxError, match= r"^<stdin>:44:3: model: error: aggregate element out of range 0 .. 63", ): Message( "P.M", [ Link(INITIAL, f, length=Number(18)), Link( f, FINAL, condition=Equal( Variable("F"), Aggregate(Number(1), Number(2), Number(64, location=Location((44, 3)))), ), ), ], {Field("F"): array_type}, )
def test_aggregate_equal_array_invalid_length() -> None: magic = Field(ID("Magic", Location((3, 5)))) structure = [ Link(INITIAL, magic, length=Number(40, location=Location((19, 17)))), Link( magic, FINAL, condition=NotEqual(Variable("Magic"), Aggregate(Number(1), Number(2)), Location((17, 3))), ), ] types = { Field("Magic"): Array( "P.Arr", ModularInteger("P.Modular", Number(128), location=Location((66, 3)))), } assert_message_model_error( structure, types, r"^" r'<stdin>:17:3: model: error: contradicting condition in "P.M"\n' r'<stdin>:3:5: model: info: on path: "Magic"\n' r'<stdin>:17:3: model: info: unsatisfied "2 [*] Modular\'Length = Magic\'Length"\n' r'<stdin>:66:3: model: info: unsatisfied "Modular\'Length = 7"\n' r'<stdin>:19:17: model: info: unsatisfied "Magic\'Length = 40"', )
def parse_type(string: str, location: int, tokens: list) -> Type: try: if tokens[3] == 'mod': return ModularInteger(tokens[1], *tokens[4:6]) if tokens[3] == 'range': tokens[6] = tokens[6]['size'] return RangeInteger(tokens[1], *tokens[4:7]) if tokens[3] == 'message': return Message(tokens[1], tokens[4]) if tokens[3] == '(': elements = dict(tokens[4:-2]) aspects = tokens[-1] if len(elements) < len(tokens[4:-2]): raise ModelError(f'"{tokens[1]}" contains duplicate elements') if 'always_valid' not in aspects: aspects['always_valid'] = False return Enumeration(tokens[1], elements, aspects['size'], aspects['always_valid']) if tokens[3] == 'new': if len(tokens) == 7: tokens.append(TRUE) return Refinement(tokens[1], *tokens[4:]) if tokens[3] == 'array of': return Array(tokens[1], tokens[4]) except ModelError as e: raise ParseFatalException(string, location, e) raise ParseFatalException(string, location, 'unexpected type')
def parse_type(string: str, location: int, tokens: ParseResults) -> Type: try: name = tokens[1] full_name = f"__PACKAGE__.{name}" if tokens[3] == "mod": return ModularInteger(full_name, *tokens[4:6]) if tokens[3] == "range": tokens[6] = tokens[6]["size"] return RangeInteger(full_name, *tokens[4:7]) if tokens[3] == "message": return MessageSpec(full_name, tokens[4]) if tokens[3] == "null message": return MessageSpec(full_name, []) if tokens[3] == "(": elements = dict(tokens[4:-2]) aspects = tokens[-1] if len(elements) < len(tokens[4:-2]): raise ModelError(f'"{name}" contains duplicate elements') if "always_valid" not in aspects: aspects["always_valid"] = False return Enumeration(full_name, elements, aspects["size"], aspects["always_valid"]) if tokens[3] == "new": return DerivationSpec(full_name, tokens[4]) if tokens[3] == "array of": return Array( full_name, Reference(tokens[4] if "." in tokens[4] else f"__PACKAGE__.{tokens[4]}")) except ModelError as e: raise ParseFatalException(string, location, e) raise ParseFatalException(string, location, "unexpected type")
def test_array_invalid_element_type() -> None: assert_type_error( Array("P.A", Array("P.B", MODULAR_INTEGER, Location((3, 4))), Location((5, 4))), r'^<stdin>:5:4: model: error: invalid element type of array "A"\n' r'<stdin>:3:4: model: info: type "B" must be scalar or non-null message$', ) assert_type_error( Array("P.A", Message("P.B", [], {}, Location((3, 4))), Location( (5, 4))), r'^<stdin>:5:4: model: error: invalid element type of array "A"\n' r'<stdin>:3:4: model: info: type "B" must be scalar or non-null message$', ) assert_type_error( Array("P.A", OPAQUE, Location((5, 4))), r'^<stdin>:5:4: model: error: invalid element type of array "A"\n' r'__BUILTINS__:0:0: model: info: type "Opaque" must be scalar or non-null message$', )
def test_array_preserve_value(enum_value: EnumValue) -> None: intval = IntegerValue(ModularInteger("Test.Int", Number(256))) intval.assign(1) enum_value.assign("One") type_array = ArrayValue(Array("Test.Array", ModularInteger("Test.Mod_Int", Number(256)))) type_array.assign([intval]) assert type_array.value == [intval] with pytest.raises(ValueError, match="cannot assign EnumValue to an array of ModularInteger"): type_array.assign([enum_value]) assert type_array.value == [intval]
def test_value_parse_from_bitstring(tlv: MessageValue, enum_value: EnumValue) -> None: # pylint: disable=protected-access intval = IntegerValue(ModularInteger("Test.Int", Number(256))) intval.parse(b"\x02") assert intval.value == 2 enum_value.parse(b"\x01") assert enum_value.value == "One" msg_array = ArrayValue(Array("Test.MsgArray", tlv._type)) tlv.set("Tag", "Msg_Data") tlv.set("Length", 4) tlv.set("Value", b"\x00\x00\x00\x00") msg_array.parse(tlv.bytestring)
def convert_to_messages(spec: Specification) -> Dict[str, Message]: types: Dict[str, Type] = {Payload().name: Payload()} messages: Dict[str, Message] = {} for t in spec.package.types: if t.name in types: raise ParserError(f'duplicate type "{t.name}"') t.full_name = f"{spec.package.identifier}.{t.name}" if isinstance(t, (ModularInteger, RangeInteger, Enumeration)): pass elif isinstance(t, Array): t.element_type.full_name = t.element_type.full_name.replace( "__PACKAGE__", spec.package.identifier) if t.element_type.name not in types: raise ParserError( f'undefined type "{t.element_type.name}" in "{t.name}"') if not isinstance(types[t.element_type.name], MessageSpec): element_type_size = types[ t.element_type.name].size.simplified() if not isinstance(element_type_size, Number) or int(element_type_size) % 8 != 0: raise ParserError( f"unsupported size ({element_type_size}) of element type " f'"{t.element_type.name}" in "{t.name}" ' "(no multiple of 8)") t = Array(t.full_name, types[t.element_type.name]) elif isinstance(t, MessageSpec): messages[t.full_name] = create_message(t.full_name, types, t.components, t.name) elif isinstance(t, DerivationSpec): base = t.base if base not in types and base not in messages: raise ParserError(f'undefined type "{t.base}" in "{t.name}"') base = qualified_type_name( t.base, spec.package.identifier, messages, f'unsupported type "{t.base}" in "{t.name}"', ) messages[t.full_name] = DerivedMessage(t.full_name, base, messages[base].structure, messages[base].types) t = MessageSpec(t.full_name, []) elif isinstance(t, Refinement): continue else: raise NotImplementedError(f'unsupported type "{type(t).__name__}"') types[t.name] = t return messages
def create_nodes(nodes: Dict[str, Node], types: Dict[str, Type], components: List[Component], message_name: str) -> None: for component in components: if component.name == 'null': nodes[component.name] = InitialNode() continue if 'Payload' in component.type: types[component.type] = Array(component.type) if component.type not in types: raise ParserError( f'reference to undefined type "{component.type}" in "{message_name}"' ) nodes[component.name] = Node(component.name, types[component.type])
def test_aggregate_equal_array_valid_length() -> None: structure = [ Link(INITIAL, Field("Magic"), length=Number(14)), Link( Field("Magic"), FINAL, condition=NotEqual(Variable("Magic"), Aggregate(Number(1), Number(2))), ), ] types = { Field("Magic"): Array("P.Arr", ModularInteger("P.Modular", Number(128))), } Message("P.M", structure, types)
def create_array_messages_message() -> Message: structure = [ Link(INITIAL, Field("Length")), Link(Field("Length"), Field("Messages"), length=Mul(Variable("Length"), Number(8))), Link(Field("Messages"), FINAL), ] types = { Field("Length"): ModularInteger("Arrays.Length", Pow(Number(2), Number(8))), Field("Messages"): Array("Arrays.Inner_Messages", Reference("Arrays.Inner_Message")), } return Message("Arrays.Messages_Message", structure, types)
def create_array(array: ArraySpec, types: Mapping[ID, Type]) -> Array: array.element_type.identifier = ID( array.element_type.full_name.replace("__PACKAGE__", str(array.package)), array.location) if array.element_type.identifier in types: element_type = types[array.element_type.identifier] else: fail( f'undefined element type "{array.element_type.identifier}"', Subsystem.PARSER, Severity.ERROR, array.element_type.location, ) return Array(array.identifier, element_type, array.location)
def create_ethernet_pdu() -> PDU: uint48 = ModularInteger('UINT48', Pow(Number(2), Number(48))) uint16 = RangeInteger('UINT16', Number(0), Sub(Pow(Number(2), Number(16)), Number(1)), Number(16)) payload_array = Array('Payload_Array') initial = InitialNode() destination = Node('Destination', uint48) source = Node('Source', uint48) tpid = Node('TPID', uint16) tci = Node('TCI', uint16) ether_type = Node('EtherType', uint16) payload = Node('Payload', payload_array) initial.edges = [Edge(destination)] destination.edges = [Edge(source)] source.edges = [Edge(tpid)] tpid.edges = [Edge(tci, Equal(Value('TPID'), Number(0x8100))), Edge(ether_type, NotEqual(Value('TPID'), Number(0x8100)), first=First('TPID'))] tci.edges = [Edge(ether_type)] ether_type.edges = [Edge(payload, LessEqual(Value('EtherType'), Number(1500)), Mul(LengthValue('EtherType'), Number(8))), Edge(payload, GreaterEqual(Value('EtherType'), Number(1536)), Sub(Last('Message'), Last('EtherType')))] payload.edges = [Edge(FINAL, And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))))] return PDU('Ethernet.Frame', initial)
def test_array_invalid_call(self) -> None: with self.assertRaises(ModelError): Array('X').size # pylint: disable=expression-not-assigned
def test_pdu_fields_ethernet(self) -> None: expected = OrderedDict([ ('Destination', Field('Destination', ModularInteger('UINT48', Pow(Number(2), Number(48))), TRUE, { '0': Variant( [], TRUE, { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47) }) })), ('Source', Field('Source', ModularInteger('UINT48', Pow(Number(2), Number(48))), TRUE, { '00': Variant( [ ('Destination', '0') ], TRUE, { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95) }) })), ('TPID', Field('TPID', RangeInteger('UINT16', Number(0), Sub(Pow(Number(2), Number(16)), Number(1)), Number(16)), Or(NotEqual(Value('TPID'), Number(0x8100)), Equal(Value('TPID'), Number(0x8100))), { '000': Variant( [ ('Destination', '0'), ('Source', '00') ], TRUE, { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111) }) })), ('TCI', Field('TCI', RangeInteger('UINT16', Number(0), Sub(Pow(Number(2), Number(16)), Number(1)), Number(16)), TRUE, { '0000': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000') ], Equal(Value('TPID'), Number(0x8100)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127) }) })), ('EtherType', Field('EtherType', RangeInteger('UINT16', Number(0), Sub(Pow(Number(2), Number(16)), Number(1)), Number(16)), Or(GreaterEqual(Value('EtherType'), Number(1536)), LessEqual(Value('EtherType'), Number(1500))), { '00000': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000') ], TRUE, { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143) }), '0001': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000') ], NotEqual(Value('TPID'), Number(0x8100)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111) }) })), ('Payload', Field('Payload', Array('Payload_Array'), And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { '000000': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000'), ('EtherType', '00000') ], LessEqual(Value('EtherType'), Number(1500)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143), Length('Payload'): Mul(LengthValue('EtherType'), Number(8)), First('Payload'): Number(144), Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)), Number(143)) }), '000001': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000'), ('EtherType', '00000') ], GreaterEqual(Value('EtherType'), Number(1536)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143), Length('Payload'): Add(Last('Message'), Number(-143)), First('Payload'): Number(144), Last('Payload'): Last('Message') }), '00010': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('EtherType', '0001') ], LessEqual(Value('EtherType'), Number(1500)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111), Length('Payload'): Mul(LengthValue('EtherType'), Number(8)), First('Payload'): Number(112), Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)), Number(111)) }), '00011': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('EtherType', '0001') ], GreaterEqual(Value('EtherType'), Number(1536)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111), Length('Payload'): Add(Last('Message'), Number(-111)), First('Payload'): Number(112), Last('Payload'): Last('Message') }) })), ('FINAL', Field('FINAL', Null(), TRUE, { '0000000': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000'), ('EtherType', '00000'), ('Payload', '000000') ], And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143), Length('Payload'): Mul(LengthValue('EtherType'), Number(8)), First('Payload'): Number(144), Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)), Number(143)) }), '0000010': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000'), ('EtherType', '00000'), ('Payload', '000001') ], And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143), Length('Payload'): Add(Last('Message'), Number(-143)), First('Payload'): Number(144), Last('Payload'): Last('Message') }), '000100': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('EtherType', '0001'), ('Payload', '00010') ], And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111), Length('Payload'): Mul(LengthValue('EtherType'), Number(8)), First('Payload'): Number(112), Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)), Number(111)) }), '000110': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('EtherType', '0001'), ('Payload', '00011') ], And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111), Length('Payload'): Add(Last('Message'), Number(-111)), First('Payload'): Number(112), Last('Payload'): Last('Message') }) })) ]) self.assertEqual(ETHERNET_PDU.fields(), expected)
def test_pdu_fields_length_after_payload(self) -> None: int_type = ModularInteger('T', Number(256)) payload_type = Array('Payload_Type') initial = InitialNode() version = Node('Version', int_type) payload = Node('Payload', payload_type) length = Node('Length', int_type) initial.edges = [Edge(version, TRUE)] version.edges = [Edge(payload, length=Value('Length'))] payload.edges = [Edge(length, first=Add(Last('Buffer'), -Length('Length'), Number(1)))] length.edges = [Edge(FINAL)] pdu = PDU('Foo', initial) expected = OrderedDict([ ('Version', Field('Version', int_type, TRUE, { '0': Variant( [], TRUE, { Length('Version'): Number(8), First('Version'): Number(0), Last('Version'): Number(7) }) })), ('Payload', Field('Payload', payload_type, TRUE, { '00': Variant( [('Version', '0')], TRUE, { Length('Version'): Number(8), First('Version'): Number(0), Last('Version'): Number(7), Length('Payload'): Value('Length'), First('Payload'): Number(8), Last('Payload'): Add(Value('Length'), Number(7)) }) })), ('Length', Field('Length', int_type, TRUE, { '000': Variant( [('Version', '0'), ('Payload', '00')], TRUE, { Length('Version'): Number(8), First('Version'): Number(0), Last('Version'): Number(7), Length('Payload'): Value('Length'), First('Payload'): Number(8), Last('Payload'): Add(Value('Length'), Number(7)), Length('Length'): Number(8), First('Length'): Add(Last('Buffer'), Number(-7)), Last('Length'): Last('Buffer') }) })), ('FINAL', Field('FINAL', Null(), TRUE, { '0000': Variant( [('Version', '0'), ('Payload', '00'), ('Length', '000')], TRUE, { Length('Version'): Number(8), First('Version'): Number(0), Last('Version'): Number(7), Length('Payload'): Value('Length'), First('Payload'): Number(8), Last('Payload'): Add(Value('Length'), Number(7)), Length('Length'): Number(8), First('Length'): Add(Last('Buffer'), Number(-7)), Last('Length'): Last('Buffer') }) })) ]) self.assertEqual(pdu.fields(), expected)
def test_array_invalid_call(self) -> None: with self.assertRaises(ModelError): # pylint: disable=expression-not-assigned Array("P.T", ModularInteger("B", Number(256))).size
[("LOW", Number(1)), ("MEDIUM", Number(4)), ("HIGH", Number(7))], Number(3), True, ) ENUMERATION_MESSAGE = Message( "Enumeration.Message", [Link(INITIAL, Field("Priority")), Link(Field("Priority"), FINAL)], {Field("Priority"): ENUMERATION_PRIORITY}, ) ENUMERATION_MODEL = Model([ENUMERATION_PRIORITY, ENUMERATION_MESSAGE]) ARRAYS_LENGTH = ModularInteger("Arrays.Length", Pow(Number(2), Number(8))) ARRAYS_MODULAR_INTEGER = ModularInteger("Arrays.Modular_Integer", Pow(Number(2), Number(16))) ARRAYS_MODULAR_VECTOR = Array("Arrays.Modular_Vector", ARRAYS_MODULAR_INTEGER) ARRAYS_RANGE_INTEGER = RangeInteger("Arrays.Range_Integer", Number(1), Number(100), Number(8)) ARRAYS_RANGE_VECTOR = Array("Arrays.Range_Vector", ARRAYS_RANGE_INTEGER) ARRAYS_ENUMERATION = Enumeration( "Arrays.Enumeration", [("ZERO", Number(0)), ("ONE", Number(1)), ("TWO", Number(2))], Number(8), False, ) ARRAYS_ENUMERATION_VECTOR = Array("Arrays.Enumeration_Vector", ARRAYS_ENUMERATION) ARRAYS_AV_ENUMERATION = Enumeration( "Arrays.AV_Enumeration", [("AV_ZERO", Number(0)), ("AV_ONE", Number(1)), ("AV_TWO", Number(2))], Number(8),