NaitLee / Cat-Printer

Application supporting Bluetooth thermal “Cat Printers”, for everyone!
GNU General Public License v3.0
350 stars 36 forks source link

BQ05 furby camera printer #99

Open ge0rg opened 6 months ago

ge0rg commented 6 months ago

I recently got a noname "Q5" instant camera with a built-in thermal printer (pictures and first analysis) and I'd like to add support for it.

It has an "app" mode where it reports as "BQ05" on Bluetooth LE and is supported by the YinTiBao Android app (com.fun.mxw).

Here's a list of the GATT characteristics:

[80:12:15:xx:xx:xx][LE]> char-desc 
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0005, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0006, uuid: 0000ae01-0000-1000-8000-00805f9b34fb
handle: 0x0007, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0008, uuid: 0000ae02-0000-1000-8000-00805f9b34fb
handle: 0x0009, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x000a, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000b, uuid: 0000ae03-0000-1000-8000-00805f9b34fb
handle: 0x000c, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000d, uuid: 0000ae04-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0010, uuid: 0000ae05-0000-1000-8000-00805f9b34fb
handle: 0x0011, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0012, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0013, uuid: 0000ae10-0000-1000-8000-00805f9b34fb
handle: 0x0040, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0041, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0042, uuid: 0000ae3b-0000-1000-8000-00805f9b34fb
handle: 0x0043, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0044, uuid: 0000ae3c-0000-1000-8000-00805f9b34fb
handle: 0x0045, uuid: 00002902-0000-1000-8000-00805f9b34fb
[80:12:15:xx:xx:xx][LE]> primary
attr handle: 0x0001, end grp handle: 0x0003 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0004, end grp handle: 0x0013 uuid: 0000ae30-0000-1000-8000-00805f9b34fb
attr handle: 0x0040, end grp handle: 0x0045 uuid: 0000ae3a-0000-1000-8000-00805f9b34fb
[80:12:15:xx:xx:xx][LE]> characteristics 
handle: 0x0002, char properties: 0x0a, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0005, char properties: 0x04, char value handle: 0x0006, uuid: 0000ae01-0000-1000-8000-00805f9b34fb
handle: 0x0007, char properties: 0x10, char value handle: 0x0008, uuid: 0000ae02-0000-1000-8000-00805f9b34fb
handle: 0x000a, char properties: 0x04, char value handle: 0x000b, uuid: 0000ae03-0000-1000-8000-00805f9b34fb
handle: 0x000c, char properties: 0x10, char value handle: 0x000d, uuid: 0000ae04-0000-1000-8000-00805f9b34fb
handle: 0x000f, char properties: 0x20, char value handle: 0x0010, uuid: 0000ae05-0000-1000-8000-00805f9b34fb
handle: 0x0012, char properties: 0x0a, char value handle: 0x0013, uuid: 0000ae10-0000-1000-8000-00805f9b34fb
handle: 0x0041, char properties: 0x04, char value handle: 0x0042, uuid: 0000ae3b-0000-1000-8000-00805f9b34fb
handle: 0x0043, char properties: 0x10, char value handle: 0x0044, uuid: 0000ae3c-0000-1000-8000-00805f9b34fb

When I try to print to it using "Test Unknown Device", I get an error 500 with the following response from the server:

{"name": "org.bluez.Error.Failed", "details": "Failed to initiate write"}

The BLEAK_LOGGING output from that is as follows:

2024-03-19 10:21:19,366 bleak.backends.bluezdbus.client MainThread DEBUG: Write Characteristic 0000ae01-0000-1000-8000-00805f9b34fb | /org/bluez/hci0/dev_80_12_15_xx_xx_xx/service0004/char0005: b'Qx\xa3\x00\x01\x00\x00\x00\xffQx\xa3\x00\x01\x00\x00\x00\xffQx\xa4\x00\x01\x002\x9e\xffQx\xbd\x00\x01\x00(\xd8\xffQx\xaf\x00\x02\x00\x00 \xe0\xffQx\xbe\x00\x01\x00\x01\x07\xffQx\xa9\x00\x01\x00\x00\x00\xff'

There is no other console output from server.py, so I'm not quite sure what's happening there, why the write fails, and how to reasonably debug it.

NaitLee commented 6 months ago

I'd suggest (as usual) to test your device with this Web application: https://print.unseen-site.fun/

This project is dying, as there are some program design mistakes, and because of many design decisions made by Python over the year, there are always obscure bugs around this project.

I'd rewrite this implementation in the future by redesigning the architecture with other technologies.

ge0rg commented 6 months ago

Thanks. Kitty Printer lists the BQ05 as a pairable device when I press "Print", but nothing happens after confirming via the "Pair" button. I'm not sure if this is due to Debian/Chromium/WebBluetooth being experimental, or lacking support for the camera.

The only thing on the JS console is this:

Web Bluetooth is experimental on this platform. See https://github.com/WebBluetoothCG/web-bluetooth/blob/main/implementation-status.md

NaitLee commented 6 months ago

You can also use that web app on mobile devices, to see if they would work somewhere else.

If not then probably we need to analyze how that proprietary app send data, or take a look at how its code works. probably the "app mode" need to be activated with the other listed ble characteristics? no idea at the moment lol

I have limited availability coding these days.

NaitLee commented 6 months ago

In the decompiled code I didn't yet see anything special. Some code there are identical to another variant of such printer apps.

I guess you really need to try to connect to it with other devices, and btw check if you need to manually "activate" the "app mode" of that camera.

don't know if I'll gift away such camera in the future, interesting lol

ge0rg commented 6 months ago

Yes, you need to activate the app mode from the camera menu to make it accessible over BLE.

I now tried Chrome 122 on Android 13 with Kitty Printer, and there also nothing happens after pressing "print" and choosing the "BQ05" from the pairing menu.

I can provide a btsnoop_hci.log from a successful print form the YinTiBao app, but I don't know enough about the printer protocol to check where exactly it deviates from what Kitty Printer sends...

NaitLee commented 6 months ago

Bluetooth data dump could help. the protocol have clear data boundary.

Try printing a white image (like 384x1 white pixels) and gather all the traffic, that means less obscure data.

A clean protocol implementation can be found at https://github.com/NaitLee/kitty-printer/blob/main/common/cat-protocol.ts#L98

I see the camera device has some ble characteristic that are not on ordinary cat printers (those non 0xae**/0xab** ones). maybe we should put attention on them.

ge0rg commented 6 months ago

I wasn't able to print a 384x1 white image because the app is weird. Here's a print-out of a 58mm x 81mm white stripe (although there is a tiny black stripe in it for some reason):

btsnoop_hci.log

NaitLee commented 6 months ago

I added an unknown 0xbc command that appeared in the dump to kitty-printer (which is easier to work on), don’t know if it makes sense.

You may try to use kitty-printer again.

I will try to find more things in the dump later.

ge0rg commented 6 months ago

Thanks, that change improved something. Now it will print a garbage line, stay there for a second, then print the bottom two thirds of the kitty demo image:

Scannen

NaitLee commented 6 months ago

I think it isn’t garbage line but lower pixels of “Welcome!” text.

Still didn’t get what does this 0xbc do. The decompiled source code doesn’t have it (no 0xbc, 188 or -68. It’s really old, seemingly)

That 0xbc message is weird, it didn’t have a usual length header. I had to send it as-is. (if it stopped working, roll it back lol) btw I had fixed mistake calculating data length in the code.

You may need to play with this line by yourself (try modifying the 0x01, 0x02, 0x01, 0x2d part, the data part should be 0x02, 0x01 among them, as indicated by their crc8 hash 0x2d) you can also host your own kitty-printer instance (it’s easy, just have https and run deno task start)

KapitanOczywisty commented 4 months ago

On my printer P7H "prepareCamera" command causes similar issues as above. In source code of iprint there is only {18, 81, 120, -68, 0, 1, 0, 1, 7, -1}, but I can't find if it's even used, at least it's closer to the proper format. Maybe BT log is be corrupted in some way...

I'm testing changes with GitHub Codespaces, and this works without a problem.