Ejemplo n.º 1
0
def test_decode_message_replyack_reply():
    """
    Test the decode routine can recognise a message frame sent as a
    reply-ack.
    """
    frame = AX25UnnumberedInformationFrame(destination='APZAIO',
                                           source='VK4MSL-7',
                                           pid=0xf0,
                                           payload=b':VK4MDL-7 :Hi{01}45')
    decoded = APRSFrame.decode(frame, logging.getLogger('decoder'))
    assert_is_not(decoded, frame)
    assert isinstance(decoded, APRSMessageFrame)
    eq_(decoded.replyack, '45')
    eq_(decoded.msgid, '01')
Ejemplo n.º 2
0
def test_transmit_waits_if_cts_reset():
    """
    Test the interface waits if CTS timer is reset.
    """
    my_port = DummyKISS()
    my_frame = AX25UnnumberedInformationFrame(
            destination='VK4BWI-4',
            source='VK4MSL',
            pid=0xf0,
            payload=b'testing')
    transmit_future = Future()

    my_interface = AX25Interface(my_port, cts_delay=0.250)

    def _on_transmit(interface, frame, **kwargs):
        try:
            eq_(len(kwargs), 0, msg='Too many arguments')
            assert_is(interface, my_interface, msg='Wrong interface')
            eq_(bytes(frame), bytes(my_frame), msg='Wrong frame')
            transmit_future.set_result(None)
        except Exception as e:
            transmit_future.set_exception(e)

    def _on_timeout():
        transmit_future.set_exception(AssertionError('Timed out'))

    # The time before transmission
    time_before = time.monotonic()

    # Set a timeout
    get_event_loop().call_later(1.0, _on_timeout)

    # Send the message
    my_interface.transmit(my_frame, _on_transmit)

    # Whilst that is pending, call reset_cts, this should delay transmission
    my_interface._reset_cts()

    yield from transmit_future

    eq_(len(my_port.sent), 1)
    (send_time, sent_frame) = my_port.sent.pop(0)

    eq_(bytes(sent_frame), bytes(my_frame))
    assert_less((time.monotonic() - send_time), 0.05)
    assert_greater(send_time - time_before, 0.25)
    assert_less(send_time - time_before, 1.05)
Ejemplo n.º 3
0
def test_transmit_sends_if_not_expired():
    """
    Test the interface sends frame if not expired.
    """
    my_port = DummyKISS()
    my_frame = AX25UnnumberedInformationFrame(
            destination='VK4BWI-4',
            source='VK4MSL',
            pid=0xf0,
            payload=b'testing')
    my_frame.deadline = time.time() + 3600.0
    transmit_future = Future()

    my_interface = AX25Interface(my_port)

    # Override clear to send expiry
    my_interface._cts_expiry = 0

    def _on_transmit(interface, frame, **kwargs):
        try:
            eq_(len(kwargs), 0, msg='Too many arguments')
            assert_is(interface, my_interface, msg='Wrong interface')
            eq_(bytes(frame), bytes(my_frame), msg='Wrong frame')
            transmit_future.set_result(None)
        except Exception as e:
            transmit_future.set_exception(e)

    def _on_timeout():
        transmit_future.set_exception(AssertionError('Timed out'))

    # The time before transmission
    time_before = time.monotonic()

    # Set a timeout
    get_event_loop().call_later(1.0, _on_timeout)

    # Send the message
    my_interface.transmit(my_frame, _on_transmit)

    yield from transmit_future

    eq_(len(my_port.sent), 1)
    (send_time, sent_frame) = my_port.sent.pop(0)

    eq_(bytes(sent_frame), bytes(my_frame))
    assert_less((time.monotonic() - send_time), 0.05)
    assert_less((send_time - time_before), 0.05)
Ejemplo n.º 4
0
def test_encode_ui():
    """
    Test that we can encode a UI frame.
    """
    frame = AX25UnnumberedInformationFrame(destination='VK4BWI',
                                           source='VK4MSL',
                                           cr=True,
                                           pid=0xf0,
                                           payload=b'This is a test')
    hex_cmp(
        bytes(frame),
        'ac 96 68 84 ae 92 e0'  # Destination
        'ac 96 68 9a a6 98 61'  # Source
        '03'  # Control
        'f0'  # PID
        '54 68 69 73 20 69 73 20 61 20 74 65 73 74'  # Payload
    )
Ejemplo n.º 5
0
def test_receive_re_filter():
    """
    Test matching messages can trigger regex filters (without SSID).
    """
    my_port = DummyKISS()
    unmatched_filter_received = []
    my_frame = AX25UnnumberedInformationFrame(destination='VK4BWI-4',
                                              source='VK4MSL',
                                              pid=0xf0,
                                              payload=b'testing')
    receive_future = Future()

    my_interface = AX25Interface(my_port)

    def _on_receive_match(interface, frame, match, **kwargs):
        try:
            eq_(len(kwargs), 0, msg='Too many arguments')
            assert_is(interface, my_interface, msg='Wrong interface')
            eq_(bytes(frame), bytes(my_frame), msg='Wrong frame')
            receive_future.set_result(None)
        except Exception as e:
            receive_future.set_exception(e)

    def _on_receive_nomatch(**kwargs):
        unmatched_filter_received.append(kwargs)

    def _on_timeout():
        receive_future.set_exception(AssertionError('Timed out'))

    # This should match
    my_interface.bind(_on_receive_match, r'^VK4[BR]WI$', ssid=None, regex=True)

    # This should not match
    my_interface.bind(_on_receive_nomatch,
                      r'^VK4[AZ]WI$',
                      ssid=None,
                      regex=True)

    # Set a timeout
    get_event_loop().call_later(1.0, _on_timeout)

    # Pass in a message
    my_port.received.emit(frame=bytes(my_frame))

    yield from receive_future
    eq_(len(unmatched_filter_received), 0)
Ejemplo n.º 6
0
def test_rx_irrelevant():
    """
    Test the digipeater module ignores irrelevant frames.
    """
    interface = DummyAPRSInterface()
    digipeater = APRSDigipeater()
    digipeater.connect(interface)
    interface.received_msg.emit(interface=interface,
                                frame=AX25UnnumberedInformationFrame(
                                    destination='VK4MSL-1',
                                    source='VK4MSL-2',
                                    repeaters=['VK4RZA', 'VK4RZB'],
                                    pid=0xff,
                                    payload=b'testing'))

    # This should have been dropped
    eq_(len(interface.transmitted), 0)
Ejemplo n.º 7
0
def test_on_receive_sol_replyack():
    """
    Test _on_receive of solicited reply-ack addressed to station.
    """
    # Create a frame
    frame = AX25UnnumberedInformationFrame(
                destination='APZAIO',
                source='VK4BWI-2',
                pid=0xf0,
                payload=b':VK4MSL-10:testing{356}123',
                repeaters=['WIDE2-1','WIDE1-1']
    )

    # Create our interface
    ax25int = DummyAX25Interface()
    aprsint = APRSInterface(ax25int, 'VK4MSL-10')

    # Inject a message handler for the message ID
    handler = DummyMessageHandler()
    aprsint._pending_msg['123'] = handler

    # Now pass the frame in as if it were just received
    aprsint._on_receive(frame)

    # There should be four calls made, one to our deduplication clean-up, the
    # second to our superclass, the third to the handler's _on_response method
    # and finally the incoming message should be emitted like a normal message.
    eq_(len(ax25int._loop.calls), 4)

    (_, callfunc) = ax25int._loop.calls.pop(0)
    eq_(callfunc, aprsint._schedule_dedup_cleanup)

    (_, callfunc) = ax25int._loop.calls.pop(0)
    assert isinstance(callfunc, partial)
    eq_(callfunc.func, super(APRSInterface, aprsint)._on_receive)

    (_, callfunc, msg) = ax25int._loop.calls.pop(0)
    eq_(callfunc, handler._on_response)
    eq_(bytes(frame), bytes(msg))

    # The message should also have been treated as a new incoming message.
    (_, callfunc) = ax25int._loop.calls.pop(0)
    assert isinstance(callfunc, partial)
    eq_(callfunc.func, aprsint.received_addressed_msg.emit)
Ejemplo n.º 8
0
def test_reception_resets_cts():
    """
    Check the clear-to-send expiry is updated with received traffic.
    """
    my_port = DummyKISS()
    my_frame = AX25UnnumberedInformationFrame(destination='VK4BWI',
                                              source='VK4MSL',
                                              pid=0xf0,
                                              payload=b'testing')

    my_interface = AX25Interface(my_port)
    cts_before = my_interface._cts_expiry

    # Pass in a message
    my_port.received.emit(frame=bytes(my_frame))
    cts_after = my_interface._cts_expiry

    assert_less(cts_before, cts_after)
    assert_greater(cts_after, time.monotonic())
Ejemplo n.º 9
0
def test_rx_hybridpath():
    """
    Test the digipeater module handles typical APRS paths.
    """
    interface = DummyAPRSInterface()
    digipeater = APRSDigipeater()
    digipeater.connect(interface)
    interface.received_msg.emit(interface=interface,
                                frame=AX25UnnumberedInformationFrame(
                                    destination='VK4MSL-1',
                                    source='VK4MSL-2',
                                    repeaters=['WIDE1-1', 'WIDE2-2'],
                                    pid=0xff,
                                    payload=b'testing'))

    # This should have been digipeated
    eq_(len(interface.transmitted), 1)
    frame = interface.transmitted.pop()
    eq_(str(frame.header.repeaters), 'VK4MSL-10*,WIDE2-2')
Ejemplo n.º 10
0
def test_rx_nexthop():
    """
    Test the digipeater module appends the correct WIDEn-N next hop.
    """
    interface = DummyAPRSInterface()
    digipeater = APRSDigipeater()
    digipeater.connect(interface)
    interface.received_msg.emit(interface=interface,
                                frame=AX25UnnumberedInformationFrame(
                                    destination='VK4MSL-1',
                                    source='VK4MSL-2',
                                    repeaters=['WIDE3-3'],
                                    pid=0xff,
                                    payload=b'testing'))

    # This should have been digipeated
    eq_(len(interface.transmitted), 1)
    frame = interface.transmitted.pop()
    eq_(str(frame.header.repeaters), 'VK4MSL-10*,WIDE3-2')
Ejemplo n.º 11
0
def test_ui_copy():
    """
    Test we can make a copy of a unnumbered information frame.
    """
    frame = AX25UnnumberedInformationFrame(destination='VK4BWI',
                                           source='VK4MSL',
                                           cr=True,
                                           pid=0xf0,
                                           payload=b'This is a test')
    framecopy = frame.copy()
    assert framecopy is not frame

    hex_cmp(
        bytes(framecopy),
        'ac 96 68 84 ae 92 e0'  # Destination
        'ac 96 68 9a a6 98 61'  # Source
        '03'  # Control
        'f0'  # PID
        '54 68 69 73 20 69 73 20 61 20 74 65 73 74'  # Payload
    )
Ejemplo n.º 12
0
def test_rx_selftodigi_first():
    """
    Test the digipeater module digipeats when own call is first.
    """
    interface = DummyAPRSInterface()
    digipeater = APRSDigipeater()
    digipeater.connect(interface)
    interface.received_msg.emit(interface=interface,
                                frame=AX25UnnumberedInformationFrame(
                                    destination='VK4MSL-1',
                                    source='VK4MSL-2',
                                    repeaters=['VK4MSL-10', 'VK4RZB'],
                                    pid=0xff,
                                    payload=b'testing'))

    # This should have been digipeated
    eq_(len(interface.transmitted), 1)
    frame = interface.transmitted.pop()

    # It should be passed through VK4MSL-10.
    eq_(str(frame.header.repeaters), 'VK4MSL-10*,VK4RZB')
Ejemplo n.º 13
0
def test_transmit_cancel():
    """
    Test that pending messages can be cancelled.
    """
    my_port = DummyKISS()
    my_frame = AX25UnnumberedInformationFrame(destination='VK4BWI-4',
                                              source='VK4MSL',
                                              pid=0xf0,
                                              payload=b'testing')

    my_interface = AX25Interface(my_port)

    # Send the message
    my_interface.transmit(my_frame)

    # Cancel it!
    my_interface.cancel_transmit(my_frame)

    # Wait a second
    yield from sleep(1)

    # Nothing should have been sent.
    eq_(len(my_port.sent), 0)