view doc/Rvinterf-tools @ 909:1e9fe07f8f09

doc/Voice-memo-utils: new article
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 29 Dec 2022 21:03:11 +0000
parents ad503b495e3e
children 71edc12b1aa7
line wrap: on
line source

This document describes the basic usage principles for our rvinterf suite of
tools, which is the subset of FC host tools for talking to TI-based GSM devices
via the RVTMUX binary packet interface.

rvtdump
=======

Rvtdump is a utility that listens on a serial port, receives traces or any other
packets emitted by the running firmware of a GSM device in TI's RVTMUX format,
decodes them into readable ASCII and emits them to stdout and/or to a log file.
It is to be invoked as follows:

rvtdump [options] /dev/ttyXXX

where the sole non-option argument is the serial port it should open and listen
on.

The available options are:

-b

	Normally the rvtdump process remains in the foreground and emits its
	output on stdout.  The -b option suppresses the normal output and causes
	rvtdump to put itself in the background: fork at startup, then have the
	parent exit while the child remains running.  -b is not useful and not
	allowed without -l.

-B baud

	Selects which RVTMUX serial channel baud rate our tool should listen
	for.  Defaults to 115200 baud, which is TI's default and is correct for
	our standard FreeCalypso firmwares, for Openmoko's legacy firmwares and
	for Pirelli's proprietary fw.  Use -B 57600 for Compal's RVTMUX, the
	one accessible via **16379#.

-d <file descriptor number>

	This option is not meant for direct use by human users.  It is inserted
	automatically when rvtdump is launched from fc-xram as the secondary
	program that immediately takes over the serial channel.

-l logfile

	Log all received and decoded packets into the specified file in addition
	to (without -b) or instead of (with -b) dumping them on stdout.  Each
	line in the log file is also time-stamped; the timestamps are in GMT
	(gmtime(3)) instead of local time - Spacefalcon the Outlaw dislikes
	local times.

rvinterf
========

Rvinterf (the specific program by this name) is an extended version of rvtdump
(see above) that decodes and dumps and/or logs any and all output generated by
the firmware running on the target just like rvtdump, but also creates a local
UNIX domain socket on the host machine to which "client" programs can connect.
"Client" programs connecting to rvinterf via this local socket interface can:

1. Receive copies of selected RVTMUX packets coming from the target;

2. Send arbitrary RVTMUX packets toward the target.

Rvinterf is invoked just like rvtdump:

rvinterf [options] /dev/ttyXXX

The following options have the same meaning as in rvtdump, see the rvtdump
section above for the details: -b, -B, -d and -l.  The only difference is that
-b without -l is potentially useful and thus allowed.  Additionally rvinterf -b
records the PID of the backgrounded process in /tmp/rvinterf.pid (inability to
write to this file produces a non-fatal warning); the intended use case is for
scripts that run rvinterf -b (perhaps as fc-xram secondary program with the FFS
editor application), perform some fc-fsio or other manipulations, and then kill
the backgrounded rvinterf process.

Additional rvinterf options which don't exist in rvtdump are:

-n

	Suppress the output on stdout like -b, but don't fork into background.
	This option is passed by "client" programs when they invoke rvinterf
	behind the scenes instead of connecting to an already-running rvinterf
	instance.

-P <boot control name>

	See Target-boot-control article.

-s pathname_for_socket

	By default the local UNIX domain socket created by rvinterf is bound to
	/tmp/rvinterf_socket; this option allows any other pathname to be
	specified.

-S <file descriptor number>

	This option is not meant for direct use by human users.  It is passed
	by "client" programs when they invoke rvinterf behind the scenes with
	an unnamed and unbound socket pair instead of connecting to an already-
	running rvinterf instance.

-w number_in_seconds

	Reliable UART communication with a Calypso GSM device that can
	potentially enter the so-called "deep sleep" mode requires certain
	special workarounds that could be described as a bit of an ugly hack:
	see the Deep-sleep-support article for the gory details.  The hack
	implemented in rvinterf is as follows: if a packet is to be sent to the
	target and more than a set time has elapsed since the last transmitted
	packet, the packet is preceded by a "wake-up shot" of 64 0 bytes
	(outside of a packet, ignored by the fw) and a 100 ms pause.

	The -w option changes the elapsed time threshold at which the "wake-up
	shot" is sent; the default is 7 s.  Specify -w 0 to disable this hack
	altogether.

Client programs
===============

We have an entire family of so-called "client" programs which connect to
rvinterf via the local socket interface and use rvinterf as the back-end engine
for communicating with GSM device firmwares.  The main ones are fc-fsio,
fc-shell and fc-tmsh described in the RVTMUX article, and the less important
ones are fc-memdump, fc-dspapidump, fc-readcal and fc-tmsync listed in
Host-tools-overview.  There is also the fcup-rvtat program which is invoked
behind the scenes by fcup-* tools (see User-phone-tools) when they are used
with the -R option.

All of these client programs can work in one of two ways: they can connect to
an already running rvinterf process through the UNIX domain socket mechanism,
or they can launch their own private instance of rvinterf behind the scenes,
using an unnamed and unbound socket pair.  (Don't try to have two or more
rvinterf instances running on the same serial port, it won't work.)  The
following command line options are standardized across all of our rvinterf
client programs:

-p /dev/ttyXXX

	Don't connect to an already running rvinterf process, instead launch a
	private instance of rvinterf on the named serial port.

-B baud
-l logfile
-w number_in_seconds

	These options are valid only when -p is used, and are passed through to
	rvinterf.

-s pathname_for_socket

	Connect to a different local UNIX domain socket pathname instead of the
	default /tmp/rvinterf_socket.  This option is valid only when -p is not
	used.

Interactive vs. one-shot operation
==================================

Our main client programs fc-fsio, fc-shell, fc-tmsh and fc-tmsync can operate
in both interactive and one-shot modes.  If there is a specific command given
on the invokation command line, that command is executed in the one-shot mode
(the program executes that one command, waits for the response from the target
if appropriate, and exits), otherwise each of the listed programs enters its
own interactive mode with its own prompt.  The more specialized client programs
fc-memdump, fc-dspapidump and fc-readcal always operate in the one-shot manner.

fc-fsio, fc-tmsync and the just-listed specialized client programs are
synchronous in nature: whether they are used interactively or in a one-shot
manner (single command per program invokation), all of their operations are
built from command-response primitives: each internal low-level function sends
a command packet to the target via rvinterf and waits for a response from the
target; not getting a response or getting a wrong or unexpected response is a
fatal error.  There is no such thing as a no-wait mode (one-shot or otherwise)
with these synchronous programs.  Furthermore, what appears to be a single
command at the high level may consist of a large number of command-response
packet exchanges under the hood, and the one-shot mode can be used equally
easily to run a simple command or a script consisting of many commands.  The
fcup-* -R mechanism (implemented by way of the fcup-rvtat back-end program) is
also synchronous like the fc-fsio and fc-tmsync family.

In contrast, fc-shell and fc-tmsh are asynchronous, and they work most naturally
in their interactive mode.  An interactive fc-shell or fc-tmsh session is a
select loop that listens simultaneously for both user command input on the
terminal and packets from the target on the rvinterf socket; user commands cause
command packets to be sent to the target and any response packets received from
the target are decoded and displayed on the terminal, but these two directions
are completely decoupled from each other.  The one-shot mode of operation is
inherently less natural with these programs, and constitutes a bit of a hack.

fc-tmsh offers the same repertoire of commands in both interactive and one-shot
modes, and each of these commands sends a Test Mode command packet to the
target.  The one-shot mode is actually two modes: one-shot with a wait for a
target response (default) and one-shot with no wait (-n option).  One-shot with
no wait is straighforward: fc-tmsh constructs the requested TM command packet,
sends it to the target via rvinterf and exits.  In the other one-shot mode
without -n, fc-tmsh sends the command packet to the target and falls into a loop
processing input from rvinterf; as soon as some (any) packet is received from
the target on the TM channel, that packet (which is decoded and displayed) is
considered to be the response and the program exits with a success indication.

fc-shell is the oddest of the bunch: the set of one-shot commands is a subset
of those available in the interactive mode, as some of the commands cannot work
outside of the interactive mode select loop environment.  Furthermore, almost
all of the one-shot commands in fc-shell always operate in the no-wait manner
whether -n is given or not.  The only fc-shell one-shot commands which wait for
a target response in the absence of -n (similarly to fc-tmsh) are AT commands.

Startup synchronization hack
============================

There is one annoying issue that has been seen with FTDI USB-serial adapters:
when the serial port served by an FTDI adapter has been receiving serial traffic
from the target while no host program is running with the port open to read it,
and then a host program is started, that newly started host program will often
get some stale or total garbage input from the freshly opened ttyUSBx port on
startup.  In most usage scenarios this issue is not a killer for our rvinterf
suite, only an annoyance: if rvinterf is started on a serial port with this
initial garbage, there will be some garbage displayed by rvinterf initially,
but then it will quickly regain synchronization with the running firmware
target.  If there is any delay between the starting of rvinterf and command-
response packet exchanges with the target (if rvinterf is run explicitly by the
operator first and then the client program, or if the client program that
launches rvinterf is an interactive one), no problems occur: rvinterf will be
in sync with the target with all initial garbage flushed by the time it needs
to do the first command-response packet exchange.

There is one potentially problematic usage scenario, though: consider what
happens when a one-shot operation is commanded, it is a type of one-shot
operation that includes waiting for a response from the target, and rvinterf is
being launched from the client program with -p.  In this scenario there will be
a command packet sent to the target as soon as rvinterf starts up, and the
client program will expect rvinterf to capture and deliver the target fw's
response correctly, but there may not be enough time for rvinterf to clear the
initial garbage presented by the imperfect serial port hardware+driver
combination.

Our solution to this potential trouble source is a hack: in the special case
when rvinterf is being launched by the client program with -p and when the
client operation to be performed falls into the category of one-shot with a wait
for the target fw response, a 30 ms delay is inserted after the return from the
vfork call that launches rvinterf and before any actual operations.  This hack
has been deemed to be acceptable because this combination of doing one-shot
operations while launching rvinterf with -p is not a very sensible way of using
our rvinterf tools generally, hence it has been deemed acceptable to add a bit
of slowdown to this rather contrived use case.