def test_reject_non_resolved_address_with_one_bond(peripheral, central,
                                                   central2):
    """validate that when a peripheral with:
          * privacy enabled
          * privacy policy set to REJECT_NON_RESOLVED_ADDRESS
          * at least a bond
        is connected by an unknown privacy enabled device then the connection
        is rejected"""
    init_privacy(central2)
    perform_bonding_with_privacy_and_disconnect(peripheral, central)

    peripheral.gap.setPeripheralPrivacyConfiguration(
        False, "REJECT_NON_RESOLVED_ADDRESS")

    advertising_data = start_advertising_of_type(peripheral,
                                                 "CONNECTABLE_UNDIRECTED")

    central2.gap.setCentralPrivacyConfiguration(False, "DO_NOT_RESOLVE")
    central2.gap.setPeripheralPrivacyConfiguration(False, "DO_NOT_RESOLVE")

    scan_results = start_scanning_for_data(central2, advertising_data)
    scan = scan_results[0]

    disconnection_cmd = peripheral.gap.waitForDisconnection.setAsync()(10000)

    central2.gap.startConnecting(scan["peer_address_type"],
                                 scan["peer_address"]).result

    assert disconnection_cmd.result
def test_privacy_random_resolvable_and_nonresolvable_address(
        peripheral, central, advertising_type, unresolvable):
    """validate that when privacy is enabled and a peripheral use a random
    resolvable address then a random resolvable address is used for all
    advertising modes."""
    init_privacy(peripheral)
    init_privacy(central)

    peripheral.gap.setPeripheralPrivacyConfiguration(unresolvable,
                                                     "DO_NOT_RESOLVE")

    advertising_data = start_advertising_of_type(peripheral, advertising_type)

    central.gap.setCentralPrivacyConfiguration(False, "DO_NOT_RESOLVE")

    scan_results = start_scanning_for_data(central, advertising_data)

    assert len(scan_results) > 0

    at_least_one_resolved = False

    for scan in scan_results:
        if scan["peer_address_type"] == "RANDOM":
            if unresolvable and advertising_type != "CONNECTABLE_UNDIRECTED":
                assert address_is_random_non_resolvable(scan["peer_address"])
            else:
                assert address_is_random_resolvable(scan["peer_address"])
            at_least_one_resolved = True

    assert at_least_one_resolved
def test_resolve_and_filter_unknown_address_with_bond_present(
        peripheral, central, peripheral2, advertising_type):
    """Ensure that if the central privacy policy is set to resolve and filter
    and the device has a bond then resolved private addresses are filtered"""
    init_privacy(peripheral2)
    perform_bonding_with_privacy_and_disconnect(peripheral, central)

    advertising_data = start_advertising_of_type(peripheral2, advertising_type)

    central.gap.setCentralPrivacyConfiguration(False, "RESOLVE_AND_FILTER")

    scan_results = start_scanning_for_data(central, advertising_data)

    assert len(scan_results) == 0
def test_central_not_resolve_policy(peripheral, central, advertising_type):
    """validate that when a peripheral with privacy enabled using private
    resolvable address advertise then a known peer that do not resolves
    addresses do not resolve the address advertised"""
    perform_bonding_with_privacy_and_disconnect(peripheral, central)

    advertising_data = start_advertising_of_type(peripheral, advertising_type)

    central.gap.setCentralPrivacyConfiguration(False, "DO_NOT_RESOLVE")
    central.gap.setPeripheralPrivacyConfiguration(False, "DO_NOT_RESOLVE")

    scan_results = start_scanning_for_data(central, advertising_data)

    for scan in scan_results:
        assert scan["peer_address_type"] == "RANDOM"
        assert address_is_random_resolvable(scan["peer_address"])
def test_resolve_and_filter_bonded_peer(peripheral, central, advertising_type):
    """Ensure that if the central privacy policy is set to resolve and filter
    bonded devices show up in scan results as resolved addresses"""
    perform_bonding_with_privacy_and_disconnect(peripheral, central)

    advertising_data = start_advertising_of_type(peripheral, advertising_type)

    central.gap.setCentralPrivacyConfiguration(False, "RESOLVE_AND_FILTER")

    scan_results = start_scanning_for_data(central, advertising_data)

    assert len(scan_results)

    for scan in scan_results:
        assert scan["peer_address_type"] == "RANDOM_STATIC_IDENTITY"
        assert address_is_random_resolvable(scan["peer_address"]) is False
        assert address_is_random_non_resolvable(scan["peer_address"]) is False
def test_resolve_and_filter_unknown_address(peripheral, central,
                                            advertising_type):
    """Ensure that if the central privacy policy is set to resolve and filter
    and the device has no bond then resolvable private addresses are not filtered"""
    init_privacy(peripheral)
    init_privacy(central)

    advertising_data = start_advertising_of_type(peripheral, advertising_type)

    central.gap.setCentralPrivacyConfiguration(False, "RESOLVE_AND_FILTER")

    scan_results = start_scanning_for_data(central, advertising_data)

    assert len(scan_results)

    for scan in scan_results:
        assert scan["peer_address_type"] == "RANDOM"
        assert address_is_random_resolvable(scan["peer_address"])
def test_non_resolved_address_with_resolve_and_forward(peripheral, central,
                                                       peripheral2,
                                                       advertising_type):
    """Ensure that if the central privacy policy is set to resolve and forward
    and the device has one bond then non resolved private addresses are forwarded"""
    init_privacy(peripheral2)
    perform_bonding_with_privacy_and_disconnect(peripheral, central)

    advertising_data = start_advertising_of_type(peripheral2, advertising_type)

    central.gap.setCentralPrivacyConfiguration(False, "RESOLVE_AND_FORWARD")

    scan_results = start_scanning_for_data(central, advertising_data)

    assert len(scan_results)

    for scan in scan_results:
        assert scan["peer_address_type"] == "RANDOM"
        assert address_is_random_resolvable(scan["peer_address"])
def test_connection_to_non_resolved_address(peripheral, central):
    """validate that when a peripheral with privacy enabled using private
    resolvable address advertise then a known peer that do not resolves
    addresses can connect to the non resolved address"""
    perform_bonding_with_privacy_and_disconnect(peripheral, central)

    advertising_data = start_advertising_of_type(peripheral,
                                                 "CONNECTABLE_UNDIRECTED")

    central.gap.setCentralPrivacyConfiguration(False, "DO_NOT_RESOLVE")
    central.gap.setPeripheralPrivacyConfiguration(False, "DO_NOT_RESOLVE")

    scan_results = start_scanning_for_data(central, advertising_data)
    scan = scan_results[0]

    assert scan["peer_address_type"] == "RANDOM"
    assert address_is_random_resolvable(scan["peer_address"])

    connect_to_address(central, peripheral, scan["peer_address_type"],
                       scan["peer_address"])
def test_reject_non_resolved_address_with_no_bond_accepts_connection(
        peripheral, central):
    """validate that when a peripheral with privacy enabled, the privacy policy
    set to REJECT_NON_RESOLVED_ADDRESS and no bond is connected by an unknown
    privacy enabled then connection is accepted"""
    init_privacy(peripheral)
    init_privacy(central)

    peripheral.gap.setPeripheralPrivacyConfiguration(
        False, "REJECT_NON_RESOLVED_ADDRESS")

    advertising_data = start_advertising_of_type(peripheral,
                                                 "CONNECTABLE_UNDIRECTED")

    central.gap.setCentralPrivacyConfiguration(False, "DO_NOT_RESOLVE")

    scan_results = start_scanning_for_data(central, advertising_data)
    scan = scan_results[0]

    connect_to_address(central, peripheral, scan["peer_address_type"],
                       scan["peer_address"])
def test_connection_with_resolved_address(peripheral, central):
    """validate that when a peripheral with privacy enabled using private
    resolvable address advertise then a known peer that resolves addresses
    can connect with the resolved address"""
    perform_bonding_with_privacy_and_disconnect(peripheral, central)

    advertising_data = start_advertising_of_type(peripheral,
                                                 "CONNECTABLE_UNDIRECTED")

    central.gap.setCentralPrivacyConfiguration(False, "RESOLVE_AND_FORWARD")
    sleep(1)
    scan_results = start_scanning_for_data(central, advertising_data)

    for scan in scan_results:
        if scan["peer_address_type"] == "RANDOM_STATIC_IDENTITY" or scan[
                "peer_address_type"] == "PUBLIC_IDENTITY":
            central_connection, _ = connect_to_address(
                central, peripheral, scan["peer_address_type"],
                scan["peer_address"])

            assert central_connection["peer_address_type"] == scan[
                "peer_address_type"]
            assert central_connection["peer_address"] == scan["peer_address"]
            break
def test_address_resolution_when_advertised(peripheral, central,
                                            advertising_type):
    """validate that when a peripheral with privacy enabled using private
    resolvable address advertise then a known peer that resolves addresses
    resolve the address advertised"""
    perform_bonding_with_privacy_and_disconnect(peripheral, central)

    advertising_data = start_advertising_of_type(peripheral, advertising_type)

    central.gap.setCentralPrivacyConfiguration(False, "RESOLVE_AND_FORWARD")

    scan_results = start_scanning_for_data(central, advertising_data)

    at_least_one_resolved = False

    for scan in scan_results:
        if scan["peer_address_type"] == "RANDOM_STATIC_IDENTITY":
            if address_is_random_resolvable(scan["peer_address"]) is False:
                if address_is_random_non_resolvable(
                        scan["peer_address"]) is False:
                    at_least_one_resolved = True
                    break

    assert at_least_one_resolved