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 *;
7
8class SimpleAddressType(IntEnum):
9    PUBLIC               = 0       # Public Device Address (default)
10    RANDOM               = 1       # Random Device Address
11
12class ExtendedAddressType(IntEnum):
13    PUBLIC               = 0       # Public Device Address (default)
14    RANDOM               = 1       # Random Device Address
15    RESOLVABLE_OR_PUBLIC = 2       # Controller generates Resolvable Private Address based on the local IRK from the resolving list.
16                                   # If the resolving list contains no matching entry, use the public address.
17    RESOLVABLE_OR_RANDOM = 3       # Controller generates Resolvable Private Address based on the local IRK from the resolving list.
18                                   # If the resolving list contains no matching entry, use the random address from LE_Set_Random_Address.
19
20class IdentityAddressType(IntEnum):
21    PUBLIC               = 0       # Public Device Address.
22    RANDOM               = 1       # Random Device Address.
23    PUBLIC_IDENTITY      = 2       # Public Identity Address (Corresponds to peer’s Resolvable Private Address).
24                                   # This value shall only be used by the Host if either the Host or the Controller does not support the LE Set Privacy Mode command.
25    RANDOM_IDENTITY      = 3       # Random (static) Identity Address (Corresponds to peer’s Resolvable Private Address).
26                                   # This value shall only be used by a Host if either the Host or the Controller does not support the LE Set Privacy Mode command.
27
28class Address:
29
30    def __init__(self, addressType, address=None):
31        self.type = addressType;
32        if not address is None:
33            if isinstance( address, (list, tuple) ):
34                self.address = list(address[ : ]);
35            else:
36                self.address = toArray(address, 6);
37        else:
38            self.address = toArray(0, 6);
39
40    def isStaticRandom(self):
41        return (self.address[5] & 0xC0) == 0xC0;
42
43    def isResolvablePrivate(self):
44        return (self.address[5] & 0xC0) == 0x40;
45
46    def isNonResolvablePrivate(self):
47        return (self.address[5] & 0xC0) == 0;
48
49    def __str__(self):
50        result = '{5:02X}:{4:02X}:{3:02X}:{2:02X}:{1:02X}:{0:02X}'.format(*self.address);
51        if self.type is None:
52            return result;
53        elif ExtendedAddressType.PUBLIC == self.type:
54            result += '(P)';
55        elif ExtendedAddressType.RANDOM == self.type:
56            result += '(R)';
57        elif ExtendedAddressType.RESOLVABLE_OR_PUBLIC == self.type:
58            result += '(p)';
59        elif ExtendedAddressType.RESOLVABLE_OR_RANDOM == self.type:
60            result += '(r)';
61        elif 0xFE == self.type:
62            result += '(u)'; # Random Device Address (Controller unable to resolve)
63        elif 0xFF == self.type:
64            result += '(a)'; # No address provided (anonymous advertisement)
65        else:
66            result += '(?)';
67        return result;
68
69    def __eq__(self, other):
70        if isinstance(other, self.__class__):
71            if (self.type is None) != (other.type is None):
72                return False;
73            return (self.type == other.type) and (self.address == other.address);
74        return False;
75
76    def __ne__(self, other):
77        if isinstance(other, self.__class__):
78            if (self.type is None) != (other.type is None):
79                return True;
80            return (self.type != other.type) or (self.address != other.address);
81        return True;
82