Plan for AT over RVTMUX

Spacefalcon the Outlaw falcon at ivan.Harhan.ORG
Fri May 29 06:23:54 CEST 2015


So I surveyed the existing mechanisms in TI's fw for sending AT commands
over RVTMUX.  I found two, neither of which is any good:

1. One can send a GPF "system primitive" containing a string of the
   form "CONFIG ATxxx" to the ACI/MMI entity (the out-of-place-looking
   CONFIG keyword needs to be there because this hack is hooked in via
   the ACI entity's pei_config function), and the AT command included
   in there will be passed to ati_execute().  But it is only a blind
   command mechanism - the output from ATI goes into a black hole -
   and there is no way to receive notifications corresponding to
   events such as incoming calls.  And because there is no mechanism
   for passing the ATI response back to the host, this facility is
   totally useless for commands whose sole purpose is to retrieve
   information from the modem.  In short, this hack is not what we are
   looking for.

2. TI's TCS211 firmware includes a component called ATP.  It is one of
   the many "dead ends" in TI's code base.  Perhaps it was still used
   at the time of TCS211 by TI's Bluetooth code (not included in our
   version of TCS211), or perhaps it was only used by what appears to
   have been an abandoned attempt to build a Riviera-based UI ("MMI")
   instead of the GPF-based BMI, but in any case it is now a service
   without users: TCS211 fw builds include ATP, but there are no
   entities in either the modem or the BMI configuration that use the
   API functions it exports.  It appears to have been intended for
   connecting Riviera-based entities to ACI, but in our actually
   working TCS211 version the ACI connection to ATP isn't there: ATP
   itself does not depend on or connect to ACI, rather something in
   ACI land needs to call an ATP registration function, and no such
   hook-up appears in our version of TCS211.

   The original version of ETM in our TCS211 reference (before I
   stripped it down for FreeCalypso) includes a command opcode handler
   that passes an AT command string given by the external host to ATP.
   When I first saw that hack in there a year and a half ago, I thought
   it was a workable way to pass AT commands over RVTMUX, but nope, it
   is actually defunct: it uses ATP services to connect to an entity
   named "AAA", but no entity actually registers under that name -
   remember, there are no entities at all in the working TCS211 fw that
   register with or make use of ATP.

As there appears to be no existing TI-defined mechanism for passing AT
commands over RVTMUX that does what we seek (an ability to operate a
GSM modem fw on single-UART targets no worse than on dual-UART ones),
I am defining and implementing my own.

Interface definition:

The first byte of every RVTMUX packet identifies the logical channel.
TI's rvt_gen.h header file assigns 0x11 through 0x18 to 8 defined
channels, of which only the first 4 (RV, L1, GPF and ETM) appear to be
used for real; the LoCosto version of RVT (which we aren't using) also
assigns 0x19 to one of two entities depending on some preprocessor
conditional.  So I'm going to grab 0x1A and 0x1B and define them to be
FreeCalypso AT-over-RVTMUX interface and the external LCD emulation
interface, respectively.

In the host->target direction all bytes after the initial 0x1A will
constitute input to ati_execute(); the terminating CR for AT commands
or ^Z for SMS entry text will be added by the receiving code in the
target fw and don't need to be passed over the wire.  In the
target->host direction all bytes after the initial 0x1A will be
whatever ATI's output function spits out; we'll sort it out
experimentally once the code is implemented.

Implementation in the target fw:

I'm hoping I won't run into any major difficulties here.  TI's ATI
code supports multiple command sources, each of which is registered
with ati_init().  The arguments to this function are the type of the
source to be registered and the callback functions for string output
and for modem control line indications; the return value is the ID of
the newly registered source; one then submits commands to ATI by
calling ati_execute() with the registered source ID and the character
string to be executed.  The implementations of various existing
sources are contained in ati_src_*.c; I'm going to create a new one
based on these existing ones, and it will do the following:

* Register with ATI at ACI pei_init() time, i.e., on boot;
* Register with RVT to receive packets sent to this AT-over-RVTMUX
  channel we are defining;
* When RVT callbacks come in (in HISR context), copy the incoming
  command into a primitive buffer allocated from GPF, and post it to
  the ACI entity's queue, repurposing an existing primitive opcode
  that appears to have been used for a very similar purpose in TI's
  Windows simulation environment;
* Hack the handler for that no-longer-used opcode from the Windows
  simulation environment to call a function in our new command source
  handler;
* Have this just-mentioned function pass the command to ati_execute();
* Have the string callback function send all output back to the host
  via rvt_send_trace_cpy().

I'm hoping to implement the above both in our own fw as well as in a
hacked-up debug version of TCS211/leo2moko.  In the case of the latter
the hack will be fully contained within ACI, which came in full source
form, as well as a trivial change to RVT (also full source) to
recognize the new AT-over-RVTMUX channel as valid.

Implementation in FC host tools:

Our suite of Unix/Linux host tools is contained in the rvinterf subtree
of our freecalypso-sw source tree.  The simplest interface program is
rvtdump: it decodes and dumps everything emitted by the target, but
there is no provision for sending any commands to the running fw.  If
one wishes to do the latter, one needs to run rvinterf instead of
rvtdump.  Rvinterf allows other programs to connect to it via local
UNIX sockets and do the following:

* Register to receive certain types of packets received from the target;
* Send arbitrary RVTMUX packets to the target.

If the behavior of the target fw in response to commands is not known
or understood yet, or if it is too difficult for a host interface
program to model, the most straightforward way to implement host
interface programs is fully asynchronous: make the host i/f program
totally oblivious to whatever correspondence may exist between host
commands and target responses.  Send host commands as the user types
them, and display messages from the target as they come in.

Our current rvinterf suite contains two such asynchronous programs:
fc-tmsh and g23sh, talking to ETM and GPF, respectively.  I am leaving
fc-tmsh in limbo for now until we get around to reintegrating and
understanding TI's L1TM code in connection with calibration, but g23sh
right now is a rather silly program, implementing just one command sp
for sending "system primitives" to GPF.

I am thinking of morphing g23sh into a slightly more general program
tentatively named fc-shell, and I envision it providing the following
capabilities:

* Sending GPF system primitives and listening for GPF responses in the
  form of traces;
* Sending AT command and SMS text entry strings to the AT-over-RVTMUX
  interface we are now defining and implementing, and listening for
  ATI responses and asynchronous notifications (incoming calls etc);
* Most basic ETM commands like ping, target reset and power-off - but
  leave more advanced ETM functionality to fc-fsio, fc-tmsh or whatever
  these tools may morph into in the future.

We are going to need to implement both fc-shell on the host side and
the ACI code on the target side described above before we will know
whether my AT-over-RVTMUX idea is any good or not.  Stay tuned!

Happy hacking,
SF


More information about the Community mailing list