#
# python-bluetooth-mesh - Bluetooth Mesh for Python
#
# Copyright (C) 2019 SILVAIR sp. z o.o.
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
#
# pylint: disable=W0223
import enum
from datetime import timedelta
from construct import (
Adapter,
BitsInteger,
BitStruct,
Bytes,
Bytewise,
Embedded,
ExprValidator,
Flag,
GreedyBytes,
GreedyRange,
Int8ul,
Int16ul,
Int24ul,
Int8sl,
Padding,
Rebuild,
Select,
Struct,
len_,
obj_,
this,
)
from bluetooth_mesh.messages.util import (
BitList,
EmbeddedBitStruct,
EnumAdapter,
EnumSwitchStruct,
LogAdapter,
NamedSelect,
Opcode,
RangeValidator,
Reversed,
SwitchStruct,
IfThenElseDefault,
enum_switch_struct_len_,
)
from bluetooth_mesh.messages.util import EnumSwitch as Switch
class SecureNetworkBeacon(enum.IntEnum):
OFF = 0x00
ON = 0x01
class GATTProxy(enum.IntEnum):
DISABLED = 0x00
ENABLED = 0x01
NOT_SUPPORTED = 0x02
class Relay(enum.IntEnum):
DISABLED = 0x00
ENABLED = 0x01
NOT_SUPPORTED = 0x02
class GATTNamespaceDescriptor(enum.IntEnum):
AUXILIARY = 0x0108
BACK = 0x0101
BACKUP = 0x0107
BOTTOM = 0x0103
EIGHTEENTH = 0x0012
EIGHTH = 0x0008
EIGHTIETH = 0x0050
EIGHTY_EIGHTH = 0x0058
EIGHTY_FIFTH = 0x0055
EIGHTY_FIRST = 0x0051
EIGHTY_FOURTH = 0x0054
EIGHTY_NINTH = 0x0059
EIGHTY_SECOND = 0x0052
EIGHTY_SEVENTH = 0x0057
EIGHTY_SIXTH = 0x0056
EIGHTY_THIRD = 0x0053
ELEVENTH = 0x000B
EXTERNAL = 0x0110
FIFTEENTH = 0x000F
FIFTH = 0x0005
FIFTIETH = 0x0032
FIFTY_EIGHTH = 0x003A
FIFTY_FIFTH = 0x0037
FIFTY_FIRST = 0x0033
FIFTY_FOURTH = 0x0036
FIFTY_NINTH = 0x003B
FIFTY_SECOND = 0x0034
FIFTY_SEVENTH = 0x0039
FIFTY_SIXTH = 0x0038
FIFTY_THIRD = 0x0035
FIRST = 0x0001
FLASH = 0x010A
FORTIETH = 0x0028
FOURTEENTH = 0x000E
FOURTH = 0x0004
FORTY_EIGHTH = 0x0030
FORTY_FIFTH = 0x002D
FORTY_FIRST = 0x0029
FORTY_FOURTH = 0x002C
FORTY_NINTH = 0x0031
FORTY_SECOND = 0x002A
FORTY_SEVENTH = 0x002F
FORTY_SIXTH = 0x002E
FORTY_THIRD = 0x002B
FRONT = 0x0100
INSIDE = 0x010B
INTERNAL = 0x010F
LEFT = 0x010D
LOWER = 0x0105
MAIN = 0x0106
NINETEENTH = 0x0013
NINTH = 0x0009
NINETIETH = 0x005A
NINETY_EIGHTH = 0x0062
NINETY_FIFTH = 0x005F
NINETY_FIRST = 0x005B
NINETY_FOURTH = 0x005E
NINETY_NINTH = 0x0063
NINETY_SECOND = 0x005C
NINETY_SEVENTH = 0x0061
NINETY_SIXTH = 0x0060
NINETY_THIRD = 0x005D
ONE_HUNDRED_AND_EIGHTEENTH = 0x0076
ONE_HUNDRED_AND_EIGHTH = 0x006C
ONE_HUNDRED_AND_EIGHTY_EIGHTH = 0x00BC
ONE_HUNDRED_AND_EIGHTY_FIFTH = 0x00B9
ONE_HUNDRED_AND_EIGHTY_FIRST = 0x00B5
ONE_HUNDRED_AND_EIGHTY_FOURTH = 0x00B8
ONE_HUNDRED_AND_EIGHTY_NINTH = 0x00BD
ONE_HUNDRED_AND_EIGHTY_SECOND = 0x00B6
ONE_HUNDRED_AND_EIGHTY_SEVENTH = 0x00BB
ONE_HUNDRED_AND_EIGHTY_SIXTH = 0x00BA
ONE_HUNDRED_AND_EIGHTY_THIRD = 0x00B7
ONE_HUNDRED_AND_ELEVENTH = 0x006F
ONE_HUNDRED_AND_FIFTEENTH = 0x0073
ONE_HUNDRED_AND_FIFTH = 0x0069
ONE_HUNDRED_AND_FIFTY_EIGHTH = 0x009E
ONE_HUNDRED_AND_FIFTY_FIFTH = 0x009B
ONE_HUNDRED_AND_FIFTY_FIRST = 0x0097
ONE_HUNDRED_AND_FIFTY_FOURTH = 0x009A
ONE_HUNDRED_AND_FIFTY_NINTH = 0x009F
ONE_HUNDRED_AND_FIFTY_SECOND = 0x0098
ONE_HUNDRED_AND_FIFTY_SEVENTH = 0x009D
ONE_HUNDRED_AND_FIFTY_SIXTH = 0x009C
ONE_HUNDRED_AND_FIFTY_THIRD = 0x0099
ONE_HUNDRED_AND_FIRST = 0x0065
ONE_HUNDRED_AND_FOURTEENTH = 0x0072
ONE_HUNDRED_AND_FOURTH = 0x0068
ONE_HUNDRED_AND_FORTY_EIGHTH = 0x0094
ONE_HUNDRED_AND_FORTY_FIFTH = 0x0091
ONE_HUNDRED_AND_FORTY_FIRST = 0x008D
ONE_HUNDRED_AND_FORTY_FOURTH = 0x0090
ONE_HUNDRED_AND_FORTY_NINTH = 0x0095
ONE_HUNDRED_AND_FORTY_SECOND = 0x008E
ONE_HUNDRED_AND_FORTY_SEVENTH = 0x0093
ONE_HUNDRED_AND_FORTY_SIXTH = 0x0092
ONE_HUNDRED_AND_FORTY_THIRD = 0x008F
ONE_HUNDRED_AND_NINETEENTH = 0x0077
ONE_HUNDRED_AND_NINTH = 0x006D
ONE_HUNDRED_AND_NINETY_EIGHTH = 0x00C6
ONE_HUNDRED_AND_NINETY_FIFTH = 0x00C3
ONE_HUNDRED_AND_NINETY_FIRST = 0x00BF
ONE_HUNDRED_AND_NINETY_FOURTH = 0x00C2
ONE_HUNDRED_AND_NINETY_NINTH = 0x00C7
ONE_HUNDRED_AND_NINETY_SECOND = 0x00C0
ONE_HUNDRED_AND_NINETY_SEVENTH = 0x00C5
ONE_HUNDRED_AND_NINETY_SIXTH = 0x00C4
ONE_HUNDRED_AND_NINETY_THIRD = 0x00C1
ONE_HUNDRED_AND_SECOND = 0x0066
ONE_HUNDRED_AND_SEVENTEENTH = 0x0075
ONE_HUNDRED_AND_SEVENTH = 0x006B
ONE_HUNDRED_AND_SEVENTY_EIGHTH = 0x00B2
ONE_HUNDRED_AND_SEVENTY_FIFTH = 0x00AF
ONE_HUNDRED_AND_SEVENTY_FIRST = 0x00AB
ONE_HUNDRED_AND_SEVENTY_FOURTH = 0x00AE
ONE_HUNDRED_AND_SEVENTY_NINTH = 0x00B3
ONE_HUNDRED_AND_SEVENTY_SECOND = 0x00AC
ONE_HUNDRED_AND_SEVENTY_SEVENTH = 0x00B1
ONE_HUNDRED_AND_SEVENTY_SIXTH = 0x00B0
ONE_HUNDRED_AND_SEVENTY_THIRD = 0x00AD
ONE_HUNDRED_AND_SIXTEENTH = 0x0074
ONE_HUNDRED_AND_SIXTH = 0x006A
ONE_HUNDRED_AND_SIXTY_EIGHTH = 0x00A8
ONE_HUNDRED_AND_SIXTY_FIFTH = 0x00A5
ONE_HUNDRED_AND_SIXTY_FIRST = 0x00A1
ONE_HUNDRED_AND_SIXTY_FOURTH = 0x00A4
ONE_HUNDRED_AND_SIXTY_NINTH = 0x00A9
ONE_HUNDRED_AND_SIXTY_SECOND = 0x00A2
ONE_HUNDRED_AND_SIXTY_SEVENTH = 0x00A7
ONE_HUNDRED_AND_SIXTY_SIXTH = 0x00A6
ONE_HUNDRED_AND_SIXTY_THIRD = 0x00A3
ONE_HUNDRED_AND_TENTH = 0x006E
ONE_HUNDRED_AND_THIRD = 0x0067
ONE_HUNDRED_AND_THIRTEENTH = 0x0071
ONE_HUNDRED_AND_THIRTY_EIGHTH = 0x008A
ONE_HUNDRED_AND_THIRTY_FIFTH = 0x0087
ONE_HUNDRED_AND_THIRTY_FIRST = 0x0083
ONE_HUNDRED_AND_THIRTY_FOURTH = 0x0086
ONE_HUNDRED_AND_THIRTY_NINTH = 0x008B
ONE_HUNDRED_AND_THIRTY_SECOND = 0x0084
ONE_HUNDRED_AND_THIRTY_SEVENTH = 0x0089
ONE_HUNDRED_AND_THIRTY_SIXTH = 0x0088
ONE_HUNDRED_AND_THIRTY_THIRD = 0x0085
ONE_HUNDRED_AND_TWELVETH = 0x0070
ONE_HUNDRED_AND_TWENTY_EIGHTH = 0x0080
ONE_HUNDRED_AND_TWENTY_FIFTH = 0x007D
ONE_HUNDRED_AND_TWENTY_FIRST = 0x0079
ONE_HUNDRED_AND_TWENTY_FOURTH = 0x007C
ONE_HUNDRED_AND_TWENTY_NINTH = 0x0081
ONE_HUNDRED_AND_TWENTY_SECOND = 0x007A
ONE_HUNDRED_AND_TWENTY_SEVENTH = 0x007F
ONE_HUNDRED_AND_TWENTY_SIXTH = 0x007E
ONE_HUNDRED_AND_TWENTY_THIRD = 0x007B
ONE_HUNDRED_EIGHTIETH = 0x00B4
ONE_HUNDRED_FIFTIETH = 0x0096
ONE_HUNDRED_FORTIETH = 0x008C
ONE_HUNDRED_NINETIETH = 0x00BE
ONE_HUNDRED_SEVENTIETH = 0x00AA
ONE_HUNDRED_SIXTIETH = 0x00A0
ONE_HUNDRED_THIRTIETH = 0x0082
ONE_HUNDRED_TWENTIETH = 0x0078
ONE_HUNDREDTH = 0x0064
OUTSIDE = 0x010C
RIGHT = 0x010E
SECOND = 0x0002
SEVENTEENTH = 0x0011
SEVENTH = 0x0007
SEVENTIETH = 0x0046
SEVENTY_EIGHTH = 0x004E
SEVENTY_FIFTH = 0x004B
SEVENTY_FIRST = 0x0047
SEVENTY_FOURTH = 0x004A
SEVENTY_NINTH = 0x004F
SEVENTY_SECOND = 0x0048
SEVENTY_SEVENTH = 0x004D
SEVENTY_SIXTH = 0x004C
SEVENTY_THIRD = 0x0049
SIXTEENTH = 0x0010
SIXTH = 0x0006
SIXTIETH = 0x003C
SIXTY_EIGHTH = 0x0044
SIXTY_FIFTH = 0x0041
SIXTY_FIRST = 0x003D
SIXTY_FOURTH = 0x0040
SIXTY_NINTH = 0x0045
SIXTY_SECOND = 0x003E
SIXTY_SEVENTH = 0x0043
SIXTY_SIXTH = 0x0042
SIXTY_THIRD = 0x003F
SUPPLEMENTARY = 0x0109
TENTH = 0x000A
THIRD = 0x0003
THIRTEENTH = 0x000D
THIRTIETH = 0x001E
THIRTY_EIGHTH = 0x0026
THIRTY_FIFTH = 0x0023
THIRTY_FIRST = 0x001F
THIRTY_FOURTH = 0x0022
THIRTY_NINTH = 0x0027
THIRTY_SECOND = 0x0020
THIRTY_SEVENTH = 0x0025
THIRTY_SIXTH = 0x0024
THIRTY_THIRD = 0x0021
TOP = 0x0102
TWELVETH = 0x000C
TWENTIETH = 0x0014
TWENTY_EIGHTH = 0x001C
TWENTY_FIFTH = 0x0019
TWENTY_FIRST = 0x0015
TWENTY_FOURTH = 0x0018
TWENTY_NINTH = 0x001D
TWENTY_SECOND = 0x0016
TWENTY_SEVENTH = 0x001B
TWENTY_SIXTH = 0x001A
TWENTY_THIRD = 0x0017
TWO_HUNDRED_AND_EIGHTEENTH = 0x00DA
TWO_HUNDRED_AND_EIGHTH = 0x00D0
TWO_HUNDRED_AND_ELEVENTH = 0x00D3
TWO_HUNDRED_AND_FIFTEENTH = 0x00D7
TWO_HUNDRED_AND_FIFTH = 0x00CD
TWO_HUNDRED_AND_FIFTY_FIFTH = 0x00FF
TWO_HUNDRED_AND_FIFTY_FIRST = 0x00FB
TWO_HUNDRED_AND_FIFTY_FOURTH = 0x00FE
TWO_HUNDRED_AND_FIFTY_SECOND = 0x00FC
TWO_HUNDRED_AND_FIFTY_THIRD = 0x00FD
TWO_HUNDRED_AND_FIRST = 0x00C9
TWO_HUNDRED_AND_FOURTEENTH = 0x00D6
TWO_HUNDRED_AND_FOURTH = 0x00CC
TWO_HUNDRED_AND_FORTY_EIGHTH = 0x00F8
TWO_HUNDRED_AND_FORTY_FIFTH = 0x00F5
TWO_HUNDRED_AND_FORTY_FIRST = 0x00F1
TWO_HUNDRED_AND_FORTY_FOURTH = 0x00F4
TWO_HUNDRED_AND_FORTY_NINTH = 0x00F9
TWO_HUNDRED_AND_FORTY_SECOND = 0x00F2
TWO_HUNDRED_AND_FORTY_SEVENTH = 0x00F7
TWO_HUNDRED_AND_FORTY_SIXTH = 0x00F6
TWO_HUNDRED_AND_FORTY_THIRD = 0x00F3
TWO_HUNDRED_AND_NINETEENTH = 0x00DB
TWO_HUNDRED_AND_NINTH = 0x00D1
TWO_HUNDRED_AND_SECOND = 0x00CA
TWO_HUNDRED_AND_SEVENTEENTH = 0x00D9
TWO_HUNDRED_AND_SEVENTH = 0x00CF
TWO_HUNDRED_AND_SIXTEENTH = 0x00D8
TWO_HUNDRED_AND_SIXTH = 0x00CE
TWO_HUNDRED_AND_TENTH = 0x00D2
TWO_HUNDRED_AND_THIRD = 0x00CB
TWO_HUNDRED_AND_THIRTEENTH = 0x00D5
TWO_HUNDRED_AND_THIRTY_EIGHTH = 0x00EE
TWO_HUNDRED_AND_THIRTY_FIFTH = 0x00EB
TWO_HUNDRED_AND_THIRTY_FIRST = 0x00E7
TWO_HUNDRED_AND_THIRTY_FOURTH = 0x00EA
TWO_HUNDRED_AND_THIRTY_NINTH = 0x00EF
TWO_HUNDRED_AND_THIRTY_SECOND = 0x00E8
TWO_HUNDRED_AND_THIRTY_SEVENTH = 0x00ED
TWO_HUNDRED_AND_THIRTY_SIXTH = 0x00EC
TWO_HUNDRED_AND_THIRTY_THIRD = 0x00E9
TWO_HUNDRED_AND_TWELVETH = 0x00D4
TWO_HUNDRED_AND_TWENTY_EIGHTH = 0x00E4
TWO_HUNDRED_AND_TWENTY_FIFTH = 0x00E1
TWO_HUNDRED_AND_TWENTY_FIRST = 0x00DD
TWO_HUNDRED_AND_TWENTY_FOURTH = 0x00E0
TWO_HUNDRED_AND_TWENTY_NINTH = 0x00E5
TWO_HUNDRED_AND_TWENTY_SECOND = 0x00DE
TWO_HUNDRED_AND_TWENTY_SEVENTH = 0x00E3
TWO_HUNDRED_AND_TWENTY_SIXTH = 0x00E2
TWO_HUNDRED_AND_TWENTY_THIRD = 0x00DF
TWO_HUNDRED_FIFTIETH = 0x00FA
TWO_HUNDRED_FORTIETH = 0x00F0
TWO_HUNDRED_THIRTIETH = 0x00E6
TWO_HUNDRED_TWENTIETH = 0x00DC
TWO_HUNDREDTH = 0x00C8
UNKNOWN = 0x0000
UPPER = 0x0104
class PublishFriendshipCredentialsFlag(enum.IntEnum):
MASTER_SECURITY = 0x00
FRIENDSHIP_SECURITY = 0x01
class StatusCode(enum.IntEnum):
SUCCESS = 0x00
INVALID_ADDRESS = 0x01
INVALID_MODEL = 0x02
INVALID_APPKEY_INDEX = 0x03
INVALID_NETKEY_INDEX = 0x04
INSUFFICIENT_RESOURCES = 0x05
KEY_INDEX_ALREADY_STORED = 0x06
INVALID_PUBLISH_PARAMETERS = 0x07
NOT_A_SUBSCRIBE_MODEL = 0x08
STORAGE_FAILURE = 0x09
FEATURE_NOT_SUPPORTED = 0x0A
CANNOT_UPDATE = 0x0B
CANNOT_REMOVE = 0x0C
CANNOT_BIND = 0x0D
TEMPORARILY_UNABLE_TO_CHANGE_STATE = 0x0E
CANNOT_SET = 0x0F
UNSPECIFIED_ERROR = 0x10
INVALID_BINDING = 0x11
class NodeIdentity(enum.IntEnum):
STOPPED = 0x00
RUNNING = 0x01
NOT_SUPPORTED = 0x02
class Friend(enum.IntEnum):
DISABLED = 0x00
ENABLED = 0x01
NOT_SUPPORTED = 0x02
class KeyRefreshPhase(enum.IntEnum):
NORMAL = 0x00
FIRST = 0x01
SECOND = 0x02
class KeyRefreshTransition(enum.IntEnum):
SECOND = 0x02
THIRD = 0x03
SecureNetworkBeaconAdapter = EnumAdapter(Int8ul, SecureNetworkBeacon)
GATTProxyAdapter = EnumAdapter(Int8ul, GATTProxy)
RelayAdapter = EnumAdapter(Int8ul, Relay)
GATTNamespaceDescriptorAdapter = EnumAdapter(Int16ul, GATTNamespaceDescriptor)
PublishFriendshipCredentialsFlagAdapter = EnumAdapter(
Flag, PublishFriendshipCredentialsFlag
)
StatusCodeAdapter = EnumAdapter(Int8ul, StatusCode)
NodeIdentityAdapter = EnumAdapter(Int8ul, NodeIdentity)
FriendAdapter = EnumAdapter(Int8ul, Friend)
TTL = RangeValidator(Int8ul, max_value=0x7F)
# fmt: off
SIGModelId = Struct(
"model_id" / Int16ul,
)
VendorModelId = Struct(
"vendor_id" / Int16ul,
"model_id" / Int16ul,
)
ModelId = NamedSelect(
vendor=VendorModelId,
sig=SIGModelId
)
# fmt: on
class AddressType(enum.Enum):
UNASSIGNED = 0
UNICAST = 1
GROUP = 2
VIRTUAL = 3
RFU = 4
ALL_PROXIES = 5
ALL_FRIENDS = 6
ALL_RELAYS = 7
ALL_NODES = 8
def get_address_type(address):
# pylint: disable=R0911
if address == 0x0000:
return AddressType.UNASSIGNED
if 0xFF00 <= address <= 0xFFFB:
return AddressType.RFU
if address == 0xFFFC:
return AddressType.ALL_PROXIES
if address == 0xFFFD:
return AddressType.ALL_FRIENDS
if address == 0xFFFE:
return AddressType.ALL_RELAYS
if address == 0xFFFF:
return AddressType.ALL_NODES
if (address & 0xC000) == 0xC000:
return AddressType.GROUP
if (address & 0x8000) == 0x8000:
return AddressType.VIRTUAL
return AddressType.UNICAST
def AddressTypeValidator(subcons, *allowed_types):
return ExprValidator(
subcons, lambda obj, ctx: get_address_type(obj) in allowed_types
)
# fmt: off
UnassignedAddress = AddressTypeValidator(
Int16ul,
AddressType.UNASSIGNED
)
UnicastAddress = AddressTypeValidator(
Int16ul,
AddressType.UNICAST
)
# TODO Fixed Groups?
GroupAddress = AddressTypeValidator(
Int16ul, AddressType.GROUP
)
VirtualLabel = AddressTypeValidator(
Int16ul,
AddressType.VIRTUAL
)
NotVirtualLabel = ExprValidator(
Int16ul,
lambda obj, ctx: get_address_type(obj) != AddressType.VIRTUAL
)
SubscriptionAddress = ExprValidator(
Int16ul,
lambda obj, ctx: get_address_type(obj) not in [AddressType.UNASSIGNED,
AddressType.UNICAST,
AddressType.ALL_NODES,
AddressType.VIRTUAL]
)
StatusSubscriptionAddress = ExprValidator(
Int16ul,
lambda obj, ctx: get_address_type(obj) not in [AddressType.UNICAST,
AddressType.ALL_NODES]
)
UnicastUnassignedAddress = AddressTypeValidator(
Int16ul,
AddressType.UNICAST,
AddressType.UNASSIGNED,
)
UnicastUnassignedGroupAddress = AddressTypeValidator(
Int16ul,
AddressType.UNICAST,
AddressType.UNASSIGNED,
AddressType.GROUP,
)
Int12ul = ExprValidator(
Int16ul,
(obj_ & 0xF000) == 0x00
)
CompositionDataPage0Element = Struct(
"location" / GATTNamespaceDescriptorAdapter,
"sig_number" / Rebuild(Int8ul, len_(this["sig_models"])),
"vendor_number" / Rebuild(Int8ul, len_(this["vendor_models"])),
"sig_models" / SIGModelId[this["sig_number"]],
"vendor_models" / VendorModelId[this["vendor_number"]],
)
CompositionDataPage0 = Struct(
"cid" / Int16ul,
"pid" / Int16ul,
"vid" / Int16ul,
"crpl" / Int16ul,
"features" / Int16ul, # TODO should be parsed
"elements" / GreedyRange(CompositionDataPage0Element),
)
ExtendedModelLongFormat = Struct(
"model_item_index" / Int8ul,
"element_offset" / Int8sl
)
ExtendedModelShortFormat = BitStruct(
"model_item_index" / BitsInteger(5),
"element_offset" / BitsInteger(3, signed=True),
)
class ExtendedModelsItemFormat(enum.IntEnum):
SHORT = 0
LONG = 1
ModelRelationItem = BitStruct(
"extended_items_count" / Rebuild(BitsInteger(6), enum_switch_struct_len_(this["extended_models_items"])),
"format" / EnumAdapter(BitsInteger(1), ExtendedModelsItemFormat),
"corresponding_present" / BitsInteger(1),
"corresponding_id" / IfThenElseDefault(this.corresponding_present, BitsInteger(8), default=0),
"extended_models_items" / Bytewise(EnumSwitchStruct(Switch(
this.format,
{
ExtendedModelsItemFormat.SHORT: ExtendedModelShortFormat[this["extended_items_count"]],
ExtendedModelsItemFormat.LONG: ExtendedModelLongFormat[this["extended_items_count"]],
}
))),
)
CompositionDataPage1Element = Struct(
"number_s" / Rebuild(Int8ul, len_(this["sig_models"])),
"number_v" / Rebuild(Int8ul, len_(this["vendor_models"])),
"sig_models" / ModelRelationItem[this["number_s"]],
"vendor_models" / ModelRelationItem[this["number_v"]],
)
CompositionDataPage1 = Struct(
'element' / GreedyRange(CompositionDataPage1Element)
)
Version = Struct(
'version_x' / Int8ul,
'version_y' / Int8ul,
'version_z' / Int8ul,
)
MeshProfileEntry = Struct(
"mesh_profile_identifier" / Int16ul,
"version" / Version,
"num_element_offsets" / Rebuild(Int8ul, len_(this["element_offset_list"])),
"element_offset_list" / Int8ul[this["num_element_offsets"]],
"additional_data_len" / Rebuild(Int16ul, len_(this["additional_data"])),
"additional_data" / Int8ul[this["additional_data_len"]],
)
CompositionDataPage2 = Struct(
'record_list' / GreedyRange(MeshProfileEntry)
)
Retransmit = BitStruct(
# sssssccc
"interval_steps" / BitsInteger(5),
"count" / BitsInteger(3),
)
# fmt: on
class RetransmitAdapter(Adapter):
_subcon = Struct("count" / Int8ul, "interval" / Int16ul)
def __init__(self, subcon, interval):
self.interval = interval
super(RetransmitAdapter, self).__init__(subcon)
def _decode(self, obj, context, path):
return dict(
count=obj["count"], interval=(obj["interval_steps"] + 1) * self.interval
)
def _encode(self, obj, context, path):
if obj["count"] > 7:
raise AttributeError("Retransmission count maximum value is 7")
if (
not 0 < obj["interval"] <= 0x20 * self.interval
or obj["interval"] % self.interval
):
raise AttributeError(
"Interval value must be in range of {min} and {max} with increment of {min}".format(
min=self.interval, max=0x20 * self.interval
)
)
return dict(
count=obj["count"],
interval_steps=int(round((obj["interval"] / self.interval) - 1)),
)
NetworkRetransmit = RetransmitAdapter(
Retransmit, 10
) # (Network Retransmit Interval Steps + 1) * 10ms
RelayRetransmit = NetworkRetransmit # (Relay Retransmit Interval Steps + 1) * 10ms
PublishRetransmit = RetransmitAdapter(
Retransmit, 50
) # (Publish Retransmit Interval Steps + 1) * 50ms
def DoubleKeyIndex(first, second):
return EmbeddedBitStruct(
"_", second / BitsInteger(12), first / BitsInteger(12), reversed=True
)
def SingleKeyIndex(name):
return EmbeddedBitStruct("_", Padding(4), name / BitsInteger(12), reversed=True)
NetAndAppKeyIndex = DoubleKeyIndex("net_key_index", "app_key_index")
AppKeyIndex = SingleKeyIndex("app_key_index")
NetKeyIndex = SingleKeyIndex("net_key_index")
class KeyIndicesAdapter(Adapter):
_subcon = GreedyRange(BitsInteger(12))
def _decode(self, obj, context, path):
"""
Flatten a list dictionaries into list of items:
[{first=1, second=2}, {last=3}] -> [1, 2, 3]
"""
ret = []
for item in obj:
if "last" in item:
ret += [item["last"]]
else:
ret += [item["first"], item["second"]]
return sorted(ret)
def _encode(self, obj, context, path):
"""
Expand a list into list of dictionaries:
[1, 2, 3] -> [{first=1, second=2}, {last=3}]
"""
ret = []
obj.sort()
while len(obj) > 1:
ret += [dict(first=obj.pop(0), second=obj.pop(0))]
if obj:
ret += [dict(last=obj.pop())]
return ret
# fmt: off
KeyIndices = KeyIndicesAdapter(
GreedyRange(
Select(
Reversed(
BitStruct(
"first" / BitsInteger(12),
"second" / BitsInteger(12),
)
),
Reversed(
BitStruct(
Padding(4),
"last" / BitsInteger(12),
)
)
)
)
)
KeyIndices.__construct_doc__ = GreedyRange(BitsInteger(12))
# fmt: on
class PublishPeriodStepResolution(enum.IntEnum):
RESOLUTION_100_MS = 0x0
RESOLUTION_1_S = 0x1
RESOLUTION_10_S = 0x2
RESOLUTION_10_MIN = 0x3
@property
def multiplier(self):
if self == PublishPeriodStepResolution.RESOLUTION_100_MS:
return timedelta(milliseconds=100)
if self == PublishPeriodStepResolution.RESOLUTION_1_S:
return timedelta(seconds=1)
if self == PublishPeriodStepResolution.RESOLUTION_10_S:
return timedelta(seconds=10)
if self == PublishPeriodStepResolution.RESOLUTION_10_MIN:
return timedelta(minutes=10)
# fmt: off
PublishPeriodStepResolutionAdapter = EnumAdapter(
BitsInteger(2),
PublishPeriodStepResolution
)
PublishPeriod = BitStruct(
"step_resolution" / PublishPeriodStepResolutionAdapter,
"number_of_steps" / BitsInteger(6),
)
ConfigBeaconGet = Struct()
ConfigBeaconSet = Struct(
"beacon" / SecureNetworkBeaconAdapter,
)
ConfigBeaconStatus = ConfigBeaconSet
class CompositionDataPage(enum.IntEnum):
ZERO = 0
FIRST = 1
SECOND = 2
TWO_HUNDRED_AND_FIFTY_FIFTH = 255
CompositionDataPageAdapter = EnumAdapter(Int8ul, CompositionDataPage)
ConfigCompositionDataGet = Struct(
"page" / CompositionDataPageAdapter,
)
ConfigCompositionData = Switch(
this.page,
{
CompositionDataPage.ZERO: CompositionDataPage0,
CompositionDataPage.FIRST: CompositionDataPage1,
CompositionDataPage.SECOND: CompositionDataPage2,
CompositionDataPage.TWO_HUNDRED_AND_FIFTY_FIFTH: GreedyBytes,
},
)
ConfigCompositionDataStatus = SwitchStruct(
"page" / CompositionDataPageAdapter,
"data" / ConfigCompositionData,
)
ConfigDefaultTTLGet = Struct()
ConfigDefaultTTLSet = Struct(
"ttl" / TTL,
)
ConfigDefaultTTLStatus = ConfigDefaultTTLSet
ConfigGATTProxyGet = Struct()
ConfigGATTProxySet = Struct(
"GATT_proxy" / GATTProxyAdapter,
)
ConfigGATTProxyStatus = ConfigGATTProxySet
ConfigRelayGet = Struct()
ConfigRelaySet = Struct(
"relay" / RelayAdapter,
"retransmit" / RelayRetransmit,
)
ConfigRelayStatus = ConfigRelaySet
ConfigModelPublicationGet = Struct(
"element_address" / UnicastAddress,
"model" / ModelId,
)
ConfigModelPublicationSet = Struct(
"element_address" / UnicastAddress,
"publish_address" / NotVirtualLabel,
*EmbeddedBitStruct(
"_",
"rfu" / BitsInteger(3),
"credential_flag" / PublishFriendshipCredentialsFlagAdapter,
"app_key_index" / BitsInteger(12),
reversed=True
),
"ttl" / TTL,
"publish_period" / PublishPeriod,
"retransmit" / PublishRetransmit,
"model" / ModelId,
)
ConfigModelPublicationStatus = Struct(
"status" / StatusCodeAdapter,
Embedded(ConfigModelPublicationSet)
)
ConfigModelPublicationVASet = Struct(
"element_address" / UnicastAddress,
"publish_address" / Bytes(16),
*EmbeddedBitStruct(
"_",
"rfu" / BitsInteger(3),
"credential_flag" / PublishFriendshipCredentialsFlagAdapter,
"app_key_index" / BitsInteger(12),
reversed=True
),
"ttl" / TTL,
"publish_period" / PublishPeriod,
"retransmit" / PublishRetransmit,
"model" / ModelId,
)
ConfigModelSubscriptionAdd = Struct(
"element_address" / UnicastAddress,
"address" / SubscriptionAddress,
"model" / ModelId,
)
ConfigModelSubscriptionDelete = ConfigModelSubscriptionAdd
ConfigModelSubscriptionOverwrite = ConfigModelSubscriptionAdd
ConfigModelSubscriptionVAAdd = Struct(
"element_address" / UnicastAddress,
"label" / Bytes(16),
"model" / ModelId,
)
ConfigModelSubscriptionVADelete = ConfigModelSubscriptionVAAdd
ConfigModelSubscriptionVAOverwrite = ConfigModelSubscriptionVAAdd
ConfigModelSubscriptionStatus = Struct(
"status" / StatusCodeAdapter,
"element_address" / UnicastAddress,
"address" / StatusSubscriptionAddress,
"model" / ModelId,
)
ConfigModelSubscriptionDeleteAll = Struct(
"element_address" / UnicastAddress,
"model" / ModelId,
)
ConfigSIGModelSubscriptionGet = Struct(
"element_address" / UnicastAddress,
"model" / SIGModelId,
)
ConfigSIGModelSubscriptionList = Struct(
"status" / StatusCodeAdapter,
"element_address" / UnicastAddress,
"model" / SIGModelId,
"addresses" / GreedyRange(Int16ul),
)
ConfigVendorModelSubscriptionGet = Struct(
"element_address" / UnicastAddress,
"model" / VendorModelId,
)
ConfigVendorModelSubscriptionList = Struct(
"status" / StatusCodeAdapter,
"element_address" / UnicastAddress,
"model" / VendorModelId,
"addresses" / GreedyRange(Int16ul),
)
ConfigNetKeyAdd = Struct(
*NetKeyIndex,
"net_key" / Bytes(16),
)
ConfigNetKeyUpdate = ConfigNetKeyAdd
ConfigNetKeyDelete = Struct(
*NetKeyIndex,
)
ConfigNetKeyStatus = Struct(
"status" / StatusCodeAdapter,
*NetKeyIndex,
)
ConfigNetKeyGet = Struct()
ConfigNetKeyList = Struct(
"net_key_indices" / KeyIndices
)
ConfigAppKeyAdd = Struct(
*NetAndAppKeyIndex,
"app_key" / Bytes(16),
)
ConfigAppKeyUpdate = ConfigAppKeyAdd
ConfigAppKeyDelete = Struct(
*NetAndAppKeyIndex,
)
ConfigAppKeyStatus = Struct(
"status" / StatusCodeAdapter,
*NetAndAppKeyIndex,
)
ConfigAppKeyGet = Struct(
*NetKeyIndex
)
ConfigAppKeyList = Struct(
"status" / StatusCodeAdapter,
*NetKeyIndex,
"app_key_indices" / KeyIndices,
)
ConfigNodeIdentityGet = Struct(
*NetKeyIndex,
)
ConfigNodeIdentitySet = Struct(
*NetKeyIndex,
"identity" / NodeIdentityAdapter,
)
ConfigNodeIdentityStatus = Struct(
"status" / StatusCodeAdapter,
Embedded(ConfigNodeIdentitySet),
)
ConfigModelAppBind = Struct(
"element_address" / UnicastAddress,
*AppKeyIndex,
"model" / ModelId,
)
ConfigModelAppUnbind = ConfigModelAppBind
ConfigModelAppStatus = Struct(
"status" / StatusCodeAdapter,
Embedded(ConfigModelAppBind),
)
ConfigSIGModelAppGet = Struct(
"element_address" / UnicastAddress,
"model" / SIGModelId,
)
ConfigSIGModelAppList = Struct(
"status" / StatusCodeAdapter,
Embedded(ConfigSIGModelAppGet),
"app key indices" / KeyIndices,
)
ConfigVendorModelAppGet = Struct(
"element_address" / UnicastAddress,
"model" / VendorModelId,
)
ConfigVendorModelAppList = Struct(
"status" / StatusCodeAdapter,
Embedded(ConfigVendorModelAppGet),
"app_key_indices" / KeyIndices,
)
ConfigNodeReset = Struct()
ConfigNodeResetStatus = Struct()
ConfigFriendGet = Struct()
ConfigFriendSet = Struct(
"friend" / FriendAdapter,
)
ConfigFriendStatus = ConfigFriendSet
ConfigKeyRefreshPhaseGet = Struct(
*NetKeyIndex,
)
ConfigKeyRefreshPhaseSet = Struct(
Embedded(ConfigKeyRefreshPhaseGet),
"transition" / EnumAdapter(Int8ul, KeyRefreshTransition),
)
ConfigKeyRefreshPhaseStatus = Struct(
"status" / StatusCodeAdapter,
*NetKeyIndex,
"phase" / EnumAdapter(Int8ul, KeyRefreshPhase),
)
ConfigHeartbeatPublicationFeatures = ExprValidator(Int16ul, lambda obj, ctx: obj <= 0x3)
ConfigHeartbeatHops = ExprValidator(Int8ul, lambda obj, ctx: obj <= 0x7F)
ConfigHeartbeatPublicationGet = Struct()
ConfigHeartbeatPublicationSet = Struct(
"destination" / UnicastUnassignedGroupAddress,
"count" / LogAdapter(Int8ul, max_value=0x10, infinity=True),
"period" / LogAdapter(Int8ul, max_value=0x10),
"ttl" / TTL,
"features" / BitList(2),
*NetKeyIndex,
)
ConfigHeartbeatPublicationStatus = Struct(
"status" / StatusCodeAdapter,
Embedded(ConfigHeartbeatPublicationSet),
)
ConfigHeartbeatSubscriptionGet = Struct()
ConfigHeartbeatSubscriptionSet = Struct(
"source" / UnicastUnassignedAddress,
"destination" / UnicastUnassignedGroupAddress,
"period_log" / LogAdapter(Int8ul, max_value=0x11),
)
ConfigHeartbeatSubscriptionStatus = Struct(
"status" / StatusCodeAdapter,
Embedded(ConfigHeartbeatSubscriptionSet),
"count" / LogAdapter(Int8ul, max_value=0x11, infinity=True),
"min_hops" / RangeValidator(Int8ul, max_value=0x7F),
"max_hops" / RangeValidator(Int8ul, max_value=0x7F),
)
ConfigLowPowerNodePollTimeoutGet = Struct(
"lpn_address" / Int16ul, # TODO
)
ConfigLowPowerNodePollTimeoutStatus = Struct(
Embedded(ConfigLowPowerNodePollTimeoutGet),
"poll_timeout" / Int24ul, # TODO
)
ConfigNetworkTransmitGet = Struct()
ConfigNetworkTransmitSet = NetworkRetransmit
ConfigNetworkTransmitStatus = ConfigNetworkTransmitSet
# fmt: on
[docs]class ConfigOpcode(enum.IntEnum):
CONFIG_APPKEY_ADD = 0x00
CONFIG_APPKEY_DELETE = 0x8000
CONFIG_APPKEY_GET = 0x8001
CONFIG_APPKEY_LIST = 0x8002
CONFIG_APPKEY_STATUS = 0x8003
CONFIG_APPKEY_UPDATE = 0x01
CONFIG_BEACON_GET = 0x8009
CONFIG_BEACON_SET = 0x800A
CONFIG_BEACON_STATUS = 0x800B
CONFIG_COMPOSITION_DATA_GET = 0x8008
CONFIG_COMPOSITION_DATA_STATUS = 0x02
CONFIG_DEFAULT_TTL_GET = 0x800C
CONFIG_DEFAULT_TTL_SET = 0x800D
CONFIG_DEFAULT_TTL_STATUS = 0x800E
CONFIG_FRIEND_GET = 0x800F
CONFIG_FRIEND_SET = 0x8010
CONFIG_FRIEND_STATUS = 0x8011
CONFIG_GATT_PROXY_GET = 0x8012
CONFIG_GATT_PROXY_SET = 0x8013
CONFIG_GATT_PROXY_STATUS = 0x8014
CONFIG_HEARBEAT_PUBLICATION_GET = 0x8038
CONFIG_HEARBEAT_PUBLICATION_SET = 0x8039
CONFIG_HEARBEAT_PUBLICATION_STATUS = 0x06
CONFIG_HEARBEAT_SUBSCRIPTION_GET = 0x803A
CONFIG_HEARBEAT_SUBSCRIPTION_SET = 0x803B
CONFIG_HEARBEAT_SUBSCRIPTION_STATUS = 0x803C
CONFIG_KEY_REFRESH_PHASE_GET = 0x8015
CONFIG_KEY_REFRESH_PHASE_SET = 0x8016
CONFIG_KEY_REFRESH_PHASE_STATUS = 0x8017
CONFIG_LOW_POWER_NODE_POLL_TIMEOUT_GET = 0x802D
CONFIG_LOW_POWER_NODE_POLL_TIMEOUT_STATUS = 0x802E
CONFIG_MODEL_APP_BIND = 0x803D
CONFIG_MODEL_APP_STATUS = 0x803E
CONFIG_MODEL_APP_UNBIND = 0x803F
CONFIG_MODEL_PUBLICATION_GET = 0x8018
CONFIG_MODEL_PUBLICATION_SET = 0x03
CONFIG_MODEL_PUBLICATION_STATUS = 0x8019
CONFIG_MODEL_PUBLICATION_VIRTUAL_ADDRESS_SET = 0x801A
CONFIG_MODEL_SUBSCRIPTION_ADD = 0x801B
CONFIG_MODEL_SUBSCRIPTION_DELETE = 0x801C
CONFIG_MODEL_SUBSCRIPTION_DELETE_ALL = 0x801D
CONFIG_MODEL_SUBSCRIPTION_OVERWRITE = 0x801E
CONFIG_MODEL_SUBSCRIPTION_STATUS = 0x801F
CONFIG_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_ADD = 0x8020
CONFIG_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_DELETE = 0x8021
CONFIG_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_OVERWRITE = 0x8022
CONFIG_NETKEY_ADD = 0x8040
CONFIG_NETKEY_DELETE = 0x8041
CONFIG_NETKEY_GET = 0x8042
CONFIG_NETKEY_LIST = 0x8043
CONFIG_NETKEY_STATUS = 0x8044
CONFIG_NETKEY_UPDATE = 0x8045
CONFIG_NETWORK_TRANSMIT_GET = 0x8023
CONFIG_NETWORK_TRANSMIT_SET = 0x8024
CONFIG_NETWORK_TRANSMIT_STATUS = 0x8025
CONFIG_NODE_IDENTITY_GET = 0x8046
CONFIG_NODE_IDENTITY_SET = 0x8047
CONFIG_NODE_IDENTITY_STATUS = 0x8048
CONFIG_NODE_RESET = 0x8049
CONFIG_NODE_RESET_STATUS = 0x804A
CONFIG_RELAY_GET = 0x8026
CONFIG_RELAY_SET = 0x8027
CONFIG_RELAY_STATUS = 0x8028
CONFIG_SIG_MODEL_APP_GET = 0x804B
CONFIG_SIG_MODEL_APP_LIST = 0x804C
CONFIG_SIG_MODEL_SUBSCRIPTION_GET = 0x8029
CONFIG_SIG_MODEL_SUBSCRIPTION_LIST = 0x802A
CONFIG_VENDOR_MODEL_APP_GET = 0x804D
CONFIG_VENDOR_MODEL_APP_LIST = 0x804E
CONFIG_VENDOR_MODEL_SUBSCRIPTION_GET = 0x802B
CONFIG_VENDOR_MODEL_SUBSCRIPTION_LIST = 0x802C
# fmt: off
ConfigMessage = SwitchStruct(
"opcode" / Opcode(ConfigOpcode),
"params" / Switch(
this.opcode,
{
ConfigOpcode.CONFIG_APPKEY_ADD: ConfigAppKeyAdd,
ConfigOpcode.CONFIG_APPKEY_DELETE: ConfigAppKeyDelete,
ConfigOpcode.CONFIG_APPKEY_GET: ConfigAppKeyGet,
ConfigOpcode.CONFIG_APPKEY_LIST: ConfigAppKeyList,
ConfigOpcode.CONFIG_APPKEY_STATUS: ConfigAppKeyStatus,
ConfigOpcode.CONFIG_APPKEY_UPDATE: ConfigAppKeyUpdate,
ConfigOpcode.CONFIG_BEACON_GET: ConfigBeaconGet,
ConfigOpcode.CONFIG_BEACON_SET: ConfigBeaconSet,
ConfigOpcode.CONFIG_BEACON_STATUS: ConfigBeaconStatus,
ConfigOpcode.CONFIG_COMPOSITION_DATA_GET: ConfigCompositionDataGet,
ConfigOpcode.CONFIG_COMPOSITION_DATA_STATUS: ConfigCompositionDataStatus,
ConfigOpcode.CONFIG_DEFAULT_TTL_GET: ConfigDefaultTTLGet,
ConfigOpcode.CONFIG_DEFAULT_TTL_SET: ConfigDefaultTTLSet,
ConfigOpcode.CONFIG_DEFAULT_TTL_STATUS: ConfigDefaultTTLStatus,
ConfigOpcode.CONFIG_FRIEND_GET: ConfigFriendGet,
ConfigOpcode.CONFIG_FRIEND_SET: ConfigFriendSet,
ConfigOpcode.CONFIG_FRIEND_STATUS: ConfigFriendStatus,
ConfigOpcode.CONFIG_GATT_PROXY_GET: ConfigGATTProxyGet,
ConfigOpcode.CONFIG_GATT_PROXY_SET: ConfigGATTProxySet,
ConfigOpcode.CONFIG_GATT_PROXY_STATUS: ConfigGATTProxyStatus,
ConfigOpcode.CONFIG_HEARBEAT_PUBLICATION_GET: ConfigHeartbeatPublicationGet,
ConfigOpcode.CONFIG_HEARBEAT_PUBLICATION_SET: ConfigHeartbeatPublicationSet,
ConfigOpcode.CONFIG_HEARBEAT_PUBLICATION_STATUS: ConfigHeartbeatPublicationStatus,
ConfigOpcode.CONFIG_HEARBEAT_SUBSCRIPTION_GET: ConfigHeartbeatSubscriptionGet,
ConfigOpcode.CONFIG_HEARBEAT_SUBSCRIPTION_SET: ConfigHeartbeatSubscriptionSet,
ConfigOpcode.CONFIG_HEARBEAT_SUBSCRIPTION_STATUS: ConfigHeartbeatSubscriptionStatus,
ConfigOpcode.CONFIG_KEY_REFRESH_PHASE_GET: ConfigKeyRefreshPhaseGet,
ConfigOpcode.CONFIG_KEY_REFRESH_PHASE_SET: ConfigKeyRefreshPhaseSet,
ConfigOpcode.CONFIG_KEY_REFRESH_PHASE_STATUS: ConfigKeyRefreshPhaseStatus,
ConfigOpcode.CONFIG_LOW_POWER_NODE_POLL_TIMEOUT_GET: ConfigLowPowerNodePollTimeoutGet,
ConfigOpcode.CONFIG_LOW_POWER_NODE_POLL_TIMEOUT_STATUS: ConfigLowPowerNodePollTimeoutStatus,
ConfigOpcode.CONFIG_MODEL_APP_BIND: ConfigModelAppBind,
ConfigOpcode.CONFIG_MODEL_APP_STATUS: ConfigModelAppStatus,
ConfigOpcode.CONFIG_MODEL_APP_UNBIND: ConfigModelAppUnbind,
ConfigOpcode.CONFIG_MODEL_PUBLICATION_GET: ConfigModelPublicationGet,
ConfigOpcode.CONFIG_MODEL_PUBLICATION_SET: ConfigModelPublicationSet,
ConfigOpcode.CONFIG_MODEL_PUBLICATION_STATUS: ConfigModelPublicationStatus,
ConfigOpcode.CONFIG_MODEL_PUBLICATION_VIRTUAL_ADDRESS_SET: ConfigModelPublicationVASet,
ConfigOpcode.CONFIG_MODEL_SUBSCRIPTION_ADD: ConfigModelSubscriptionAdd,
ConfigOpcode.CONFIG_MODEL_SUBSCRIPTION_DELETE: ConfigModelSubscriptionDelete,
ConfigOpcode.CONFIG_MODEL_SUBSCRIPTION_DELETE_ALL: ConfigModelSubscriptionDeleteAll,
ConfigOpcode.CONFIG_MODEL_SUBSCRIPTION_OVERWRITE: ConfigModelSubscriptionOverwrite,
ConfigOpcode.CONFIG_MODEL_SUBSCRIPTION_STATUS: ConfigModelSubscriptionStatus,
ConfigOpcode.CONFIG_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_ADD: ConfigModelSubscriptionVAAdd,
ConfigOpcode.CONFIG_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_DELETE: ConfigModelSubscriptionVADelete,
ConfigOpcode.CONFIG_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_OVERWRITE: ConfigModelSubscriptionVAOverwrite,
ConfigOpcode.CONFIG_NETKEY_ADD: ConfigNetKeyAdd,
ConfigOpcode.CONFIG_NETKEY_DELETE: ConfigNetKeyDelete,
ConfigOpcode.CONFIG_NETKEY_GET: ConfigNetKeyGet,
ConfigOpcode.CONFIG_NETKEY_LIST: ConfigNetKeyList,
ConfigOpcode.CONFIG_NETKEY_STATUS: ConfigNetKeyStatus,
ConfigOpcode.CONFIG_NETKEY_UPDATE: ConfigNetKeyUpdate,
ConfigOpcode.CONFIG_NETWORK_TRANSMIT_GET: ConfigNetworkTransmitGet,
ConfigOpcode.CONFIG_NETWORK_TRANSMIT_SET: ConfigNetworkTransmitSet,
ConfigOpcode.CONFIG_NETWORK_TRANSMIT_STATUS: ConfigNetworkTransmitStatus,
ConfigOpcode.CONFIG_NODE_IDENTITY_GET: ConfigNodeIdentityGet,
ConfigOpcode.CONFIG_NODE_IDENTITY_SET: ConfigNodeIdentitySet,
ConfigOpcode.CONFIG_NODE_IDENTITY_STATUS: ConfigNodeIdentityStatus,
ConfigOpcode.CONFIG_NODE_RESET: ConfigNodeReset,
ConfigOpcode.CONFIG_NODE_RESET_STATUS: ConfigNodeResetStatus,
ConfigOpcode.CONFIG_RELAY_GET: ConfigRelayGet,
ConfigOpcode.CONFIG_RELAY_SET: ConfigRelaySet,
ConfigOpcode.CONFIG_RELAY_STATUS: ConfigRelayStatus,
ConfigOpcode.CONFIG_SIG_MODEL_APP_GET: ConfigSIGModelAppGet,
ConfigOpcode.CONFIG_SIG_MODEL_APP_LIST: ConfigSIGModelAppList,
ConfigOpcode.CONFIG_SIG_MODEL_SUBSCRIPTION_GET: ConfigSIGModelSubscriptionGet,
ConfigOpcode.CONFIG_SIG_MODEL_SUBSCRIPTION_LIST: ConfigSIGModelSubscriptionList,
ConfigOpcode.CONFIG_VENDOR_MODEL_APP_GET: ConfigVendorModelAppGet,
ConfigOpcode.CONFIG_VENDOR_MODEL_APP_LIST: ConfigVendorModelAppList,
ConfigOpcode.CONFIG_VENDOR_MODEL_SUBSCRIPTION_GET: ConfigVendorModelSubscriptionGet,
ConfigOpcode.CONFIG_VENDOR_MODEL_SUBSCRIPTION_LIST: ConfigVendorModelSubscriptionList,
}
)
)
# fmt: on