Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions tests/default_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,29 @@
("stored_scratchpad", SCRATCHPAD_INFO),
("configuration_data_content", TEST_CDC1)
])

NODE_CONFIG_FOR_SETTING = {
"sink_id": SINK_ID,
"node_role": 1,
"node_address": 1516,
"network_address": 879123,
"network_channel": 7,
"app_config_diag": 30,
"app_config_seq": 300,
"app_config_data": bytes.fromhex("90807060"),
"channel_map": 120,
"cipher_key": bytes.fromhex("102030"),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some zero padding in the gw for the keys?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the gateway would just return an error if the key size is incorrect. This library doesn't do any checks as long as the protobuf messages are valid. It helps with testing, we can generate "bad" messages using this library.

"authentication_key": bytes.fromhex("AABBCC"),
"started": True,
"network_keys": {
"cipher": bytes.fromhex("5000"),
"authentication": bytes.fromhex("6000"),
"sequence": 6767
},
"management_keys": {
"cipher": bytes.fromhex("10AA"),
"authentication": bytes.fromhex("20BB"),
"sequence": 520
},
}

14 changes: 14 additions & 0 deletions tests/test_set_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,17 @@ def test_generate_parse_response_with_readonly_fields():
for k, v in request.__dict__.items():
assert v == request2.__dict__[k]


def test_generate_parse_request_with_writeable_fields():
request = wirepas_mesh_messaging.SetConfigRequest(
SINK_ID, NODE_CONFIG_FOR_SETTING, REQUEST_ID
)

request2 = wirepas_mesh_messaging.SetConfigRequest.from_payload(
request.payload
)

assert NODE_CONFIG_FOR_SETTING == request2.new_config
for k, v in request.__dict__.items():
assert v == request2.__dict__[k]

50 changes: 40 additions & 10 deletions wirepas_mesh_messaging/config_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,33 +243,63 @@ def set_config_otap(message_obj, dic):
set_scratchpad_target(message_obj.target_and_action, dic["target_and_action"])


def parse_config_keys(message_obj, dic):
def parse_config_wo_fields(message_obj, dic):
"""
Parses network keys.
Parses the message_obj for write only (wo) fields and copies them into
dic.

The keys are only available on a SinkNewConfig message.
Write only fields are ones that are only available on a SinkNewConfig
message.

Args:
message_obj (proto): protocol buffer object
dic (dict): the dictionary where to copy the keys into
dic (dict): the dictionary where to copy the wo fields

"""

parse_optional_field(message_obj.keys, "cipher", dic, "cipher_key")
parse_optional_field(message_obj.keys, "authentication", dic, "authentication_key")

if message_obj.HasField("network_keys"):
dic["network_keys"] = {
"cipher": message_obj.network_keys.cipher,
"authentication": message_obj.network_keys.authentication,
"sequence": message_obj.network_keys.sequence
}

if message_obj.HasField("management_keys"):
dic["management_keys"] = {
"cipher": message_obj.management_keys.cipher,
"authentication": message_obj.management_keys.authentication,
"sequence": message_obj.management_keys.sequence
}


def set_config_keys(message_obj, dic):
def set_config_wo_fields(message_obj, dic):
"""
Sets network keys.
Sets the message_obj with the write only (wo) fields present in dic.

The keys are only available on a SinkNewConfig message.
Write only fields are ones that are only available on a SinkNewConfig
message.

Args:
message_obj (proto): protocol buffer object
dic (dict): the dictionary where to copy the keys from
dic (dict): the dictionary where to copy the wo fields from

"""
set_optional_field(message_obj, "cipher", dic, "cipher_key")
set_optional_field(message_obj, "authentication", dic, "authentication_key")

set_optional_field(message_obj.keys, "cipher", dic, "cipher_key")
set_optional_field(message_obj.keys, "authentication", dic, "authentication_key")

if "network_keys" in dic:
message_obj.network_keys.cipher = dic["network_keys"]["cipher"]
message_obj.network_keys.authentication = dic["network_keys"]["authentication"]
message_obj.network_keys.sequence = dic["network_keys"]["sequence"]

if "management_keys" in dic:
message_obj.management_keys.cipher = dic["management_keys"]["cipher"]
message_obj.management_keys.authentication = dic["management_keys"]["authentication"]
message_obj.management_keys.sequence = dic["management_keys"]["sequence"]


def parse_config_ro(message_obj, dic):
Expand Down
1 change: 1 addition & 0 deletions wirepas_mesh_messaging/gateway_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ class GatewayFeature(enum.Enum):
GW_FEATURE_UNKNOWN = GatewayFeature_pb.UNKNOWN
GW_FEATURE_SCRATCHPAD_CHUNK_V1 = GatewayFeature_pb.SCRATCHPAD_CHUNK_V1
GW_FEATURE_CONFIGURATION_DATA_V1 = GatewayFeature_pb.CONFIGURATION_DATA_V1
GW_FEATURE_SINK_KEY_MANAGEMENT_V1 = GatewayFeature_pb.SINK_KEY_MANAGEMENT_V1

16 changes: 12 additions & 4 deletions wirepas_mesh_messaging/set_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@

from .config_helper import (
parse_config_rw,
parse_config_keys,
set_config_rw,
set_config_keys,
parse_config_ro,
parse_config_otap,
set_config_otap,
set_config_ro,
set_config_wo_fields,
parse_config_wo_fields,
)


Expand All @@ -43,6 +43,14 @@ class SetConfigRequest(Request):
cipher_key (bytearray)
authentication_key (bytearray)
started (bool)
network_keys (dict): with following required keys:
cipher (bytearray)
authentication (bytearray)
sequence (int)
management_keys (dict): with following required keys:
cipher (bytearray)
authentication (bytearray)
sequence (int)

Note: app_config_data/app_config_seq/app_config_data must all be defined to change one of them
only relevant keys for new config has to be defined
Expand Down Expand Up @@ -71,7 +79,7 @@ def from_payload(cls, payload):
new_config = {}
new_config["sink_id"] = req.config.sink_id
parse_config_rw(req.config, new_config)
parse_config_keys(req.config, new_config)
parse_config_wo_fields(req.config, new_config)

return cls(req.config.sink_id, new_config, d["req_id"], time_ms_epoch=d["time_ms_epoch"])

Expand All @@ -84,7 +92,7 @@ def payload(self):

set_config.config.sink_id = self.sink_id
set_config_rw(set_config.config, self.new_config)
set_config_keys(set_config.config.keys, self.new_config)
set_config_wo_fields(set_config.config, self.new_config)

return message.SerializeToString()

Expand Down