Tech 10 min read

Reverse-Engineering the HP Sprocket 200 BLE Protocol to Print from a PC

IkesanContents

I picked up an HP Sprocket 200 secondhand. It’s a mobile photo printer that uses ZINK paper, designed to print from a smartphone via the official app. Just like when I got a thermal printer working from a PC before, I wanted to see if I could print from a PC with this one too.

Why This Printer

ZINK paper is cross-compatible between the HP Sprocket and Canon iNSPiC lines. However, HP’s genuine paper is hard to find and has limited availability. Canon iNSPiC paper is much easier to get.

So the plan was: buy a cheap used Sprocket, use Canon paper. But it’s not that simple. Even though ZINK paper is technically compatible across brands, most printers won’t work without the Smart Sheet (a blue sheet) that comes at the bottom of each genuine paper pack. This sheet is used for printer calibration, so if you just load third-party paper without one, it usually refuses to print.

That means the sweet spot is “a used unit that comes with genuine paper.” Armed with this knowledge, I was digging through the junk section at Sofmap and found a Sprocket 200 with genuine ZINK paper included for about 2,000 yen. Instant buy. For some reason this particular unit came with a full pack of genuine paper.

Unboxing

HP Sprocket and Canon iNSPiC paper package

I only bought the HP Sprocket. The Canon iNSPiC ZINK photo paper (20 sheets) is insurance for when HP paper runs out.

HP Sprocket 200 box contents

Inside the Sprocket 200 box. It came with the printer, a USB cable, a ZINK photo paper sample pack, and a safety information sheet. The unit is palm-sized with a speckled pattern on the surface.

Loading ZINK Paper

HP genuine and Canon ZINK paper packages

HP genuine (10 sheets) and Canon iNSPiC (10 sheets) ZINK paper. Same ZINK technology inside, but the packaging and included Smart Sheets are different.

Smart Sheet comparison

Top is the HP genuine Smart Sheet, bottom is Canon’s. The Smart Sheet is a blue sheet placed at the bottom of each pack. It feeds through first when you load paper and is used for calibration.

ZINK paper and Smart Sheet laid out

Left is the ZINK photo paper, right is the Smart Sheet. For this test, I used an HP genuine Smart Sheet but loaded Canon iNSPiC paper. As long as calibration passes with the HP Smart Sheet, the actual paper should work even if it’s third-party.

ZINK paper front and back

The white side is the print surface, and the side with the brand logo is the back. You load it into the printer with the back side facing down. If you look closely, the HP and Canon papers have a slightly different tint. Even with the same ZINK technology, there might be minor differences in manufacturing lots or specs.

Sprocket ejecting the Smart Sheet

After loading the HP genuine Smart Sheet together with Canon paper and powering on, the printer automatically ejected the Smart Sheet (blue paper) first. Calibration completed without issues. It accepted the third-party paper.

Can It Print from a PC?

There are no PC/Mac drivers or desktop apps for the HP Sprocket. HP Smart (HP’s universal printer app) doesn’t support the Sprocket either. Officially, the smartphone app is the only option.

That said, there are some unofficial approaches people have reported.

Method 1: Bluetooth OBEX File Transfer (Windows/Mac)

The simplest approach. Send an image file directly via Windows’ Bluetooth “Send a file” menu.

  1. Power on the Sprocket 200 and pair it with your PC
  2. Taskbar Bluetooth icon -> “Send a file”
  3. Select the Sprocket as the destination
  4. Choose an image file and send

No app filters or margin adjustments — it just sends the raw image. There are reports that this also works via Bluetooth settings on Mac.

However, the Sprocket 200 has Bluetooth 5.0, and depending on firmware, the OBEX Push Profile (OPP) may be disabled. Apparently it worked fairly reliably on the original Sprocket (Bluetooth 3.0), but for the 200 you just have to try it and see.

Method 2: obexftp Command (Linux/Raspberry Pi)

This has been confirmed to work in “pibooth,” a Raspberry Pi photo booth project.

sudo apt-get install bluetooth libbluetooth-dev obexftp
obexftp --nopath --noconn --uuid none --bluetooth [MACアドレス] --channel 4 -p image.png

Channel 4 appears to be specific to the HP Sprocket. Since it isn’t recognized as a CUPS printer, you have to use obexftp to talk to it directly.

Method 3: Android Emulator (Doesn’t Work)

There’s a lot of info online about running the HP Sprocket app in BlueStacks or similar, but major Android emulators don’t support Bluetooth passthrough, so this doesn’t work.

My Plan

Try Method 1 (OBEX) first. If that fails, try Method 2 (obexftp) from Mac/Linux. With the thermal printer last time, I was able to reverse-engineer the BLE protocol and control it, but for the Sprocket there’s almost no public info on the proprietary protocol. If OBEX doesn’t work, it could be a dead end.

Trying BLE Connection

Before OBEX, I decided to try connecting via BLE directly. No paper loaded — just testing the connection.

Note: this unit’s battery appears to be dead, so it won’t power on without microUSB power. It’s a junk item, so no surprise. I’ll just keep USB plugged in.

Device Discovery

Scanning with bleak, it showed up as HP Sprocket 200 (8C:2D). The advertisement data contained a proprietary service UUID 6822d239-7b61-4718-bdc1-189221946209 with a 6-byte payload of 62 49 06 00 06 00.

Service Structure

After connecting and enumerating GATT services, only one custom service was visible.

UUID (suffix)PropertiesSuspected Purpose
...051ewrite, write-without-responseData transmission (images/commands)
...3658read, notify, indicateResponse reception
...2eeereadStatus?

The thermal printer from last time (Mini Printer Sugar) used an ISSSC Transparent UART service to send ESC/POS commands, but the Sprocket 200 is a completely proprietary protocol. Neither the service UUID nor the characteristic UUIDs match any known BLE profiles.

Read Results

I read the two readable characteristics, but both returned empty data. Subscribing to notifications for 5 seconds yielded nothing.

Char ...3658 (read/notify): empty
Char ...2eee (read):        read error
Notifications:              none in 5 seconds

The printer likely requires an initialization command (handshake) on the write characteristic before it will send any responses.

Command Probing

To explore the protocol without wasting paper, I sent various byte sequences to the write characteristic and watched for notification responses.

Results:

  • 0x00-0x7F (MSB = 0): No response. Not recognized as commands
  • 0x80-0xFF (MSB = 1): All returned the same 81 01 00 02
  • Structured multi-byte commands (header + length + payload format) also all returned 81 01 00 02
  • ESC/POS sequences, HP ASCII magic bytes, etc. — same result
Sent: 0xFF       → Response: 81 01 00 02
Sent: 0x80 0x01  → Response: 81 01 00 02
Sent: 0x80 0x0A 0x00 0x00 (FW ver?) → Response: 81 01 00 02
Sent: 0x1B 0x40 (ESC @)             → Response: none

81 01 00 02 is probably a generic error response. Since the response is the same regardless of command content, the device likely requires authentication or session establishment, and won’t process individual commands until that’s done.

Blind probing over BLE alone wasn’t going to yield any more information.

Bluetooth Classic (RFCOMM) Connection

I found tylerhahn/ivy2-sprocket2 on GitHub (an HP Sprocket 2 fork of a Canon IVY 2 driver) that used RFCOMM, so I tried BT Classic as well.

SDP (Service Discovery)

After pairing with blueutil, I retrieved SDP records via IOBluetooth.

Service NameRFCOMM ChannelUUID
(custom)100000000-DECA-FADE-DECA-DEAFDECACAFF
SPP SERVER20x1101 (SerialPort)

RFCOMM Connection Results

Channel 1 (custom UUID): Connection succeeded. MTU 1006. The moment I connected, the printer started sending FF 55 02 00 EE 10 (6 bytes) at roughly 1-second intervals.

<< FF 55 02 00 EE 10  (approx. every 1 second, continuous)

This is a status beacon. Sending anything back doesn’t change it. Even sending commands containing the ivy2 protocol start code 0x430F got no reaction — the beacon content stayed the same.

FF 55 appears to be the message header, and the remaining 02 00 EE 10 is likely status information. Since there was no paper loaded, EE and 10 might be error codes (e.g., paper empty).

Channel 2 (SPP SERVER): Connection succeeded. MTU 1006. No data received regardless of what was sent.

Compatibility with ivy2 Protocol

The ivy2-sprocket2 README says “May need protocol adjustments,” and there’s no evidence it was actually tested on real hardware. In practice, the Sprocket 200 doesn’t respond to the 0x430F start code and communicates using its own FF 55 protocol. It’s safe to say there’s no protocol-level compatibility with the Canon IVY 2.

Protocol Analysis

Using BLE packet captures and existing reverse-engineering information, I analyzed the HP Sprocket 200’s BLE communication protocol.

BLE Framing Layer

There’s a proprietary framing layer on top of GATT. The first byte of each BLE packet is a frame header, and the rest is payload.

byte[0] = [last_flag:1][sequence:7]
byte[1:] = HPLPP message fragment
  • last_flag (bit 7): 1 = final packet
  • sequence (bit 0-6): sequence number starting from 1
  • Messages that fit within a single MTU start with 0x81 (seq=1, last=true)

This explains the mysterious 81 01 00 02 from earlier.

81       → BLE frame: seq=1, last=true
01 00 02 → HPLPP message: command=ERROR(0x01), payload=00 02

The device was returning ERROR for all commands sent before session establishment.

HPLPP Protocol

The HP Sprocket 200 has the internal codename “IBIZA” and uses the HPLPP protocol. This is different from the Manta packets (start code 0x1B2A) used by older models (original Sprocket, etc.) and the ivy2 protocol (0x430F).

The first byte of an HPLPP message is the command code. The main commands are as follows.

CommandCodeDirectionPurpose
IF_CONFIG_REQ0x0A->BLE interface configuration request
IF_CONFIG_RSP0x0B<-Returns MTU and ACK interval
RD_STATUS_REQ0x08->Status read
RD_STATUS_RSP0x09<-Battery, print state, etc.
RD_SYS_ATT_REQ0x04->Device attribute read
RD_SYS_ATT_RSP0x05<-FW version, serial, etc.
PRINT_START_REQ0x0C->Start print (send file length)
PRINT_START_RSP0x0D<-Returns job ID and file handle
FILE_WRITE_REQ0x0E->Send image data (chunks)
FILE_WRITE_RSP0x0F<-Write acknowledgment
ERROR0x01<-Error response

Session Establishment

After BLE connection, you must send IF_CONFIG_REQ first. Without this, the device returns ERROR for every command.

送信: 81 0A 01 00
      ^^          BLEフレーム (seq=1, last)
         ^^       IF_CONFIG_REQ (0x0A)
            ^^    BLEインターフェース (0x01)
               ^^ ACK周期 = 0

受信: 81 0B 01 02 02 00
      ^^                BLEフレーム
         ^^             IF_CONFIG_RSP (0x0B)
            ^^ ^^       MTU = 258
                  ^^    上り ACK周期 = 2
                     ^^ (パディング)

Reading Device Information

After session establishment, you can read status and device attributes.

送信: 81 08 01 02 03 06 09   (RD_STATUS_REQ + フィールドID)
FieldValue
SYSTEM_FLAGS0x05000000
PRINT_STATUS16 (no paper)
BATTERY_LEVEL100 (USB powered)
BATTERY_STATUS1 (charging)
NUM_HOSTS0
送信: 81 04 01 02 03 05 09 0A 0B 0C   (RD_SYS_ATT_REQ + フィールドID)
FieldValue
SW_VERSIONM1L1FA1839AR
PROTOCOL_VERSION256
NAMEHP Sprocket 200 (8C:2D)
SERIALTH8B93225J
SUPER_MODEL0x6249
SUB_MODEL0x0600
BT_MACF4:39:09:D2:8C:2D
HW_VERSION4138

PRINT_STATUS = 16 is the error code for no paper. Once paper is loaded, this value should change to indicate the printer is ready.

The print sequence inferred from the communication capture is as follows.

graph TD
    A[BLE接続] --> B[IF_CONFIG_REQ]
    B --> C[IF_CONFIG_RSP<br/>MTU=258]
    C --> D[RD_STATUS_REQ]
    D --> E{PRINT_STATUS<br/>確認}
    E -->|紙なし| F[エラー: 印刷不可]
    E -->|OK| G[PRINT_START_REQ<br/>ファイル長を送信]
    G --> H[PRINT_START_RSP<br/>ジョブID + ファイルハンドル]
    H --> I[FILE_WRITE_REQ<br/>JPEGチャンク送信]
    I --> J[FILE_WRITE_RSP]
    J -->|残りあり| I
    J -->|完了| K[印刷実行]

The image is sent as JPEG, 668x1002 pixels, compressed at quality=90, split into chunks.

What I Confirmed Without Paper

ItemResult
BLE connectionOK
Session establishment (IF_CONFIG)OK
Device info readOK (FW, serial, MAC, etc.)
Status readOK (PRINT_STATUS=16 = no paper)
Protocol identifiedHPLPP (HP proprietary, codename IBIZA)
Print commandsIdentified (PRINT_START -> FILE_WRITE)

If PRINT_STATUS changes when paper is loaded, then it’s just a matter of sending the JPEG.

I prepared a test image.

Test print illustration

Already converted to JPEG 668x1002px at quality=90 to match the Sprocket’s print spec.

Loading Paper and Checking Status

I loaded Canon iNSPiC ZINK paper together with an HP genuine Smart Sheet. PRINT_STATUS changed from 16 (no paper) to 1 (ready to print).

PRINT_STATUS: 1(印刷可能)
BATTERY_LEVEL: 94
BATTERY_STATUS: 1(充電中)

The Byte Order Trap

The first send attempt failed. All integer values in the HPLPP protocol are little-endian, and I was sending the file length as big-endian.

# NG: ビッグエンディアン
struct.pack('>I', 146002)  # → 00 02 3A 52
# プリンターはLE読みで 0x523A0200 = 1.3GB と誤解

# OK: リトルエンディアン
struct.pack('<I', 146002)  # → 52 3A 02 00
# プリンターは正しく 146002 バイトと認識

Because the file length was wrong, the printer never returned STATUS_COMPLETE after receiving all the data — it just kept waiting for more.

Transfer Success

After fixing the byte order, FILE_WRITE_RSP started returning correct progress.

FILE_WRITE 146002 bytes (chunk=500B)
  15000/146002 (10%) recv=15000 total=146002
  30000/146002 (20%) recv=30000 total=146002
  ...
  135000/146002 (92%) recv=135000 total=146002
  COMPLETE! 146002/146002

Transfer: 293 chunks

STATUS_COMPLETE (status code 2) was returned, confirming the printer received all data.

Printing from the Sprocket

After the transfer completed, the printer automatically started printing. The paper slowly emerged from the output slot.

Print result

Successfully printed directly to the HP Sprocket 200 from a PC via BLE. It printed fine on Canon iNSPiC paper, though the colors were slightly muted. Apparently this is a common issue when using third-party ZINK paper — since the Smart Sheet calibration is optimized for genuine paper, colors shift a bit with compatible paper. It’s perfectly usable in practice, but if color accuracy matters, stick with HP genuine paper.

Left: HP genuine paper, Right: Canon iNSPiC paper

Same image printed on the same printer, side by side. Left is HP genuine paper, right is Canon iNSPiC paper. You can see a subtle difference in color tone. The genuine paper looks slightly more subdued. It’s not a dramatic difference, but given that the Smart Sheet calibration is tuned for genuine paper, some color shift with compatible paper is inevitable.

Transfer Speed

Sending a 143KB JPEG in 293 chunks of 500 bytes each is pretty slow. There’s a wait for FILE_WRITE_RSP after each chunk, so it takes roughly a minute in practice. Increasing the chunk size should help, but that requires tuning around the BLE MTU limit and ACK interval. That said, for printing on 2x3 inch ZINK paper, speed is rarely an issue.


By the way, I had been running this whole experiment assuming the battery was dead and USB power was required. But after printing a few sheets, it started running on battery alone. Apparently the battery revived after being charged continuously during use. Lucky find for a junk item.