scripts: use std library for jam crc32 calculation
[openwrt/staging/hauke.git] / scripts / cfe-partition-tag.py
1 #!/usr/bin/env python3
2
3 """
4 CFE Partition Tag
5
6 {
7 u32 part_id;
8 u32 part_size;
9 u16 flags;
10 char part_name[33];
11 char part_version[21];
12 u32 part_crc32;
13 }
14
15 """
16
17 import argparse
18 import os
19 import struct
20 import binascii
21
22
23 PART_NAME_SIZE = 33
24 PART_VERSION_SIZE = 21
25
26
27 def auto_int(x):
28 return int(x, 0)
29
30 def str_to_bytes_pad(string, size):
31 str_bytes = string.encode()
32 num_bytes = len(str_bytes)
33 if (num_bytes >= size):
34 str_bytes = str_bytes[:size - 1] + '\0'.encode()
35 else:
36 str_bytes += '\0'.encode() * (size - num_bytes)
37 return str_bytes
38
39 def create_tag(args, in_bytes, size):
40 # JAM CRC32 is bitwise not and unsigned
41 crc = (~binascii.crc32(in_bytes) & 0xFFFFFFFF)
42
43 tag = bytearray()
44 tag += struct.pack('>I', args.part_id)
45 tag += struct.pack('>I', size)
46 tag += struct.pack('>H', args.part_flags)
47 tag += str_to_bytes_pad(args.part_name, PART_NAME_SIZE)
48 tag += str_to_bytes_pad(args.part_version, PART_VERSION_SIZE)
49 tag += struct.pack('>I', crc)
50
51 return tag
52
53 def create_output(args):
54 in_st = os.stat(args.input_file)
55 in_size = in_st.st_size
56
57 in_f = open(args.input_file, 'r+b')
58 in_bytes = in_f.read(in_size)
59 in_f.close()
60
61 tag = create_tag(args, in_bytes, in_size)
62
63 out_f = open(args.output_file, 'w+b')
64 out_f.write(tag)
65 out_f.close()
66
67 def main():
68 global args
69
70 parser = argparse.ArgumentParser(description='')
71
72 parser.add_argument('--flags',
73 dest='part_flags',
74 action='store',
75 type=auto_int,
76 help='Partition Flags')
77
78 parser.add_argument('--id',
79 dest='part_id',
80 action='store',
81 type=auto_int,
82 help='Partition ID')
83
84 parser.add_argument('--input-file',
85 dest='input_file',
86 action='store',
87 type=str,
88 help='Input file')
89
90 parser.add_argument('--output-file',
91 dest='output_file',
92 action='store',
93 type=str,
94 help='Output file')
95
96 parser.add_argument('--name',
97 dest='part_name',
98 action='store',
99 type=str,
100 help='Partition Name')
101
102 parser.add_argument('--version',
103 dest='part_version',
104 action='store',
105 type=str,
106 help='Partition Version')
107
108 args = parser.parse_args()
109
110 if ((not args.part_flags) or
111 (not args.part_id) or
112 (not args.input_file) or
113 (not args.output_file) or
114 (not args.part_name) or
115 (not args.part_version)):
116 parser.print_help()
117 else:
118 create_output(args)
119
120 main()