blob: da62a45c05fe97ee4460b911241b0c2a24c807d7 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright (c) 2023 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import re
import subprocess
import sys
CHIP_TOPDIR = os.path.dirname(os.path.realpath(__file__))[:-len(os.path.join('src', 'setup_payload', 'tests'))]
sys.path.insert(0, os.path.join(CHIP_TOPDIR, 'src', 'setup_payload', 'python'))
from SetupPayload import CommissioningFlow, SetupPayload # noqa: E402
def payload_param_dict():
return {
'Version': None,
'VendorID': None,
'ProductID': None,
'Custom flow': None,
'Discovery Bitmask': None,
'Short discriminator': None,
'Long discriminator': None,
'Passcode': None
}
def remove_escape_sequence(data):
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', data)
return result
def chip_tool_parse_setup_payload(chip_tool, payload):
cmd_args = [chip_tool, 'payload', 'parse-setup-payload', payload]
data = subprocess.check_output(cmd_args).decode('utf-8')
data = remove_escape_sequence(data)
parsed_params = payload_param_dict()
for key in parsed_params:
k_st = data.find(key)
if k_st == -1:
continue
# 1 is for ":"
k_end = k_st + len(key) + 1
k_nl = data.find('\n', k_end)
parsed_params[key] = data[k_end:k_nl].split()[0]
return parsed_params
def generate_payloads(in_params):
payloads = SetupPayload(in_params['Long discriminator'], in_params['Passcode'],
in_params['Discovery Bitmask'], CommissioningFlow(in_params['Custom flow']),
in_params['VendorID'], in_params['ProductID'])
manualcode = payloads.generate_manualcode()
qrcode = payloads.generate_qrcode()
return manualcode, qrcode
def verify_generated_payloads(in_params, manualcode_params, qrcode_params):
assert in_params['Version'] == int(manualcode_params['Version'], 0)
assert in_params['Passcode'] == int(manualcode_params['Passcode'], 0)
assert in_params['Short discriminator'] == int(manualcode_params['Short discriminator'], 0)
if in_params['Custom flow'] != 0:
assert in_params['VendorID'] == int(manualcode_params['VendorID'], 0)
assert in_params['ProductID'] == int(manualcode_params['ProductID'], 0)
assert in_params['Version'] == int(qrcode_params['Version'], 0)
assert in_params['VendorID'] == int(qrcode_params['VendorID'], 0)
assert in_params['ProductID'] == int(qrcode_params['ProductID'], 0)
assert in_params['Custom flow'] == int(qrcode_params['Custom flow'], 0)
assert in_params['Discovery Bitmask'] == int(qrcode_params['Discovery Bitmask'], 0)
assert in_params['Passcode'] == int(qrcode_params['Passcode'], 0)
assert in_params['Long discriminator'] == int(qrcode_params['Long discriminator'], 0)
def get_payload_params(discriminator, passcode, discovery=4, flow=0, vid=0, pid=0, version=0, short_discriminator=None):
p = payload_param_dict()
p['Version'] = version
p['VendorID'] = vid
p['ProductID'] = pid
p['Custom flow'] = flow
p['Discovery Bitmask'] = discovery
p['Long discriminator'] = discriminator
p['Short discriminator'] = short_discriminator if short_discriminator is not None else (discriminator >> 8)
p['Passcode'] = passcode
return p
def test_code_generation(chip_tool):
test_data_set = [
get_payload_params(3840, 20202021),
get_payload_params(3781, 12349876, flow=1, vid=1, pid=1),
get_payload_params(2310, 23005908, flow=2, vid=0xFFF3, pid=0x8098),
get_payload_params(3091, 43338551, discovery=2, flow=2, vid=0x1123, pid=0x0012),
get_payload_params(80, 54757432, discovery=6, flow=2, vid=0x2345, pid=0x1023),
get_payload_params(174, 81235604, discovery=7, flow=1, vid=0x45, pid=0x10),
]
for test_params in test_data_set:
manualcode, qrcode = generate_payloads(test_params)
manualcode_params = chip_tool_parse_setup_payload(chip_tool, manualcode)
qrcode_params = chip_tool_parse_setup_payload(chip_tool, qrcode)
verify_generated_payloads(test_params, manualcode_params, qrcode_params)
def test_onboardingcode_parsing():
# This test dataset is generated using `chip-tool payload parse-setup-payload <payload>`
test_data_set = [
{
'code': '34970112332',
'res': get_payload_params(discriminator=None, passcode=20202021, discovery=None,
flow=0, vid=None, pid=None, version=0, short_discriminator=15),
},
{
'code': '745492075300001000013',
'res': get_payload_params(discriminator=None, passcode=12349876, discovery=None,
flow=2, vid=1, pid=1, version=0, short_discriminator=14),
},
{
'code': '619156140465523329207',
'res': get_payload_params(discriminator=None, passcode=23005908, discovery=None,
flow=2, vid=65523, pid=32920, version=0, short_discriminator=9),
},
{
'code': '702871264504387000187',
'res': get_payload_params(discriminator=None, passcode=43338551, discovery=None,
flow=2, vid=4387, pid=18, version=0, short_discriminator=12),
},
{
'code': '402104334209029041311',
'res': get_payload_params(discriminator=None, passcode=54757432, discovery=None,
flow=2, vid=9029, pid=4131, version=0, short_discriminator=0),
},
{
'code': '403732495800069000166',
'res': get_payload_params(discriminator=None, passcode=81235604, discovery=None,
flow=2, vid=69, pid=16, version=0, short_discriminator=0),
},
{
'code': 'MT:U9VJ0OMV172PX813210',
'res': get_payload_params(discriminator=3431, passcode=49910688, discovery=2,
flow=0, vid=4891, pid=2, version=0, short_discriminator=None),
},
{
'code': 'MT:00000CQM00KA0648G00',
'res': get_payload_params(discriminator=3840, passcode=20202021, discovery=4,
flow=0, vid=0, pid=0, version=0, short_discriminator=None),
},
{
'code': 'MT:A3L90ARR15G6N57Y900',
'res': get_payload_params(discriminator=3781, passcode=12349876, discovery=4,
flow=1, vid=1, pid=1, version=0, short_discriminator=None),
},
{
'code': 'MT:MZWA6G6026O2XP0II00',
'res': get_payload_params(discriminator=2310, passcode=23005908, discovery=4,
flow=2, vid=65523, pid=32920, version=0, short_discriminator=None),
},
{
'code': 'MT:KSNK4M5113-JPR4UY00',
'res': get_payload_params(discriminator=3091, passcode=43338551, discovery=2,
flow=2, vid=4387, pid=18, version=0, short_discriminator=12),
},
{
'code': 'MT:0A.T0P--00Y0OJ0.510',
'res': get_payload_params(discriminator=80, passcode=54757432, discovery=6,
flow=2, vid=9029, pid=4131, version=0, short_discriminator=None),
},
{
'code': 'MT:EPX0482F26DAVY09R10',
'res': get_payload_params(discriminator=174, passcode=81235604, discovery=7,
flow=1, vid=69, pid=16, version=0, short_discriminator=None),
},
]
for test_payload in test_data_set:
payload = SetupPayload.parse(test_payload['code'])
assert payload.long_discriminator == test_payload['res']['Long discriminator']
assert payload.short_discriminator == test_payload['res']['Short discriminator']
assert payload.pincode == test_payload['res']['Passcode']
assert payload.discovery == test_payload['res']['Discovery Bitmask']
assert payload.flow == test_payload['res']['Custom flow']
assert payload.vid == test_payload['res']['VendorID']
assert payload.pid == test_payload['res']['ProductID']
def main():
if len(sys.argv) == 2:
chip_tool = sys.argv[1]
test_code_generation(chip_tool)
test_onboardingcode_parsing()
if __name__ == '__main__':
main()