blob: 653b7e0d3f9b69104a6ed32d48064c01f2592797 [file] [log] [blame]
Jon Salzf10ef792014-04-01 14:25:36 +08001#!/usr/bin/python
2#
3# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7
8"""A command-line tool for reg code handling."""
9
10
Jon Salz34008632014-07-08 16:27:40 +080011import base64
Jon Salz1c954152014-04-08 11:48:39 +080012import binascii
Jon Salz2fc97202014-04-21 16:42:59 +080013import logging
Jon Salz1c954152014-04-08 11:48:39 +080014import random
15import sys
16
Jon Salzf10ef792014-04-01 14:25:36 +080017import factory_common # pylint: disable=W0611
18from cros.factory.hacked_argparse import CmdArg, Command, ParseCmdline
Jon Salz1c954152014-04-08 11:48:39 +080019from cros.factory.proto import reg_code_pb2
Hung-Te Lincf12e8e2015-11-24 14:13:19 +080020from cros.factory.test import dut as dut_module
Hung-Te Lin3f096842016-01-13 17:37:06 +080021from cros.factory.test.rules import registration_codes
22from cros.factory.test.rules.registration_codes import RegistrationCode
Jon Salz2fc97202014-04-21 16:42:59 +080023from cros.factory.tools.build_board import BuildBoard
Hung-Te Lin4e6357c2016-01-08 14:32:00 +080024from cros.factory.utils import sys_utils
Jon Salzf10ef792014-04-01 14:25:36 +080025
26
27@Command('decode',
28 CmdArg('regcode', metavar='REGCODE',
29 help='Encoded registration code string'))
30def Decode(options):
31 reg_code = RegistrationCode(options.regcode)
32 if reg_code.proto:
33 print reg_code.proto
34 else:
35 print reg_code
36
37
Jon Salz1c954152014-04-08 11:48:39 +080038@Command(
Hung-Te Lin56b18402015-01-16 14:52:30 +080039 'generate-dummy',
40 CmdArg('--board', '-b', metavar='BOARD', required=True,
41 help=('Board to generate codes for. This must be exactly the '
42 'same as the HWID board name, except lowercase. For '
43 'boards with variants (like "daisy_spring"), use only '
44 'the variant name ("spring").')),
45 CmdArg('--type', '-t', metavar='TYPE', required=True,
46 choices=['unique', 'group'],
47 help='The type of code to generate (choices: %(choices)s)'),
48 CmdArg('--seed', '-s', metavar='INT', type=int, default=None,
49 help='Seed to use for pseudo-random payload; defaults to clock'))
Jon Salz1c954152014-04-08 11:48:39 +080050def GenerateDummy(options):
51 print ('*** This may be used only to generate a code for testing, '
52 'not for a real device.')
53 yes_no = raw_input('*** Are you OK with that? (yes/no) ')
54 if yes_no != 'yes':
55 print 'Aborting.'
56 sys.exit(1)
57
58 random.seed(options.seed)
59 proto = reg_code_pb2.RegCode()
60 proto.content.code_type = (reg_code_pb2.UNIQUE_CODE
61 if options.type == 'unique'
62 else reg_code_pb2.GROUP_CODE)
63
64 # Use this weird magic string for the first 16 characters to make it
65 # obvious that this is a dummy code. (Base64-encoding this string
66 # results in a reg code that looks like
Jon Salz34008632014-07-08 16:27:40 +080067 # '=CiwKIP______TESTING_______'...)
Jon Salz1c954152014-04-08 11:48:39 +080068 proto.content.code = (
Hung-Te Lin56b18402015-01-16 14:52:30 +080069 '\xff\xff\xff\xff\xffLD\x93 \xd1\xbf\xff\xff\xff\xff\xff' + ''.join(
70 chr(random.getrandbits(8))
71 for i in range(registration_codes.REGISTRATION_CODE_PAYLOAD_BYTES - 16)))
Jon Salz1c954152014-04-08 11:48:39 +080072 proto.content.device = options.board.lower()
73 proto.checksum = (
Hung-Te Lin56b18402015-01-16 14:52:30 +080074 binascii.crc32(proto.content.SerializeToString()) & 0xFFFFFFFF)
Jon Salz1c954152014-04-08 11:48:39 +080075
Jon Salz34008632014-07-08 16:27:40 +080076 encoded_string = '=' + base64.urlsafe_b64encode(
77 proto.SerializeToString()).strip()
Jon Salz1c954152014-04-08 11:48:39 +080078
79 # Make sure the string can be parsed as a sanity check (this will catch,
80 # e.g., invalid device names)
81 reg_code = RegistrationCode(encoded_string)
82 print
83 print reg_code.proto
84 print encoded_string
85
86
Jon Salz2fc97202014-04-21 16:42:59 +080087@Command(
Hung-Te Lin56b18402015-01-16 14:52:30 +080088 'check',
89 CmdArg(
90 '--unique-code', '-u', metavar='UNIQUE_CODE',
91 help='Unique/user code to check (default: ubind_attribute RW VPD value)'),
92 CmdArg(
93 '--group-code', '-g', metavar='GROUP_CODE',
94 help='Group code to check (default: gbind_attribute RW VPD value)'),
95 CmdArg(
96 '--board', '-b', metavar='BOARD',
97 help='Board to check (default: from .default_board or lsb-release)'))
Jon Salz2fc97202014-04-21 16:42:59 +080098def Check(options):
99 if not options.board:
100 options.board = BuildBoard().short_name
101 logging.info('Device name: %s', options.board)
102
103 rw_vpd = None
104 success = True
Hung-Te Lincf12e8e2015-11-24 14:13:19 +0800105 dut = dut_module.Create()
Jon Salz2fc97202014-04-21 16:42:59 +0800106
107 for code_type, vpd_attribute, code in (
108 (RegistrationCode.Type.UNIQUE_CODE,
109 'ubind_attribute', options.unique_code),
110 (RegistrationCode.Type.GROUP_CODE,
111 'gbind_attribute', options.group_code)):
112
113 if not code:
114 if rw_vpd is None:
Hung-Te Linf5f2d7f2016-01-08 17:12:46 +0800115 if sys_utils.InChroot():
Jon Salz2fc97202014-04-21 16:42:59 +0800116 sys.stderr.write('error: cannot read VPD from chroot; use -u/-g\n')
117 sys.exit(1)
118
Hung-Te Lincf12e8e2015-11-24 14:13:19 +0800119 rw_vpd = dut.vpd.rw.GetAll()
Jon Salz2fc97202014-04-21 16:42:59 +0800120 code = rw_vpd.get(vpd_attribute)
121 if not code:
122 sys.stderr.write('error: %s is not present in RW VPD\n' %
123 vpd_attribute)
124 sys.exit(1)
125
126 try:
127 registration_codes.CheckRegistrationCode(code, code_type, options.board)
128 logging.info('%s: success', code_type)
129 except registration_codes.RegistrationCodeException as e:
130 success = False
131 logging.error('%s: failed: %s', code_type, str(e))
132
133 sys.exit(0 if success else 1)
134
135
Jon Salzf10ef792014-04-01 14:25:36 +0800136def main():
Jon Salz2fc97202014-04-21 16:42:59 +0800137 logging.basicConfig(level=logging.INFO)
Jon Salzf10ef792014-04-01 14:25:36 +0800138 options = ParseCmdline('Registration code tool.')
139 options.command(options)
140
141
142if __name__ == '__main__':
143 main()