Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Readers > Kobo Reader > Kobo Developer's Corner

Notices

Reply
 
Thread Tools Search this Thread
Old 10-28-2022, 07:26 PM   #16
elinkser
Groupie
elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.
 
Posts: 185
Karma: 146236
Join Date: Oct 2022
Device: Kobo Clara HD
Hey I appreciate the effort.


***UPDATE Dec 4***
So I finally got around to building from source, and found einkvnc does indeed work on my Kobo Clara HD, with droidVNC-NG (from F-Droid) running as VNC server on my phone! The display is upside down and there is no touch on the Kobo, but the resolution is clear and the response is good for browsing.

Note* If someone is building Plato with the Linaro build tools, they might get a GLIBC not found error as described here:
https://kobzol.github.io/rust/ci/202...der-glibc.html

I took their advice and used an old Linaro release from here:
https://releases.linaro.org/componen...nux-gnueabihf/

Also the download.sh script in the /eink-vnc-main/client/ folder referred to a non-findable target so I changed the line to:
archive="plato-0.9.34.zip"
and plopped that zip (that was produced by the plato build) in the folder.




The weird thing is, I went back and tested the original (prebuilt) binary, and it ALSO works!?!


So I'm chalking the original error up to a flaky network connection. But I'm glad it happened because it got me to 1)use the fantastic Rust build system, and 2)build and install Plato, which is a pretty cool complement to KOReader.


So congrats on the great work, and sorry for the confusion.
Einkvnc IS working on Kobo Clara HD!

Last edited by elinkser; 02-21-2023 at 09:34 PM. Reason: build tips
elinkser is offline   Reply With Quote
Old 11-02-2022, 08:09 PM   #17
elinkser
Groupie
elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.
 
Posts: 185
Karma: 146236
Join Date: Oct 2022
Device: Kobo Clara HD
Quote:
Originally Posted by DNSB View Post
It worked. It makes it much easier when scrolling through messages.
Agreed.Although I tend to not like javascript thingies that obstruct visibility, printability, and searchability of web content, the tradeoff in readability seems worth it in this kind of long debug outburst.
elinkser is offline   Reply With Quote
Old 12-14-2022, 08:22 PM   #18
elinkser
Groupie
elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.
 
Posts: 185
Karma: 146236
Join Date: Oct 2022
Device: Kobo Clara HD
***SECURITY REMINDER***
DO NOT ACTUALLY DO THE FOLLOWING ON A PHONE THAT YOU DO BANKING WITH!
E.G.IF YOU HAD TELNET SERVER RUNNING OR OTHER UNKNOWN VULNERABILITY ON YOUR KOBO, THE VNC GIVES AN INTRUDER ACCESS TO YOUR PHONE VIA YOUR KOBO.
USE A DUMMY PHONE OR TABLET TO PLAY WITH.
***END SECURITY REMINDER***


* UPDATE: droidVNC-NG has a sliding scale that sets the size of the window that will appear on your Kobo (you have to stop the server to adjust it).
Note that if you set the slider too far to the right, einkvnc won't display.
I set the slider 70% of the way over for my Clara.
The vnc client view on the Kobo is in portrait orientation, even if you rotate the Kobo display, so if your Android rotation is landscape, you have to slide the scale even more to the left and everything will be tiny!

Conveniently, droidVNC-NG (the android VNC server from f-droid) almost always seems to present me with the same server address each time I've run it.
*But check, because every once in a while it changes, and you will be spinning your wheels if you don't catch it.

So I can access it handily from the nickel menu:

menu_item :main :Einkvnc :cmd_spawn :quiet:exec /mnt/onboard/opt/einkvnc 192.168.43.1 5900 --password mypassword --contrast 2
chain_success :dbg_toast :Started einkvnc 192.168.43.1 5900
chain_failure :dbg_toast :Error


** Actually....that was only true while using a third device as the hotspot server. Now that I've been using the droidVNC-NG server device as the hotspot server too, the vnc server address seems to change EVERY time! Not so handy for the nickel menu. But since you are already networked with the Kobo, it is no biggie to run the einkvnc command in a ConnectBot telnet client app running on the droidVNC-NG server device.

***SECURITY REMINDER***
Telnet sessions are in cleartext INCLUDING LOGIN SESSIONS, so only use on a private network, if at all!
If you always have DEVMODE set to ON for whatever reasons , that means Telnet is on by default, unless you toggle it off , e.g. using NickelMenu.

You can install KOReader to get the more secure SSH option, and NiLuJe's kobostuff provides a package that includes an SSH binary.

You can start the KOReader SSH server via NickelMenu.


**********************************

***UPDATE*** See post #20, two posts down, to see how NickelDBus fixes our problem!

It's a pretty cool way to browse in eink on a Clara HD while controlling by inputting on my tablet.
HOWEVER...Consider the security implications of accessing a secure device (phone that you do banking/email on) from an insecure device i.e. ereader.

You may try setting ForceWifiOn=true (if you haven't done so already) in your config file [DeveloperSettings] (in KOReader, navigate to .kobo/Kobo/Kobo eReader.conf, Open With Text editor) or else the dropouts may cause frustration.


I have found that none of my Android devices need to be internet-connected to set up as a hotspot so the Kobo can network with my tablet or keyboard-equipped Blackberry Priv with no internet!
*Note:The open source droidVNC-NG vnc server requires minimum Android 7 so the Priv is a no-go, being locked at 6, although it can run ConnectBot, and closed source vnc server Alpha Vnc Lite.

Unfortunately einkvnc does only fill about 3/4 of the Kobo Clara HD display.

It would be great if I could change some parameter to make it fill the whole display. I tried building with changed resolution/dpi but no luck!


***ADDITIONAL DEBUGGING***

We see the ClaraHD display size from "eink-vnc-main/client/src/device.rs":
"nova" => Device {
model: Model::ClaraHD,
proto: TouchProto::MultiB,
dims: (1072, 1448),
dpi: 300,
},


We can get logging info using the "RUST_LOG=info" setting when invoking einkvnc:
http://rust-lang-nursery.github.io/log/env_logger/


So if we try invoking the einkvnc vnc client(from a remote Telnet terminal) at three different scaling settings of the droidVNC-NG vncserver running on the android tablet, we get the following results:

Spoiler:

(droidVNC-NG vnc server scaling @ 70%)
# RUST_LOG=info ./einkvnc 192.168.43.185 5900 --password mypw --contrast 2
[2023-04-09T18:11:33Z INFO einkvnc] connecting to 192.168.43.185:5900
[2023-04-09T18:11:34Z INFO einkvnc] connected to "Nexus 7", 864x1344 framebuffer
[2023-04-09T18:11:34Z INFO einkvnc] received PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }
[2023-04-09T18:11:35Z INFO einkvnc] enforced PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 }
Framebuffer rotation: 1 -> 1.
[2023-04-09T18:11:35Z INFO einkvnc] Missed frame, excess Δt: 54ms
[2023-04-09T18:11:36Z INFO einkvnc] Missed frame, excess Δt: 70ms
...

(droidVNC-NG vnc server scaling @ 80%)
# RUST_LOG=info ./einkvnc 192.168.43.185 5900 --password mypw --contrast 2
[2023-04-09T18:19:00Z INFO einkvnc] connecting to 192.168.43.185:5900
[2023-04-09T18:19:01Z INFO einkvnc] connected to "Nexus 7", 1152x1536 framebuffer
[2023-04-09T18:19:01Z INFO einkvnc] received PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }
[2023-04-09T18:19:02Z INFO einkvnc] enforced PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 }
Framebuffer rotation: 1 -> 1.
[2023-04-09T18:19:03Z INFO einkvnc] Missed frame, excess Δt: 184ms
[2023-04-09T18:19:11Z INFO einkvnc] Missed frame, excess Δt: 175ms
...

(droidVNC-NG vnc server scaling @ 90%)
# RUST_LOG=info ./einkvnc 192.168.43.185 5900 --password mypw --contrast 2
[2023-04-09T18:26:44Z INFO einkvnc] connecting to 192.168.43.185:5900
[2023-04-09T18:26:45Z INFO einkvnc] connected to "Nexus 7", 1152x1728 framebuffer
[2023-04-09T18:26:45Z INFO einkvnc] received PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }
[2023-04-09T18:26:47Z INFO einkvnc] enforced PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 }
Framebuffer rotation: 1 -> 1.
Bus error


Now try the "RUST_LOG=debug" setting for a little more detailed info at the 70% and 75% server scaling settings:

(droidVNC-NG vnc server scaling @ 70%)
# RUST_LOG=debug ./einkvnc 192.168.43.5 5900 --password mypw --contrast 2
[2023-04-10T21:03:42Z INFO einkvnc] connecting to 192.168.43.5:5900
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] <- Version::Rfb38
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] -> Version::Rfb38
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] <- SecurityTypes([VncAuthentication, Unknown(16)])
[2023-04-10T21:03:42Z DEBUG einkvnc] available authentication methods: [Password]
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] -> SecurityType::VncAuthentication
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] -> ClientInit { shared: true }
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] <- ServerInit { framebuffer_width: 864, framebuffer_height: 1344, pixel_format: PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }, name: "Nexus 7" }
[2023-04-10T21:03:42Z INFO einkvnc] connected to "Nexus 7", 864x1344 framebuffer
[2023-04-10T21:03:42Z INFO einkvnc] received PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] 0
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] 01
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] 02
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] <- FramebufferUpdate { count: 1 }
[2023-04-10T21:03:42Z DEBUG einkvnc::vnc::client] <- Rectangle { x_position: 0, y_position: 0, width: 864, height: 1344, encoding: Raw }
[2023-04-10T21:03:43Z DEBUG einkvnc::vnc::client] <- ...pixels
[2023-04-10T21:03:43Z DEBUG einkvnc::vnc::client] 1
[2023-04-10T21:03:43Z DEBUG einkvnc::vnc::client] -> SetPixelFormat(PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 })
[2023-04-10T21:03:43Z DEBUG einkvnc::vnc::client] 2
[2023-04-10T21:03:43Z DEBUG einkvnc::vnc::client] 3
[2023-04-10T21:03:43Z INFO einkvnc] enforced PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 }
[2023-04-10T21:03:43Z DEBUG einkvnc::vnc::client] -> SetEncodings([CopyRect, Zrle])
Framebuffer rotation: 1 -> 1.
[2023-04-10T21:03:43Z DEBUG einkvnc] End of frame!
[2023-04-10T21:03:44Z DEBUG einkvnc::vnc::client] <- FramebufferUpdate { count: 1 }
[2023-04-10T21:03:44Z DEBUG einkvnc::vnc::client] <- Rectangle { x_position: 0, y_position: 0, width: 864, height: 1344, encoding: Zrle }
[2023-04-10T21:03:44Z DEBUG einkvnc::vnc::client] <- ...compressed pixels
[2023-04-10T21:03:44Z DEBUG einkvnc] Put pixels
[2023-04-10T21:03:44Z DEBUG einkvnc] network Δt: 0
[2023-04-10T21:03:44Z DEBUG einkvnc] postproc Δt: 0
[2023-04-10T21:03:44Z DEBUG einkvnc] draw Δt: 0
[2023-04-10T21:03:44Z DEBUG einkvnc] rects Δt: 0
...
[2023-04-10T21:07:28Z DEBUG einkvnc] Put pixels
[2023-04-10T21:07:28Z DEBUG einkvnc] network Δt: 1000
[2023-04-10T21:07:28Z DEBUG einkvnc] postproc Δt: 1001
[2023-04-10T21:07:28Z DEBUG einkvnc] draw Δt: 1001
[2023-04-10T21:07:28Z DEBUG einkvnc] rects Δt: 1001
[2023-04-10T21:07:28Z DEBUG einkvnc] End of frame!
[2023-04-10T21:07:28Z DEBUG einkvnc] Updating dirty rect Rectangle { min: Point { x: 0, y: 0 }, max: Point { x: 864, y: 1344 } }
...


(droidVNC-NG vnc server scaling @ 75%)
# RUST_LOG=debug ./einkvnc 192.168.43.5 5900 --password mypw --contrast 2
[2023-04-10T21:11:06Z INFO einkvnc] connecting to 192.168.43.5:5900
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] <- Version::Rfb38
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] -> Version::Rfb38
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] <- SecurityTypes([VncAuthentication, Unknown(16)])
[2023-04-10T21:11:06Z DEBUG einkvnc] available authentication methods: [Password]
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] -> SecurityType::VncAuthentication
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] -> ClientInit { shared: true }
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] <- ServerInit { framebuffer_width: 1152, framebuffer_height: 1440, pixel_format: PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }, name: "Nexus 7" }
[2023-04-10T21:11:06Z INFO einkvnc] connected to "Nexus 7", 1152x1440 framebuffer
[2023-04-10T21:11:06Z INFO einkvnc] received PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] 0
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] 01
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] 02
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] <- FramebufferUpdate { count: 1 }
[2023-04-10T21:11:06Z DEBUG einkvnc::vnc::client] <- Rectangle { x_position: 0, y_position: 0, width: 1152, height: 1440, encoding: Raw }
[2023-04-10T21:11:08Z DEBUG einkvnc::vnc::client] <- ...pixels
[2023-04-10T21:11:08Z DEBUG einkvnc::vnc::client] 1
[2023-04-10T21:11:08Z DEBUG einkvnc::vnc::client] -> SetPixelFormat(PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 })
[2023-04-10T21:11:08Z DEBUG einkvnc::vnc::client] 2
[2023-04-10T21:11:08Z DEBUG einkvnc::vnc::client] 3
[2023-04-10T21:11:08Z INFO einkvnc] enforced PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 }
[2023-04-10T21:11:08Z DEBUG einkvnc::vnc::client] -> SetEncodings([CopyRect, Zrle])
Framebuffer rotation: 1 -> 1.
[2023-04-10T21:11:08Z DEBUG einkvnc] End of frame!
[2023-04-10T21:11:08Z DEBUG einkvnc::vnc::client] <- FramebufferUpdate { count: 1 }
[2023-04-10T21:11:08Z DEBUG einkvnc::vnc::client] <- Rectangle { x_position: 0, y_position: 0, width: 1152, height: 1440, encoding: Zrle }
[2023-04-10T21:11:08Z DEBUG einkvnc::vnc::client] <- ...compressed pixels
[2023-04-10T21:11:08Z DEBUG einkvnc] Put pixels
[2023-04-10T21:11:08Z DEBUG einkvnc] network Δt: 0
[2023-04-10T21:11:08Z DEBUG einkvnc] postproc Δt: 0
[2023-04-10T21:11:08Z DEBUG einkvnc] draw Δt: 0
[2023-04-10T21:11:08Z DEBUG einkvnc] rects Δt: 0
...
[2023-04-10T21:31:09Z DEBUG einkvnc] Put pixels
[2023-04-10T21:31:09Z DEBUG einkvnc] network Δt: 1365
[2023-04-10T21:31:09Z DEBUG einkvnc] postproc Δt: 1365
[2023-04-10T21:31:09Z DEBUG einkvnc] draw Δt: 1365
[2023-04-10T21:31:09Z DEBUG einkvnc] rects Δt: 1365
[2023-04-10T21:31:09Z DEBUG einkvnc] End of frame!
[2023-04-10T21:31:09Z DEBUG einkvnc] Updating dirty rect Rectangle { min: Point { x: 0, y: 0 }, max: Point { x: 1152, y: 1440 } }
[2023-04-10T21:31:09Z INFO einkvnc] Missed frame, excess Δt: 1341ms
...







Although the einkvnc client debug messages indicate drawing to the screen at the 75% scaling, the display does not actually get updated. Note that the droidVNC-NG "75%" scaling sets the x-dimension to 1152, which is beyond the 1072 x-dimension of the Clara, unlike the 864 x-dimension of the droidVNC-NG "70%" scaling.


Of the four server scaling settings tested, only the 70% setting yields a framebuffer size (864x1344) that is within the limits of the ClaraHD display size (1072x1448).


I found by adjusting the android tablet's resolution in Display settings (or DPI/minimum width in Developer settings) I could make things bigger on the screen (less items fit on the screen, consequently more scrolling is required).

However, the vnc client window on the Clara continued to be the same size - still about three quarters of the display.


***

*EDIT:Looks like full screen vnc with touch input and landscape rotation is also available via chroot. Extra Clara HD config steps on post #46.

Last edited by elinkser; 05-15-2023 at 04:45 PM. Reason: debug with logging
elinkser is offline   Reply With Quote
Old 04-11-2023, 06:06 PM   #19
elinkser
Groupie
elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.
 
Posts: 185
Karma: 146236
Join Date: Oct 2022
Device: Kobo Clara HD
RECOMPILE einkvnc TO RUN IN LANDSCAPE MODE:

RECOMPILE einkvnc TO RUN IN LANDSCAPE MODE:
** tested only on my Clara HD, try at your own risk! **


***SECURITY REMINDER***
Telnet sessions are in cleartext INCLUDING LOGIN SESSIONS, so only use on a private network, if at all!
If you always have DEVMODE set to ON for whatever reasons , that means Telnet is on by default, unless you toggle it off , e.g. using NickelMenu.

You can install KOReader to get the more secure SSH option, and NiLuJe's kobostuff provides a package that includes an SSH binary.

You can start the KOReader SSH server via NickelMenu.

**********************************


NOTE: YOU MUST ALSO ROTATE THE VNC SERVER DEVICE TO LANDSCAPE ORIENTATION.

(Put the ClaraHD in landscape mode using the SECOND nickel menu entry):
# Nickel_Orientation Actions
menu_item : main : Orientation - LANDSCAPE - handle above : nickel_orientation: landscape
menu_item : main : Orientation - LANDSCAPE - handle below : nickel_orientation: inverted_landscape
menu_item : main : Orientation - PORTRAIT - handle on left : nickel_orientation: inverted_portrait
menu_item : main : Orientation - PORTRAIT - handle on right : nickel_orientation: portrait
#



IF YOU RUN THE ORIGINAL BINARY (FROM A TELNET CLIENT):

(droidVNC-NG vnc server scaling @ 70%, LANDSCAPE ORIENTATION)
# RUST_LOG=debug ./einkvnc 192.168.43.235 5900 --password mypw --contrast 2
Spoiler:

[2023-04-11T20:15:58Z INFO einkvnc] connecting to 192.168.43.235:5900
[2023-04-11T20:15:58Z DEBUG einkvnc::vnc::client] <- Version::Rfb38
[2023-04-11T20:15:58Z DEBUG einkvnc::vnc::client] -> Version::Rfb38
[2023-04-11T20:15:59Z DEBUG einkvnc::vnc::client] <- SecurityTypes([VncAuthentication, Unknown(16)])
[2023-04-11T20:15:59Z DEBUG einkvnc] available authentication methods: [Password]
[2023-04-11T20:15:59Z DEBUG einkvnc::vnc::client] -> SecurityType::VncAuthentication
[2023-04-11T20:15:59Z DEBUG einkvnc::vnc::client] -> ClientInit { shared: true }
[2023-04-11T20:15:59Z DEBUG einkvnc::vnc::client] <- ServerInit { framebuffer_width: 1408, framebuffer_height: 840, pixel_format: PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }, name: "Nexus 7" }
[2023-04-11T20:15:59Z INFO einkvnc] connected to "Nexus 7", 1408x840 framebuffer
[2023-04-11T20:15:59Z INFO einkvnc] received PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }
[2023-04-11T20:15:59Z DEBUG einkvnc::vnc::client] 0
[2023-04-11T20:15:59Z DEBUG einkvnc::vnc::client] 01
[2023-04-11T20:15:59Z DEBUG einkvnc::vnc::client] 02
[2023-04-11T20:15:59Z DEBUG einkvnc::vnc::client] <- FramebufferUpdate { count: 1 }
[2023-04-11T20:15:59Z DEBUG einkvnc::vnc::client] <- Rectangle { x_position: 0, y_position: 0, width: 1408, height: 840, encoding: Raw }
[2023-04-11T20:16:00Z DEBUG einkvnc::vnc::client] <- ...pixels
[2023-04-11T20:16:00Z DEBUG einkvnc::vnc::client] 1
[2023-04-11T20:16:00Z DEBUG einkvnc::vnc::client] -> SetPixelFormat(PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 })
[2023-04-11T20:16:00Z DEBUG einkvnc::vnc::client] 2
[2023-04-11T20:16:00Z DEBUG einkvnc::vnc::client] 3
[2023-04-11T20:16:00Z INFO einkvnc] enforced PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 }
[2023-04-11T20:16:00Z DEBUG einkvnc::vnc::client] -> SetEncodings([CopyRect, Zrle])
Framebuffer rotation: 1 -> 1.
[2023-04-11T20:16:00Z DEBUG einkvnc] End of frame!
[2023-04-11T20:16:00Z DEBUG einkvnc::vnc::client] <- FramebufferUpdate { count: 1 }
[2023-04-11T20:16:00Z DEBUG einkvnc::vnc::client] <- Rectangle { x_position: 0, y_position: 0, width: 1408, height: 840, encoding: Zrle }
[2023-04-11T20:16:00Z DEBUG einkvnc::vnc::client] <- ...compressed pixels
[2023-04-11T20:16:00Z DEBUG einkvnc] Put pixels
[2023-04-11T20:16:00Z DEBUG einkvnc] network Δt: 0
[2023-04-11T20:16:00Z DEBUG einkvnc] postproc Δt: 0
[2023-04-11T20:16:00Z DEBUG einkvnc] draw Δt: 2
[2023-04-11T20:16:00Z DEBUG einkvnc] rects Δt: 2


LANDSCAPE MODE DIDN'T WORK.
NOW RECOMPILE THE einkvnc SOURCE:

$ cd Downloads/eink-vnc-main/

$ grep -n -r -C2 'Framebuffer rotation:' client/
client/src/framebuffer/kobo1.rs-321- self.frame_size = (self.var_info.yres * self.fix_info.line_length) as libc::size_t;
client/src/framebuffer/kobo1.rs-322-
client/src/framebuffer/kobo1.rs:323: println!("Framebuffer rotation: {} -> {}.", n, self.rotation());
client/src/framebuffer/kobo1.rs-324-
client/src/framebuffer/kobo1.rs-325- Ok((self.var_info.xres, self.var_info.yres))

$ grep -n -r -C2 'set_rotation(' client/
client/src/main.rs-206- {
client/src/main.rs-207- let startup_rotation = 1;
client/src/main.rs:208: fb.set_rotation(startup_rotation).ok();
client/src/main.rs-209- }
client/src/main.rs-210-
--
client/src/framebuffer/mod.rs-45- fn wait(&self, token: u32) -> Result<i32, Error>;
client/src/framebuffer/mod.rs-46- fn save(&self, path: &str) -> Result<(), Error>;
client/src/framebuffer/mod.rs:47: fn set_rotation(&mut self, n: i8) -> Result<(u32, u32), Error>;
client/src/framebuffer/mod.rs-48- fn set_monochrome(&mut self, enable: bool);
client/src/framebuffer/mod.rs-49- fn set_dithered(&mut self, enable: bool);
--

MODIFY LINE 207 in main.rs TO:
{
let startup_rotation = rotarg;
fb.set_rotation(startup_rotation).ok();
}


ADD AN ADDITIONAL ARGUMENT TO main.rs AT LINE 102:
.arg(
Arg::with_name("ROTARG")
.help("rotation (1-4), tested on a Clara HD, try at own risk")
.long("rotarg")
.takes_value(true),
)
.get_matches();

let rotarg = value_t!(matches.value_of("ROTARG"), i8).unwrap_or(1);
if (rotarg < 1) || (rotarg > 4) {
rotarg = 1;
}
let host = matches.value_of("HOST").unwrap();


$ cd client/

$ ./build.sh

$ cp target/arm-unknown-linux-gnueabihf/release/einkvnc ../einkvncROTARG


COPY THE einkvncROTARG BINARY TO YOUR KOBO AND TRY AGAIN:

(droidVNC-NG vnc server scaling @ 70%, LANDSCAPE ORIENTATION)
# RUST_LOG=debug ./einkvncROTARG 192.168.43.235 5900 --password mypw --contrast 2 --rotarg 2
Spoiler:

[2023-04-11T21:31:12Z INFO einkvnc] connecting to 192.168.43.235:5900
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] <- Version::Rfb38
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] -> Version::Rfb38
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] <- SecurityTypes([VncAuthentication, Unknown(16)])
[2023-04-11T21:31:12Z DEBUG einkvnc] available authentication methods: [Password]
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] -> SecurityType::VncAuthentication
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] -> ClientInit { shared: true }
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] <- ServerInit { framebuffer_width: 1408, framebuffer_height: 840, pixel_format: PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }, name: "Nexus 7" }
[2023-04-11T21:31:12Z INFO einkvnc] connected to "Nexus 7", 1408x840 framebuffer
[2023-04-11T21:31:12Z INFO einkvnc] received PixelFormat { bits_per_pixel: 32, depth: 32, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 0, green_shift: 8, blue_shift: 16 }
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] 0
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] 01
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] 02
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] <- FramebufferUpdate { count: 1 }
[2023-04-11T21:31:12Z DEBUG einkvnc::vnc::client] <- Rectangle { x_position: 0, y_position: 0, width: 1408, height: 840, encoding: Raw }
[2023-04-11T21:31:13Z DEBUG einkvnc::vnc::client] <- ...pixels
[2023-04-11T21:31:13Z DEBUG einkvnc::vnc::client] 1
[2023-04-11T21:31:13Z DEBUG einkvnc::vnc::client] -> SetPixelFormat(PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 })
[2023-04-11T21:31:13Z DEBUG einkvnc::vnc::client] 2
[2023-04-11T21:31:13Z DEBUG einkvnc::vnc::client] 3
[2023-04-11T21:31:13Z INFO einkvnc] enforced PixelFormat { bits_per_pixel: 8, depth: 16, big_endian: false, true_colour: true, red_max: 255, green_max: 255, blue_max: 255, red_shift: 16, green_shift: 8, blue_shift: 0 }
[2023-04-11T21:31:13Z DEBUG einkvnc::vnc::client] -> SetEncodings([CopyRect, Zrle])
Framebuffer rotation: 2 -> 2.
[2023-04-11T21:31:13Z DEBUG einkvnc] End of frame!
[2023-04-11T21:31:13Z DEBUG einkvnc::vnc::client] <- FramebufferUpdate { count: 1 }
[2023-04-11T21:31:13Z DEBUG einkvnc::vnc::client] <- Rectangle { x_position: 0, y_position: 0, width: 1408, height: 840, encoding: Zrle }
[2023-04-11T21:31:13Z DEBUG einkvnc::vnc::client] <- ...compressed pixels
[2023-04-11T21:31:13Z DEBUG einkvnc] Put pixels
[2023-04-11T21:31:13Z DEBUG einkvnc] network Δt: 0
[2023-04-11T21:31:13Z DEBUG einkvnc] postproc Δt: 0
[2023-04-11T21:31:13Z DEBUG einkvnc] draw Δt: 0
[2023-04-11T21:31:13Z DEBUG einkvnc] rects Δt: 0




***LANDSCAPE MODE IS WORKING WITH RECOMPILED SOURCE!***

Try running it from your android phone running telnet app ConnectBot:
# ./einkvncROTARG 192.168.43.235 5900 --password mypw --contrast 2 --rotarg 2 &
# vi hellovnc.txt
(:wq to quit)
# pkill ./einkvncROTARG


These are the rotarg values for each orientation on the Clara HD:
# Nickel_Orientation Actions
menu_item : main : Orientation - LANDSCAPE - handle above : nickel_orientation: landscape -> --rotarg 4
menu_item : main : Orientation - LANDSCAPE - handle below : nickel_orientation: inverted_landscape -> --rotarg 2
menu_item : main : Orientation - PORTRAIT - handle on left : nickel_orientation: inverted_portrait -> --rotarg 1
menu_item : main : Orientation - PORTRAIT - handle on right : nickel_orientation: portrait -> --rotarg 3
#



Pssst...
***
For those who don't have time or resources for a recompile, it is theoretically possible to just modify the einkvnc binary in a hex editor to run in landscape mode.
Don't ask me who is making this claim - let's just say you got it from "Diff" and "Hexdump" - Try at your own risk!
***

First download the official binary:
wget https://github.com/everydayanchovies.../0.1.0/einkvnc

Remember line 207 in src/main.rs that shows startup_rotation being hardcoded equal to 1?

Well it shows up in address 00023578:01 20 A0 E3 in einkvnc1 that we compiled ourself:

$ hexedit einkvnc1

00023564 FC 13 8D E5 F8 53 8D E5 80 10 8D E5 2C 30 91 E5 05 10 A0 E1 .....S......,0......
00023578 01 20 A0 E3 84 50 8D E5 33 FF 2F E1 70 06 9D E5 00 00 50 E3 . ...P..3./.p.....P.
0002358C 03 00 00 0A 74 06 9D E5 00 04 8D E5 01 0B 8D E2 B6 BA 03 EB ....t...............


So copy the official binary to einkvnc2 and try to find the equivalent address (which will show a slightly different surrounding data due to differing build environments used):

$ cp einkvnc einkvnc2

$ hexedit einkvnc2

00048AA8 96 0F 8E E2 F8 43 8D E5 2C 30 91 E5 04 10 A0 E1 01 20 A0 E3 .....C..,0....... ..
00048ABC 33 FF 2F E1 58 06 9D E5 00 00 50 E3 03 00 00 0A 5C 06 9D E5 3./.X.....P.....\...


See the "01 20 A0 E3" after the "F8 43 8D E5 2C 30 91 E5 04 10 A0 E1"?

Edit the "01 20 A0 E3" at address 00048AB8 to "02 20 A0 E3"
(Ctrl-x to save and exit)

COPY THE MODDED einkvnc2 BINARY TO YOUR KOBO AND TRY AGAIN:


NOTE: YOU MUST ALSO ROTATE THE VNC SERVER DEVICE TO LANDSCAPE ORIENTATION.

Put the ClaraHD in landscape mode using the SECOND nickel menu entry):
# Nickel_Orientation Actions
menu_item : main : Orientation - LANDSCAPE - handle above : nickel_orientation: landscape
menu_item : main : Orientation - LANDSCAPE - handle below : nickel_orientation: inverted_landscape
menu_item : main : Orientation - PORTRAIT - handle on left : nickel_orientation: inverted_portrait
menu_item : main : Orientation - PORTRAIT - handle on right : nickel_orientation: portrait
#


Run your modded binary from a telnet client (like ConnectBot from F-Droid.org) e.g. from your vnc server device :

(droidVNC-NG vnc server scaling @ 70%, LANDSCAPE ORIENTATION)
# RUST_LOG=debug ./einkvnc2 192.168.43.235 5900 --password mypw --contrast 2

***Try at your own risk! Yes it's just software, but if your device gets locked in an unknown state, you are 100% responsible!***

Last edited by elinkser; 05-19-2023 at 06:39 PM. Reason: rotarg fix
elinkser is offline   Reply With Quote
Old 04-21-2023, 10:51 PM   #20
elinkser
Groupie
elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.
 
Posts: 185
Karma: 146236
Join Date: Oct 2022
Device: Kobo Clara HD
RUN einkvnc2 FROM NICKEL MENU

RUN einkvnc2 FROM NICKEL MENU


*NOTE: You must install NickelDBus to implement this NickelMenu entry because it requires the user to enter the last 3 digits of the VNC server address, since those digits seem to change with each session (when running the hotspot server from the same device as the VNC server).

And NickelDBus actually allows you to enter an input line of text, with onscreen keyboard and all, though there are not many examples out there that I could find. So I had to rely on this outdated example to get me started.


So, as before:

ROTATE THE VNC SERVER DEVICE TO LANDSCAPE ORIENTATION.

Put the ClaraHD in landscape mode using the SECOND nickel menu entry):
# Nickel_Orientation Actions
menu_item : main : Orientation - LANDSCAPE - handle above : nickel_orientation: landscape
menu_item : main : Orientation - LANDSCAPE - handle below : nickel_orientation: inverted_landscape
menu_item : main : Orientation - PORTRAIT - handle on left : nickel_orientation: inverted_portrait
menu_item : main : Orientation - PORTRAIT - handle on right : nickel_orientation: portrait
#


Create the following script /mnt/onboard/opt/vncNexus.sh:

#!/bin/sh
# vncNexus connect command
strip_qndb_prefix() {
printf "%s" ${1#dlgConfirmTextInput }
}
qndb -m dlgConfirmCreate true
qndb -m dlgConfirmSetTitle "Enter VNC address fourth octet:"
qndb -m dlgConfirmSetLEPlaceholder "einkvnc2 192.168.43.fourthoctet"
qndb -m dlgConfirmShow
result=$(qndb -s dlgConfirmTextInput)
fourthoctet=$(strip_qndb_prefix "$result")
vnccmd="/mnt/onboard/opt/einkvnc2 192.168.43.$fourthoctet 5900 --password mypw --contrast 2 "
qndb -m mwcToast 3000 "$vnccmd"
eval "$vnccmd"


You can start and stop the einkvnc2 VNC client (you created in the previous post) with the following NickelMenu entries (in /mnt/onboard/.adds/nm/config.txt):

menu_item :main :Einkvnc2 192.168.43.suffix :cmd_spawn :quiet:exec /mnt/onboard/opt/vncNexus.sh
chain_success :dbg_toast :Started einkvnc2
chain_failure :dbg_toast :Error
menu_item :main :Stop einkvnc2 :cmd_spawn :quiet:/usr/bin/pkill einkvnc2
chain_success :dbg_toast :Stopped einkvnc2
chain_failure :dbg_toast :Error

Last edited by elinkser; 04-24-2023 at 02:49 PM. Reason: corrected term
elinkser is offline   Reply With Quote
Old 04-25-2023, 04:13 PM   #21
elinkser
Groupie
elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.
 
Posts: 185
Karma: 146236
Join Date: Oct 2022
Device: Kobo Clara HD
IMPROVE SECURITY OF SHELL SCRIPT PROCESSING OF USER INPUT:

IMPROVE SECURITY OF SHELL SCRIPT PROCESSING OF USER INPUT:



It is unlikely that our Kobo device will be made "secure" by improving the security of the shell script alone, but why not at least make an honest attempt to minimize the vulnerability?



We can get some idea of the nature of the threat from:
https://portswigger.net/web-security...mand-injection

Ways of injecting OS commands

A variety of shell metacharacters can be used to perform OS command injection attacks.
A number of characters function as command separators, allowing commands to be chained together. The following command separators work on both Windows and Unix-based systems:

& && | ||

The following command separators work only on Unix-based systems:

; Newline (0x0a or \n)

On Unix-based systems, you can also use backticks or the dollar character to perform inline execution of an injected command within the original command:

`injected command`
$(injected command)

How to prevent OS command injection attacks

By far the most effective way to prevent OS command injection vulnerabilities is to never call out to OS commands from application-layer code. In virtually every case, there are alternate ways of implementing the required functionality using safer platform APIs.

If it is considered unavoidable to call out to OS commands with user-supplied input, then strong input validation must be performed. Some examples of effective validation include:

Validating against a whitelist of permitted values.
Validating that the input is a number.
Validating that the input contains only alphanumeric characters, no other syntax or whitespace.

Never attempt to sanitize input by escaping shell metacharacters. In practice, this is just too error-prone and vulnerable to being bypassed by a skilled attacker.



We get an example of validating input from:
https://www.fosslinux.com/101589/bas...rabilities.htm

For example, let’s say you have a Bash script that prompts the user to enter a filename and then performs some operation on that file. To sanitize the user input and prevent potential code injection attacks, you could use the following code to validate the input:

#!/bin/bash

# Prompt the user for a filename
read -p "Enter the filename: " filename

# Sanitize the input using a regular expression
if [[ $filename =~ ^[a-zA-Z0-9_./-]+$ ]]; then
# The input is valid, perform some operation on the file
echo "Performing operation on file: $filename"
else
# The input is invalid, exit the script with an error message
echo "Invalid filename: $filename"
exit 1
fi

In this example, the regular expression ^[a-zA-Z0-9_./-]+$ is used to match only alphanumeric characters, underscores, slashes, dots, and hyphens. This allows the user to enter filenames with standard characters without allowing any special characters that could be used to inject malicious code into the script.


***
In our vncNexus.sh script from the previous post, we can sanitize the fourthOctet variable with:

if [[ $fourthOctet =~ ^[0-9]+$ ]]; then
echo "$fourthOctet is numeric"
else
$fourthOctet = "invalid"
fi



We also need to do string-to-integer conversions (and back) for bounds checking:
https://stackoverflow.com/questions/...back-to-string

***
In our vncNexus.sh script, we can thus process the fourthOctet variable for bounds-checking with:

num=$((fourthOctet))
if [[ $num -ge 0 ] && [ $num -le 255 ]]
then
break
fi

Putting it all together in a new more secure script vncNexus2.sh
(removed printf, added error msg)

************

#!/bin/sh
# vncNexus2 connect address - more secure version

num=256
while [ $(expr "$num") -lt 0 ] || [ $(expr "$num") -gt 255 ]
do
qndb -m dlgConfirmCreate true
qndb -m dlgConfirmSetTitle "Enter VNC address fourth octet (0-255):"
qndb -m dlgConfirmSetLEPlaceholder "einkvnc2 192.168.43.fourthOctet"
qndb -m dlgConfirmShow
result=$(qndb -s dlgConfirmTextInput)
fourthOctet=$(echo $result | sed 's/dlgConfirmTextInput //')
num=$(echo $fourthOctet | sed 's/[^0-9]//g')
num=${num:-256}
if [ "$num" != "$fourthOctet" ]
then
num=256
fi
done

pwlen=33
while [ $(expr "$pwlen") -lt 6 ] || [ $(expr "$pwlen") -gt 32 ]
do
qndb -m dlgConfirmCreate true
qndb -m dlgConfirmSetTitle "Enter VNC password (6-32 alphanumeric characters):"
qndb -m dlgConfirmSetLEPlaceholder "abcdefg123"
qndb -m dlgConfirmShow
result=$(qndb -s dlgConfirmTextInput)
mypw=$(echo $result | sed 's/dlgConfirmTextInput //')
vncpw=$(echo $mypw | sed 's/[^A-Za-z0-9]//g')
vncpw=${vncpw:-0}
pwlen=$(expr "$vncpw" : "$vncpw")
done

vnccmd="/mnt/onboard/alpinex/einkvnc2 192.168.43.$num 5900 --password $vncpw --contrast 2"
qndb -m mwcToast 3000 "$vnccmd"
vncerr=$($vnccmd 2>&1)
qndb -m mwcToast 3000 "${vncerr:-"Bye!"}"


************

Last edited by elinkser; 06-01-2023 at 09:08 PM. Reason: removed printf, added error msg
elinkser is offline   Reply With Quote
Old 02-12-2024, 06:32 PM   #22
noobyme
Member
noobyme began at the beginning.
 
Posts: 17
Karma: 10
Join Date: Apr 2023
Device: Kobo Nia
For the noobs out there, look at releases on the github pages, there's a einkvnc file. Drag that into your kobo somewhere, same place as your books. Ssh into it, cd.../ snoop around looking for it. There were no instructions for noobs like me so I'm writing this for the next noob. Otherwise you have to compile source code on own. Has anybody got this working in 2024? Did it break
noobyme is offline   Reply With Quote
Old 02-12-2024, 10:17 PM   #23
elinkser
Groupie
elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.elinkser has survived committing the World's Second Greatest Blunder.
 
Posts: 185
Karma: 146236
Join Date: Oct 2022
Device: Kobo Clara HD
See if you can follow the steps I went through in 2023 on my Clara HD. It's not that long ago.
elinkser is offline   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
New "VNC" viewer for recent Kobo devices and firmware NiMa Kobo Developer's Corner 23 02-12-2024 06:51 PM
how to VNC viewer fonzie4msg Kindle Developer's Corner 52 04-23-2013 10:23 AM
VNC Client on a large format Android or Linux Device? grumpy3b Android Devices 14 04-16-2011 02:38 PM
Anyone using a VNC client on their iOS Device to access Windows apps? grumpy3b Apple Devices 13 04-10-2011 09:43 PM
Android VNC viewer (use your PC from the eDGe!) devseev enTourage Archive 2 04-11-2010 01:21 AM


All times are GMT -4. The time now is 01:21 PM.


MobileRead.com is a privately owned, operated and funded community.