From 902ed8a3fd67c786fd3176de52ec0ddc54492be5 Mon Sep 17 00:00:00 2001 From: Kolton Yager Date: Mon, 20 Nov 2023 14:22:12 -0800 Subject: [PATCH] Fix for issue #146 The issue arises due to the reMarkable software version no longer being accurately reflected in `/etc/version`. This causes rmview to think it is connecting to an older version. I've fixed this by switching rmview's SW version logic over to the semantic versioning scheme used by recent releases. The SW version is taken from the `REMARKABLE_RELEASE_VERSION` value in `/usr/share/remarkable/update.conf`, as suggested by @Eeems. Support for older versions is to be maintained by mapping the older timestamp version numbers back to the corresponding semantic versions. --- src/rmview/connection.py | 18 +++++++++++++++++- src/rmview/rmparams.py | 12 ++++++++++++ src/rmview/rmview.py | 6 +++--- src/rmview/screenstream/screenshare.py | 2 +- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/rmview/connection.py b/src/rmview/connection.py index 7c92473..31b1a5b 100644 --- a/src/rmview/connection.py +++ b/src/rmview/connection.py @@ -2,6 +2,8 @@ from PyQt5.QtCore import * from PyQt5.QtWidgets import * +from .rmparams import timestamp_to_version + import paramiko import struct @@ -161,7 +163,20 @@ def _getVersion(self): def _getSwVersion(self): _, out, _ = self.client.exec_command("cat /etc/version") - return int(out.read().decode("utf-8")) + version_ts = int(out.read().decode("utf-8")) + version = timestamp_to_version(version_ts) + + try: + _, out, err = self.client.exec_command(r"grep 'REMARKABLE_RELEASE_VERSION=' /usr/share/remarkable/update.conf " + r"| sed -r 's/(REMARKABLE_RELEASE_VERSION=)([0-9a-zA-Z.]+)/\2/'") + config_version = tuple(int(v) for v in out.read().decode("utf-8").strip().split('.')) + if (len(config_version) < 4): config_version += (0,)*(len(config_version) - 4); + version = config_version + log.debug("Using update.conf as SW version authority") + except Exception as e: + log.debug("Using /etc/version as SW version authority") + + return version @pyqtSlot() @@ -179,6 +194,7 @@ def run(self): self.client.hostname = self.address self.client.deviceVersion, self.client.fullDeviceVersion = self._getVersion() self.client.softwareVersion = self._getSwVersion() + log.info("Detected SW version: {}".format('.'.join(str(v) for v in self.client.softwareVersion))) self.signals.onConnect.emit(self.client) except Exception as e: log.error("Could not connect to %s: %s", self.address, e) diff --git a/src/rmview/rmparams.py b/src/rmview/rmparams.py index 3bb972a..4fcd5e5 100644 --- a/src/rmview/rmparams.py +++ b/src/rmview/rmparams.py @@ -9,6 +9,18 @@ '2.9.1.236': 20210820111232 } +# This mapping was adapted from the above `SW_VER_TIMESTAMPS` dictionary. +# Newer versions do not use timestamp based versioning, and are likewise not represented here. +def timestamp_to_version(ts): + if ts < SW_VER_TIMESTAMPS["2.7"]: + return (2, 6, 0, 0) + elif ts < SW_VER_TIMESTAMPS["2.9"]: + return (2, 7, 0, 0) + elif ts < SW_VER_TIMESTAMPS["2.9.1.236"]: + return (2, 9, 0, 0) + else: + return (2, 9, 1, 236) + # evtype_sync = 0 e_type_key = 1 diff --git a/src/rmview/rmview.py b/src/rmview/rmview.py index 2643c1e..3eb32a8 100644 --- a/src/rmview/rmview.py +++ b/src/rmview/rmview.py @@ -302,7 +302,7 @@ def connected(self, ssh): self.ssh = ssh self.viewer.setWindowTitle("rMview - " + ssh.hostname) - log.info("Detected %s", ssh.fullDeviceVersion) + log.info("Detected device: %s", ssh.fullDeviceVersion) version = ssh.deviceVersion if version not in [1, 2]: log.error("Device is unsupported: '%s' [%s]", ssh.fullDeviceVersion, version or "unknown device") @@ -312,11 +312,11 @@ def connected(self, ssh): backend = self.config.get('backend', 'auto') if backend == 'auto': - if ssh.softwareVersion >= SW_VER_TIMESTAMPS['2.9']: + if ssh.softwareVersion >= (2, 9, 0, 0): backend = 'screenshare' else: backend = 'vncserver' - if ssh.softwareVersion >= SW_VER_TIMESTAMPS['2.7']: + if ssh.softwareVersion >= (2, 7, 0, 0): log.warning("Detected version 2.7 or 2.8. The server might not work with these versions.") log.info("Using backend '%s'", backend) diff --git a/src/rmview/screenstream/screenshare.py b/src/rmview/screenstream/screenshare.py index 404a180..e00d657 100644 --- a/src/rmview/screenstream/screenshare.py +++ b/src/rmview/screenstream/screenshare.py @@ -134,7 +134,7 @@ def startVncClient(self, challenge=None): def run(self): log.info("Connecting to ScreenShare, make sure you enable it") try: - if self.ssh.softwareVersion > SW_VER_TIMESTAMPS['2.9.1.236']: + if self.ssh.softwareVersion > (2, 9, 1, 236): log.warning("Authenticating, please wait...") challengeReader = ChallengeReaderProtocol(self.runVnc) reactor.listenUDP(5901, challengeReader)