Skip to content

Commit 45c035e

Browse files
committed
Added command line arguments input support for cmake script
1 parent c5c68f3 commit 45c035e

File tree

4 files changed

+112
-20
lines changed

4 files changed

+112
-20
lines changed

config/esp32/components/chip/Kconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,7 @@ menu "CHIP Device Layer"
898898
default n
899899
help
900900
This option enables the system statistics to be sent to the insights cloud.
901-
901+
902902
config ENABLE_BUILD_TIME_PARTITION_SCRIPT
903903
bool "Enable script to build fctry and esp_secure_cert partition in during build time."
904904
default n

config/esp32/components/chip/factory.cmake

+41-13
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,52 @@ function(generate_build_time_partition fctry_partition esp_secure_cert_partition
3434
message(STATUS "secure_cert_partition_offset : ${secure_cert_partition_offset}")
3535

3636
if("${fctry_partition_size}" AND "${fctry_partition_offset}")
37-
set(MY_BULB_NAME "My bulb")
38-
set(VENDOR_NAME "Test-vendor")
39-
set(HARDWARE_VERSION 1)
40-
set(HARDWARE_VERSION_STR "Devkit")
41-
set(VENDOR_ID 0xFFF2)
42-
set(PRODUCT_ID 0x8001)
43-
set(DAC_CERT "${chip_root_abs_path}/credentials/test/attestation/Chip-Test-DAC-FFF2-8001-0008-Cert.der")
44-
set(DAC_KEY "${chip_root_abs_path}/credentials/test/attestation/Chip-Test-DAC-FFF2-8001-0008-Key.der")
45-
set(PAI_CERT "${chip_root_abs_path}/credentials/test/attestation/Chip-Test-PAI-FFF2-8001-Cert.der")
46-
set(CERT_DCLRN "${chip_root_abs_path}/credentials/test/certification-declaration/Chip-Test-CD-FFF2-8001.der")
47-
set(PASSCODE 20202020)
48-
set(DISCRIMINATOR 3841)
37+
set(DEFAULT_DEVICE_NAME "My bulb")
38+
set(DEFAULT_VENDOR_NAME "Test-vendor")
39+
set(DEFAULT_HARDWARE_VERSION 1)
40+
set(DEFAULT_HARDWARE_VERSION_STR "Devkit")
41+
set(DEFAULT_VENDOR_ID 0xFFF2)
42+
set(DEFAULT_PRODUCT_ID 0x8001)
43+
set(DEFAULT_DAC_CERT "${chip_root_abs_path}/credentials/test/attestation/Chip-Test-DAC-FFF2-8001-0008-Cert.der")
44+
set(DEFAULT_DAC_KEY "${chip_root_abs_path}/credentials/test/attestation/Chip-Test-DAC-FFF2-8001-0008-Key.der")
45+
set(DEFAULT_PAI_CERT "${chip_root_abs_path}/credentials/test/attestation/Chip-Test-PAI-FFF2-8001-Cert.der")
46+
set(DEFAULT_CERT_DCLRN "${chip_root_abs_path}/credentials/test/certification-declaration/Chip-Test-CD-FFF2-8001.der")
47+
set(DEFAULT_PASSCODE 20202020)
48+
set(DEFAULT_DISCRIMINATOR 3841)
49+
50+
set(DEVICE_NAME ${DEFAULT_DEVICE_NAME} CACHE STRING "My bulb")
51+
set(VENDOR_NAME ${DEFAULT_VENDOR_NAME} CACHE STRING "Test-vendor")
52+
set(HARDWARE_VERSION ${DEFAULT_HARDWARE_VERSION} CACHE STRING 1)
53+
set(HARDWARE_VERSION_STR ${DEFAULT_HARDWARE_VERSION_STR} CACHE STRING "Devkit")
54+
set(VENDOR_ID ${DEFAULT_VENDOR_ID} CACHE STRING 0xFFF2)
55+
set(PRODUCT_ID ${DEFAULT_PRODUCT_ID} CACHE STRING 0x8001)
56+
set(DAC_CERT ${DEFAULT_DAC_CERT} CACHE STRING "${chip_root_abs_path}/credentials/test/attestation/Chip-Test-DAC-FFF2-8001-0008-Cert.der")
57+
set(DAC_KEY ${DEFAULT_DAC_KEY} CACHE STRING "${chip_root_abs_path}/credentials/test/attestation/Chip-Test-DAC-FFF2-8001-0008-Key.der")
58+
set(PAI_CERT ${DEFAULT_PAI_CERT} CACHE STRING "${chip_root_abs_path}/credentials/test/attestation/Chip-Test-PAI-FFF2-8001-Cert.der")
59+
set(CERT_DCLRN ${DEFAULT_CERT_DCLRN} CACHE STRING "${chip_root_abs_path}/credentials/test/certification-declaration/Chip-Test-CD-FFF2-8001.der")
60+
set(PASSCODE ${DEFAULT_PASSCODE} CACHE STRING 20202020)
61+
set(DISCRIMINATOR ${DEFAULT_DISCRIMINATOR} CACHE STRING 3841)
62+
63+
message(STATUS "Bulb Name: ${DEVICE_NAME}")
64+
message(STATUS "Vendor Name: ${VENDOR_NAME}")
65+
message(STATUS "Hardware Version: ${HARDWARE_VERSION}")
66+
message(STATUS "Hardware Version String: ${HARDWARE_VERSION_STR}")
67+
message(STATUS "Vendor ID: ${VENDOR_ID}")
68+
message(STATUS "Product ID: ${PRODUCT_ID}")
69+
message(STATUS "DAC Cert: ${DAC_CERT}")
70+
message(STATUS "DAC Key: ${DAC_KEY}")
71+
message(STATUS "PAI Cert: ${PAI_CERT}")
72+
message(STATUS "Certification Declaration: ${CERT_DCLRN}")
73+
message(STATUS "Passcode: ${PASSCODE}")
74+
message(STATUS "Discriminator: ${DISCRIMINATOR}")
75+
4976

5077
# Execute Factory partition image generation; this always executes as there is no way to specify for CMake to watch for
5178
# contents of the base dir changing.
5279
add_custom_target(build_time_partition ALL
5380
COMMAND ${generate_esp32_chip_factory_bin.py} -d ${DISCRIMINATOR}
5481
-p ${PASSCODE}
55-
--product-name "${MY_BULB_NAME}"
82+
--product-name "${DEVICE_NAME}"
5683
--vendor-name "${VENDOR_NAME}"
5784
--vendor-id ${VENDOR_ID}
5885
--product-id ${PRODUCT_ID}
@@ -66,6 +93,7 @@ function(generate_build_time_partition fctry_partition esp_secure_cert_partition
6693
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
6794
)
6895

96+
6997
set(factory_partition_bin ${CMAKE_BINARY_DIR}/bin/factory_partition.bin)
7098
set(esp_secure_cert_partition_bin ${CMAKE_BINARY_DIR}/bin/esp_secure_cert_partititon.bin)
7199
idf_component_get_property(main_args esptool_py FLASH_ARGS)

scripts/setup/requirements.esp32.txt

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ reedsolo>=1.5.3,<=1.5.4
99
bitstring>=3.1.6,<4
1010
ecdsa>=0.16.0
1111
construct==2.10.54
12+
pypng==0.0.21
13+
PyQRCode==1.2.1
1214
python-socketio<5
1315
itsdangerous<2.1 ; python_version < "3.11"
1416
esp_idf_monitor==1.1.1

scripts/tools/generate_esp32_chip_factory_bin.py

+68-6
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@
1818

1919
import argparse
2020
import base64
21+
import csv
2122
import enum
23+
import hashlib
24+
import json
2225
import logging
2326
import os
27+
import pyqrcode
2428
import sys
25-
from types import SimpleNamespace
2629

30+
from types import SimpleNamespace
2731
import cryptography.x509
2832
from bitarray import bitarray
2933
from bitarray.util import ba2int
@@ -32,6 +36,8 @@
3236
CHIP_TOPDIR = os.path.dirname(os.path.realpath(__file__))[:-len(os.path.join('scripts', 'tools'))]
3337
sys.path.insert(0, os.path.join(CHIP_TOPDIR, 'scripts', 'tools', 'spake2p'))
3438
from spake2p import generate_verifier # noqa: E402 isort:skip
39+
sys.path.insert(0,os.path.join(CHIP_TOPDIR, 'src', 'setup_payload','python'))
40+
from generate_setup_payload import SetupPayload, CommissioningFlow
3541

3642
if os.getenv('IDF_PATH'):
3743
sys.path.insert(0, os.path.join(os.getenv('IDF_PATH'),
@@ -48,11 +54,13 @@
4854

4955
TOOLS = {}
5056

51-
5257
FACTORY_PARTITION_CSV = 'nvs_partition.csv'
5358
FACTORY_PARTITION_BIN = 'factory_partition.bin'
5459
NVS_KEY_PARTITION_BIN = 'nvs_key_partition.bin'
5560
ESP_SECURE_CERT_PARTITION_BIN = 'esp_secure_cert_partititon.bin'
61+
CONFIG_FILE = 'config.json'
62+
ONBOARDING_DATA_FILE = 'onboarding_codes.csv'
63+
QROCDE_FILE = 'qrcode.png'
5664

5765
FACTORY_DATA = {
5866
# CommissionableDataProvider
@@ -167,6 +175,25 @@
167175
}
168176

169177

178+
def save_config(args):
179+
with open(CONFIG_FILE, 'w') as config_file:
180+
json.dump(vars(args), config_file)
181+
182+
def load_config():
183+
try:
184+
with open(CONFIG_FILE, 'r') as config_file:
185+
return json.load(config_file)
186+
except FileNotFoundError:
187+
return None
188+
189+
def calculate_hash(data):
190+
return hashlib.sha256(data.encode('utf-8')).hexdigest()
191+
192+
193+
def args_changed(current_args, saved_args):
194+
return calculate_hash(json.dumps(vars(current_args))) != calculate_hash(json.dumps(saved_args))
195+
196+
170197
class CalendarTypes(enum.Enum):
171198
Buddhist = 0
172199
Chinese = 1
@@ -602,6 +629,12 @@ def any_base_int(s): return int(s, 0)
602629
help='Do not generate the factory partition binary')
603630
parser.add_argument('--output_dir', type=str, default='bin', help='Created image output file path')
604631

632+
parser.add_argument('-cf', '--commissioning-flow', type=any_base_int, default=0,
633+
help='Device commissioning flow, 0:Standard, 1:User-Intent, 2:Custom. \
634+
Default is 0.', choices=[0, 1, 2])
635+
parser.add_argument('-dm', '--discovery-mode', type=any_base_int, default=1,
636+
help='Commissionable device discovery networking technology. \
637+
0:WiFi-SoftAP, 1:BLE, 2:On-network. Default is BLE.', choices=[0, 1, 2])
605638
parser.set_defaults(generate_bin=True)
606639

607640
return parser.parse_args()
@@ -632,13 +665,42 @@ def generate_factory_partiton_binary(args):
632665
def set_up_out_dirs(args):
633666
os.makedirs(args.output_dir, exist_ok=True)
634667

668+
def generate_onboarding_data(args):
669+
payloads = SetupPayload(args.discriminator, args.passcode, args.discovery_mode, CommissioningFlow(args.commissioning_flow),
670+
args.vendor_id, args.product_id)
671+
logging.info('Discovery mode' + str(args.discovery_mode))
672+
chip_qrcode = payloads.generate_qrcode()
673+
chip_manualcode = payloads.generate_manualcode()
674+
# ToDo: remove this if qrcode tool can handle the standard manual code format
675+
if args.commissioning_flow == CommissioningFlow.Standard:
676+
chip_manualcode = chip_manualcode[:4] + '-' + chip_manualcode[4:7] + '-' + chip_manualcode[7:]
677+
else:
678+
chip_manualcode = '"' + chip_manualcode[:4] + '-' + chip_manualcode[4:7] + '-' + chip_manualcode[7:11] + '\n' + chip_manualcode[11:15] + '-' + chip_manualcode[15:18] + '-' + chip_manualcode[18:20] + '-' + chip_manualcode[20:21] + '"'
679+
680+
logging.info('Generated QR code: ' + chip_qrcode)
681+
logging.info('Generated manual code: ' + chip_manualcode)
682+
683+
csv_data = 'qrcode,manualcode,discriminator,passcode\n'
684+
csv_data += chip_qrcode + ',' + chip_manualcode + ',' + str(args.discriminator) + ',' + str(args.passcode) + '\n'
685+
686+
with open(os.path.join(args.output_dir,ONBOARDING_DATA_FILE), 'w') as f:
687+
f.write(csv_data)
688+
689+
chip_qr = pyqrcode.create(chip_qrcode, version=2, error='M')
690+
chip_qr.png(os.path.join(args.output_dir,QROCDE_FILE), scale=6)
691+
635692

636693
def main():
694+
saved_args = load_config()
637695
args = get_args()
638-
set_up_out_dirs(args)
639-
set_up_factory_data(args)
640-
generate_factory_partiton_binary(args)
641-
696+
if saved_args is None or args_changed(args, saved_args):
697+
set_up_out_dirs(args)
698+
set_up_factory_data(args)
699+
generate_factory_partiton_binary(args)
700+
generate_onboarding_data(args)
701+
save_config(args)
702+
else:
703+
logging.info("No changes in arguments. Skipping partition generation.")
642704

643705
if __name__ == "__main__":
644706
logging.basicConfig(format='[%(asctime)s] [%(levelname)7s] - %(message)s', level=logging.INFO)

0 commit comments

Comments
 (0)