• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright 2020 The Pigweed Authors
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may not
5# use this file except in compliance with the License. You may obtain a copy of
6# the License at
7#
8#     https://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations under
14# the License.
15"""Decodes and detokenizes Base64-encoded strings in serial output.
16
17The output is printed or saved to a file. Input is not supported.
18"""
19
20import argparse
21import sys
22from typing import BinaryIO, Iterable
23
24import serial
25from pw_tokenizer import database, detokenize, tokens
26
27
28def _parse_args():
29    """Parses and return command line arguments."""
30
31    parser = argparse.ArgumentParser(
32        description=__doc__,
33        formatter_class=argparse.RawDescriptionHelpFormatter,
34        parents=[database.token_databases_parser()],
35    )
36    parser.add_argument(
37        '-d',
38        '--device',
39        required=True,
40        help='The serial device from which to read',
41    )
42    parser.add_argument(
43        '-b',
44        '--baudrate',
45        type=int,
46        default=115200,
47        help='The baud rate for the serial device',
48    )
49    parser.add_argument(
50        '-o',
51        '--output',
52        type=argparse.FileType('wb'),
53        default=sys.stdout.buffer,
54        help=(
55            'The file to which to write the output; '
56            'provide - or omit for stdout.'
57        ),
58    )
59    parser.add_argument(
60        '-p',
61        '--prefix',
62        default=detokenize.BASE64_PREFIX,
63        help=(
64            'The one-character prefix that signals the start of a '
65            'Base64-encoded message. (default: $)'
66        ),
67    )
68    parser.add_argument(
69        '-s',
70        '--show_errors',
71        action='store_true',
72        help=(
73            'Show error messages instead of conversion specifiers when '
74            'arguments cannot be decoded.'
75        ),
76    )
77
78    return parser.parse_args()
79
80
81def _detokenize_serial(
82    databases: Iterable,
83    device: str,
84    baudrate: int,
85    show_errors: bool,
86    output: BinaryIO,
87    prefix: str,
88) -> None:
89    if output is sys.stdout:
90        output = sys.stdout.buffer
91
92    detokenizer = detokenize.Detokenizer(
93        tokens.Database.merged(*databases), show_errors=show_errors
94    )
95    serial_device = serial.Serial(port=device, baudrate=baudrate)
96
97    try:
98        detokenizer.detokenize_base64_live(serial_device, output, prefix)
99    except KeyboardInterrupt:
100        output.flush()
101
102
103def main():
104    _detokenize_serial(**vars(_parse_args()))
105    return 0
106
107
108if __name__ == '__main__':
109    sys.exit(main())
110