Repository: pwr-Solaar/Solaar

Issue:
Why can't Solaar load information about my m510 Logitech wireless mouse?
I have the mk550 Wireless Wave combo. Solaar picks up my keyboard just fine, showing it has an encrypted connection and full battery. However, my m510 mouse is shown by Solaar to have an unknown amount of battery charge and an unencrypted connection. The options to enable smooth scrolling and side scrolling are also greyed out with a warning icon next to them saying that read/write operation failed, but the mouse still works fine. So why is this? What can I do so that I will see accurate information? And if it isn't an encrypted connection, how do I make it secure?



Discussion:
As it happens, keyboards **need** to be encrypted to protect against wireless key-sniffing.  Mouse movements and button presses do not need that sort of protection (unless, perhaps, the layout of things on the screen that are being interacted with by the user are in a fixed, known, position and that a third {_malicious_} party can know _what_ all the things are)! :see_no_evil:   

Perhaps the link is encrypted, but reporting just failed. Can you run solaar with the `--debug` option from a terminal and copy the output? You can strip the repetitive ones that appear when you move a mouse.

Confirmed with mouse M510 : 
- battery charge info is unknown ;
- smooth scrolling & side scrolling  are greyed out.

Solaar version (on Fedora 24) : 
solaar-0.9.2-4.20150528 (git cf27328)

Output of `$ solaar -d` (output from detected keyboard K520 is also included) : 

```
$ solaar -d
12:07:24,679     INFO [MainThread] root: language en_IE (UTF-8), translations path None
/usr/lib/python2.7/site-packages/solaar/gtk.py:34: PyGIWarning: Gtk was imported without specifying a version first. Use gi.require_version('Gtk', '3.0') before import to ensure that the right version gets loaded.
  __import__(module)
/usr/lib/python2.7/site-packages/solaar/ui/notify.py:33: PyGIWarning: Notify was imported without specifying a version first. Use gi.require_version('Notify', '0.7') before import to ensure that the right version gets loaded.
  from gi.repository import Notify
/usr/lib/python2.7/site-packages/solaar/ui/tray.py:148: PyGIWarning: AppIndicator3 was imported without specifying a version first. Use gi.require_version('AppIndicator3', '0.1') before import to ensure that the right version gets loaded.
  from gi.repository import AppIndicator3
12:07:24,745     INFO [MainThread] solaar.upower: connected to system dbus, watching for suspend/resume events

(solaar:17533): Gtk-WARNING **: Theme parsing error: gtk.css:1:8: Expected a valid selector

(solaar:17533): Gtk-WARNING **: Theme parsing error: gtk.css:28:4: Junk at end of value for padding
12:07:24,779     INFO [MainThread] solaar.ui.notify: starting desktop notifications
12:07:24,800     INFO [MainThread] solaar.listener: starting receiver listening threads
12:07:24,805     INFO [MainThread] solaar.listener: receiver event add DeviceInfo(path=u'/dev/hidraw0', vendor_id=u'046d', product_id=u'c52b', serial=u'', release='1203', manufacturer='Logitech', product='USB Receiver', interface=2, driver=u'logitech-djreceiver')
12:07:24,810     INFO [ReceiverListener:hidraw0] logitech_receiver.listener: started with <UnifyingReceiver(/dev/hidraw0,13)> (13)
12:07:24,810     INFO [ReceiverListener:hidraw0] solaar.listener: <UnifyingReceiver(/dev/hidraw0,13)>: notifications listener has started (13)
12:07:24,814     INFO [ReceiverListener:hidraw0] logitech_receiver.receiver: <UnifyingReceiver(/dev/hidraw0,13)>: receiver notifications enabled => ('wireless', 'software present')
12:07:24,820     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <UnifyingReceiver(/dev/hidraw0,13)>: present, No paired devices. (0) 
12:07:24,822     INFO [ReceiverListener:hidraw0] logitech_receiver.receiver: <UnifyingReceiver(/dev/hidraw0,13)>: found new device 1 (4051)
12:07:24,822     INFO [ReceiverListener:hidraw0] solaar.listener: Notification(1,41,04,125140) triggered new device <PairedDevice(1,4051,M510)> (mouse)
12:07:24,826     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <UnifyingReceiver(/dev/hidraw0,13)>: present, 1 paired device. (0) 
12:07:24,982     INFO [ReceiverListener:hidraw0] logitech_receiver.receiver: <PairedDevice(1,4051,M510)>: device notifications enabled None
12:07:25,076     INFO [ReceiverListener:hidraw0] solaar.configuration: saved {u'1020:D0280AEA': {u'_name': u'Wireless Mouse M215'}, u'4051:409BDB26': {u'_name': u'Wireless Mouse M510'}, u'2011:BCFA5C62': {u'fn-swap': False, u'_name': u'Wireless Keyboard K520'}, u'4055:8EF6BE22': {u'_name': u'Unknown device 4055'}, u'_version': u'0.9.2', u'200F:D0280AEA': {u'_name': u'? (200F)'}} to /home/didier/.config/solaar/config.json
12:07:25,173     INFO [ReceiverListener:hidraw0] solaar.configuration: saved {u'1020:D0280AEA': {u'_name': u'Wireless Mouse M215'}, u'4051:409BDB26': {u'_name': u'Wireless Mouse M510'}, u'2011:BCFA5C62': {u'fn-swap': False, u'_name': u'Wireless Keyboard K520'}, u'4055:8EF6BE22': {u'_name': u'Unknown device 4055'}, u'_version': u'0.9.2', u'200F:D0280AEA': {u'_name': u'? (200F)'}} to /home/didier/.config/solaar/config.json
12:07:25,266    ERROR [ReceiverListener:hidraw0] logitech_receiver.listener: processing Notification(1,41,04,125140)
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/logitech_receiver/listener.py", line 185, in run
    self._notifications_callback(n)
  File "/usr/lib/python2.7/site-packages/solaar/listener.py", line 207, in _notifications_handler
    _notifications.process(dev, n)
  File "/usr/lib/python2.7/site-packages/logitech_receiver/notifications.py", line 54, in process
    return _process_device_notification(device, status, notification)
  File "/usr/lib/python2.7/site-packages/logitech_receiver/notifications.py", line 97, in _process_device_notification
    return _process_hidpp10_notification(device, status, n)
  File "/usr/lib/python2.7/site-packages/logitech_receiver/notifications.py", line 174, in _process_hidpp10_notification
    status.changed(active=link_established)
  File "/usr/lib/python2.7/site-packages/logitech_receiver/status.py", line 269, in changed
    self.read_battery(timestamp)
  File "/usr/lib/python2.7/site-packages/logitech_receiver/status.py", line 226, in read_battery
    if battery is None and _hidpp20.FEATURE.SOLAR_DASHBOARD in d.features:
TypeError: argument of type 'NoneType' is not iterable
12:07:25,268     INFO [ReceiverListener:hidraw0] logitech_receiver.receiver: <UnifyingReceiver(/dev/hidraw0,13)>: found new device 2 (2011)
12:07:25,268     INFO [ReceiverListener:hidraw0] solaar.listener: Notification(2,41,04,311120) triggered new device <PairedDevice(2,2011,K520)> (keyboard)
12:07:25,271     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <UnifyingReceiver(/dev/hidraw0,13)>: present, 2 paired devices. (0) 

(solaar:17533): Gdk-CRITICAL **: gdk_window_thaw_toplevel_updates: assertion 'window->update_and_descendants_freeze_count > 0' failed
12:07:26,075     INFO [ReceiverListener:hidraw0] logitech_receiver.receiver: <PairedDevice(2,2011,K520)>: device notifications enabled ('battery status',)
12:07:26,076     INFO [ReceiverListener:hidraw0] solaar.configuration: saved {u'1020:D0280AEA': {u'_name': u'Wireless Mouse M215'}, u'4051:409BDB26': {u'_name': u'Wireless Mouse M510'}, u'2011:BCFA5C62': {u'fn-swap': False, u'_name': u'Wireless Keyboard K520'}, u'4055:8EF6BE22': {u'_name': u'Unknown device 4055'}, u'_version': u'0.9.2', u'200F:D0280AEA': {u'_name': u'? (200F)'}} to /home/didier/.config/solaar/config.json
12:07:27,077     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <PairedDevice(2,2011,K520)>: paired online, {'BATTERY LEVEL': NamedInt(90, 'full'), 'BATTERY CHARGING': False, 'BATTERY STATUS': NamedInt(0, 'discharging'), 'LINK ENCRYPTED': True, 'NOTIFICATION FLAGS': 1048576, 'ERROR': None} (1) 
12:07:27,078     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <PairedDevice(2,2011,K520)>: paired online, {'BATTERY LEVEL': NamedInt(90, 'full'), 'BATTERY CHARGING': False, 'BATTERY STATUS': NamedInt(0, 'discharging'), 'LINK ENCRYPTED': True, 'NOTIFICATION FLAGS': 1048576, 'ERROR': None} (0) 
12:07:27,247  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(1,4051,M510)>: unrecognized Notification(1,02,00,00FD0F0000000000000000)
12:07:27,255  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(1,4051,M510)>: unrecognized Notification(1,02,00,00FAFFFF00000000000000)
12:07:27,263  WARNING [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(1,4051,M510)>: unrecognized Notification(1,02,00,00F7EFFF00000000000000)
...
```

@didierm Can you reproduce the issue with the code from the master branch?

I'm having the same problem with an M510 mouse, and I can, indeed, reproduce the issue with the code from the master branch.

However, curiously, I have another M510 mouse with a different receiver, and THAT works perfectly (has worked perfectly for a year or two, in fact; that's why I got an M510 for my desktop, too).  When I compare outputs from `solaar show`, I get some interesting differences.  From the M510/receiver combination that works properly (older):

```
Unifying Receiver
  Device path  : /dev/hidraw2
  USB id       : 046d:c52b
  Serial       : 1AF09551
    Firmware   : 12.01.B0019
    Bootloader : 02.14
  Has 2 paired device(s) out of a maximum of 6.
  Notifications: wireless, software present (0x000900)
  Device activity counters: 3=71

  2: Wireless Solar Keyboard K750
     Codename     : K750
     Kind         : keyboard
     Wireless PID : 4002
     Protocol     : HID++ 2.0
     Polling rate : 20 ms (50Hz)
     Serial number: 042980F9
     The power switch is located on the edge of top right corner.
     Battery: unknown (device is offline).

  3: Wireless Mouse M510
     Codename     : M510
     Kind         : mouse
     Wireless PID : 1025
     Protocol     : HID++ 1.0
     Polling rate : 8 ms (125Hz)
     Serial number: 5264A7DE
          Firmware: 23.01.B0016
     The power switch is located on the base.
     Notifications: battery status (0x100000).
     Battery: good, discharging.
```

And from the combination where I can't get any data from it (newer):

```
Unifying Receiver
  Device path  : /dev/hidraw3
  USB id       : 046d:c52b
  Serial       : A1938105
    Firmware   : 12.03.B0025
    Bootloader : 02.15
    Other      : AA.AA
  Has 1 paired device(s) out of a maximum of 6.
  Notifications: wireless, software present (0x000900)
  Device activity counters: 1=76

  1: Wireless Mouse M510
     Codename     : M510
     Kind         : mouse
     Wireless PID : 4051
     Protocol     : HID++ 4.5
     Polling rate : 8 ms (125Hz)
     Serial number: A1938105
     The power switch is located on the base.
     Battery status unavailable.
```

It looks to me like there's slightly newer firmware on newer receivers (12.03.B0019 compared with 12.03.B0025, with a newer bootloader as well).  Plus, the newer mouse is reporting the HID++ 4.5 protocol, not HID++ 1.0 from the older mouse.

I'll admit I am unfamiliar with the exact underlying protocols in play here, but if I were to take an educated guess, I'd say the culprit might be Logitech sneaking newer code into an unlabeled newer model of the M510, specifically the HID++ 4.5 protocol.

I've also tried swapping the pairings (newer mouse paired to older receiver and vice versa), but I still get the same result: Solaar can't read from the newer mouse.

Hope this helps!

I can confirm what @CaptainSpam  said. I just bought a M510 today and here is what I found:

1) Solaar cannot read my M510 properties too. It does not report battery nor does it allow turn on/off scrolling and side scrolling features

2) My receiver looks exactly like the newer receiver @CaptainSpam has, firmware 12.03.B0025 and bootloader 02.15 and other AA.AA

3) My M510 mouse reports as HID++ 1.0, wireless PID 4051

4) `solaar-cli show` does not information like @CaptainSpam put, but I can see it through GUI

5) Ubuntu 16.04 with 0.9.2 Solaar

So, besides Mouse HID protocol everything is like @CaptainSpam  and I have same problem here. Although I have 2 unifying receivers at home, both have same versions so I cannot confirm is this mouse would work with old receiver. I have a Anywhere MX at work, I will verify the receiver to see if ti is a older version.

A side note: Logitech already sneaked new features in unlabeled newer products. Last week I was looking for a pair of keyboards, on for home desktop and other for work notebook. I chose the K270 because it is cheap in Brazil and does what I need. I bought one K270 it was not unifying but nano receiver. I went back to store and found out there are two versions of K270, the one bundled in MK270 is no unifying and the one sold separately can be unifying. The only difference is a small symbol on the box and, after open box, the back of keyboard is dark gray on non-unifying and light gray on the unifying. Exactly same product is sold under label K270 with two different radio technology. By the way, nano receiver for MK270 bundle is not recognized by solaar besides solaar states it can work with M185 mouse.

@CaptainSpam and @Lekensteyn ,

Interesting enough I have a M510 and Unifying receiver as your "newer" and I have a Unifying receiver exactly like your "older" receiver. Same results here. I also have a K270 (unifying receiver, it reports HID++ 2.0 - while solaar has a descriptor for a K270 with HID++ 1.0). 

Based on that I changed `lib/logitech_receiver/descriptors.py`:

```
--- a/lib/logitech_receiver/descriptors.py
+++ b/lib/logitech_receiver/descriptors.py
@@ -143,9 +143,7 @@ _PERFORMANCE_MX_DPIS = _NamedInts.range(0x81, 0x8F, lambda x: str((x - 0x80) * 1
 # Keyboards

 _D('Wireless Keyboard K230', protocol=2.0, wpid='400D')
-_D('Wireless Keyboard K270', protocol=1.0,
-                               registers=(_R.battery_status, ),
-                               )
+_D('Wireless Keyboard K270', protocol=2.0, wpid='4003')
 _D('Wireless Keyboard MK330')
 _D('Wireless Compact Keyboard K340', protocol=1.0, wpid='2007',
                                registers=(_R.battery_status, ),
@@ -242,6 +240,7 @@ _D('Wireless Mouse M510', protocol=1.0, wpid='1025',
                                                        _RS.side_scroll(),
                                                ],
                                )
+_D('Wireless Mouse M510v2', protocol=4.5, wpid='4051')
 _D('Couch Mouse M515', protocol=2.0, wpid='4007')
```

Notice I have to duplicate the M510 code adding a v2 in front of it or solaar would complain about duplicate code name. Now the best part:

```
$ bin/solaar show 
Unifying Receiver
  Device path  : /dev/hidraw1
  USB id       : 046d:c52b
  Serial       : 891696B8
    Firmware   : 12.03.B0025
    Bootloader : 02.15
    Other      : AA.AA
  Has 2 paired device(s) out of a maximum of 6.
  Notifications: wireless, software present (0x000900)
  Device activity counters: 1=106, 2=117

  1: Wireless Mouse M510v2
     Codename     : M510v2
     Kind         : mouse
     Wireless PID : 4051
     Protocol     : HID++ 4.5
     Polling rate : 8 ms (125Hz)
     Serial number: 8989B04C
          Firmware: RQM 62.00.B0013
     The power switch is located on the base.
     Supports 22 HID++ 2.0 features:
         0: ROOT                   {0000}   
         1: FEATURE SET            {0001}   
         2: DEVICE FW VERSION      {0003}   
         3: DEVICE NAME            {0005}   
         4: RESET                  {0020}   
         5: BATTERY STATUS         {1000}   
         6: unknown:1802           {1802}   internal, hidden
         7: unknown:1810           {1810}   internal, hidden
         8: unknown:1830           {1830}   internal, hidden
         9: unknown:1862           {1862}   internal, hidden
        10: unknown:1890           {1890}   internal, hidden
        11: unknown:18A0           {18A0}   internal, hidden
        12: unknown:18B1           {18B1}   internal, hidden
        13: REPROG CONTROLS V4     {1B04}   
        14: WIRELESS DEVICE STATUS {1D4B}   
        15: unknown:1DF0           {1DF0}   hidden
        16: unknown:1DF3           {1DF3}   internal, hidden
        17: unknown:1E00           {1E00}   hidden
        18: unknown:1EB0           {1EB0}   internal, hidden                                                                     [18/389]
        19: unknown:1F03           {1F03}   internal, hidden
        20: LOWRES WHEEL           {2130}   
        21: POINTER SPEED          {2205}   
     Battery: 70%, discharging.

  2: Wireless Keyboard K270
     Codename     : K270
     Kind         : keyboard
     Wireless PID : 4003
     Protocol     : HID++ 2.0
     Polling rate : 20 ms (50Hz)
     Serial number: 3D7504FA
          Firmware: RQK 35.00.B0017
     The power switch is located on the top case.
     Supports 12 HID++ 2.0 features:
         0: ROOT                   {0000}   
         1: FEATURE SET            {0001}   
         2: DEVICE FW VERSION      {0003}   
         3: DEVICE NAME            {0005}   
         4: BATTERY STATUS         {1000}   
         5: unknown:1820           {1820}   hidden
         6: REPROG CONTROLS        {1B00}   
         7: WIRELESS DEVICE STATUS {1D4B}   
         8: unknown:1DF0           {1DF0}   hidden
         9: unknown:1DF3           {1DF3}   hidden
        10: ENCRYPTION             {4100}   
        11: KEYBOARD LAYOUT        {4520}   
     Has 8 reprogrammable keys:
         0: Play/Pause                 => Play/Pause                    nonstandard
         1: Mute                       => Mute                          nonstandard
         2: Volume Down                => Volume Down                   nonstandard
         3: Volume Up                  => Volume Up                     nonstandard
         4: MY HOME                    => HomePage                      nonstandard, reprogrammable
         5: Mail                       => Email                         nonstandard, reprogrammable
         6: SLEEP                      => Sleep                         nonstandard, reprogrammable
         7: Calculator                 => Calculator                    nonstandard, reprogrammable
     Battery: 90%, discharging.
```

Both my K270 and M510 started to report correctly. Yet, the smooth scrolling is not enabled on the GUI.

@CaptainSpam , could you please check the P/n and S/n inside battery case of both your M510? I want to compare to mine.
As I said before, I have two K270, one come in combo and other alone, one has M/n ...42 and other M/n ...15. Logitech sites makes no distinguish between both.

I will PR this but want to investigate more first.

Interesting, so the mouse was using HID++ 1.0 before (which was being phased out), but now changed to a newer HID++ version (4.5). I'll ask Logitech, maybe they can provide more details.

> but now changed to a newer HID++ version (4.5). I'll ask Logitech, maybe they can provide more details.

And K270 (unifying version - remember I also have one not unifying) was introduced to solaar as HID++ 1.0 but, mine is HID++ version 2.0.

For the records, since solaar only handles hipp 1.0 and 2.0, defining M510 with 2.0 on descriptors.py results on the same output.

In time, how do we handle such situations? MK270 combo has K270 that is not unifying and has different wireless PID as the K270 unifying version. Since both are HIDpp 2.0 I guess we can put both together in descriptors file. However, if a K270 hipp 1.0 does exist out there, we will break compatibility. Create a second descriptor like I did for M510? Call it "mkII", "v2" or ...? Suggestions  welcome.

@jrbenito : The P/N on the older M510 is 810-001724, and the newer one is 810-004790.  My older M510 lists a PID rather than an S/N, and that is LZ518B4.  The newer one has an S/N of 1630LZ0HVWH8.

@CaptainSpam ,

As expected, my M510 is also P/N 810-004790. Likewise my two K270 keyboards that have two different M/N and are different in radio technology. Thanks to Logitech for not documenting this clearly.

Well, we need to differentiate these two M510 by their WPID I guess.

Thanks.

@jrbenito : Just tested out your code (insofar as it relates to the M510v2), and that seems to do the trick on my end, too, apart from the sidescroll and smoothscroll options, like you mentioned.  That'll do for me, until we learn more about HID++ 4.5.  Thanks!

I got some feedback days ago, but only managed to read it now.

Good news is that there is no difference between 4.5 and 2.0. Logitech is trying to phase out their "SetPoint" software in favor of "Logitech Options" and by using different numbers, they can control which software takes control.

Here is a copy of the document: https://lekensteyn.nl/files/logitech/hidpp4-getprotocolversion.txt
@jrbenito Want to give this a go? I guess that you need to change "2.0" to also accept 3.x and 4.x as aliases (compared to 2.x).

See also #308 for a possible issue related to this version check

> Want to give this a go? I guess that you need to change "2.0" to also accept 3.x and 4.x as aliases (compared to 2.x).

I did a quick look into 'lib/logitech_receiver/hidpp10.py' and 'lib/logitech_receiver/hidpp20.py' files and my first impression is that 'hidpp20.py' is already looking for everything equal or greater than 2.0 and 'hidpp10.py' is looking for everything less than 1.0. So, no changes necessary.

However, I do need to investigate why side scroll and smoothscroll options are not working.

@CaptainSpam , Is solaar able to configure those features on your old M510?
@jrbenito : It can indeed, on the older M510.  The newer M510, even with the change you added, can't.
For the records, modifying the [descriptors.py](https://github.com/pwr/Solaar/blob/a750b32d1495cd8a483f12bd09e6f266e7c65095/lib/logitech_receiver/descriptors.py) to file to not specify any protocol, wpid or codename for M510 ([similar to this](https://github.com/pwr/Solaar/blob/a750b32d1495cd8a483f12bd09e6f266e7c65095/lib/logitech_receiver/descriptors.py#L225) instead of [this](https://github.com/pwr/Solaar/blob/a750b32d1495cd8a483f12bd09e6f266e7c65095/lib/logitech_receiver/descriptors.py#L241-L247)) makes Solaar correct read my HID++ 2,0 and I guess it will also read @CaptainSpam  old version HID++1.0 without creating any new descriptor. However, this makes it impossible to specify features and registers and they are not guessed. Any suggestion? Adding codenames like: M510mkII is a bit odd since Logitech does not differentiate. Maybe change the logic to not assert features and registers but do execute one or another based on protocol.

[Assert code](https://github.com/pwr/Solaar/blob/a750b32d1495cd8a483f12bd09e6f266e7c65095/lib/logitech_receiver/descriptors.py#L55-L71) for protocol features, codename, wpid (every device with HID++ 2.0 has wpid start with 4)

Comments welcome
One option is to recognize both HID++ versions, allowing registers and features to co-exist in the description (these are mutually exclusive anyway). One problem with that is that you do not know the supported registers/feature set before enumeration..
Following the investigation, I issued `solaar -dd config 1` commad and got (cut):

```
<Setting([feature:toggle] M510v2:smooth-scroll=None)>
# Smooth Scrolling
# High-sensitivity mode for vertical scroll with the wheel.
#   possible values: on/true/t/yes/y/1 or off/false/f/no/n/0
15:05:44,239    DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000D 212000]
15:05:44,332    DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000D 00000000000000000000000000000000]
15:05:44,333     INFO [MainThread] solaar.configuration: saved {u'4051:8989B04C': {'_name': u'Wireless Mouse M510'}, '_version': u'0.9.2'} to /home/jbenito/.config/solaar/config.json
smooth-scroll = ? (failed to read from device)
```

The two DEBUG lines are issuing `w[10 01 000D 212000]` to the device, and getting back `r[11 01 000D 00000000000000000000000000000000]` witch is considered failed. 

Trying to set the config by issuing `solaar -dd config 1 smooth-scroll on`:

```
15:09:36,047    DEBUG [MainThread] logitech_receiver.settings: smooth-scroll: write True to <PairedDevice(1,4051,M510v2)>
15:09:36,048     INFO [MainThread] solaar.configuration: saved {u'4051:8989B04C': {u'smooth-scroll': True, u'_name': u'Wireless Mouse M510'}, u'_version': u'0.9.2'} to /home/jbenito/.config/solaar/config.json
15:09:36,048    DEBUG [MainThread] logitech_receiver.settings: BooleanValidator: prepare_write(True, None) => 1
15:09:36,048    DEBUG [MainThread] logitech_receiver.settings: smooth-scroll: prepare write(True) => 1
15:09:36,048    DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000A 212000]
15:09:36,141    DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000A 00000000000000000000000000000000]
solaar: error: failed to set 'smooth-scroll' = 'True' [True]
```
Again, it receives same error back from the device. Here I spot a bug and opened [new ticket (#314)](#314).

Ignoring the bug found above, I got a USBpcap on windows configuring this mouse with the Logitech Options software (setpoint software does not work with new version of M510). Since @github won´t allow me to attach PCAP, here is a summary:

-Set smooth scroll:
Software issues: `CONTROL response data: 1001141d010000` 
    -> `10 01 141d 010000` (short message, device 01, feature to set 141d?, parameter 010000)
Device answers: `Leftover Capture Data: 1101141d01000000000000000000000000000000` 
    -> `11 01 141d 01000...` (long message, device 01, feature set 141d, states 0100...)

-Unset smooth scroll:
Software issues: `CONTROL response data: 1001141d000000`
    -> `10 01 141d` 
Device answers: `Leftover Capture Data: 1101141d00000000000000000000000000000000`
    -> `11 01 141d 00000...`

Checking full debug output from solaar I could not find any attempt to read/write from/to `141d`. 
File [log-show.txt](https://github.com/pwr/Solaar/files/613800/log-show.txt) has output from `solaar -dd show 1`
File [log-config.txt](https://github.com/pwr/Solaar/files/613801/log-config.txt) has output from `solaar -dd config 1`
File [log-set_config.txt](https://github.com/pwr/Solaar/files/613809/log-set_config.txt) has output from `solaar -dd config 1 smooth-scroll on`

As far as I can tell for feature "Smooth Scrolling", solaar uses `HI_RES_SCROLLING=0x2120` and query device with `w[10 01 0009 212000]` getting response as `r[11 01 0009 00000000000000000000000000000000]`.


I´ve implemented feature LOWRES_WHELL and this set the smooth-scroll for this mouse.

Please, take a look [on my repo](https://github.com/jrbenito/Solaar/commit/f4b565759bab58617d970fa2b4f7313d86a78486)

@Lekensteyn ,

This makes sense? I tested by setting it on Linux, and verifying on windows (without turn mouse off) with Logitech Options. Than I set it to false on windows and verified on Linux its state has changed.

@CaptainSpam ,

Could you try this? Although I can set the feature with solaar, the wheel does not work while it is on and work again after turn feature off. I think this can be something with input, I will do a xev once I get time again.
For the records, I tried `xev` and turned on the feature. No button event is generated while with feature off the events are correct generated. 

Also, if I unset LOWRES_WHELL on Linux, move the receiver to Windows machine, set the feature (on Logitech Options software it is called Smooth Scrolling), move receiver back to Linux (all without turn mouse off), scrolling stop work. It work again if I, again unset feature on Linux Solaar and/or Windows Logitech Options. This confirms that feature LOWRES_WHELL is the right one to (un)set for Smooth Scrolling on this mouse. However, as already said, `xev` shows no event when feature is on while correct shows button events when LOWRES_WHELL is off. _Maybe something ignored at kernel level?_

@Lekensteyn any idea?
@jrbenito I'll have a look at it later, poke me in meantime if I forget about it :-)

Brief comments:
>     -> 10 01 141d 010000 (short message, device 01, feature to set 141d?, parameter 010000)

IIRC this means feature index 14h (20) LOWRES WHEEL (feature ID 2130). I will try to request some documentation, are there other features you want to learn about?
>  I will try to request some documentation, are there other features you want to learn about?

For the LOWRES_WHEEL I would like to know what happens to the button events when it is turned on. Meanwhile feature is already "working", we can turn it on/off and all information about M510 is available at GUI. Need to figure out the best way to PR this, will wait for your comments.

Regarding other features, I think we need to figure out how to correct assert receivers because some does not report max device supported and this is how we differentiate between them. All my other devices have support, to close other tickets we might need help from device owners (_no logs, no bugs_ as we use to say at my workplace). Anyway, any information is better than no information right?
@jrbenito The max devices question was already answered, there is no such field on older receivers using the "Quad" protocol.

I'll ask for docs for LOWRES_WHEEL (2130) after the weekend, might have a higher success probability for obvious reasons :D
@jrbenito : Sorry, I didn't have a chance to test things out until now.  Unfortunately, assuming I've got the right code installed, now Solaar doesn't even show the newer M510 in the device list, connected or not.  The old M510 still works the same, though.
@CaptainSpam If it does not show, can you run `solaar --debug` and post the output here? (upload a .txt file or add the output if it is not too large)

(jrbenito, I just sent a mail for lowres wheel docs request)
Here's my debug output.  Everything up to the TypeError happens almost immediately, and the large amount of "unrecognized Notification" errors happen as the mouse is moving beyond that.

[solaar_debug.txt](https://github.com/pwr/Solaar/files/635329/solaar_debug.txt)

@jrbenito Please find the docs for the Ratchet Wheel feature (0x2130) at https://lekensteyn.nl/files/logitech/x2130_ratchetwheel.html

@CaptainSpam If you use Python 3, do you still have the issue?
@Lekensteyn I do.  Python 3 gives me the same problem.  Here's the debug output from running it that way, just in case:

[solaar_debug_python3.txt](https://github.com/pwr/Solaar/files/643458/solaar_debug_python3.txt)

(between that one and the initial debug log, I cleared out my config.json from ~/.config/solaar; I tried running it in Python 2 again with a clean config file, but got the same result)
@Lekensteyn ,

thanks, will check docs a bit further. At first glance my attention was caught by: 

> When  reports are diverted to HID++ they are not reported on HID.

So, since Linux does not process HID++ events, just HID, this explains why turning on this feature makes the wheel not recognized by `xev`. No way to make it work without patching Linux Kernel. I guess the same applies to some other features like remap keys. 

@CaptainSpam .

Sorry for delay, last two weeks and maybe this one I have lot of work and no time to check. Will do as soon as possible.
@jrbenito It can work when diverted to HID++, but that is ideally handled in the kernel (like how the T650 touchpad and some other touch mice have their multi-touch support in the kernel).

To implement this in userspace instead, you would need to create a "uinput" device (for a userspace input device) where you can send events to.
PR #337 also implement LOWRES_WHEEL for M185 mice.

Resolving patch:
diff --git a/lib/logitech_receiver/descriptors.py b/lib/logitech_receiver/descriptors.py
--- a/lib/logitech_receiver/descriptors.py
+++ b/lib/logitech_receiver/descriptors.py
@@ -250,6 +250,10 @@ def _D(name, codename=None, kind=None, wpid=None, protocol=None, registers=None,
 							_RS.side_scroll(),
 						],
 				)
+_D('Wireless Mouse M510', codename='M510v2', protocol=2.0, wpid='4051',
+				settings=[
+							_FS.lowres_smooth_scroll(),
+				])
 _D('Couch Mouse M515', protocol=2.0, wpid='4007')
 _D('Wireless Mouse M525', protocol=2.0, wpid='4013')
 _D('Touch Mouse M600', protocol=2.0, wpid='401A')


Test patch: