1# -*- coding: utf-8 -*-
2# Copyright 2019 Oticon A/S
3# SPDX-License-Identifier: Apache-2.0
4
5from enum import IntEnum;
6from components.utils import *;
7from components.basic_commands import *;
8from components.address import *;
9from components.events import *;
10
11class AddressResolution(IntEnum):
12    DISABLE = 0                    # Disable Private Address resolution
13    ENABLE  = 1                    # Enable Private Address resolution
14
15class PrivacyMode(IntEnum):
16    NETWORK_PRIVACY = 0
17    DEVICE_PRIVACY  = 1
18
19class ResolvableAddresses:
20    """
21        Resolvable Addresses handles some aspects of Resolvable Private Addresses.
22        - Clear List of Resolvable Private Addresses.
23        - Add Device to List of Resolvable Private Addresses.
24        - Remove Device from List of Resolvable Private Addresses.
25        - Set timeout for changing a Resolvable Private Address.
26        - Enable resolving of Private Resolvable Addresses.
27        - Disable resolving of Private Resolvable Addresses.
28    """
29    """
30        Constructor:
31            transport - PTTT_nwtsim object
32            idx       - Number; Device identifier
33            trace     - Trace object
34            localIRK  - Array of 16 Bytes holding the Local IRK or None if Local IRK is 16 zeros.
35    """
36    def __init__(self, transport, idx, trace, localIRK=None):
37        self.transport = transport;
38        self.idx = idx;
39        self.trace = trace;
40        self.localIRK = [ 0 for _ in range(16) ] if localIRK is None else localIRK[ : ];
41        self.rawMode = True;
42
43    def __verifyAndShowEvent(self, expectedEvent):
44        event = get_event(self.transport, self.idx, 100);
45        self.trace.trace(7, str(event));
46        return event.event == expectedEvent;
47
48    def __getCommandCompleteEvent(self):
49        return not self.rawMode or self.__verifyAndShowEvent(Events.BT_HCI_EVT_CMD_COMPLETE);
50
51    """
52        Clear list of Resolvable Addresses
53    """
54    def clear(self):
55        status = le_clear_resolving_list(self.transport, self.idx, 100);
56        self.trace.trace(6, "LE Clear Resolving List Command returns status: 0x%02X" % status);
57        return self.__getCommandCompleteEvent() and (status == 0);
58
59    """
60        Add entry to list of Resolvable Addresses
61
62        peerAddress is an Address object; A SimpleAddressType Identity address
63        peerIRK     is None or an array of 16 Bytes
64    """
65    def add(self, peerAddress, peerIRK=None):
66        if peerIRK is None:
67            peerIRK = [ 0 for _ in range(16) ];
68        status = le_add_device_to_resolving_list(self.transport, self.idx, peerAddress.type, peerAddress.address, peerIRK, self.localIRK, 100);
69        self.trace.trace(6, "LE Add Device to Resolving List Command returns status: 0x%02X" % status);
70        return self.__getCommandCompleteEvent() and (status == 0);
71
72    """
73        Remove entry from list of Resolvable Addresses
74
75        peerAddress is an Address object; A SimpleAddressType Identity address
76    """
77    def remove(self, peerAddress):
78        status = le_remove_device_from_resolving_list(self.transport, self.idx, peerAddress.type, peerAddress.address, 100);
79        self.trace.trace(6, "LE Remove Device from Resolving List Command returns status: 0x%02X" % status);
80        return self.__getCommandCompleteEvent() and (status == 0);
81
82    def __enable(self, enable):
83        status = le_set_address_resolution_enable(self.transport, self.idx, enable, 100);
84        self.trace.trace(6, "LE Set Address Resolution " + ("Enable" if enable else "Disable") + " Command returns status: 0x%02X" % status);
85        return self.__getCommandCompleteEvent() and (status == 0);
86
87    """
88        Enable Address Resolution via list of Resolvable Addresses
89    """
90    def enable(self):
91        return self.__enable(AddressResolution.ENABLE);
92
93    """
94        Disable Address Resolution via list of Resolvable Addresses
95    """
96    def disable(self):
97        return self.__enable(AddressResolution.DISABLE);
98
99    """
100        Set Timeout for Address Resolution via list of Resolvable Addresses
101    """
102    def timeout(self, timeout):
103        status = le_set_resolvable_private_address_timeout(self.transport, self.idx, timeout, 100);
104        self.trace.trace(6, "LE Set Resolvable Private Address Timeout Command returns status: 0x%02X" % status);
105        return self.__getCommandCompleteEvent() and (status == 0);
106
107