File: named.py

package info (click to toggle)
zigpy-znp 0.13.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,120 kB
  • sloc: python: 14,459; makefile: 6
file content (387 lines) | stat: -rw-r--r-- 10,177 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
from __future__ import annotations

import enum
import typing
import logging
import dataclasses

import zigpy.types
from zigpy.zdo.types import Status as ZDOStatus  # noqa: F401

from . import basic, zigpy_types

LOGGER = logging.getLogger(__name__)

JSONType = typing.Dict[str, typing.Any]


class AddrMode(basic.enum8):
    """Address mode."""

    _missing_ = enum.Enum._missing_  # There are no missing members

    NOT_PRESENT = 0x00
    Group = 0x01
    NWK = 0x02
    IEEE = 0x03

    Broadcast = 0x0F


class AddrModeAddress:
    def __new__(cls, mode=None, address=None):
        if mode is not None and address is None and isinstance(mode, cls):
            other = mode
            return cls(mode=other.mode, address=other.address)

        instance = super().__new__(cls)

        if mode is not None and mode == AddrMode.NOT_PRESENT:
            raise ValueError(f"Invalid address mode: {mode}")

        instance.mode = None if mode is None else AddrMode(mode)
        instance.address = (
            None if address is None else instance._get_address_type()(address)
        )

        return instance

    @classmethod
    def from_zigpy_type(
        cls, zigpy_addr: zigpy.types.AddrModeAddress
    ) -> AddrModeAddress:
        return cls(
            mode=AddrMode[zigpy_addr.addr_mode.name],
            address=zigpy_addr.address,
        )

    def as_zigpy_type(self) -> zigpy.types.AddrModeAddress:
        return zigpy.types.AddrModeAddress(
            addr_mode=zigpy.types.AddrMode[self.mode.name],
            address=self.address,
        )

    def _get_address_type(self):
        return {
            AddrMode.NWK: zigpy_types.NWK,
            AddrMode.Group: zigpy_types.NWK,
            AddrMode.Broadcast: zigpy_types.NWK,
            AddrMode.IEEE: zigpy_types.EUI64,
        }[self.mode]

    @classmethod
    def deserialize(cls, data: bytes) -> tuple[AddrModeAddress, bytes]:
        mode, data = AddrMode.deserialize(data)
        address, data = zigpy_types.EUI64.deserialize(data)

        if mode != AddrMode.IEEE:
            address, _ = zigpy_types.NWK.deserialize(address.serialize())

        return cls(mode=mode, address=address), data

    def serialize(self) -> bytes:
        result = (
            self.mode.serialize() + self._get_address_type()(self.address).serialize()
        )

        if self.mode != AddrMode.IEEE:
            result += b"\x00\x00\x00\x00\x00\x00"

        return result

    def __eq__(self, other):
        if not isinstance(other, type(self)):
            return NotImplemented

        return self.mode == other.mode and self.address == other.address

    def __repr__(self) -> str:
        return f"{type(self).__name__}(mode={self.mode!r}, address={self.address!r})"


class GroupId(basic.uint16_t, repr="hex"):  # type: ignore[call-arg]
    """Group ID class"""


class ScanType(basic.enum8):
    EnergyDetect = 0x00
    Active = 0x01
    Passive = 0x02
    Orphan = 0x03


@dataclasses.dataclass(frozen=True)
class Param:
    """Schema parameter"""

    name: str
    type: type = None
    description: str = ""
    optional: bool = False


class Status(basic.enum8):
    SUCCESS = 0x00
    FAILURE = 0x01
    INVALID_PARAMETER = 0x02
    INVALID_TASK = 0x03
    MSG_BUFFER_NOT_AVAIL = 0x04
    INVALID_MSG_POINTER = 0x05
    INVALID_EVENT_ID = 0x06
    INVALID_INTERRUPT_ID = 0x07
    NO_TIMER_AVAIL = 0x08
    NV_ITEM_UNINIT = 0x09
    NV_OPER_FAILED = 0x0A
    INVALID_MEM_SIZE = 0x0B
    NV_BAD_ITEM_LEN = 0x0C

    MEM_ERROR = 0x10
    BUFFER_FULL = 0x11
    UNSUPPORTED_MODE = 0x12
    MAC_MEM_ERROR = 0x13

    SAPI_IN_PROGRESS = 0x20
    SAPI_TIMEOUT = 0x21
    SAPI_INIT = 0x22

    NOT_AUTHORIZED = 0x7E

    MALFORMED_CMD = 0x80
    UNSUP_CLUSTER_CMD = 0x81

    OTA_ABORT = 0x95
    OTA_IMAGE_INVALID = 0x96
    OTA_WAIT_FOR_DATA = 0x97
    OTA_NO_IMAGE_AVAILABLE = 0x98
    OTA_REQUIRE_MORE_IMAGE = 0x99

    APS_FAIL = 0xB1
    APS_TABLE_FULL = 0xB2
    APS_ILLEGAL_REQUEST = 0xB3
    APS_INVALID_BINDING = 0xB4
    APS_UNSUPPORTED_ATTRIB = 0xB5
    APS_NOT_SUPPORTED = 0xB6
    APS_NO_ACK = 0xB7
    APS_DUPLICATE_ENTRY = 0xB8
    APS_NO_BOUND_DEVICE = 0xB9
    APS_NOT_ALLOWED = 0xBA
    APS_NOT_AUTHENTICATED = 0xBB

    SEC_NO_KEY = 0xA1
    SEC_OLD_FRM_COUNT = 0xA2
    SEC_MAX_FRM_COUNT = 0xA3
    SEC_CCM_FAIL = 0xA4
    SEC_FAILURE = 0xAD

    NWK_INVALID_PARAM = 0xC1
    NWK_INVALID_REQUEST = 0xC2
    NWK_NOT_PERMITTED = 0xC3
    NWK_STARTUP_FAILURE = 0xC4
    NWK_ALREADY_PRESENT = 0xC5
    NWK_SYNC_FAILURE = 0xC6
    NWK_TABLE_FULL = 0xC7
    NWK_UNKNOWN_DEVICE = 0xC8
    NWK_UNSUPPORTED_ATTRIBUTE = 0xC9
    NWK_NO_NETWORKS = 0xCA
    NWK_LEAVE_UNCONFIRMED = 0xCB
    NWK_NO_ACK = 0xCC  # not in spec
    NWK_NO_ROUTE = 0xCD

    # The operation is not supported in the current configuration
    MAC_UNSUPPORTED = 0x18

    # The operation could not be performed in the current state
    MAC_BAD_STATE = 0x19

    # The operation could not be completed because no memory resources were available
    MAC_NO_RESOURCES = 0x1A

    # For internal use only
    MAC_ACK_PENDING = 0x1B

    # For internal use only
    MAC_NO_TIME = 0x1C

    # For internal use only
    MAC_TX_ABORTED = 0x1D

    # For internal use only - A duplicated entry is added to the source matching table
    MAC_DUPLICATED_ENTRY = 0x1E

    # The frame counter puportedly applied by the originator of the received frame
    # is invalid
    MAC_COUNTER_ERROR = 0xDB

    # The key purportedly applied by the originator of the received frame is not allowed
    MAC_IMPROPER_KEY_TYPE = 0xDC

    # The security level purportedly applied by the originator of the received frame
    # does not meet the minimum security level
    MAC_IMPROPER_SECURITY_LEVEL = 0xDD

    # The received frame was secured with legacy security which is not supported
    MAC_UNSUPPORTED_LEGACY = 0xDE

    # The security of the received frame is not supported
    MAC_UNSUPPORTED_SECURITY = 0xDF

    # The beacon was lost following a synchronization request
    MAC_BEACON_LOSS = 0xE0

    # The operation or data request failed because of activity on the channel
    MAC_CHANNEL_ACCESS_FAILURE = 0xE1

    # The MAC was not able to enter low power mode.
    MAC_DENIED = 0xE2

    # Unused
    MAC_DISABLE_TRX_FAILURE = 0xE3

    # Cryptographic processing of the secure frame failed
    MAC_SECURITY_ERROR = 0xE4

    # The received frame or frame resulting from an operation or data request is
    # too long to be processed by the MAC
    MAC_FRAME_TOO_LONG = 0xE5

    # Unused
    MAC_INVALID_GTS = 0xE6

    # The purge request contained an invalid handle
    MAC_INVALID_HANDLE = 0xE7

    # The API function parameter is out of range
    MAC_INVALID_PARAMETER = 0xE8

    # The operation or data request failed because no acknowledgement was received
    MAC_NO_ACK = 0xE9

    # The scan request failed because no beacons were received or the orphan scan failed
    # because no coordinator realignment was received
    MAC_NO_BEACON = 0xEA

    # The associate request failed because no associate response was received or the
    # poll request did not return any data
    MAC_NO_DATA = 0xEB

    # The short address parameter of the start request was invalid
    MAC_NO_SHORT_ADDRESS = 0xEC

    # Unused
    MAC_OUT_OF_CAP = 0xED

    # A PAN identifier conflict has been detected and communicated to the PAN
    # coordinator
    MAC_PAN_ID_CONFLICT = 0xEE

    # A coordinator realignment command has been received
    MAC_REALIGNMENT = 0xEF

    # The associate response, disassociate request, or indirect data transmission failed
    # because the peer device did not respond before the transaction expired or was
    # purged
    MAC_TRANSACTION_EXPIRED = 0xF0

    # The request failed because MAC data buffers are full
    MAC_TRANSACTION_OVERFLOW = 0xF1

    # Unused
    MAC_TX_ACTIVE = 0xF2

    # The operation or data request failed because the security key is not available
    MAC_UNAVAILABLE_KEY = 0xF3

    # The set or get request failed because the attribute is not supported
    MAC_UNSUPPORTED_ATTRIBUTE = 0xF4

    # The data request failed because neither the source address nor destination address
    # parameters were present
    MAC_INVALID_ADDRESS = 0xF5

    # Unused
    MAC_ON_TIME_TOO_LONG = 0xF6

    # Unused
    MAC_PAST_TIME = 0xF7

    # The start request failed because the device is not tracking the beacon of its
    # coordinator
    MAC_TRACKING_OFF = 0xF8

    # Unused
    MAC_INVALID_INDEX = 0xF9

    # The scan terminated because the PAN descriptor storage limit was reached
    MAC_LIMIT_REACHED = 0xFA

    # A set request was issued with a read-only identifier
    MAC_READ_ONLY = 0xFB

    # The scan request failed because a scan is already in progress
    MAC_SCAN_IN_PROGRESS = 0xFC

    # The beacon start time overlapped the coordinator transmission time
    MAC_SUPERFRAME_OVERLAP = 0xFD

    # The AUTOPEND pending all is turned on
    MAC_AUTOACK_PENDING_ALL_ON = 0xFE

    # The AUTOPEND pending all is turned off
    MAC_AUTOACK_PENDING_ALL_OFF = 0xFF


class ResetReason(basic.enum8):
    PowerUp = 0x00
    External = 0x01
    Watchdog = 0x02


class ResetType(basic.enum8):
    Hard = 0x00
    Soft = 0x01
    Shutdown = 0x02


class KeySource(basic.FixedList, item_type=basic.uint8_t, length=8):
    pass


class StartupOptions(basic.bitmap8):
    NONE = 0

    ClearConfig = 1 << 0
    ClearState = 1 << 1
    AutoStart = 1 << 2

    # FrameCounter should persist across factory resets.
    # This should not be used as part of FN reset procedure.
    # Set to reset the FrameCounter of all Nwk Security Material
    ClearNwkFrameCounter = 1 << 7


class DeviceLogicalType(basic.enum8):
    Coordinator = 0
    Router = 1
    EndDevice = 2


class DeviceTypeCapabilities(basic.bitmap8):
    Coordinator = 1 << 0
    Router = 1 << 1
    EndDevice = 1 << 2


class ClusterIdList(
    basic.LVList, item_type=zigpy_types.ClusterId, length_type=basic.uint8_t
):
    pass


class NWKList(basic.LVList, item_type=zigpy_types.NWK, length_type=basic.uint8_t):
    pass


class NwkMode(basic.enum8):
    Star = 0
    Tree = 1
    Mesh = 2