|
18 | 18 |
|
19 | 19 | import argparse
|
20 | 20 | import base64
|
| 21 | +import enum |
21 | 22 | import logging
|
22 | 23 | import os
|
23 | 24 | import sys
|
24 | 25 | from types import SimpleNamespace
|
25 | 26 |
|
26 | 27 | import cryptography.x509
|
| 28 | +from bitarray import bitarray |
| 29 | +from bitarray.util import ba2int |
27 | 30 | from esp_secure_cert.tlv_format import generate_partition_ds, generate_partition_no_ds, tlv_priv_key_t, tlv_priv_key_type_t
|
28 | 31 |
|
29 | 32 | CHIP_TOPDIR = os.path.dirname(os.path.realpath(__file__))[:-len(os.path.join('scripts', 'tools'))]
|
|
149 | 152 | 'encoding': 'hex2bin',
|
150 | 153 | 'value': None,
|
151 | 154 | },
|
| 155 | + # DeviceInfoProvider |
| 156 | + 'cal-types': { |
| 157 | + 'type': 'data', |
| 158 | + 'encoding': 'u32', |
| 159 | + 'value': None, |
| 160 | + }, |
| 161 | + 'locale-sz': { |
| 162 | + 'type': 'data', |
| 163 | + 'encoding': 'u32', |
| 164 | + 'value': None, |
| 165 | + }, |
| 166 | + |
| 167 | + # Other device info provider keys are dynamically generated |
| 168 | + # in the respective functions. |
152 | 169 | }
|
153 | 170 |
|
154 | 171 |
|
| 172 | +class CalendarTypes(enum.Enum): |
| 173 | + Buddhist = 0 |
| 174 | + Chinese = 1 |
| 175 | + Coptic = 2 |
| 176 | + Ethiopian = 3 |
| 177 | + Gregorian = 4 |
| 178 | + Hebrew = 5 |
| 179 | + Indian = 6 |
| 180 | + Islamic = 7 |
| 181 | + Japanese = 8 |
| 182 | + Korean = 9 |
| 183 | + Persian = 10 |
| 184 | + Taiwanese = 11 |
| 185 | + |
| 186 | + |
| 187 | +# Supported Calendar types is stored as a bit array in one uint32_t. |
| 188 | +def calendar_types_to_uint32(calendar_types): |
| 189 | + result = bitarray(32, endian='little') |
| 190 | + result.setall(0) |
| 191 | + for calendar_type in calendar_types: |
| 192 | + try: |
| 193 | + result[CalendarTypes[calendar_type].value] = 1 |
| 194 | + except KeyError: |
| 195 | + logging.error('Unknown calendar type: %s', calendar_type) |
| 196 | + logging.error('Supported calendar types: %s', ', '.join(CalendarTypes.__members__)) |
| 197 | + sys.exit(1) |
| 198 | + return ba2int(result) |
| 199 | + |
| 200 | + |
155 | 201 | def ishex(s):
|
156 | 202 | try:
|
157 | 203 | _ = int(s, 16)
|
158 | 204 | return True
|
159 | 205 | except ValueError:
|
160 | 206 | return False
|
161 | 207 |
|
| 208 | +# get_fixed_label_dict() converts the list of strings to per endpoint dictionaries. |
| 209 | +# example input : ['0/orientation/up', '1/orientation/down', '2/orientation/down'] |
| 210 | +# example output : {'0': [{'orientation': 'up'}], '1': [{'orientation': 'down'}], '2': [{'orientation': 'down'}]} |
| 211 | + |
| 212 | + |
| 213 | +def get_fixed_label_dict(fixed_labels): |
| 214 | + fl_dict = {} |
| 215 | + for fl in fixed_labels: |
| 216 | + _l = fl.split('/') |
| 217 | + |
| 218 | + if len(_l) != 3: |
| 219 | + logging.error('Invalid fixed label: %s', fl) |
| 220 | + sys.exit(1) |
| 221 | + |
| 222 | + if not (ishex(_l[0]) and (len(_l[1]) > 0 and len(_l[1]) < 16) and (len(_l[2]) > 0 and len(_l[2]) < 16)): |
| 223 | + logging.error('Invalid fixed label: %s', fl) |
| 224 | + sys.exit(1) |
| 225 | + |
| 226 | + if _l[0] not in fl_dict.keys(): |
| 227 | + fl_dict[_l[0]] = list() |
| 228 | + |
| 229 | + fl_dict[_l[0]].append({_l[1]: _l[2]}) |
| 230 | + |
| 231 | + return fl_dict |
| 232 | + |
162 | 233 | # get_supported_modes_dict() converts the list of strings to per endpoint dictionaries.
|
163 | 234 | # example with semantic tags
|
164 | 235 | # input : ['0/label1/1/"1\0x8000, 2\0x8000" 1/label2/1/"1\0x8000, 2\0x8000"']
|
@@ -302,6 +373,52 @@ def populate_factory_data(args, spake2p_params):
|
302 | 373 | if args.hw_ver_str:
|
303 | 374 | FACTORY_DATA['hw-ver-str']['value'] = args.hw_ver_str
|
304 | 375 |
|
| 376 | + if args.calendar_types: |
| 377 | + FACTORY_DATA['cal-types']['value'] = calendar_types_to_uint32(args.calendar_types) |
| 378 | + |
| 379 | + # Supported locale is stored as multiple entries, key format: "locale/<index>, example key: "locale/0" |
| 380 | + if args.locales: |
| 381 | + FACTORY_DATA['locale-sz']['value'] = len(args.locales) |
| 382 | + |
| 383 | + for i in range(len(args.locales)): |
| 384 | + _locale = { |
| 385 | + 'type': 'data', |
| 386 | + 'encoding': 'string', |
| 387 | + 'value': args.locales[i] |
| 388 | + } |
| 389 | + FACTORY_DATA.update({'locale/{:x}'.format(i): _locale}) |
| 390 | + |
| 391 | + # Each endpoint can contains the fixed lables |
| 392 | + # - fl-sz/<index> : number of fixed labels for the endpoint |
| 393 | + # - fl-k/<ep>/<index> : fixed label key for the endpoint and index |
| 394 | + # - fl-v/<ep>/<index> : fixed label value for the endpoint and index |
| 395 | + if args.fixed_labels: |
| 396 | + dict = get_fixed_label_dict(args.fixed_labels) |
| 397 | + for key in dict.keys(): |
| 398 | + _sz = { |
| 399 | + 'type': 'data', |
| 400 | + 'encoding': 'u32', |
| 401 | + 'value': len(dict[key]) |
| 402 | + } |
| 403 | + FACTORY_DATA.update({'fl-sz/{:x}'.format(int(key)): _sz}) |
| 404 | + |
| 405 | + for i in range(len(dict[key])): |
| 406 | + entry = dict[key][i] |
| 407 | + |
| 408 | + _label_key = { |
| 409 | + 'type': 'data', |
| 410 | + 'encoding': 'string', |
| 411 | + 'value': list(entry.keys())[0] |
| 412 | + } |
| 413 | + _label_value = { |
| 414 | + 'type': 'data', |
| 415 | + 'encoding': 'string', |
| 416 | + 'value': list(entry.values())[0] |
| 417 | + } |
| 418 | + |
| 419 | + FACTORY_DATA.update({'fl-k/{:x}/{:x}'.format(int(key), i): _label_key}) |
| 420 | + FACTORY_DATA.update({'fl-v/{:x}/{:x}'.format(int(key), i): _label_value}) |
| 421 | + |
305 | 422 | # SupportedModes are stored as multiple entries
|
306 | 423 | # - sm-sz/<ep> : number of supported modes for the endpoint
|
307 | 424 | # - sm-label/<ep>/<index> : supported modes label key for the endpoint and index
|
@@ -467,6 +584,13 @@ def any_base_int(s): return int(s, 0)
|
467 | 584 | help=('128-bit unique identifier for generating rotating device identifier, '
|
468 | 585 | 'provide 32-byte hex string, e.g. "1234567890abcdef1234567890abcdef"'))
|
469 | 586 |
|
| 587 | + # These will be used by DeviceInfoProvider |
| 588 | + parser.add_argument('--calendar-types', nargs='+', |
| 589 | + help=('List of supported calendar types.\nSupported Calendar Types: Buddhist, Chinese, Coptic, Ethiopian, ' |
| 590 | + 'Gregorian, Hebrew, Indian, Islamic, Japanese, Korean, Persian, Taiwanese')) |
| 591 | + parser.add_argument('--locales', nargs='+', help='List of supported locales, Language Tag as defined by BCP47, eg. en-US en-GB') |
| 592 | + parser.add_argument('--fixed-labels', nargs='+', |
| 593 | + help='List of fixed labels, eg: "0/orientation/up" "1/orientation/down" "2/orientation/down"') |
470 | 594 | parser.add_argument('--supported-modes', type=str, nargs='+', required=False,
|
471 | 595 | help='List of supported modes, eg: mode1/label1/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode2/label2/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode3/label3/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode"')
|
472 | 596 |
|
|
0 commit comments