blob: 41dae95f52bce3cfedfd182842878d08cb7dd14f [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 Salz1c954152014-04-08 11:48:39 +080011import binascii
12import random
13import sys
14
Jon Salzf10ef792014-04-01 14:25:36 +080015import factory_common # pylint: disable=W0611
16from cros.factory.hacked_argparse import CmdArg, Command, ParseCmdline
Jon Salz1c954152014-04-08 11:48:39 +080017from cros.factory.proto import reg_code_pb2
18from cros.factory.test import registration_codes
Jon Salzf10ef792014-04-01 14:25:36 +080019from cros.factory.test.registration_codes import RegistrationCode
20
21
22@Command('decode',
23 CmdArg('regcode', metavar='REGCODE',
24 help='Encoded registration code string'))
25def Decode(options):
26 reg_code = RegistrationCode(options.regcode)
27 if reg_code.proto:
28 print reg_code.proto
29 else:
30 print reg_code
31
32
Jon Salz1c954152014-04-08 11:48:39 +080033@Command(
34 'generate-dummy',
35 CmdArg('--board', '-b', metavar='BOARD', required=True,
36 help=('Board to generate codes for. This must be exactly the '
37 'same as the HWID board name, except lowercase. For '
38 'boards with variants (like "daisy_spring"), use only '
39 'the variant name ("spring").')),
40 CmdArg('--type', '-t', metavar='TYPE', required=True,
41 choices=['unique', 'group'],
42 help='The type of code to generate (choices: %(choices)s)'),
43 CmdArg('--seed', '-s', metavar='INT', type=int, default=None,
44 help='Seed to use for pseudo-random payload; defaults to clock'))
45def GenerateDummy(options):
46 print ('*** This may be used only to generate a code for testing, '
47 'not for a real device.')
48 yes_no = raw_input('*** Are you OK with that? (yes/no) ')
49 if yes_no != 'yes':
50 print 'Aborting.'
51 sys.exit(1)
52
53 random.seed(options.seed)
54 proto = reg_code_pb2.RegCode()
55 proto.content.code_type = (reg_code_pb2.UNIQUE_CODE
56 if options.type == 'unique'
57 else reg_code_pb2.GROUP_CODE)
58
59 # Use this weird magic string for the first 16 characters to make it
60 # obvious that this is a dummy code. (Base64-encoding this string
61 # results in a reg code that looks like
62 # '=CiwKIP//////TESTING///////'...)
63 proto.content.code = (
64 '\xff\xff\xff\xff\xffLD\x93 \xd1\xbf\xff\xff\xff\xff\xff' + "".join(
65 chr(random.getrandbits(8))
66 for i in range(registration_codes.REGISTRATION_CODE_PAYLOAD_BYTES - 16)))
67 proto.content.device = options.board.lower()
68 proto.checksum = (
69 binascii.crc32(proto.content.SerializeToString()) & 0xFFFFFFFF)
70
71 encoded_string = '=' + binascii.b2a_base64(proto.SerializeToString()).strip()
72
73 # Make sure the string can be parsed as a sanity check (this will catch,
74 # e.g., invalid device names)
75 reg_code = RegistrationCode(encoded_string)
76 print
77 print reg_code.proto
78 print encoded_string
79
80
Jon Salzf10ef792014-04-01 14:25:36 +080081def main():
82 options = ParseCmdline('Registration code tool.')
83 options.command(options)
84
85
86if __name__ == '__main__':
87 main()