def check_off_mesh_routes():
    # If a node itself adds a route, the route entry will be seen twice in
    # its WPAN_THREAD_OFF_MESH_ROUTES list (one time as part of network-wide
    # network data and again as part of the local network data). Note that
    # `r1 and `r2` each add a route, while `sed2` does not.
    verify(
        len(wpan.parse_list(r1.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
        NUM_ROUTES + NUM_ROUTES_LOCAL)
    verify(
        len(wpan.parse_list(r2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
        NUM_ROUTES + NUM_ROUTES_LOCAL)
    verify(
        len(wpan.parse_list(sed2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
        NUM_ROUTES)
def verify_no_address(node_list, prefix):
    """
    This function verifies that none of nodes in the `node_list` contain an IPv6 address with the given `prefix`.
    """
    for node in node_list:
        all_addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_ALL_ADDRESSES))
        verify(all([not addr.startswith(prefix[:-1]) for addr in all_addrs]))
def verify_address(node_list, prefix):
    """
    This function verifies that all nodes in the `node_list` contain an IPv6 address with the given `prefix`.
    """
    for node in node_list:
        all_addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_ALL_ADDRESSES))
        verify(any([addr.startswith(prefix[:-1]) for addr in all_addrs]))
def verify_prefix(node_list, prefix, on_mesh=True, slaac=True, def_route=False, priority='med'):
    """
    This function verifies that all the nodes in the given `node_list` contain an IPv6 address with the given prefix,
    and that the given prefix is present in the on-mesh prefixes list with the given flags (on-mesh, slaac, etc).
    """
    for node in node_list:
        all_addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_ALL_ADDRESSES))
        verify(any([addr.startswith(prefix[:-1]) for addr in all_addrs]))

        prefixes = wpan.parse_on_mesh_prefix_result(node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES))
        for p in prefixes:
            if p.prefix == prefix:
                verify(p.prefix_len == '64')
                verify(p.is_stable())
                verify(p.is_on_mesh() == on_mesh)
                verify(p.is_def_route() == def_route)
                verify(p.is_slaac() == slaac)
                verify(p.is_dhcp() == False)
                verify(p.priority == priority)
#


def check_child_table():
    # Checks the child table includes the expected number of children.
    child_table = wpan.parse_list(parent.get(wpan.WPAN_THREAD_CHILD_TABLE))
    verify(len(child_table) == NUM_CHILDREN)


# Verify that all children are present in the child table
check_child_table()

# Remember number of NCP state changes (using "stat:ncp" property) per child
child_num_state_changes = []
for child in all_children:
    child_num_state_changes.append(len(wpan.parse_list(child.get("stat:ncp"))))

# Reset the parent
parent.reset()


def check_parent_is_associated():
    verify(parent.is_associated())


wpan.verify_within(check_parent_is_associated, 5)

# Verify that all the children are recovered and present in the parent's
# child table again (within 5 seconds).
wpan.verify_within(check_child_table, 9)
parent2.whitelist_node(child)

parent1.form("inform-parent")
parent2.join_node(parent1, wpan.JOIN_TYPE_ROUTER)
child.join_node(parent2, wpan.JOIN_TYPE_SLEEPY_END_DEVICE);
child.set(wpan.WPAN_POLL_INTERVAL, '300')

#-----------------------------------------------------------------------------------------------------------------------
# Test implementation
#

CHILD_SUPERVISION_CHECK_TIMEOUT = 2
PARENT_SUPERVISION_INTERVAL = 1

# Verify the `child` is attached to `parent2`.
child_table = wpan.parse_list(parent2.get(wpan.WPAN_THREAD_CHILD_TABLE))
verify(len(child_table) == 1)

# Remove the `child` from whitelist of `parent2` and add it to whitelist of `parent1` instead.
parent1.whitelist_node(child)
parent2.un_whitelist_node(child)

# Enable supervision check on the `child` and also on `parent1`.

child.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, str(CHILD_SUPERVISION_CHECK_TIMEOUT))
parent1.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL))

# Since child supervision is not enabled on `parent2` and the `child` is
# removed from whitelist on `parent2`, after the supervision check timeout
# the `child` should realize that it can no longer talk to its current
# parent (`parent2`) and try to reattach. All re-attach attempts to `parent2`
def check_ip6_addresses():
    # Verify that SLAAC addresses are removed on r2 and c2
    verify_no_address([r2, c2], PREFIX)
    # And that user-added address matching the prefix is not removed on r1
    r1_addrs = wpan.parse_list(r1.get(wpan.WPAN_IP6_ALL_ADDRESSES))
    verify(IP_ADDRESS in r1_addrs)
# List of multicast addresses subscribed by routers only
router_mcast_addrs = mcast_addrs + [
    "ff02::2",   # All routers link-local
    "ff03::2"    # All routers realm-local
]

check_multicast_addresses(router, router_mcast_addrs)
check_multicast_addresses(fed, router_mcast_addrs)
check_multicast_addresses(sed, mcast_addrs)

# Add a multicast address

MCAST_ADDR = "ff02::114"

for node in [router, fed, sed]:
    node.add(wpan.WPAN_IP6_MULTICAST_ADDRESSES, MCAST_ADDR)
    addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_MULTICAST_ADDRESSES))
    verify(MCAST_ADDR in addrs)

    node.remove(wpan.WPAN_IP6_MULTICAST_ADDRESSES, MCAST_ADDR)
    addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_MULTICAST_ADDRESSES))
    verify(not MCAST_ADDR in addrs)

#-----------------------------------------------------------------------------------------------------------------------
# Test finished

wpan.Node.finalize_all_nodes()

print '\'{}\' passed.'.format(test_name)
Exemplo n.º 9
0

wpan.verify_within(check_child_addresses_on_parent, WAIT_TIME)

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Check the child recovery after a parent reset using quick re-attach
# ("Child Update" exchange).

# Disable supervision check on the child.
child.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, '1000')
child.set(wpan.WPAN_POLL_INTERVAL, '10000')
time.sleep(0.1)

# We use the "stat:ncp" wpantund property to verify that child does not
# get detached.
child_num_state_changes = len(wpan.parse_list(child.get("stat:ncp")))

# Reset parent and wait for it to be associated.
parent.reset()
wpan.verify_within(check_parent_is_associated, WAIT_TIME)

child.set(wpan.WPAN_POLL_INTERVAL, '100')

# Verify that we again see all the child addresses in the parent's child table.
# Note that child should register its addresses using "Child Update
# Request" exchange.
wpan.verify_within(check_child_addresses_on_parent, WAIT_TIME)

# Verify that there was no state change on child.
verify(child_num_state_changes == len(wpan.parse_list(child.get("stat:ncp"))))
def check_multicast_addresses(node, mcast_addr_list):
    addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_MULTICAST_ADDRESSES))
    for addr in mcast_addr_list:
        verify(addr in addrs)
joiner3.set(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH, '0')
verify(int(joiner3.get(wpan.WPAN_THREAD_JOINER_DISCERNER_BIT_LENGTH), 0) == 0)
verify(int(joiner3.get(wpan.WPAN_THREAD_JOINER_DISCERNER_VALUE), 0) == 0)

# Adding Joiners on Commissioner

commr.commissioner_start()

commr.commissioner_add_joiner_with_discerner(DISCERNER1, D_LEN1, PSK1,
                                             JOINER_TIMOUT)
commr.commissioner_add_joiner_with_discerner(DISCERNER2, D_LEN2, PSK2,
                                             JOINER_TIMOUT)
commr.commissioner_add_joiner(EUI64_3, PSK3, JOINER_TIMOUT)

verify(
    len(wpan.parse_list(commr.get(wpan.WPAN_THREAD_COMMISSIONER_JOINERS))) ==
    3)

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Start `joiner2` first

# Starting with `joiner2` verifies the behavior of Commissioner to
# prefer the Joiner entry with the longest matching discriminator. Note
# that `joiner2` uses a longer discriminator compared to `joiner1` with
# similar value.

joiner2.joiner_join(PSK2)
verify(joiner2.get(wpan.WPAN_STATE) == wpan.STATE_COMMISSIONED)
joiner2.joiner_attach()

def check_ip6_addresses():
    # Verify that SLAAC addresses are removed on r2 and c2
    verify_no_address([r2,c2], PREFIX)
    # And that user-added address matching the preifx is not removed on r1
    r1_addrs = wpan.parse_list(r1.get(wpan.WPAN_IP6_ALL_ADDRESSES))
    verify(IP_ADDRESS in r1_addrs)
r1.remove_prefix(PREFIX)
wpan.verify_within(check_prefix_and_slaac_address_are_removed, WAIT_INTERVAL)

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IP_ADDRESS = PREFIX + "1234"

# Explicitly add an address with the prefix on r1
r1.add_ip6_address_on_interface(IP_ADDRESS)

# Afterwards, add the prefix on r2 (with SLAAC flag)
r2.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True)
wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)

# Verify that on r1 we do see the user-added address
r1_addrs = wpan.parse_list(r1.get(wpan.WPAN_IP6_ALL_ADDRESSES))
verify(IP_ADDRESS in r1_addrs)

# Also verify that adding the prefix did not add a SLAAC address for same prefix on r1
r1_addrs.remove(IP_ADDRESS);
verify(all([not addr.startswith(PREFIX[:-1]) for addr in r1_addrs]))

# Remove the PREFIX on r2
r2.remove_prefix(PREFIX)

def check_ip6_addresses():
    # Verify that SLAAC addresses are removed on r2 and c2
    verify_no_address([r2,c2], PREFIX)
    # And that user-added address matching the preifx is not removed on r1
    r1_addrs = wpan.parse_list(r1.get(wpan.WPAN_IP6_ALL_ADDRESSES))
    verify(IP_ADDRESS in r1_addrs)
Exemplo n.º 14
0
def check_child_is_reattached():
    verify(
        len(wpan.parse_list(child.get("stat:ncp"))) > child_num_state_changes)
    child_is_in_parent2_table = (len(
        wpan.parse_list(parent2.get(wpan.WPAN_THREAD_CHILD_TABLE))) == 1)
    verify(child.is_associated())
def check_child_table():
    # Checks the child table includes the expected number of children.
    child_table = wpan.parse_list(parent.get(wpan.WPAN_THREAD_CHILD_TABLE))
    verify(len(child_table) == NUM_CHILDREN)
#       "00:00:06.475 ago -> offline"
#    ]
#

def check_child_table():
    # Checks the child table includes the expected number of children.
    child_table = wpan.parse_list(parent.get(wpan.WPAN_THREAD_CHILD_TABLE))
    verify(len(child_table) == NUM_CHILDREN)

# Verify that all children are present in the child table
check_child_table()

# Remember number of NCP state changes (using "stat:ncp" property) per child
child_num_state_changes = []
for child in all_children:
    child_num_state_changes.append(len(wpan.parse_list(child.get("stat:ncp"))))

# Reset the parent
parent.reset()

def check_parent_is_associated():
    verify(parent.is_associated())

wpan.verify_within(check_parent_is_associated, 5)

# Verify that all the children are recovered and present in the parent's child table again (within 5 seconds).
wpan.verify_within(check_child_table, 9)

# Verify that number of state changes on all children stays as before (indicating they did not get detached).
for i in range(len(all_children)):
    verify(child_num_state_changes[i] == len(wpan.parse_list(all_children[i].get("stat:ncp"))))
def check_multicast_addresses(node, mcast_addr_list):
    addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_MULTICAST_ADDRESSES))
    for addr in mcast_addr_list:
        verify(addr in addrs)
def check_child_table():
    # Checks the child table includes the expected number of children.
    child_table = wpan.parse_list(parent.get(wpan.WPAN_THREAD_CHILD_TABLE))
    verify(len(child_table) == NUM_CHILDREN)
# List of multicast addresses subscribed by routers only
router_mcast_addrs = mcast_addrs + [
    "ff02::2",  # All routers link-local
    "ff03::2",  # All routers realm-local
]

check_multicast_addresses(router, router_mcast_addrs)
check_multicast_addresses(fed, router_mcast_addrs)
check_multicast_addresses(sed, mcast_addrs)

# Add a multicast address

MCAST_ADDR = "ff02::114"

for node in [router, fed, sed]:
    node.add(wpan.WPAN_IP6_MULTICAST_ADDRESSES, MCAST_ADDR)
    addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_MULTICAST_ADDRESSES))
    verify(MCAST_ADDR in addrs)

    node.remove(wpan.WPAN_IP6_MULTICAST_ADDRESSES, MCAST_ADDR)
    addrs = wpan.parse_list(node.get(wpan.WPAN_IP6_MULTICAST_ADDRESSES))
    verify(MCAST_ADDR not in addrs)

# -----------------------------------------------------------------------------------------------------------------------
# Test finished

wpan.Node.finalize_all_nodes()

print('\'{}\' passed.'.format(test_name))
c2.whitelist_node(r3)

# Wait for c2 to detach from r2 and attach to r3.
#
# Upon re-attach, previous parent r2 is notified and should remove c2 from
# its child table.

def check_c2_is_removed_from_r2_child_table():
    child_table = wpan.parse_list(r2.get(wpan.WPAN_THREAD_CHILD_TABLE))
    verify(len(child_table) == 0)

wpan.verify_within(check_c2_is_removed_from_r2_child_table, REATTACH_WAIT_TIME)

# Verify that both c2, c3 are children of r3

child_table = wpan.parse_list(r3.get(wpan.WPAN_THREAD_CHILD_TABLE))
verify(len(child_table) == 2)

# New network topology
#
#     r1 ---- r2 ---- r3
#     |               /\
#     |              /  \
#     c1           c2(s) c3

# From r1 send again to c2 (which is now a child of r3).
#
# Note that r1 still has r2 as the destination for c2's address in its address
# cache table.  But since r2 is aware that c2 is no longer its child, when it
# receives the IPv6 message with c2's address, r2 itself would do an address
# query for the address and forward the IPv6 message.
def check_c2_is_removed_from_r2_child_table():
    child_table = wpan.parse_list(r2.get(wpan.WPAN_THREAD_CHILD_TABLE))
    verify(len(child_table) == 0)
Exemplo n.º 22
0
        (r1_type == wpan.NODE_TYPE_LEADER and r2_type == wpan.NODE_TYPE_ROUTER)
        or (
            r2_type == wpan.NODE_TYPE_LEADER
            and r1_type == wpan.NODE_TYPE_ROUTER
        )
    )


wpan.verify_within(check_r1_r2_roles, short_wait)

# Verify all nodes have both prefixes


def check_prefixes():
    verify_prefix([r1, r2, c1, c2], prefix1)
    verify_prefix([r1, r2, c1, c2], prefix2)


wpan.verify_within(check_prefixes, short_wait)

# Verify that the children stayed with their parents
verify(len(wpan.parse_list(r1.get(wpan.WPAN_THREAD_CHILD_TABLE))) == 1)
verify(len(wpan.parse_list(r2.get(wpan.WPAN_THREAD_CHILD_TABLE))) == 1)

# -----------------------------------------------------------------------------------------------------------------------
# Test finished

wpan.Node.finalize_all_nodes()

print('\'{}\' passed.'.format(test_name))
test_prefix_add_remove()

leader.add_prefix(prefix2, stable=True)
test_prefix_add_remove()

leader.remove_prefix(prefix1)
test_prefix_add_remove()

leader.remove_prefix(prefix2)
test_prefix_add_remove()

leader.add_route(prefix1, stable=False)
num_routes = num_routes + 1
test_prefix_add_remove()
verify(
    len(wpan.parse_list(c2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
    num_routes)

leader.add_route(prefix2, stable=True)
num_routes = num_routes + 1
test_prefix_add_remove()
verify(
    len(wpan.parse_list(c2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
    num_routes)

leader.add_prefix(prefix3, stable=True)
test_prefix_add_remove()
verify(
    len(wpan.parse_list(c2.get(wpan.WPAN_THREAD_OFF_MESH_ROUTES))) ==
    num_routes)
Exemplo n.º 24
0
def check_c_is_removed_from_r1_child_table():
    child_table = wpan.parse_list(r1.get(wpan.WPAN_THREAD_CHILD_TABLE))
    verify(len(child_table) == 0)

def check_r1_router_table():
    router_table = wpan.parse_router_table_result(
        r1.get(wpan.WPAN_THREAD_ROUTER_TABLE))
    verify(len(router_table) == 2)
    for entry in router_table:
        verify(entry.rloc16 == r1_rloc or entry.is_link_established())


wpan.verify_within(check_r1_router_table, WAIT_TIME)

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Check that r1 detected both TREL and 15.4 as supported radio by r2

r1_radios = wpan.parse_list(r1.get(wpan.WPAN_OT_SUPPORTED_RADIO_LINKS))
verify(
    len(r1_radios) == 2 and (wpan.RADIO_LINK_IEEE_802_15_4 in r1_radios)
    and (wpan.RADIO_LINK_TREL_UDP6 in r1_radios))

r2_radios = wpan.parse_list(r2.get(wpan.WPAN_OT_SUPPORTED_RADIO_LINKS))
verify(
    len(r2_radios) == 2 and (wpan.RADIO_LINK_IEEE_802_15_4 in r2_radios)
    and (wpan.RADIO_LINK_TREL_UDP6 in r2_radios))


def check_r1_sees_r2_has_two_radio_links():
    r1_neighbor_radios = wpan.parse_multi_radio_result(
        r1.get(wpan.WPAN_OT_NEIGHBOR_TABLE_MULTI_RADIO_INFO))
    verify(len(r1_neighbor_radios) == 1)
    verify(len(r1_neighbor_radios[0].radios) == 2)
def check_child_is_reattached():
    verify(len(wpan.parse_list(child.get("stat:ncp"))) > child_num_state_changes)
    child_is_in_parent2_table = (len(wpan.parse_list(parent2.get(wpan.WPAN_THREAD_CHILD_TABLE)))==1)
    verify(child.is_associated())
Exemplo n.º 27
0
r2.un_allowlist_node(c)
r1.allowlist_node(c)
c.allowlist_node(r1)

# Wait for c to detach from r2 and attach to r1.


def check_c_is_removed_from_r2_child_table():
    child_table = wpan.parse_list(r2.get(wpan.WPAN_THREAD_CHILD_TABLE))
    verify(len(child_table) == 0)


wpan.verify_within(check_c_is_removed_from_r2_child_table, REATTACH_WAIT_TIME)

# check that c is now a child of r1
child_table = wpan.parse_list(r1.get(wpan.WPAN_THREAD_CHILD_TABLE))
verify(len(child_table) == 1)

# Send a single UDP message from r2 to c
#
# This adds an address cache entry on r2 for c pointing to r1 (the current parent of c).

sender = r2.prepare_tx(r2_address, c_address, "Hi from r2 to c")
recver = c.prepare_rx(sender)
wpan.Node.perform_async_tx_rx()
verify(sender.was_successful and recver.was_successful)

# Force c to switch its parent from r1 to r3
#
#   r3 ---- r1 ---- r2
#   | \
Exemplo n.º 28
0
parent2.whitelist_node(child)

parent1.form("inform-parent")
parent2.join_node(parent1, wpan.JOIN_TYPE_ROUTER)
child.join_node(parent2, wpan.JOIN_TYPE_SLEEPY_END_DEVICE)
child.set(wpan.WPAN_POLL_INTERVAL, '300')

# -----------------------------------------------------------------------------------------------------------------------
# Test implementation
#

CHILD_SUPERVISION_CHECK_TIMEOUT = 2
PARENT_SUPERVISION_INTERVAL = 1

# Verify the `child` is attached to `parent2`.
child_table = wpan.parse_list(parent2.get(wpan.WPAN_THREAD_CHILD_TABLE))
verify(len(child_table) == 1)

# Remove the `child` from whitelist of `parent2` and add it to whitelist
# of `parent1` instead.
parent1.whitelist_node(child)
parent2.un_whitelist_node(child)

# Enable supervision check on the `child` and also on `parent1`.

child.set(
    wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT,
    str(CHILD_SUPERVISION_CHECK_TIMEOUT),
)
parent1.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL,
            str(PARENT_SUPERVISION_INTERVAL))
wpan.verify_within(check_prefix_and_slaac_address_are_removed, WAIT_INTERVAL)

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Check behavior when a user-added address with same prefix already exists.

IP_ADDRESS = PREFIX + "1234"

# Explicitly add an address with the prefix on r1
r1.add_ip6_address_on_interface(IP_ADDRESS)

# Afterwards, add the prefix on r2 (with SLAAC flag)
r2.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True)
wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)

# Verify that on r1 we do see the user-added address
r1_addrs = wpan.parse_list(r1.get(wpan.WPAN_IP6_ALL_ADDRESSES))
verify(IP_ADDRESS in r1_addrs)

# Also verify that adding the prefix did not add a SLAAC address for same
# prefix on r1
r1_addrs.remove(IP_ADDRESS)
verify(all([not addr.startswith(PREFIX[:-1]) for addr in r1_addrs]))

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Check behavior when a user-added address with same prefix is removed
# (SLAAC module should add a SLAAC address).

r1.remove_ip6_address_on_interface(IP_ADDRESS)
wpan.verify_within(check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
verify([node.find_ip6_address_with_prefix(PREFIX)
        for node in all_nodes] == slaac_addrs)
Exemplo n.º 30
0
def check_child_is_reattached():
    verify(
        len(wpan.parse_list(child.get("stat:ncp"))) > child_num_state_changes)
    verify(child.is_associated())
# On node2, form a network with same parameters but a different mesh-local
# prefix
node2.form(
    NET_NAME,
    channel=CHANNEL,
    panid=PANID,
    xpanid=XPANID,
    key=KEY,
    mesh_local_prefix=ML_PREFIX_2,
)

# Node 2 is expected to attach to node1 and adopt the mesh-local prefix
# from node1

verify(node2.is_associated())
verify(
    node2.get(wpan.WPAN_IP6_MESH_LOCAL_PREFIX)
    == node1.get(wpan.WPAN_IP6_MESH_LOCAL_PREFIX)
)

# Ensure that there are only two addresses on the node2 (link-local and mesh-local address) and that RLOC
# address is correctly filtered (by wpantund).
verify(len(wpan.parse_list(node2.get(wpan.WPAN_IP6_ALL_ADDRESSES))) == 2)

# -----------------------------------------------------------------------------------------------------------------------
# Test finished

wpan.Node.finalize_all_nodes()

print('\'{}\' passed.'.format(test_name))
c2 = wpan.Node(wpan.NODE_TREL)
c3 = wpan.Node(wpan.NODE_15_4_TREL)

# -----------------------------------------------------------------------------------------------------------------------
# Init all nodes

wpan.Node.init_all_nodes()

# -----------------------------------------------------------------------------------------------------------------------
# Test implementation

WAIT_TIME = 5

# Verify that each node supports the correct radio links:

parent_radios = wpan.parse_list(parent.get(wpan.WPAN_OT_SUPPORTED_RADIO_LINKS))
verify(
    len(parent_radios) == 2
    and (wpan.RADIO_LINK_IEEE_802_15_4 in parent_radios)
    and (wpan.RADIO_LINK_TREL_UDP6 in parent_radios))

c1_radios = wpan.parse_list(c1.get(wpan.WPAN_OT_SUPPORTED_RADIO_LINKS))
verify(len(c1_radios) == 1 and wpan.RADIO_LINK_IEEE_802_15_4 in c1_radios)

c2_radios = wpan.parse_list(c2.get(wpan.WPAN_OT_SUPPORTED_RADIO_LINKS))
verify(len(c2_radios) == 1 and wpan.RADIO_LINK_TREL_UDP6 in c2_radios)

c3_radios = wpan.parse_list(c3.get(wpan.WPAN_OT_SUPPORTED_RADIO_LINKS))
verify(
    len(c3_radios) == 2 and (wpan.RADIO_LINK_IEEE_802_15_4 in c3_radios)
    and (wpan.RADIO_LINK_TREL_UDP6 in c3_radios))