mfg_tool: Generate onboarding payloads using chip-tool

qrcodetool behaves differently on macos and linux which breaks the
mfg_tool.py on linux. chip-tool has the facility to generate the
onboarding payloads.

Unique-id belongs to chip-factory namespace and it was present in
chip-config, fixed it.
This commit is contained in:
Shubham Patil
2022-06-16 22:56:52 +05:30
parent 613f617a3a
commit 0fd164ad0a
3 changed files with 56 additions and 55 deletions
+2 -12
View File
@@ -7,8 +7,8 @@ chip-cert provides command line interface (CLI) utility used for generating and
* [SPAKE2P Parameters Tool](https://github.com/project-chip/connectedhomeip/tree/master/src/tools/spake2p), * [SPAKE2P Parameters Tool](https://github.com/project-chip/connectedhomeip/tree/master/src/tools/spake2p),
spake2p tool provides command line interface (CLI) utility used for generating spake parameters (PIN code and verifier) for device manufacturing provisioning. spake2p tool provides command line interface (CLI) utility used for generating spake parameters (PIN code and verifier) for device manufacturing provisioning.
* [QR Code Tool](https://github.com/project-chip/connectedhomeip/tree/master/src/qrcodetool), * [chip-tool](https://github.com/project-chip/connectedhomeip/tree/master/examples/chip-tool),
qrcodetool generates onboarding QR code payload and manual pairing code. chip-tool supports generating onboarding QR code payload and manual pairing code.
* [Mass Manufacturing Utility](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/mass_mfg.html#manufacturing-utility), * [Mass Manufacturing Utility](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/mass_mfg.html#manufacturing-utility),
mfg_gen.py to create factory NVS partition images. mfg_gen.py to create factory NVS partition images.
@@ -30,16 +30,6 @@ ninja -C out/host
``` ```
Above commands will generate spake2p and chip-cert at `esp-matter/connectedhomeip/connectedhomeip/out/host`. Above commands will generate spake2p and chip-cert at `esp-matter/connectedhomeip/connectedhomeip/out/host`.
#### Build qrcodetool
```
cd path/to/esp-matter/connectedhomeip/connectedhomeip
ninja -C out/host src/qrcodetool
# This builds the qrcodetool at path out/host/obj/src/qrcodetool/bin
# Move this to out/host to keep all the tools at the same path
cp out/host/obj/src/qrcodetool/bin/qrcodetool out/host
```
#### Add the tools path to $PATH #### Add the tools path to $PATH
``` ```
export PATH="$PATH:path/to/esp-matter/connectedhomeip/connectedhomeip/out/host" export PATH="$PATH:path/to/esp-matter/connectedhomeip/connectedhomeip/out/host"
+1 -3
View File
@@ -60,11 +60,9 @@ CHIP_KEY_MAP = {
'type': 'file', 'type': 'file',
'encoding': 'binary', 'encoding': 'binary',
}, },
},
'chip-config': {
'unique-id': { 'unique-id': {
'type': 'data', 'type': 'data',
'encoding': 'string', 'encoding': 'hex2bin',
}, },
}, },
} }
+53 -40
View File
@@ -43,7 +43,7 @@ if not os.getenv('IDF_PATH'):
TOOLS = { TOOLS = {
'spake2p' : None, 'spake2p' : None,
'chip-cert' : None, 'chip-cert' : None,
'qrcodetool': None, 'chip-tool': None,
'mfg_gen' : None, 'mfg_gen' : None,
} }
@@ -74,6 +74,11 @@ INVALID_PASSCODES = [ 00000000, 11111111, 22222222, 33333333, 44444444, 55555555
UUIDs = list() UUIDs = list()
# Lengths for manual pairing codes and qrcode
SHORT_MANUALCODE_LEN = 11
LONG_MANUALCODE_LEN = 21
QRCODE_LEN = 22
def vid_pid_str(vid, pid): def vid_pid_str(vid, pid):
return '_'.join([hex(vid)[2:], hex(pid)[2:]]) return '_'.join([hex(vid)[2:], hex(pid)[2:]])
@@ -91,9 +96,9 @@ def check_tools_exists():
logging.error('chip-cert not found, please add chip-cert path to PATH environment variable') logging.error('chip-cert not found, please add chip-cert path to PATH environment variable')
sys.exit(1) sys.exit(1)
TOOLS['qrcodetool'] = shutil.which('qrcodetool') TOOLS['chip-tool'] = shutil.which('chip-tool')
if TOOLS['qrcodetool'] is None: if TOOLS['chip-tool'] is None:
logging.error('qrcodetool not found, please add qrcodetool path to PATH environment variable') logging.error('chip-tool not found, please add chip-tool path to PATH environment variable')
sys.exit(1) sys.exit(1)
TOOLS['mfg_gen'] = os.sep.join([os.getenv('IDF_PATH'), 'tools', 'mass_mfg', 'mfg_gen.py']) TOOLS['mfg_gen'] = os.sep.join([os.getenv('IDF_PATH'), 'tools', 'mass_mfg', 'mfg_gen.py'])
@@ -104,7 +109,7 @@ def check_tools_exists():
logging.debug('Using following tools:') logging.debug('Using following tools:')
logging.debug('spake2p: {}'.format(TOOLS['spake2p'])) logging.debug('spake2p: {}'.format(TOOLS['spake2p']))
logging.debug('chip-cert: {}'.format(TOOLS['chip-cert'])) logging.debug('chip-cert: {}'.format(TOOLS['chip-cert']))
logging.debug('qrcodetool: {}'.format(TOOLS['qrcodetool'])) logging.debug('chip-tool: {}'.format(TOOLS['chip-tool']))
logging.debug('mfg_gen: {}'.format(TOOLS['mfg_gen'])) logging.debug('mfg_gen: {}'.format(TOOLS['mfg_gen']))
def execute_cmd(cmd): def execute_cmd(cmd):
@@ -457,46 +462,55 @@ def generate_partitions(suffix, size):
] ]
execute_cmd(cmd) execute_cmd(cmd)
def get_setup_payload_data(args, discriminator, passcode): def get_manualcode_args(args, discriminator, passcode):
data = 'version 0\n' payload_args = list()
data += 'vendorID ' + str(args.vendor_id) + '\n' payload_args.append('--discriminator')
data += 'productID ' + str(args.product_id) + '\n' payload_args.append(str(discriminator))
data += 'commissioningFlow ' + str(args.commissioning_flow) + '\n' payload_args.append('--setup-pin-code')
data += 'rendezVousInformation ' + str(1 << args.discovery_mode) + '\n' payload_args.append(str(passcode))
data += 'discriminator ' + str(discriminator) + '\n' payload_args.append('--version')
data += 'setUpPINCode ' + str(passcode) + '\n' payload_args.append('0')
return data payload_args.append('--vendor-id')
payload_args.append(str(args.vendor_id))
payload_args.append('--product-id')
payload_args.append(str(args.product_id))
payload_args.append('--commissioning-mode')
payload_args.append(str(args.commissioning_flow))
return payload_args
def get_chip_qrcode(file): def get_qrcode_args(args, discriminator, passcode):
data = subprocess.check_output([TOOLS['qrcodetool'], 'generate-qr-code', '-f', file]) payload_args = get_manualcode_args(args, discriminator, passcode)
data = data.decode('utf-8').splitlines() payload_args.append('--rendezvous')
qrcodeline = data[-1].split(': ') payload_args.append(str(1 << args.discovery_mode))
return payload_args
if qrcodeline[1] == 'QR Code': def get_chip_qrcode(payload_args):
return qrcodeline[-1] cmd_args = [TOOLS['chip-tool'], 'payload', 'generate-qrcode']
else: cmd_args.extend(payload_args)
logging.error('Failed to generate QR code') data = subprocess.check_output(cmd_args)
return None
def get_chip_manualcode(file): # Command output is as below:
data = subprocess.check_output([TOOLS['qrcodetool'], 'generate-manual-code', '-f', file]) # \x1b[0;32m[1655386003372] [23483:7823617] CHIP: [TOO] QR Code: MT:Y.K90-WB010E7648G00\x1b[0m
data = data.decode('utf-8').splitlines() return data.decode('utf-8').split('QR Code: ')[1][:QRCODE_LEN]
manualcodeline = data[-1].split(': ')
if manualcodeline[1] == 'Manual Code': def get_chip_manualcode(payload_args, commissioning_flow):
return manualcodeline[-1] cmd_args = [TOOLS['chip-tool'], 'payload', 'generate-manualcode']
else: cmd_args.extend(payload_args)
logging.error('Failed to generate manual code') data = subprocess.check_output(cmd_args)
return None
# Command output is as below:
# \x1b[0;32m[1655386909774] [24424:7837894] CHIP: [TOO] Manual Code: 749721123365521327689\x1b[0m\n
# OR
# \x1b[0;32m[1655386926028] [24458:7838229] CHIP: [TOO] Manual Code: 34972112338\x1b[0m\n
# Length of manual code depends on the commissioning flow:
# For standard commissioning flow it is 11 digits
# For User-intent and custom commissioning flow it is 21 digits
manual_code_len = LONG_MANUALCODE_LEN if commissioning_flow else SHORT_MANUALCODE_LEN
return data.decode('utf-8').split('Manual Code: ')[1][:manual_code_len]
def generate_onboarding_data(args, index, discriminator, passcode): def generate_onboarding_data(args, index, discriminator, passcode):
setup_payload_file = os.sep.join(['', 'tmp', 'setup_payload_{}.txt'.format(args.vendor_id, args.product_id)]) chip_manualcode = get_chip_manualcode(get_manualcode_args(args, discriminator, passcode), args.commissioning_flow)
chip_qrcode = get_chip_qrcode(get_qrcode_args(args, discriminator, passcode))
with open(setup_payload_file, 'w') as f:
f.write(get_setup_payload_data(args, discriminator, passcode))
chip_qrcode = get_chip_qrcode(setup_payload_file)
chip_manualcode = get_chip_manualcode(setup_payload_file)
logging.info('Generated QR code: ' + chip_qrcode) logging.info('Generated QR code: ' + chip_qrcode)
logging.info('Generated manual code: ' + chip_manualcode) logging.info('Generated manual code: ' + chip_manualcode)
@@ -514,7 +528,6 @@ def generate_onboarding_data(args, index, discriminator, passcode):
chip_qr = pyqrcode.create(chip_qrcode, version=2, error='M') chip_qr = pyqrcode.create(chip_qrcode, version=2, error='M')
chip_qr.png(qrcode_file, scale=6) chip_qr.png(qrcode_file, scale=6)
os.remove(setup_payload_file)
logging.info('Generated onboarding data and QR Code') logging.info('Generated onboarding data and QR Code')
def validate_args(args): def validate_args(args):