otp.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/usr/bin/env python3
  2. import logging
  3. import argparse
  4. import os
  5. import sys
  6. import re
  7. import struct
  8. import datetime
  9. class Main:
  10. def __init__(self):
  11. # command args
  12. self.parser = argparse.ArgumentParser()
  13. self.parser.add_argument("-d", "--debug", action="store_true", help="Debug")
  14. self.subparsers = self.parser.add_subparsers(help="sub-command help")
  15. self.parser_generate = self.subparsers.add_parser(
  16. "generate", help="OTP HW version generator"
  17. )
  18. self.parser_generate.add_argument(
  19. "--version", type=int, help="Version", required=True
  20. )
  21. self.parser_generate.add_argument(
  22. "--firmware", type=int, help="Firmware", required=True
  23. )
  24. self.parser_generate.add_argument(
  25. "--body", type=int, help="Body", required=True
  26. )
  27. self.parser_generate.add_argument(
  28. "--connect", type=int, help="Connect", required=True
  29. )
  30. self.parser_generate.add_argument(
  31. "--name", type=str, help="Name", required=True
  32. )
  33. self.parser_generate.add_argument("file", help="Output file")
  34. self.parser_generate.set_defaults(func=self.generate)
  35. # logging
  36. self.logger = logging.getLogger()
  37. def __call__(self):
  38. self.args = self.parser.parse_args()
  39. if "func" not in self.args:
  40. self.parser.error("Choose something to do")
  41. # configure log output
  42. self.log_level = logging.DEBUG if self.args.debug else logging.INFO
  43. self.logger.setLevel(self.log_level)
  44. self.handler = logging.StreamHandler(sys.stdout)
  45. self.handler.setLevel(self.log_level)
  46. self.formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(message)s")
  47. self.handler.setFormatter(self.formatter)
  48. self.logger.addHandler(self.handler)
  49. # execute requested function
  50. self.args.func()
  51. def generate(self):
  52. self.logger.debug(f"Generating OTP")
  53. if self.args.name:
  54. name = re.sub(
  55. "[^a-zA-Z0-9.]", "", self.args.name
  56. ) # Filter all special characters
  57. name = list(
  58. map(str, map(ord, name[0:8]))
  59. ) # Strip to 8 chars and map to ascii codes
  60. while len(name) < 8:
  61. name.append("0")
  62. n1, n2, n3, n4, n5, n6, n7, n8 = map(int, name)
  63. data = struct.pack(
  64. "<BBBBLBBBBBBBB",
  65. self.args.version,
  66. self.args.firmware,
  67. self.args.body,
  68. self.args.connect,
  69. int(datetime.datetime.now().timestamp()),
  70. n1,
  71. n2,
  72. n3,
  73. n4,
  74. n5,
  75. n6,
  76. n7,
  77. n8,
  78. )
  79. open(self.args.file, "wb").write(data)
  80. if __name__ == "__main__":
  81. Main()()