Fix Media Key in Logitech OMM(onboard memory manager)

Logitech's OMM(onboard memory manager) is originally designed for pro-gamer, but many use it as a replacement for G-HUB. The OMM itself is fully portable: one single file, don't write anything to system, don't run in background and can be fully unloaded once finishing setup -- exactly what a software should be.

However there is a bug in OMM as it can't set media keys -- volume adjust, mute, pause... -- properly. There're some reports(1. 2.) on reddit but only got useless canned response from Logitech. A walkaround is to use G-HUB to set the media keys and OMM for the rest, but it's annoying.

Update: there is a new version 2.0.1639 released on 9/5/23, different interface same bug. The article is based on an old version but applies to both.

The Problem

This is based on Logitech OMM, Ver 1.1.6805 released on 6/1/22, latest as of writing.

The onboard memory can be set through LGS(if the mouse supports) or G-HUB, both set the media keys correctly. However a properly setup media key will just show Media Key in OMM instead of actual key name. If the key is set through OMM, then it wouldn't work at all.

With the help of usbhid-dump utility in Linux, I was able to get some insights.

run usbhid-dump -e stream to dump raw USB:

To compare, for Volume Down:

from good working LGS:

1
2
03 EA 00 00 00
03 00 00 00 00

non-working OMM:

1
2
03 EA 0C 00 00
03 00 00 00 00

OMM is sending different code than others, but why the code and why it fails?

The Specs

Know little about USB but a quick search found the USB HID PDF. On p.126, as show below, Volume Down has code 0xEA(usage id) in "Consumer page"(0x0C). consumer-page

hid-code

0xEA is usage id and 0x0C is the usage page, OMM sends both(03 EA 0C 00 00), looks good? On the other hand, LGS sends 0xEA , the usage id only, and missing usage page(03 EA 00 00 00) -- looks wrong but it's working.


On another PDF p.36 the 5 bytes data is a "short item".

short-report

Here 03 means there're 4 bytes data following(03 EA 0C 00 00) which matches the usb dump.

Back to first PDF, p. 20, on how to decode the data:

usage-report


The bug

So for 03 EA 0C 00 00, since 03 means 4 bytes data, and per the spec, the lower 2 bytes are usage id and higher 2 bytes are usage page, i.e., both take 2 bytes, so OMM should send 03 EA 00 0C 00 !!! As OMM sending 03 EA 0C 00 00, EA 0C(0xCEA ) becomes the usage id, obviously this wouldn't work. And when configured from LGS, the usage id is 0xEA, but OMM expecting 0xCEA for Volume Down display, thus it will show a general Media Key.

Since 03 EA 00 00 00 is the correct data, looks like we must set the correct usage id while the usage page can be 0, this makes sense because for short item with 1 or 2 bytes data, only usage id is sent and usage page is ignored, maybe the usage page is set/sent elsewhere? I didn't go further, as 03 EA 00 00 00 from LGS works, the OMM can be modified to match it.

The fix

I hate to post this as OMM isn't open source.....the OMM binary can be modified with dnSpy. Change 3 places:

  1. OnboardMemoryManager.Helpers->HIDConsumperDevice->HIDConsumerDevice()

    dnSpy shows:

    1
    2
    3
    4
    5
    6
    7
    8
    	new HIDConsumerDevice.LocalizedHIDScanCode("Action_Consumer_Key_Next_Track", 0xC, 0xB5, 0xE019),
    new HIDConsumerDevice.LocalizedHIDScanCode("Action_Consumer_Key_Previous_Track", 0xC, 0xB6, 0xE010),
    new HIDConsumerDevice.SystemHIDScanCode("Stop", 0xC, 0xB7, 0xE024),
    ...................
    new HIDConsumerDevice.SystemHIDScanCode("WWW Forward", 0xC, 0x225, 0xE069),
    new HIDConsumerDevice.SystemHIDScanCode("WWW Stop", 0xC, 0x226, 0xE068),
    new HIDConsumerDevice.SystemHIDScanCode("WWW Refresh", 0xC, 0x227, 0xE067),
    new HIDConsumerDevice.SystemHIDScanCode("WWW Favorites", 0xC, 0x22A, 0xE066)

    Change all these 0xC to 0.

  2. OnboardMemoryManager.Models->HIDAction->CONSUMER_KEYS

    Change "PLAY_PAUSE" "MUTE" "NEXT_TRACK"... , substract every "0xC??" value by 0xC00, i.e., removing leading 0xC.

    For example, "VOLUME_DOWN":

    1
    public const HIDAction.CONSUMER_KEYS VOLUME_DOWN = 0xCEA;

    change it to

    1
    public const HIDAction.CONSUMER_KEYS VOLUME_DOWN = 0xEA;

    Same for the rest.

  3. OnboardMemoryManager.Models->HIDActionsDefaults->Items
    Same as above, change 0xCCD to 0xCD, 0xCB6 to 0xB6...

    1
    2
    3
    4
    		new HIDAction((HIDAction.CONSUMER_KEYS)0xCCD, null),
    new HIDAction((HIDAction.CONSUMER_KEYS)0xCB6, null),
    ............
    new HIDAction((HIDAction.CONSUMER_KEYS)0xCEA, null),

Here is my modified OMM V1 V2. USE IT AT YOUR OWN RISK. or you can always do the mod yourself.


Modified OMM and LGS, with correct "Volume UP/Volume Down".

omm-lgs