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.
UPDATE: Andreas Schier has written an open-source java toolchain for Beagle: https://github.com/schierla/jbeagle
UPDATE: Florian Echtler has built two Python scripts, one emulating the server and another one for the client. The server allows you to send images to your reader: http://floe.butterbrot.org/matrix/hacking/txtr/
Part 1: http://hackcorellation.blogspot.de/2013/07/txtr-beagle-teardown-part-1.html
Part 3: http://hackcorellation.blogspot.de/2013/07/txtr-beagle-part-3-storage-and-transfer.html
Part 4: http://hackcorellation.blogspot.de/2013/07/txtr-beagle-card-parser.html
Part 5: http://hackcorellation.blogspot.de/2013/07/txtr-beagle-native-code-analysis.html
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.Part 3: http://hackcorellation.blogspot.de/2013/07/txtr-beagle-part-3-storage-and-transfer.html
Part 4: http://hackcorellation.blogspot.de/2013/07/txtr-beagle-card-parser.html
Part 5: http://hackcorellation.blogspot.de/2013/07/txtr-beagle-native-code-analysis.html
Here's the [obscured] output from my device:
Connecting…Issuing the INFO command:
Bluetooth connect OK.
Bluetooth Protocol v8
Accepted commands:
(GET)PARTNER, GETBOOKS, (DELETE)BOOK, QUIT, MEMORY, INFO, HELP, etc.
PROTOCOL VERSION=8Issuing GETBOOKS:
FIRMWARE ID=Beagle-F-U BUILDDATE=18.April.2013 GIT=cxxxxxx IAP=0 BLUETOOTH=u.3
DEVICE SERIAL=8888888 BDADDR=00:xx:xx:xx:xx:xx DISPLAY=V110
# bookselect button activated
VCOM VALUE=1910
SDCONTENT REVISION=2
OPTION LOWFLASH=0 FFTBT=1INFOOK
BOOK ID=1111111111111111 FIRSTPAGE=1 LASTPAGE=19 CURRENTPAGE=19 AUTHOR=sgsdfgsdfgdgsd TITLE=sdfgsdfgsdfgsdfg
BOOK ID=888888888888888 FIRSTPAGE=1 LASTPAGE=183 CURRENTPAGE=5 AUTHOR=adfrgsdfgsdfgsdfgsdfgsdfg TITLE=sdfgsdfgsdfgsdfgsdfg
BOOK ID=888888888888 FIRSTPAGE=1 LASTPAGE=423 CURRENTPAGE=1 AUTHOR=TG9uZG9uLCBKYWNr TITLE=V2hpdGUgRmFuZw
BOOK ID=888888888888888 FIRSTPAGE=1 LASTPAGE=447 CURRENTPAGE=321 AUTHOR=sdfgsdfgsdfgsdfg TITLE=sdfgsdfgsdfgsdfg
GETBOOKSOK
Issuing MEMORY:
BOOKS USE=4 MAXIMUM=15QUIT:
CLUSTERS USE=21 MAXIMUM=255 SIZE=59
MEM TOTAL=8192 FREE=2168
MEMORYOK
QUITOKPartner:
PARTNER ID=B234E345D123
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.
Storage
The storage archive contains the following data:
- fonts
- hyphenation dictionaries (de, en, es, fr, it, pt)
- some web tracking databases (cache and cookies), Google analytics client id
- Adobe Digital Edition - activation xml; I assume this is some fingerprint used to register the pdf parser with Adobe (http://adeactivate.adobe.com/adept)
- fingerprint id - either for the phone or the Beagle, not sure
- adobe DRM registration id - xml
- authenti[fi]cation xml containing user and token, in my case Facebook
- billing info xml
- preferences xml - for the app
App
The apk was unpacked and the .dex file was passed to the dex2jar utility. Jd-gui was used to browse and dump the decompiled source code. I will not post any code dump since it's probably illegal.
However, it's probably no problem to post the package structure and figure out what might be happening.
There's the Google analytics package there but I've seen that in almost every Android app.
Facebook is there for login.
http://actionbarsherlock.com/
GMS is play services SDK.
The sonyericsson package implements a humanized version of touch zooming, I haven't studied that yet.
https://github.com/akquinet/androlog
https://github.com/akquinet/roboject
And a bunch of other stuff, but it's interesting to note the renderer service has only two renderers: EPUB and PDF.
Jumping over some details, it seems that the books are rendered on the Android device inside a Bitmap object http://developer.android.com/reference/android/graphics/Bitmap.html
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).
public void getPixels (int[] pixels, int offset, int stride, int x, int y, int width, int height)Added in API level 1Returns in pixels[] a copy of the data in the bitmap. Each value is a packed int representing aColor
. 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. x The x coordinate of the first pixel to read from the bitmap y The y coordinate of the first pixel to read from the bitmap width The number of pixels to read from each row height The number of rows to read Throws
IllegalArgumentException if x, y, width, height exceed the bounds of the bitmap, or if abs(stride) < width. ArrayIndexOutOfBoundsException 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.
The 4-bit format is called 3BIT+DITHER.
This comment has been removed by a blog administrator.
ReplyDeleteIt's hard to come by experienced people on txtr Beagle. Thank you for sharing Liguis.
ReplyDeleteCheck this out too:
Medical Records Software
I simply want to tell you that I am new to weblog and definitely liked this blog site. Very likely I’m going to bookmark your blog . You absolutely have wonderful stories. Cheers for sharing with us your blog.
ReplyDeleteVLC Media Player