add logging capability
This commit is contained in:
parent
c760bf2fb3
commit
fb64863bbe
|
@ -49,6 +49,12 @@ CTRL-A is the escape character. CTRL-A + Q quits megacom. CTRL-A + CTRL-A sends
|
||||||
|
|
||||||
there will be more keyboard shortcuts later, hopefully
|
there will be more keyboard shortcuts later, hopefully
|
||||||
|
|
||||||
|
### non-tty mode
|
||||||
|
|
||||||
|
megacom can be run even if stdin is not a tty. in this mode, keyboard shortcuts (CTRL-A) are
|
||||||
|
disabled and input is passed through verbatim. this can be useful to pipe input and output out of a
|
||||||
|
UART device with programs that are not tty-aware
|
||||||
|
|
||||||
### baud
|
### baud
|
||||||
|
|
||||||
any standard baud rate (as an integer) which is supported by pyserial can be used. usually you want
|
any standard baud rate (as an integer) which is supported by pyserial can be used. usually you want
|
||||||
|
|
|
@ -2,6 +2,8 @@ import argparse
|
||||||
import asyncio
|
import asyncio
|
||||||
import contextlib
|
import contextlib
|
||||||
import errno
|
import errno
|
||||||
|
import fcntl
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
|
@ -31,29 +33,39 @@ MODE_LOOKUP = {
|
||||||
|
|
||||||
|
|
||||||
class TtyRaw:
|
class TtyRaw:
|
||||||
__slots__ = ["isatty", "fd", "settings"]
|
__slots__ = ["isatty", "infd", "outfd", "settings"]
|
||||||
isatty: bool
|
isatty: bool
|
||||||
fd: int
|
infd: int
|
||||||
|
outfd: int
|
||||||
settings: List[Any]
|
settings: List[Any]
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.isatty = False
|
self.isatty = False
|
||||||
self.fd = 0
|
self.infd = 0
|
||||||
|
self.outfd = 0
|
||||||
self.settings = []
|
self.settings = []
|
||||||
|
|
||||||
def __enter__(self) -> None:
|
def __enter__(self) -> 'TtyRaw':
|
||||||
if sys.stdin.isatty():
|
if sys.stdin.isatty():
|
||||||
self.isatty = True
|
self.isatty = True
|
||||||
self.fd = sys.stdin.fileno()
|
self.infd = sys.stdin.fileno()
|
||||||
self.settings = termios.tcgetattr(self.fd)
|
self.outfd = sys.stdout.fileno()
|
||||||
tty.setraw(self.fd)
|
self.settings = termios.tcgetattr(self.infd)
|
||||||
return None
|
tty.setraw(self.infd)
|
||||||
|
return self
|
||||||
|
|
||||||
def __exit__(self, exc_type: Optional[Type[BaseException]],
|
def __exit__(self, exc_type: Optional[Type[BaseException]],
|
||||||
exc_value: Optional[BaseException],
|
exc_value: Optional[BaseException],
|
||||||
exc_traceback: Optional[TracebackType]) -> Literal[False]:
|
exc_traceback: Optional[TracebackType]) -> Literal[False]:
|
||||||
if self.isatty:
|
if self.isatty:
|
||||||
termios.tcsetattr(self.fd, termios.TCSADRAIN, self.settings)
|
termios.tcsetattr(self.infd, termios.TCSADRAIN, self.settings)
|
||||||
|
# unset nonblocking modes
|
||||||
|
flags = fcntl.fcntl(self.infd, fcntl.F_GETFL)
|
||||||
|
flags = flags & (~os.O_NONBLOCK)
|
||||||
|
fcntl.fcntl(self.infd, fcntl.F_SETFL, flags)
|
||||||
|
flags = fcntl.fcntl(self.outfd, fcntl.F_GETFL)
|
||||||
|
flags = flags & (~os.O_NONBLOCK)
|
||||||
|
fcntl.fcntl(self.outfd, fcntl.F_SETFL, flags)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,15 +86,21 @@ ESC_CHAR = b"\x01"
|
||||||
|
|
||||||
|
|
||||||
class KeycodeHandler:
|
class KeycodeHandler:
|
||||||
__slots__ = ["exit_flag", "esc"]
|
__slots__ = ["exit_flag", "esc", "isatty"]
|
||||||
exit_flag: asyncio.Event
|
exit_flag: asyncio.Event
|
||||||
esc: bool
|
esc: bool
|
||||||
|
isatty: bool
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self, isatty: bool) -> None:
|
||||||
self.exit_flag = asyncio.Event()
|
self.exit_flag = asyncio.Event()
|
||||||
self.esc = False
|
self.esc = False
|
||||||
|
self.isatty = isatty
|
||||||
|
|
||||||
def process(self, byte: bytes) -> bytes:
|
def process(self, byte: bytes) -> bytes:
|
||||||
|
# only translate or eat input if stdin is actually a tty
|
||||||
|
if not self.isatty:
|
||||||
|
return byte
|
||||||
|
|
||||||
if self.esc:
|
if self.esc:
|
||||||
self.esc = False
|
self.esc = False
|
||||||
if byte == b"q":
|
if byte == b"q":
|
||||||
|
@ -104,7 +122,7 @@ class KeycodeHandler:
|
||||||
return byte
|
return byte
|
||||||
|
|
||||||
|
|
||||||
async def megacom(tty: str, baud: int, mode: str, logfile: Optional[str]) -> None:
|
async def megacom(ttyraw: TtyRaw, tty: str, baud: int, mode: str, logfile: Optional[str]) -> None:
|
||||||
(stdin, stdout) = await setup_async()
|
(stdin, stdout) = await setup_async()
|
||||||
|
|
||||||
m = MODE_RE.match(mode)
|
m = MODE_RE.match(mode)
|
||||||
|
@ -124,7 +142,7 @@ async def megacom(tty: str, baud: int, mode: str, logfile: Optional[str]) -> Non
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
keycodes = KeycodeHandler()
|
keycodes = KeycodeHandler(ttyraw.isatty)
|
||||||
|
|
||||||
loop.add_signal_handler(signal.SIGINT, lambda: keycodes.exit_flag.set())
|
loop.add_signal_handler(signal.SIGINT, lambda: keycodes.exit_flag.set())
|
||||||
|
|
||||||
|
@ -268,6 +286,6 @@ def main() -> None:
|
||||||
parser.add_argument("-l", "--logfile", type=str, default="", help="file to log to")
|
parser.add_argument("-l", "--logfile", type=str, default="", help="file to log to")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
with TtyRaw():
|
with TtyRaw() as ttyraw:
|
||||||
asyncio.run(megacom(args.tty, args.baud, args.mode,
|
asyncio.run(megacom(ttyraw, args.tty, args.baud, args.mode,
|
||||||
args.logfile if args.logfile != "" else None))
|
args.logfile if args.logfile != "" else None))
|
||||||
|
|
Loading…
Reference in New Issue