[ir] Web-based Remote Control

I presume the codes received from the IR need not be the standard ones, or could be codes from the other modes, and then mapped to codes or macros.

I'm thinking in terms of a custom handset (probably JP1), with extra buttons used as direct-dial for specific channels.

Any reason this might not work?
AFAIK the ir3.map can only be used to map one hex code to another hex code so could potentially be used to map codes above 83 into those understood by the Humax but I don't think it can be used to assign multiple button pushes or macros
 
Last edited:
AFAIK the ir3.map can only be used to map one hex code to another hex code so could potentially be used to map codes above 83 into those understood by the Humax but I don't think it can be used to assign multiple button pushes or macros
ir3.map can have multiple actions in response to a single button, and should work with extra codes as long as they're passed up from the front panel, an example from another one of my boxes:

46:40,40,40,f8,c,3,a:Subtitle button = VOL-, VOL-, VOL-, WAIT 8 seconds, 0, 1, 8
 
This sounds good (my supported user now requires support just to change channel). What I'm planning is an extended big-button remote, with the innards of a JP1 (URC1280, or possibly two) coupled to custom buttons with big labels.

I guess I can pick up the actual received code (whether it does anything or not) by running the debug log?
 
I tried out a multiple action setting and it appears to be a pretty reliable way of crashing the system :(
Code:
Your Humax crashed and some packages may have been disabled as a precaution. (2 instances)
  ... view the crash.log for more details. (2 instances)
Code:
63       ... flag prevented plugin disable ...
62    Humax crashed at Mon Jun 15 11:22:44 UTC 2020 - Uptime: 169
61       ... flag prevented plugin disable ...
60    Humax crashed at Mon Jun 15 11:19:31 UTC 2020 - Uptime: 24068
using
Code:
1f:03,03:VOL+ 
40:04,04:VOL-
Crashdiag shows:
Code:
*********** Core file /mod/core/humaxtv.1592219970.366 ***********
Mon Jun 15 12:19:30 BST 2020
Core was generated by `/usr/bin/humaxtv'.
Program terminated with signal 11, Segmentation fault.
#0  0x2aadb5ec in _ftext () from /var/lib/humaxtv_backup/mod/libir3.so
[Current thread is 1 (Thread 21496)]
Thread
#0  0x2aadb5ec in _ftext () from /var/lib/humaxtv_backup/mod/libir3.so

Thread 114
#0  0x2c59ee3c in recvmsg () from /lib/libpthread.so.0
#1  0x2c59ee20 in recvmsg () from /lib/libpthread.so.0

Thread 113
#0  0x2c5b16bc in ioctl () from /lib/libc.so.0
#1  0x2c08e24c in ?? () from /usr/lib/libnexus.so

Thread 110
#0  0x2c597680 in pthread_mutex_lock () from /lib/libpthread.so.0
#1  0x2c15e370 in BKNI_AcquireMutex () from /usr/lib/libnexus.so
#2  0x2c0f0d54 in NEXUS_P_Scheduler_Step () from /usr/lib/libnexus.so
#3  0x2c0f1160 in ?? () from /usr/lib/libnexus.so

Thread 88
#0  0x2c59ee3c in recvmsg () from /lib/libpthread.so.0
#1  0x2c59ee20 in recvmsg () from /lib/libpthread.so.0

Thread 76
#0  0x2c5b2c20 in select () from /lib/libc.so.0
#1  0x2aaf0638 in ?? () from /var/lib/humaxtv_backup/mod/libnugget.so

Thread 75
#0  0x2c58d1ec in mq_timedreceive () from /lib/librt.so.0
#1  0x2c58d1cc in mq_timedreceive () from /lib/librt.so.0

Thread 72
#0  0x2c59e5dc in read () from /lib/libpthread.so.0
#1  0x2c59e5c0 in read () from /lib/libpthread.so.0

Thread 70
#0  0x2c5b2c20 in select () from /lib/libc.so.0
#1  0x008fd36c in ?? ()

Thread 7
#0  0x2c59ea6c in accept () from /lib/libpthread.so.0
#1  0x2c59ea50 in accept () from /lib/libpthread.so.0

Thread 6
#0  0x2c5b2c20 in select () from /lib/libc.so.0
#1  0x0089b848 in ?? ()



*********** Core file /mod/core/humaxtv.1592220163.367 ***********
Mon Jun 15 12:22:43 BST 2020
Core was generated by `/usr/bin/humaxtv'.
Program terminated with signal 11, Segmentation fault.
#0  0x2aadb5ec in _ftext () from /var/lib/humaxtv_backup/mod/libir3.so
[Current thread is 1 (Thread 6506)]
Thread
#0  0x2aadb5ec in _ftext () from /var/lib/humaxtv_backup/mod/libir3.so

Thread 114
#0  0x2c59ee3c in recvmsg () from /lib/libpthread.so.0
#1  0x2c59ee20 in recvmsg () from /lib/libpthread.so.0

Thread 113
#0  0x2c5b16bc in ioctl () from /lib/libc.so.0
#1  0x2c08e24c in ?? () from /usr/lib/libnexus.so

Thread 88
#0  0x2c59ee3c in recvmsg () from /lib/libpthread.so.0
#1  0x2c59ee20 in recvmsg () from /lib/libpthread.so.0

Thread 76
#0  0x2c5b2c20 in select () from /lib/libc.so.0
#1  0x2aaf0638 in ?? () from /var/lib/humaxtv_backup/mod/libnugget.so

Thread 75
#0  0x2c58d1ec in mq_timedreceive () from /lib/librt.so.0
#1  0x2c58d1cc in mq_timedreceive () from /lib/librt.so.0

Thread 72
#0  0x2c59e5dc in read () from /lib/libpthread.so.0
#1  0x2c59e5c0 in read () from /lib/libpthread.so.0

Thread 70
#0  0x2c5b2c20 in select () from /lib/libc.so.0
#1  0x008fd36c in ?? ()

Thread 7
#0  0x2c59ea6c in accept () from /lib/libpthread.so.0
#1  0x2c59ea50 in accept () from /lib/libpthread.so.0

Thread 6
#0  0x2c5b2c20 in select () from /lib/libc.so.0
#1  0x0089b848 in ?? ()



humax /mnt/hd2/mod/git #
 
I'm trying to simplify/lock out functions on the supported user's HDR. Here's my ir3.map:

Code:
00:00:POWER
02::SOURCE -> disabled
03:03,13:ONE -> BBC ONE
04:04,13:TWO -> BBC TWO
05:05,13:THREE -> ITV
06:06,13:FOUR -> Channel 4
07:07,13:FIVE -> Channel 5
08:0b,13:SIX -> BBC FOUR (9)
09:08,13:SEVEN -> ITV2 (6)
0a:03,0c,13:EIGHT -> ITV3 (10)
0b:04,06,13:NINE -> ITV4 (24)
0c:04,07,13:ZERO -> Yesterday (25)
0d::TV/RADIO -> disabled
0e:0e:MENU
0f::P- -> disabled
10::P+ -> disabled
11:11:UP
12:12:LEFT
13:13:OK
14:14:RIGHT
15:15:DOWN
16:16:EXIT
18:18:MUTE
1a::YELLOW -> disabled
1b:1b:GUIDE
1c::RED -> disabled
1d::GREEN -> disabled
1e::BLUE -> disabled
1f:1f:VOL+
40:40:VOL-
41:41:BACK
42:42:OPT+
43:43:INFO
45::AUDIO -> disabled
46::SUB -> disabled
4b::PORTAL -> disabled
4c::SLEEP -> disabled
4d::LIST -> disabled
4e::WIDE -> disabled
4f::V-FORMAT -> disabled
60:60:PLAY
61:61:REC
62:62:PAUSE
63:63:STOP
64:64:FF
65:65:REW
66:66:SKIP/BACK
67:67:SKIP/FORW
6a::ADDBOOKMARK -> disabled
6b::BOOKMARKS -> disabled
6c::SLOW -> disabled
6e::TEXT -> disabled
6f:6f:MEDIA
70:70:MODE
71:71:MODE1
72:72:MODE2
73:73:MODE3
74:74:MODE4
75:75:MODE5
76:76:MODE6
7f:7f:CURMODE
80:80:PVR
81:81:TV
82:82:DVD
83:83:AUDIOD
Packages have been updated, the box has been rebooted umpteen times, the mode has been checked (Mode 1)... but the litmus test of pressing "List" still produces a list (when the map file says to disable that button).

The only other thing I can think of (and I can't sort out right now) is CF3.11. Could that be the problem?
 
It looks fine - you'll have to increase the debug level and see what the log says.

Run the ir3/debugon diagnostic, reboot and look at humaxtv.log if I remember correctly.
 
Would it be better to assign the channels to be allocated to buttons 6-9 to lcn 6-9 with tunefix so that the numbers shown in the EPG and when switching channels matched the buttons that need to be pressed.
I think it would simpler for a supported user to say ITV4 is channel 9, than for her having to remember to press 9 for channel 24.

The top channels could also be allocated to a favourite group so that if P+/- were enabled the user just cycled through the top channels rather than the 100s of the full epg.
I am not (quite) senile but I like to cycle through a favourites list when looking for something to watch.
 
The top channels could also be allocated to a favourite group so that if P+/- were enabled the user just cycled through the top channels rather than the 100s of the full epg.
Not worth it, and no guarantee of retaining its favourites setting.

Would it be better to assign the channels to be allocated to buttons 6-9 to lcn 6-9 with tunefix so that the numbers shown in the EPG and when switching channels matched the buttons that need to be pressed.
I think it would simpler for a supported user to say ITV4 is channel 9, than for her having to remember to press 9 for channel 24.
This is a half-way house to a modified JP1 remote which has 16 individual buttons for channels.

Another idea I have had is to retain all the commands and set to mode 2 (with a standard handset having full control), but inject commands from the reduced handset on mode 1 and translate them in ir3.map. Are the actual codes listed anywhere?
 
Not worth it, and no guarantee of retaining its favourites setting.
The favourites group can be enforced using boot-settings and the only time I lose the setting is if use the remote to switch to a channel outside the favourite list which you have prevented by nobbling the number buttons.
 
It's not a problem anyway - I've stripped out the other services with tunefix. Madam holds the buttons down too long, the main problem was ending up god knows where after pressing CH+ or CH- (when she thinks she's operating the volume control).
 
Another idea I have had is to retain all the commands and set to mode 2 (with a standard handset having full control), but inject commands from the reduced handset on mode 1 and translate them in ir3.map. Are the actual codes listed anywhere?
I hope I'm not treading on any toes, but I can't find this discussed/listed anywhere so I've done some digging and dissection:

IR Code Patterns Reported by the "ir3/debugon" Diagnostic

With the ir package installed, and the ir3/debugon diagnostic run (and rebooted), the humaxtv.log file accumulates the IR codes received by the HDR (even codes not meant for it - for example I can see codes reported from my TV handset). For example:

1594146667609.png

Let's take line 489: Real IR code: 0x000001 0xf90610fa (6) [foreign=0]
  • "Real IR code:" is a constant prefix;
  • "0x000001" is a repeat flag;
  • "0xf90610fa" is the actual code;
  • "(6)" is the extracted function;
  • "[foreign=0]" indicates whether the code is applicable to the 'FOX in its current mode.
Repeat Flag

This field is either "00000000" or "0x000001"; "0x" is a prefix indicating what follows if a hex string, and I guess "00000000" is a bug and should read "0x000000".

"00000000": This is the first transmission of this code;​
"0x000001": This is a subsequent transmission of this code in continuous sequence.​

Code

The "0x" prefix indicates what follows is a hex string, in this case 8 digits (32 bits). The hex string comprises three fields (using the example above):

f9: Check (1 byte)​
06: Function (1 byte)​
10fa: Mode (two bytes)​

The check byte is the logical inversion of the function byte; thus: 0xF9 + 0x06 = 0xFF. Any codes received which do not meet this condition will probably be rejected.

The mode bytes filter out IR commands sent to other devices or 'FOXes operating on different modes. By experiment, the relevant modes appear to be:

Mode 1: 0x1000​
Mode 2: 0x10fa​
Mode 3: 0x10fb​
Mode 4: 0x10fc​
Mode 5: 0x10fd​
Mode 6: 0x10fe​

The Humax remote also sends 0x10ff in the process of changing mode.

"Foreign" Flag

This indicates whether the mode bytes correspond with the current mode of the 'FOX, or are rejected as "foreign":

"[foreign=0]": The mode bytes correspond with the current mode of the 'FOX;​
"[foreign=1]": The mode bytes do not correspond with the current mode of the 'FOX, and the function will not be acted on.​

Function

The mapping between function bytes and button names can be obtained by the CLI command ir -l. However, for convenience, here is an edited version of the output (eliminating duplications):

Code:
HEX       FUNCTION
***       ********
00        POWER
02        SOURCE
03        ONE
04        TWO
05        THREE
06        FOUR
07        FIVE
08        SIX
09        SEVEN
0A        EIGHT
0B        NINE
0C        ZERO
0D        TV/RADIO
0E        MENU
0F        P-
10        P+
11        UP
12        LEFT
13        OK
14        RIGHT
15        DOWN
16        EXIT
18        MUTE
1A        YELLOW
1B        GUIDE
1C        RED
1D        GREEN
1E        BLUE
1F        VOL+
40        VOL-
41        BACK
42        OPT+
43        INFO
45        AUDIO
46        SUB
4B        PORTAL
4C        SLEEP
4D        LIST
4E        WIDE
4F        V-FORMAT
60        PLAY
61        REC
62        PAUSE
63        STOP
64        FF
65        REW
66        SKIP/BACK
67        SKIP/FORW
6A        ADDBOOKMARK
6B        BOOKMARKS
6C        SLOW
6E        TEXT
6F        MEDIA
70        MODE
71        MODE1
72        MODE2
73        MODE3
74        MODE4
75        MODE5
76        MODE6
7F        CURMODE
80        PVR
81        TV
82        DVD
83        AUDIOD

What's all this worth? Well, by picking up button presses in other modes or from other remotes, they can be translated to actual functions in the /mod/boot/ir3.map file, and by turning the function on in WebIF >> Settings >> Settings for ir package >> Use custom map file? = YES they should act on the 'FOX.
 
Last edited:
Packages have been updated, the box has been rebooted umpteen times, the mode has been checked (Mode 1)... but the litmus test of pressing "List" still produces a list (when the map file says to disable that button).

The only other thing I can think of (and I can't sort out right now) is CF3.11. Could that be the problem?
One thing that just came to mind - have you enabled the map file?

1594156843411.png

If it's enabled, you'll see lines like this in the humaxtv.log

Code:
Initialising IR3 v1.12
IR3 debug: 1
IR3 Mode: 1 (0x1000)
IR3 - Loading custom keymap.
Read 207 bytes from map file.
IR3 map line: [46:40,40,40,f8,c,3,a:Subtitle button = VOL-, VOL-, VOL-, WAIT 8 seconds, 0, 1, 8]
IR3 map line: [0x7887827d:0:Discrete power off]
 
Repeat Flag

This field is either "00000000" or "0x000001"; "0x" is a prefix indicating what follows if a hex string, and I guess "00000000" is a bug and should read "0x000000".

"00000000": This is the first transmission of this code;"0x000001": This is a subsequent transmission of this code in continuous sequence.
The code has this field as 0 = 'button down' and 1 = 'button up'
(I didn't write the core of this, that was PhilHDR, I added macros and mappings and a few other things later.)
 
One thing that just came to mind - have you enabled the map file?
Yes. I'm having a play at home, and I'll have another go on the target system tomorrow. Possibly I might not have appreciated it is necessary to reboot every time the map file is tweaked.

The code has this field as 0 = 'button down' and 1 = 'button up'
No, sorry - hold a button down for a long time and you get a stream of reports with one initial "0" followed by loads of "1"s. If 0x000001 meant "button up", there would only be one.

This could provide a mechanism to suppress fumbles due to holding buttons down: filter out 0x000001 strings.
 
Last edited:
I've hit a problem: in testing, I have found that if I disable a native button (mode 2), and try to substitute a foreign button (mode 1) for that function, the translation occurs but then the translated code is blocked. Is that intentional?

ir3.map:
Code:
4d::LIST -> disabled
0xb24d1000:4d:Mode1 LIST -> LIST

humaxtv.log:
Code:
Real IR code: 00000000 0xf30c10fa (c) [foreign=0]      ----"0" button, native
Real IR code: 0x000001 0xf30c10fa (c) [foreign=0]      ----"0" button, native (cont)
Blocking 4d.
Real IR code: 00000000 0xb24d10fb (4d) [foreign=1]      ----"LIST" button, native
Blocking 4d.
Real IR code: 0x000001 0xb24d10fb (4d) [foreign=1]      ----"LIST" button, native (cont)
Real IR code: 00000000 0xf30c1000 (c) [foreign=1]      ----"0" button, mode1
Real IR code: 0x000001 0xf30c1000 (c) [foreign=1]      ----"0" button, mode1 (cont)
Foreign b24d1000 mapped to 4d      ----"LIST" button, mode1
Blocking 4d.
Real IR code: 00000000 0xb24d10fb (4d) [foreign=1]
Foreign b24d1000 mapped to 4d      ----"LIST" button, mode1
Blocking 4d.
Real IR code: 0x000001 0xb24d10fb (4d) [foreign=1]
Foreign b24d1000 mapped to 4d      ----"LIST" button, mode1
Blocking 4d.
Real IR code: 0x000001 0xb24d10fb (4d) [foreign=1]
Foreign b24d1000 mapped to 4d      ----"LIST" button, mode1
Blocking 4d.
Real IR code: 0x000001 0xb24d10fb (4d) [foreign=1]
Real IR code: 00000000 0xf30c10fa (c) [foreign=0]      ----"0" button, native
Blocking 4d.
Real IR code: 00000000 0xb24d10fb (4d) [foreign=1]      ----"LIST" button, native
Blocking 4d.
Real IR code: 0x000001 0xb24d10fb (4d) [foreign=1]      ----"LIST" button, native (cont)

Notice that the native button, which should be 0xb24d10fa, has been recorded as 0xb24d10fb. Is that how the disable is implemented - by casting it into a different mode space?
 
By removing the suppression of the native LIST button, the translation of the foreign LIST button now works:
Code:
Real IR code: 00000000 0xb24d10fa (4d) [foreign=0]
Real IR code: 0x000001 0xb24d10fa (4d) [foreign=0]
Real IR code: 0x000001 0xb24d10fa (4d) [foreign=0]
Real IR code: 00000000 0xb24d10fa (4d) [foreign=0]
Real IR code: 0x000001 0xb24d10fa (4d) [foreign=0]
Foreign b24d1000 mapped to 4d
Real IR code: 00000000 0xb24d10fa (4d) [foreign=0]
Foreign b24d1000 mapped to 4d
Real IR code: 0x000001 0xb24d10fa (4d) [foreign=0]
Foreign b24d1000 mapped to 4d
Real IR code: 0x000001 0xb24d10fa (4d) [foreign=0]
Foreign b24d1000 mapped to 4d
Real IR code: 0x000001 0xb24d10fa (4d) [foreign=0]
Foreign b24d1000 mapped to 4d
Real IR code: 00000000 0xb24d10fa (4d) [foreign=0]
Foreign b24d1000 mapped to 4d
Real IR code: 0x000001 0xb24d10fa (4d) [foreign=0]
Foreign b24d1000 mapped to 4d
Real IR code: 0x000001 0xb24d10fa (4d) [foreign=0]
 
No, sorry - hold a button down for a long time and you get a stream of reports with one initial "0" followed by loads of "1"s. If 0x000001 meant "button up", there would only be one.

This could provide a mechanism to suppress fumbles due to holding buttons down: filter out 0x000001 strings.
0x1 apparently sends a 'KeyUp' event to the humax software - that would explain the notes in the code.

Yes, it should be possible to filter duplicates.
 
From the wiki:
Code:
0x7887827d:0:Discrete power off

How is that a "discrete power off"? The "0" function is power toggle.
 
I've hit a problem: in testing, I have found that if I disable a native button (mode 2), and try to substitute a foreign button (mode 1) for that function, the translation occurs but then the translated code is blocked. Is that intentional?

That's going to require more thought.
The way that mapping works is that it builds up a lookup table in memory. The lookup table is just 256 bytes, with one slot for each original function.
For a direct substitution, the table just gets the replacement code, there are special values for ignore and macro.

Here's the relevant code for this part:

C:
                        unsigned int newcode = irMap[keycode] & 0xff;
                        if (newcode == MAP_IGNORE)
                        {
                                a1[1]++;
                                if (debug)
                                        fprintf(stderr,
                                            "Blocking %x.\n", keycode);
                        }

So (there's that word again), it maps LIST and gets MAP_IGNORE back and so blocks the code by incrementing the mode value (as you surmised).
There's a bug though, which you've found. Foreign code mapping happens first and isn't taken into account when it should be. I'll get that fixed.

How is that a "discrete power off"? The "0" function is power toggle.
Because it can only work if the box is up and running... if it's in standby, nothing happens.

My remote is programmed to use 0 0 0 as power on, and that code as power off and it works well.
 
Back
Top