Electronics and programming interspersed at various levels of difficulty.

Thursday, July 18, 2013

txtr Beagle - Part two - software

Bluetooth

Thanks to Moritz I was able to connect to txtr via the Bluetooth SPP profile. To do this you need to disable the txtr app that is installed on your phone and install any app that does Bluetooth serial debugging. I used "Bluetooth SPP", available freely on the Play Store.

Turn on Bluetooth on the phone and Beagle, start the app and choose "Real-time mode". Inside the prompt you should type "HELP" (all caps) followed by the enter key (not "Done") so a newline is inserted after the command. You should see a listing of available commands.
Here's the [obscured] output from my device:

Not much to see here but I assume the BOOK command signals the device that an upload is about to start. I was initially considering the fact that a different Bluetooth channel (binary) was used for the transfer but giving how much time it takes to actually transfer a book they might actually be using the same (Serial) channel.

Android

The apk and application storage were retrieved from the device using TitaniumBackup.

The settings flag is Bitmap.Config.ARGB_8888, which means each pixel is stored on 4 bytes.

For grayscale conversion a new bitmap is created and receives a color matrix filter with saturation set to zero. For raw retrieval, the getPixels() method is called with the parameters (int[480000], 0, 600, 0, 0, 600, 800).

Returns in pixels[] a copy of the data in the bitmap. Each value is a packed int representing a Color. The stride parameter allows the caller to allow for gaps in the returned pixels array between rows. For normal packed results, just pass width for the stride value. The returned colors are non-premultiplied ARGB values.

Parameters

pixels

The array to receive the bitmap's colors

offset

The first index to write into pixels[]

stride

The number of entries in pixels[] to skip between rows (must be >= bitmap's width). Can be negative.

Throws

if the pixels array is too small to receive the specified number of pixels.

There are a few native methods stored in librenderer.so (5 MBytes!) most notably getCurrentScreenBuffer() which does not return anything.

Transferring

The main actions are stored in BeagleDevice.class, showing some more commands than what HELP listed:

DELETEBOOK ID=[id]

VIRGIN

ENDBOOK

PAGE [pagenum] - also passes a byte[] array, used for uploading

UTILITYPAGE [pagenum] - with byte[] parameter

OPTION LOWFLASH=[num]

VCOM [num]

BOOK ID=[num]

TITLE [string]

AUTHOR [string]

I'll go over some details in a next post, for now what's interesting is the transfer payload type. It's a compressed byte[] array retrieved by calling convertToZipped4bpp(int[], 600, 800, 16, false)native method.
The 4-bit format is called 3BIT+DITHER.

21 comments:

thanks for the teardown. Got myself a Beagle today and am very curious, if there's a way to pass the complicated process to get an ebook file on the device (upload to txtr.com, download on phone, upload to device). My knowledge of this hacking stuff tends to zero but I admire guys like you who try their best to free devices like the Beagle.

I am looking forward to your next posts regarding this device. Thanks for the effort

Hey Czery, Ligius,a friend of mine has reverse-engineered the book transfer last weekend.He wanted to clean up the code (Python) a little bit before putting it on GitHub over the next days: https://github.com/floe

Yes, transfer works via BT Serial Port Profile using the BOOK, PAGE, ... commands.However, images are PGM files with a special zlib compression, so you have to convert them first.The code is still very rough, but I guess Florian will put it online soon.If you are impatient (or curious): write a small script that poses as a Beagle and let the Android txtr app connect to it - that's (partially) how Florian reverse-engineered the exact protocol.

Thanks for the comments, I added a final(?) chapter describing how to protocol works.Anyone can develop an Android or even Python app to talk to the device and upload the books, but I haven't actually provided any code. It should be a 2 hour job.

Your piece of software seems absolutely fantastic. Call me stupid, but I couldn't for the life of me, figure out how to pair the beagle with a pc. I never got past, the "please return to the txtr beagle app to finish pairing" screen. Do you have any tips on that. With that of course Jbeagle just says "searching for begale" (This is on windows by the way).

Windows 8.1 or 10? Click start, type 'add device', select 'add or remove devices', select the Bluetooth section. Now keep pressed on the power button of the Beagle until it starts flashing blue, it should be in pairing mode. It should afterwards appear in the Windows dialog.For more control over PDF rendering check out my fork of the project https://github.com/ligius-/jbeagle

Problem is, that when I put my beagle into pairing mode, when connected to a PC it will just say, "Pairing successful, please return to the txtr app". If I launch JBeagle in this state, it will just say "searching for beagle", and than the beagle will give a timeout message after a while, but JBeagle fail to find it. I can connect the beagle to and android device through to -soon to be shut down but still operating- official app, and then it will say "Waiting for books", when in bluetooth mode, and like that I can even transfer a book. I have Win10 on my main pc, but if needed I have a Pc in the house With Win8.1 (On that it does the same thing BTW), and WinXP if that helps. Also in bluetooth settings its says that if for example the beagle is on COM port N than the "beagle spp dev" is on COM N-1. (I don't know if that is supposed to be like that or not). So if you have any idea what I am doing wrong, please hit me with t :D

Well I did just that, 3 times, just to make sure, I also removed th batteries in the beagle and restarted, the computer just to make absolutely sure, But I am stuck at the "Searching for beagle screen" . Tried it with the win8 pc --->same. Also I got the compiled java package to rule out the problem with eclipse, but no change. By the way my beagle is a Hungarian language model... Does that make a difference? Also, is there a way for me to tell, where the process gets stuck? Also as I stated before the begale gets stuck on screen that says "Bluetooth pairing successful. Please return to the txt app to continue pairing... So at the moment I am completely stumped...

I have the German model, though it should not be any difference. As soon as the device is paired in Windows the Bluecove library should take care of connecting to it.If you have some knowledge of Java, start the app in Debug mode, set a breakpoint in BeagleUtil.java:53 and try to step over the code. See if it throws any exceptions there. I'll be happy to assist.

Sadly I know nothing about java, but I have seen other programming languages (c# and visual basic), so at least I have a basic idea :D. Very nice from the original programmer to comment to every subroutine what it does. So I found the bit where it searches for the beagle

beagle = BeagleUtil.searchForBeagle();

This is the line it gets stuck on. It does not even exit with an exeption, it just stays there. I guess BeagleUtil.searchForBeagle(); is a subroutine defined somewhere else. How can I find where that is?

Press F3 to go to that function. Press F5 to step into it. Press F6 to step over functions. Select a text and press Ctrl+Shift+i to see an evaluation of that expression. F8 to resume running. By stepping over stuff you are able to see if something throws an exception (jumps to the catch block) and see what the exception is. I would have modified the code to show the exceptions in the console, but have not bothered to do that.

I've made a new release a few days ago on my Github project that addresses that issue - the Hungarian version of Beagle is shown as 'txtr beagle' instead of 'Beagle'. A nicer way to do that would be to have a list of BT devices from which to choose. Next release maybe... Also included are some small features and fixes (reconnection, keep-alive ping)