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, encode, 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=encode.NESTED_TOKEN_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), 94 prefix=prefix, 95 show_errors=show_errors, 96 ) 97 serial_device = serial.Serial(port=device, baudrate=baudrate) 98 99 try: 100 detokenizer.detokenize_base64_live(serial_device, output) 101 except KeyboardInterrupt: 102 output.flush() 103 104 105def main(): 106 _detokenize_serial(**vars(_parse_args())) 107 return 0 108 109 110if __name__ == '__main__': 111 sys.exit(main()) 112