| #!/usr/bin/env python3 |
| # Copyright 2020 The Pigweed Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| """Decodes and detokenizes Base64-encoded strings in serial output. |
| |
| The output is printed or saved to a file. Input is not supported. |
| """ |
| |
| import argparse |
| import sys |
| from typing import BinaryIO, Iterable |
| |
| import serial # type: ignore |
| from pw_tokenizer import database, detokenize, tokens |
| |
| |
| def _parse_args(): |
| """Parses and return command line arguments.""" |
| |
| parser = argparse.ArgumentParser( |
| description=__doc__, |
| formatter_class=argparse.RawDescriptionHelpFormatter, |
| parents=[database.token_databases_parser()]) |
| parser.add_argument('-d', |
| '--device', |
| required=True, |
| help='The serial device from which to read') |
| parser.add_argument('-b', |
| '--baudrate', |
| type=int, |
| default=115200, |
| help='The baud rate for the serial device') |
| parser.add_argument('-o', |
| '--output', |
| type=argparse.FileType('wb'), |
| default=sys.stdout.buffer, |
| help=('The file to which to write the output; ' |
| 'provide - or omit for stdout.')) |
| parser.add_argument( |
| '-p', |
| '--prefix', |
| default=detokenize.BASE64_PREFIX, |
| help=('The one-character prefix that signals the start of a ' |
| 'Base64-encoded message. (default: $)')) |
| parser.add_argument( |
| '-s', |
| '--show_errors', |
| action='store_true', |
| help=('Show error messages instead of conversion specifiers when ' |
| 'arguments cannot be decoded.')) |
| |
| return parser.parse_args() |
| |
| |
| def _detokenize_serial(databases: Iterable, device: serial.Serial, |
| baudrate: int, show_errors: bool, output: BinaryIO, |
| prefix: str) -> None: |
| if output is sys.stdout: |
| output = sys.stdout.buffer |
| |
| detokenizer = detokenize.Detokenizer(tokens.Database.merged(*databases), |
| show_errors=show_errors) |
| serial_device = serial.Serial(port=device, baudrate=baudrate) |
| |
| try: |
| detokenizer.detokenize_base64_live(serial_device, output, prefix) |
| except KeyboardInterrupt: |
| output.flush() |
| |
| |
| def main(): |
| _detokenize_serial(**vars(_parse_args())) |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |