Architecture & Tools

Background

LinHES 7 introduced a number of changes to the way remotes and associated devices are handled. This is largely being picked up from changes in the Linux base. The way remotes are now handled is significantly different and also requires a different tool set to build and diagnose an implementation. In general this new implementation is a significant improvement in what was previously a rather adhoc structure.

This guide will attempt to introduce you to the new architecture and tool sets relevant to LinHES.

Architecture

The following picture is a logical representation of how various blocks in LinHES are connected.

LinHES Remote Architecture

As of LinHES 7, many of the remote drivers are included in the kernel whereas previously they were part of the lirc subsystem. However not all remote receiver devices have been ported to the kernel so some of these drivers still reside within lirc as before. Those drivers follow the "Legacy Remote Driver" path instead of the "In Kernel Remote Driver" path. The Legacy Remote Drivers follow the same debugging procedures and lirc related files as before.

For the in kernel drivers, if Lircd is not running then by default the In Kernel Remote Driver will issue keyboard and/or mouse events. These events will be seen by higher level applications such as X and MythTV as if normal keyboard and mouse events occurred. Thus if you do not require certain lirc functions such as irexec and irxevent then you can quite happily not use lirc at all. Note, some remotes actually do issue mouse events such as certain imon remotes.

Remote Receiver

Each Remote Receiver will be identified by a unique device ID which will be associated by a driver that recognizes that ID. In most cases this should automatically make the needed associations. In some rare cases more than one driver may try to associate with the device which can cause conflicts. In these exceptional cases, this device can be blacklisted from the driver or the driver itself can be blacklisted.

The device ID can normally be found using tools such "lsusb" where you may see an entry similar to:

Bus 003 Device 002: ID 15c2:0043 SoundGraph Inc.

In Kernel Remote Driver

The driver does not actually know about the remote, it only sees the IR codes received by and translated by the Remote Receiver. The Remote Receiver may use any number of protocols (e.g. RC6, imon, etc) and its associated driver will normally understand all of the protocol variants that the Remote Receiver supports.

The Remote Driver will interact with the Remote Receiver in order to maintain the device and of course receive information from the remote itself. Depending on the Remote Receiver and associated Remote, the driver may separate the events as keyboard and mouse events. In this case you may see entries in "/dev/input/by-id" with entries such as "usb-15c2_0043-event-if00" and "usb-15c2_0043-event-mouse". Note in customization it is generally safer to specify a driver using its "/dev/input/by-id" path rather than the "/dev/input" path as the "/dev/input" path can change.

Legacy Remote Driver

The function is similar to the "In Kernel Remote Driver" however it exists within the LIRC domain and follows the implementation described at lirc.org. This type of driver will not create anything in the /dev/input hierarchy and does not use the ir-keytable functionality. Instead you can use mode2 to see the output from this driver before it is modified by lircd.conf.

ir-keytable

ir-keytable interacts with the In Kernel Remote Driver and normalizes its output. It utilizes a keymap file normally found in "/etc/rc_keymaps" and the default association with the driver will be defined by "/etc/rc_maps.cfg"

There are a number of things that you can do with ir-keytable including:
  • Identify the driver and its protocols (eg. ir-keytable)
  • Monitor the driver output of received events from the Remote Receiver (eg. ir-keytable -t)
  • configure the driver for items such as protocols (eg. ir-keytable -p RC6, LIRC, etc)
  • Load a specific or custom keymap for a driver (eg. ir-keytable -w /etc/rc_keymaps/imon_mce)

For example, in one of my systems ir-keytable returns:

# ir-keytable
Found /sys/class/rc/rc0/ (/dev/input/event7) with:
        Driver imon, table rc-imon-pad
        Supported protocols: RC-6 other
        Enabled protocols: RC-6
        Repeat delay = 500 ms, repeat period = 33 ms

I also force my imon receiver (to generate the above) to use the RC6 protocol and the imon_mce keytable instead of the default imon protocol and imon keymap using:

/usr/bin/ir-keytable -c -p RC6 -w /etc/rc_keymaps/imon_mce

As of R8.2 the keymaps are stored in /usr/lib/udev/rc_keymaps. You may have to copy to the /etc/rc_keymaps directory and delete the first comment line as ir-keytable now chokes on it as of LineHES 8.2 (likely an ir-keytable bug).

I test the output of my driver using "ir-keytable -t" which yields output such as:

# ir-keytable -t
Testing events. Please, press CTRL-C to abort.
1330396066.132941: event MSC: scancode = 800ff418
1330396066.132950: event key down: KEY_PAUSE (0x0077)
1330396066.132951: event sync

NOTE: for "ir-keytable -t" to work, lirc must not be running. Disable lirc using "sv stop lircd" or "sv stop remotes" (depends on LinHES version).

If your keymap file does not match the input protocol from the driver then you will only see output similar to:

# ir-keytable -t
Testing events. Please, press CTRL-C to abort.
1330396066.132941: event MSC: scancode = 800ff418
1330396066.132951: event sync

It is important to note that if you use lirc then the code numbers (such as (0x0077)) are used by lircd.conf.

Remote Driver Event interface

The In Kernel Remote Driver will output events to only one of the standard keyboard/mouse interface, /dev/lirc?, or devinput. If you do not enable lirc then the driver will default to the standard keyboard/mouse event interface. In most cases this will be fine for mythtv and will be the simplest way to implement your system.

If however, you want to use some of lirc's higher functions such as irexec (I use this to have my remote shutdown the system) then you will want to use one of the other interfaces. In most cases there is nothing to do to create devinput but to use /dev/lirc? you will need to specifically tell ir-keytable to use the lirc protocol in addition to any other protocols if it does not do so already. Use "ir-keytable" to see which protocols are enabled and see of LIRC is one of them. If not you can try "ir-keytable -p lirc" plus any other protocol such rc-6 to add it in.

If the lirc protocol is enabled and the driver supports it, you will see a file such as /dev/lirc0 or /dev/lirc1 etc. From here you can have lirc set up the way you always have in the past and likely be able to use your standard lircd.conf file. If the driver does not create /dev/lirc? then chances are it only uses devinput. If you have to use devinput then you will likely not be able to use your normal lircd.conf file but instead you will need to use the standard devinput version of lircd.conf which is in "/usr/share/lirc/remotes/devinput/lircd.conf.devinput".

Note The Legacy Remote Driver only uses the /dev/lirc? interface as it always has.

Normally all of the current driver to lirc associations are handled in /etc/sv/lircd/run with a default to using /dev/lirc?
If the run file does not already do this then to hook lirc into the devinput interface you will need to create a file called /etc/runit/lirc.sh which contains a line similar to:

/usr/sbin/lircd -r -n --driver devinput -d /dev/input/by-id/usb-15c2_0043-event-if00 --output /var/run/lirc/lircd

LIRC

In LinHES, LIRC is normally running and is initiated and configured by /etc/sv/lircd/run. To customize the lirc config files please refer to the Remotes wiki entry.

Note if you are using devinput you will need to use the devinput version of lircd.conf. Depending on the driver this may still require some minor modification. The lircd.conf entries must match the number output (e.g. 0x0077) that you saw using "ir-keytable -t". If it does not then you will not see any output from lirc.

To test the output of lirc, you should use irw. If you have everything configured properly then you will see output similar to:

# irw
0000000080010077 00 KEY_PAUSE devinput
0000000080010077 00 KEY_PAUSE_UP devinput

More detailed information on LIRC, though somewhat outdated, can be found at: http://lirc.org/html/index.html

lircrc

Finally you need to map the key code maps from lircd.conf to specific execution. Lircrc takes these commands and applies specific rules such as what keyboard command to send based on the application calling it (eg. mythtv, irexec, mplayer, xine, etc). It also allows you to add rules such as absorb excessive key presses (eg. repeat=3) or insert delay (e.g. delay=1). Of course each lircrc entry must match the label output from lircd.conf. Using the examples above an entry might look like:

# Pause
begin
       prog = mythtv
       button = KEY_PAUSE
       config = P
end

If this is configured properly then mythtv (and irexec, etc) will behave as you expect.

For more information on lircrc see also: http://lirc.org/html/configure.html#lircrc_format

MythTV LIRC Socket Binding

Mythtv needs to know where to bind to lirc. On a fresh install this will be properly set but in certain upgrade paths, the binding may no longer be valid. Check "Service Menu -> Mythtv Configuration -> Setup -> General -> Page 9(last page)" and ensure 'lirc daemon socket' is set to '/var/run/lirc/lircd'. A restart is necessary after this change.

MythTV Key Bindings

In most cases people do not modify the MythTV key bindings and thus the output of lircrc will normally map fine and in a consistent fashion. If for some reason you are convinced that the mapping up to lircrc is correct yet certain keys are not doing what you expect then you can verify the values assigned to the key bindings in the MythTV setup menu.

See Service Menu -> MythTV Configuration -> Edit Keys

In this menu you will see a list of "Contexts" in the left pane and the various key "Actions" in the right pane. Assigned keys are in the boxes at the bottom. Note you can add more than one key to the action you want and the defaults do that in some cases.

Using the earlier example of KEY_PAUSE mapping to P, you can verify that Context of TV Playback -> PAUSE has a value of P.

For more information on MythTV keybindings see also: http://www.mythtv.org/wiki/Keybindings

LinHES Important Remote Related Files

The following list of files & directories are used in LinHES to connect everything together.

/etc/rc_keymaps

This directory contains the various keymaps for each type of remote. This keymap is used by ir-keytable and a default set of tables will be loaded based on the driver which gets loaded. This can be overridden as described in ir-keytable.

/etc/sv/remotes/run

Added in R7.3 to replace /etc/sv/lircd/run.

This file should NOT BE MODIFIED. /etc/sv/remotes/run is similar to /etc/sv/lircd/run. The main difference is that /etc/sv/remotes/run allows each remote to be started using commands in the remote template's (~/remotes or /usr/MythVantage/templates) remote.run file. If /etc/remote.run is not found lircd will try to start the remote. If you want all the commands in /etc/sv/remotes/run to be ignored create /etc/runit/lirc.sh.

/etc/sv/lircd/run

Replaced in R7.3 with /etc/sv/remotes/run.

This file should NOT BE MODIFIED. This file contains the logic that starts lircd for each type of remote and links lircd to the relevant config files and sockets (connectors to other processes such as drivers). However you can look at it to determine the logic used for your remote. If you want to modify how lircd starts then see /etc/runit/lirc.sh.

/etc/runit/lirc.sh

You can create this file and enter your custom remote start up commands. If this file exists and is executable then /etc/sv/lircd/run and /etc/sv/remotes/run will execute /etc/runit/lirc.sh and the rest of the commands in /etc/sv/lircd/run and /etc/sv/remotes/run will be ignored. Using the iMon example, lirc.sh would contain:

/usr/sbin/lircd -r -n --driver devinput -d /dev/SoundGraph --output /var/run/lirc/lircd

~/remotes

Typically ~/remotes is /home/mythtv/remotes.

This directory contains any custom remotes you have defined. In ~/remotes you would create a sub-directory with the name of the remote you want to create. Inside this sub-directory you can create your own custom lircd.conf, lircrc, remote picture, and remote.run files. Once this is created your new remote will be available from the LinHES Service Menu for selection among all of the standard remotes.

File Filename Example Notes
lircd.conf lircd* lircd.conf.dvico
lircrc lircrc* lircrc.txt-dvico
picture preview.jpg preview.jpg Must be named preview.jpg
remote.run remote.run* remote.run.dvico

/usr/MythVantage/templates

This directory contains all of the standard files for remotes, LCD, transmitters, etc.
  • remotes - LinHES remotes with associated lircd.conf, lircrc, remote picture and remote.run files.
  • LCD - LCD configuration files for various LCD and VFD types
  • transmit - LinHES transmitters (e.g. IR)

/etc/lircd.conf

Sometimes also in /etc/lirc/lircd.conf

This file should NOT BE MODIFIED. If you used the Service Menu then this file should contain one or more UNIQUE includes from either /usr/MythVantage/templates or ~/remotes. These includes will reference either the standard or your custom definitions.

/etc/lircrc

Sometimes also in /etc/lirc/lircrc

This file should NOT BE MODIFIED. If you used the Service Menu then this file should contain one or more UNIQUE includes from either /usr/MythVantage/templates or ~/remotes. These includes will reference either the standard or your custom definitions.

/etc/remote.run

Added in R7.3.

This file should NOT BE MODIFIED. If you used the Service Menu then this file would have been copied from the selected remote in either /usr/MythVantage/templates or ~/remotes. If this file exists /etc/sv/remotes/run will run it to setup your remote.

Tools

With the changes to the architecture in LinHES 7 (and Linux in general) usage of tools related to remotes has changed to some degree. For example, mode2 which used to test the output of the Legacy Remote Driver is now replaced by *ir-keytable -t*for the In Kernel Remote Driver. Below is a list of the common tools used to trace your message flow:

lsusb

Lists USB devices including Remote Receivers attached via USB. You can use this to find the device type which the Remote Driver will find and map to.

ir-keytable -t

NOTE: for "ir-keytable -t" to work, lirc must not be running. Stop lirc using "sv stop lircd" or "sv stop remotes". After testing you can start lirc using "sv start lircd" or "sv start remotes".

Shows the output of the In Kernel Remote Driver before it enters lirc.
  • If you get no output then it could be any of the following:
    • the driver is not set to a protocol that is actually being used by the Remote Receiver (e.g. RC-6, imon);
    • the driver and Remote Receiver device are not connected;
    • the wrong driver is mapped to the device;
  • If you get only raw translated codes then your keymap file does not match the Remote Receiver and Remote.
  • If you get translated output (e.g. KEY_PAUSE (0x0077)) then the driver and keymap is working.

mode2

This tool is part of the Legacy Remote Driver tool chain. It will show you the raw output of the Legacy Remote Driver before it is transformed by lircd.conf. The output codes should match the entries in lircd.conf. Note that in this case lircd.conf may be using maps and truncating part of the code to simplify the lircd.conf format. These masks, truncations and data size are defined at the beginning of the lircd.conf file.

irw

Shows the output from lirc after being mapped through lircd.conf.

If you get no output from irw but ir-keytable worked then it may be any of the following:
  • lirc is not connected through the correct event interface from the driver
  • the output codes from ir-keytable do not match the entries in lircd.conf

ircat

Shows the output from lirc after being mapped through lircrc. The output should match the command name (ie. "config" in the lircrc file entry) being sent to the lirc client program or "prog" (e.g. mythtv).

The format of the command is:

ircat <program name>

for example:
ircat mythtv

  • If you get output from irw but no output from ircat then chances are the lircrc file does not exist or the "button" entry does not match the lircd.conf entry (as output by irw).
  • If you get some output from ircat then check the "button" and "prog" labels in lircrc are correct. e.g. prog = mythtv and button = <lircd.conf entries>

This is the last step before you enter mythtv. If ircat shows proper output but mythtv is not working then you should verify that the mythtv settings are correct. Specifically refer to MythTV LIRC Socket Binding and MythTV Key Bindings.

Reference Material

ArchitectureV9.ppt - LinHES Remote Architecture PPT (77.5 kB) christian, 03/20/2012 07:13 pm

LinHES-Remote-ArchV9.1.JPG - LinHES Remote Architecture (63 kB) christian, 03/20/2012 07:13 pm