예제 #1
0
파일: _tracer.py 프로젝트: alkasm/pyuavcan
def _unittest_udp_tracer() -> None:
    from pytest import approx
    from ipaddress import ip_address
    from pyuavcan.transport import Priority, ServiceDataSpecifier
    from pyuavcan.transport.udp import UDPTransport
    from ._ip import MACHeader, IPHeader, UDPHeader, service_data_specifier_to_udp_port

    tr = UDPTransport.make_tracer()
    ts = Timestamp.now()

    ds = ServiceDataSpecifier(11, ServiceDataSpecifier.Role.RESPONSE)
    trace = tr.update(
        UDPCapture(
            ts,
            RawPacket(
                MACHeader(memoryview(b""), memoryview(b"")),
                IPHeader(ip_address("127.0.0.42"), ip_address("127.0.0.63")),
                UDPHeader(12345, service_data_specifier_to_udp_port(ds)),
                memoryview(b"".join(
                    UDPFrame(
                        priority=Priority.SLOW,
                        transfer_id=1234567890,
                        index=0,
                        end_of_transfer=True,
                        payload=memoryview(b"Hello world!"),
                    ).compile_header_and_payload())),
            ),
        ))
    assert isinstance(trace, TransferTrace)
    assert trace.timestamp == ts
    assert trace.transfer_id_timeout == approx(
        AlienTransferReassembler.MAX_TRANSFER_ID_TIMEOUT)  # Initial value.
    assert trace.transfer.metadata.transfer_id == 1234567890
    assert trace.transfer.metadata.priority == Priority.SLOW
    assert trace.transfer.metadata.session_specifier.source_node_id == 42
    assert trace.transfer.metadata.session_specifier.destination_node_id == 63
    assert trace.transfer.metadata.session_specifier.data_specifier == ds
    assert trace.transfer.fragmented_payload == [memoryview(b"Hello world!")]

    assert None is tr.update(
        pyuavcan.transport.Capture(ts))  # Another transport, ignored.

    assert None is tr.update(
        UDPCapture(  # Malformed frame.
            ts,
            RawPacket(
                MACHeader(memoryview(b""), memoryview(b"")),
                IPHeader(ip_address("127.0.0.42"), ip_address("127.1.0.63")),
                UDPHeader(1, 1),
                memoryview(b""),
            ),
        ))
예제 #2
0
def _unittest_udp_tracer() -> None:
    import socket
    from pytest import approx
    from ipaddress import ip_address
    from pyuavcan.transport import Priority, ServiceDataSpecifier
    from pyuavcan.transport.udp import UDPTransport
    from ._ip import service_data_specifier_to_udp_port

    tr = UDPTransport.make_tracer()
    ts = Timestamp.now()
    ds = ServiceDataSpecifier(11, ServiceDataSpecifier.Role.RESPONSE)

    # VALID SERVICE FRAME
    llp = LinkLayerPacket(
        protocol=socket.AF_INET,
        source=memoryview(b""),
        destination=memoryview(b""),
        payload=memoryview(b"".join([
            # IPv4
            b"\x45\x00",
            (20 + 8 + 24 + 12).to_bytes(
                2,
                "big"),  # Total length (incl. the 20 bytes of the IP header)
            b"\x7e\x50\x40\x00\x40",  # ID, flags, fragment offset, TTL
            b"\x11",  # Protocol (UDP)
            b"\x00\x00",  # IP checksum (unset)
            ip_address("127.0.0.42").packed,  # Source
            ip_address("127.0.0.63").packed,  # Destination
            # UDP/IP
            (12345).to_bytes(2, "big"),  # Source port
            service_data_specifier_to_udp_port(ds).to_bytes(
                2, "big"),  # Destination port
            (8 + 24 + 12).to_bytes(
                2,
                "big"),  # Total length (incl. the 8 bytes of the UDP header)
            b"\x00\x00",  # UDP checksum (unset)
            # UAVCAN/UDP
            b"".join(
                UDPFrame(
                    priority=Priority.SLOW,
                    transfer_id=1234567890,
                    index=0,
                    end_of_transfer=True,
                    payload=memoryview(b"Hello world!"),
                ).compile_header_and_payload()),
        ])),
    )
    ip_packet = IPPacket.parse(llp)
    assert ip_packet is not None
    assert ip_packet.source_destination == (ip_address("127.0.0.42"),
                                            ip_address("127.0.0.63"))
    assert ip_packet.protocol == 0x11
    udp_packet = UDPIPPacket.parse(ip_packet)
    assert udp_packet is not None
    assert udp_packet.source_port == 12345
    assert udp_packet.destination_port == service_data_specifier_to_udp_port(
        ds)
    trace = tr.update(UDPCapture(ts, llp))
    assert isinstance(trace, TransferTrace)
    assert trace.timestamp == ts
    assert trace.transfer_id_timeout == approx(2.0)  # Initial value.
    assert trace.transfer.metadata.transfer_id == 1234567890
    assert trace.transfer.metadata.priority == Priority.SLOW
    assert trace.transfer.metadata.session_specifier.source_node_id == 42
    assert trace.transfer.metadata.session_specifier.destination_node_id == 63
    assert trace.transfer.metadata.session_specifier.data_specifier == ds
    assert trace.transfer.fragmented_payload == [memoryview(b"Hello world!")]

    # ANOTHER TRANSPORT, IGNORED
    assert None is tr.update(pyuavcan.transport.Capture(ts))

    # MALFORMED - UAVCAN/UDP IS EMPTY
    llp = LinkLayerPacket(
        protocol=socket.AF_INET,
        source=memoryview(b""),
        destination=memoryview(b""),
        payload=memoryview(b"".join([
            # IPv4
            b"\x45\x00",
            (20 + 8 + 24 + 12).to_bytes(
                2,
                "big"),  # Total length (incl. the 20 bytes of the IP header)
            b"\x7e\x50\x40\x00\x40",  # ID, flags, fragment offset, TTL
            b"\x11",  # Protocol (UDP)
            b"\x00\x00",  # IP checksum (unset)
            ip_address("127.0.0.42").packed,  # Source
            ip_address("127.0.0.63").packed,  # Destination
            # UDP/IP
            (1).to_bytes(2, "big"),  # Source port
            (1).to_bytes(2, "big"),  # Destination port
            (8).to_bytes(
                2,
                "big"),  # Total length (incl. the 8 bytes of the UDP header)
            b"\x00\x00",  # UDP checksum (unset)
            # UAVCAN/UDP is missing
        ])),
    )
    ip_packet = IPPacket.parse(llp)
    assert ip_packet is not None
    assert ip_packet.source_destination == (ip_address("127.0.0.42"),
                                            ip_address("127.0.0.63"))
    assert ip_packet.protocol == 0x11
    udp_packet = UDPIPPacket.parse(ip_packet)
    assert udp_packet is not None
    assert udp_packet.source_port == 1
    assert udp_packet.destination_port == 1
    assert None is tr.update(UDPCapture(ts, llp))