diff options
Diffstat (limited to 'content/posts/WIP-xprinter-wifi')
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/80XX_Programmer_Manual.pdf | bin | 1084986 -> 0 bytes | |||
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/index.org | 352 | ||||
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/xprinter_advanced.png | bin | 24148 -> 0 bytes | |||
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/xprinter_lp0.reg | bin | 216 -> 0 bytes | |||
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/xprinter_set_net.png | bin | 11419 -> 0 bytes | |||
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/xprinter_setup_tool.png | bin | 46156 -> 0 bytes | |||
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/xprinter_usb_wireshark.png | bin | 1084854 -> 0 bytes | |||
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/xprinter_wifi_screenshot.png | bin | 123067 -> 0 bytes | |||
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/xprinter_wine_regedit.png | bin | 18164 -> 0 bytes | |||
| -rw-r--r-- | content/posts/WIP-xprinter-wifi/xprinter_wireshark.png | bin | 160032 -> 0 bytes | 
10 files changed, 0 insertions, 352 deletions
| diff --git a/content/posts/WIP-xprinter-wifi/80XX_Programmer_Manual.pdf b/content/posts/WIP-xprinter-wifi/80XX_Programmer_Manual.pdfBinary files differ deleted file mode 100644 index 83579ca..0000000 --- a/content/posts/WIP-xprinter-wifi/80XX_Programmer_Manual.pdf +++ /dev/null diff --git a/content/posts/WIP-xprinter-wifi/index.org b/content/posts/WIP-xprinter-wifi/index.org deleted file mode 100644 index af726b6..0000000 --- a/content/posts/WIP-xprinter-wifi/index.org +++ /dev/null @@ -1,352 +0,0 @@ -#+TITLE: Reverse engineering a thermal printer's WiFi setup commands -#+DATE: 2021-10-12T15:57:12-04:00 -#+DRAFT: true -#+SHOWTOC: true -#+DESCRIPTION: Setting up an Xprinter thermal receipt printer WiFi from Linux -#+TAGS[]: linux hardware -#+KEYWORDS[]: linux hardware -#+SLUG: -#+SUMMARY: - -* Introduction - -  I recently purchased a thermal receipt printer off of [[https://web.archive.org/web/20211012195845/https://www.aliexpress.com/item/32842111016.html?spm=a2g0s.9042311.0.0.207d4c4d6xNWgO][AliExpress]] for a -  project. It features both WiFi and USB connectivity which I thought -  was really cool for the price. - -  To my dismay, I realized after purchasing that the drivers and -  configuration application only run on Windows. - -  This wasn't a huge deal, as thermal printers generally use the -  somewhat kinda standardized command set called [[https://github.com/escpos/escpos][ESC/POS]]. Unfortunately -  while many of the formatting commands are shared between printers, the -  commands to setup the WiFi connection don't seem to be documented -  anywhere, and I suspect are device-specific. - -  Since booting into Windows every time I want to manage the printer's -  network settings isn't ideal, I decided to reverse engineer the -  WiFi configuration commands. - -  Initially I tried to run the configuration tool in wine, but it -  couldn't communicate with the printer over USB, which wasn't too -  surprising. - -* Running in Windows - -  I booted my spare laptop into windows and launched the config tool -  there. - -  I then setup the WiFi through =Advanced -> Set Net= - -  #+ATTR_HTML: :title Xprinter config tool running in wine -  #+ATTR_HTML: :alt Xprinter config tool running in wine -  [[file:xprinter_setup_tool.png]] - - -  #+ATTR_HTML: :title Xprinter advanced settings -  #+ATTR_HTML: :alt Xprinter advanced settings -  [[file:xprinter_advanced.png]] - -  #+ATTR_HTML: :title Xprinter net settings -  #+ATTR_HTML: :alt Xprinter net settings -  [[file:xprinter_set_net.png]] - -  At this point I noticed that the application supported configuring the -  printer over the network, meaning I might be able to change the -  settings under wine again, as network sockets should work normally. - -* Wireshark on Linux - -  After rebooting into Linux and testing my assumption, it turned out to -  be half true, I was able to run the configuration tool over the -  network without issue and print from it, but I couldn't configure the -  WiFi. - -  While I could have stopped there I decided to go one step further and -  reverse the command sequence that configures the WiFi settings so I -  could re-configure the printer's WiFi over USB if it ever got messed -  up. - -  To do that, I sniffed the traffic going from the Xprinter application -  and the printer's socket using Wireshark, assuming the commands it -  sends over the network are the same ones it sends over USB. - -  [[file:xprinter_wireshark.png]] - -  In the examples below I've encoded the data being sent to hex to make -  it easier to understand the contents of the packets. - -  Based on the traffic, I was able to come up with the following. - -** Setting IP address - -   The following sets -   - IP =192.168.0.7= - -   The IP hex: -   #+begin_src ruby -   [192, 168, 0, 7].map { _1.to_s(16).rjust(2, '0') } -   #+end_src - -   #+RESULTS: -   | c0 | a8 | 00 | 07 | - -   Packet contents from wireshark: - -   =0000   1f 1b 1f 22 c0 a8 00 07= - -   | Description    | Characters    | -   |----------------+---------------| -   | Unit separator | =1f=          | -   | Escape         | =1b=          | -   | Unit separator | =1f=          | -   | Command code   | =22=          | -   | IP             | =c0 a8 00 07= | - -** Setting subnet Mask - -   The following sets -   - Subnet mask =255.255.255.0= - -   Subnet mask to hex: -   #+begin_src ruby -   [255, 255, 255, 0].map { _1.to_s(16).rjust(2, '0') } -   #+end_src - -   #+RESULTS: -   | ff | ff | ff | 00 | - -   Packet contents from wireshark: - -   =0000   1f 1b 1f b0 ff ff ff 00= - -   | Description    | Character     | -   |----------------+---------------| -   | Unit separator | =1f=          | -   | Escape         | =1b=          | -   | Unit separator | =1f=          | -   | Command code   | =b0=          | -   | Subnet mask    | =ff ff ff 00= | - -** Setting gateway - -   The following sets -   - Gateway =192.168.0.1= - -   Subnet mask to hex: -   #+begin_src ruby -   [192, 168, 0, 1].map { _1.to_s(16).rjust(2, '0') } -   #+end_src - -   #+RESULTS: -   | c0 | a8 | 00 | 01 | - -   Packet contents from wireshark: - -   =0000   1f 1b 1f b1 c0 a8 00 01= - -   | Description    | Character     | -   |----------------+---------------| -   | Unit separator | =1f=          | -   | Escape         | =1b=          | -   | Unit separator | =1f=          | -   | Command code   | =b1=          | -   | Net Mask        | =c0 a8 00 01= | - -** Setting IP, subnet mask, and gateway - -   The following sets -   - IP =192.168.0.1= -   - Subnet mask =255.255.255.0= -   - Gateway =192.168.0.1= - -   Packet contents from wireshark: - -   =0000   1f 1b 1f b2 c0 a8 00 07 ff ff ff 00 c0 a8 00 01= - -   | Purpose        | Character     | -   |----------------+---------------| -   | Unit separator | =1f=          | -   | Escape         | =1b=          | -   | Unit separator | =1f=          | -   | Command code   | =b2=          | -   | IP             | =c0 a8 00 07= | -   | Subnet mask    | =ff ff ff 00= | -   | Gateway        | =c0 a8 00 01= | - -** Setting WiFi network - -   The following sets -   - SSID =SSID_HERE= -   - Key =PASSWORD_HERE= -   - Key Type =WPA2_AES_PSK= - -   SSID to hex: -   #+begin_src ruby -   "SSID_HERE".bytes.map { _1.to_s(16) } -   #+end_src - -   #+RESULTS: -   | 53 | 53 | 49 | 44 | 5f | 48 | 45 | 52 | 45 | - -   Key to hex: -   #+begin_src ruby -   "PASSWORD_HERE".bytes.map { _1.to_s(16) } -   #+end_src - -   #+RESULTS: -   | 50 | 41 | 53 | 53 | 57 | 4f | 52 | 44 | 5f | 48 | 45 | 52 | 45 | - -   Packet contents from wireshark (including string representation): -     #+begin_src -     0000   1f 1b 1f b3 06 53 53 49 44 5f 48 45 52 45 00 50   .....SSID_HERE.P -     0010   41 53 53 57 4f 52 44 5f 48 45 52 45 00            ASSWORD_HERE. -     #+end_src - -   | Purpose         | Character       | -   |-----------------+-----------------| -   | Unit separator  | =1f=            | -   | Escape          | =1b=            | -   | Unit separator  | =1f=            | -   | Command code    | =b3=            | -   | Key type        | =06=            | -   | SSID            | =SSID_HERE=     | -   | NUL-termination | =00=            | -   | Key             | =PASSWORD_HERE= | -   | NUL-termination | =00=            | - -   If the WiFi key type is anything like the menu, the other key types -   are as follows - -   | Key Type             | Value | -   |----------------------+-------| -   | =NULL=               | =00=  | -   | =WEP64=              | =01=  | -   | =WEP128=             | =02=  | -   | =WPA_AES_PSK=        | =03=  | -   | =WPA_TKIP_PSK=       | =04=  | -   | =WPA_TKIP_AES_PSK=   | =05=  | -   | =WPA2_AES_PSK=       | =06=  | -   | =WPA2_TKIP=          | =07=  | -   | =WPA2_TKIP_AES_PSK=  | =08=  | -   | =WPA_WPA2_MixedMode= | =09=  | - -** Setting all network options - -   The following sets -   - IP =192.168.0.7= -   - Subnet mask =255.255.255.0= -   - Gateway =192.168.0.1= -   - SSID =SSID_HERE= -   - Key =PASSWORD_HERE= -   - Key Type =WPA2_AES_PSK= - -   Packet contents from wireshark (including string representation): - -   #+begin_src -   0000   1f 1b 1f b4 c0 a8 00 07 ff ff ff 00 c0 a8 00 01   ................ -   0010   06 53 53 49 44 5f 48 45 52 45 00 50 41 53 53 57   .SSID_HERE.PASSW -   0020   4f 52 44 5f 48 45 52 45 00                        ORD_HERE. -   #+end_src - -   | Description     | Character       | -   |-----------------+-----------------| -   | Unit Separator  | =1f=            | -   | Escape          | =1b=            | -   | Unit Separator  | =1f=            | -   | Command Code    | =b4=            | -   | IP              | =c0 a8 00 07=   | -   | NetMask         | =ff ff ff 00=   | -   | Gateway         | =c0 a8 00 01=   | -   | Key Type        | =06=            | -   | SSID            | =SSID_HERE=     | -   | NUL-termination | =00=            | -   | Key             | =PASSWORD_HERE= | -   | NUL-termination | =00=            | - -* Post-packet analysis - -  At this point, after writing an application that could send -  identical packets given the correct input, I realized that for some -  reason, my printer was not responding to the commands issued from -  either the config utility or my program. - -  I tried to look deeper for better documentation, but was only able -  to come across [[file:80XX_Programmer_Manual.pdf][this PDF]] from their [[https://xprinter.com.ua/terms--conditions.html][Russian language website]], which -  unfortunately still didn't contain the WiFi setup instructions. - -  I was also able to find [[https://github.com/daotuyen9244/XprinterPOS][this]] GitHub repo that seems to contain some -  commands for Xprinter systems, but not the ones I need. - -  The data sheets on the Xprinter website claims they have the Linux -  test utility, which should contain the necessary tools to configure -  wifi on the printers, but it seems they only support Android and -  Windows. - -* Wine USB attempt 2 - -  I tried again to get the printer software to work under wine. It -  turns out wine only looks at =/dev/lp*= devices by default and -  doesn't add =/dev/usb/lp*=. This time I searched the wine wiki for -  ways to get the Linux =/dev/usb/lp0= device to show up as =LPT1= -  under wine. After some digging it appears you can tell wine which -  devices to map to =COM= / =LPT= ports with registry values. - -  It's described in section [[https://wiki.winehq.org/Wine_User's_Guide#Serial_and_Parallel_Ports][4.3.1]] on the [[https://wiki.winehq.org/Wine_User's_Guide][Wine User's Guide]]. - -  I followed the guide and created the following registry key. - -  #+ATTR_HTML: :title Adding the registry key in wine -  #+ATTR_HTML: :alt wine regedit -  [[file:xprinter_wine_regedit.png]] - -  I then restarted the wine server using the following command. - -  #+begin_src shell -  wineserver -k -  #+end_src - -  I've exported the registry entry [[file:xprinter_lp0.reg][here]] in case anyone wants to do the -  same. - -  At that point the Xprinter setup tool was able to recognize the -  printer as =LPT1=. - -  I then setup wireshark to be able to sniff USB traffic using the -  their guide [[https://wiki.wireshark.org/CaptureSetup/USB][here]]. - -  From there I was able to figure out which USB hub it was running -  through and its device ID, and filter it out using a wireshark -  filter. - -  #+ATTR_HTML: :title wireshark USB sniffing -  #+ATTR_HTML: :alt wireshark USB sniffing -  [[file:xprinter_usb_wireshark.png]] - -  After sniffing the USB traffic sent by the xprinter configuration -  app, it looks identical to what was being sent over the TCP -  connection, meaning what I built should have worked. - -* The solution - -  So apparently I made some assumptions when starting this project -  that turned out to not be true. - -  It seems only the command to set all options at once consistently -  works, even when using the Xprinter setup tool from within Windows. -  The printer will also not allow you to reconfigure it's WiFi unless -  connected over USB. - -  After I narrowed down the number of commands I was testing to only -  =xb4= and only trying over USB, it worked fine. - -  I suppose I should have checked that all the commands worked -  properly from the beginning, but I did learn a lot along the way -  so it wasn't a total loss. - -  After figuring out the issue, I wrote a small command line tool to -  configure the printer. You can check it out [[https://github.com/dantecatalfamo/xprinter-wifi][here]]. - -  #+ATTR_HTML: :title Xprinter WiFi config tool screenshot -  #+ATTR_HTML: :alt Xprinter WiFi config tool screenshot -  [[file:xprinter_wifi_screenshot.png]] diff --git a/content/posts/WIP-xprinter-wifi/xprinter_advanced.png b/content/posts/WIP-xprinter-wifi/xprinter_advanced.pngBinary files differ deleted file mode 100644 index ded4185..0000000 --- a/content/posts/WIP-xprinter-wifi/xprinter_advanced.png +++ /dev/null diff --git a/content/posts/WIP-xprinter-wifi/xprinter_lp0.reg b/content/posts/WIP-xprinter-wifi/xprinter_lp0.regBinary files differ deleted file mode 100644 index 1233a6d..0000000 --- a/content/posts/WIP-xprinter-wifi/xprinter_lp0.reg +++ /dev/null diff --git a/content/posts/WIP-xprinter-wifi/xprinter_set_net.png b/content/posts/WIP-xprinter-wifi/xprinter_set_net.pngBinary files differ deleted file mode 100644 index 329422a..0000000 --- a/content/posts/WIP-xprinter-wifi/xprinter_set_net.png +++ /dev/null diff --git a/content/posts/WIP-xprinter-wifi/xprinter_setup_tool.png b/content/posts/WIP-xprinter-wifi/xprinter_setup_tool.pngBinary files differ deleted file mode 100644 index a5e5004..0000000 --- a/content/posts/WIP-xprinter-wifi/xprinter_setup_tool.png +++ /dev/null diff --git a/content/posts/WIP-xprinter-wifi/xprinter_usb_wireshark.png b/content/posts/WIP-xprinter-wifi/xprinter_usb_wireshark.pngBinary files differ deleted file mode 100644 index 18a8bfb..0000000 --- a/content/posts/WIP-xprinter-wifi/xprinter_usb_wireshark.png +++ /dev/null diff --git a/content/posts/WIP-xprinter-wifi/xprinter_wifi_screenshot.png b/content/posts/WIP-xprinter-wifi/xprinter_wifi_screenshot.pngBinary files differ deleted file mode 100644 index be5ff65..0000000 --- a/content/posts/WIP-xprinter-wifi/xprinter_wifi_screenshot.png +++ /dev/null diff --git a/content/posts/WIP-xprinter-wifi/xprinter_wine_regedit.png b/content/posts/WIP-xprinter-wifi/xprinter_wine_regedit.pngBinary files differ deleted file mode 100644 index c8ff03c..0000000 --- a/content/posts/WIP-xprinter-wifi/xprinter_wine_regedit.png +++ /dev/null diff --git a/content/posts/WIP-xprinter-wifi/xprinter_wireshark.png b/content/posts/WIP-xprinter-wifi/xprinter_wireshark.pngBinary files differ deleted file mode 100644 index 1b70a27..0000000 --- a/content/posts/WIP-xprinter-wifi/xprinter_wireshark.png +++ /dev/null | 
