bdring / Grbl_Esp32

A port of Grbl CNC Firmware for ESP32
GNU General Public License v3.0
1.68k stars 527 forks source link

Help on decoding strange message from proprietary vigotec firmware #639

Closed arkypita closed 3 years ago

arkypita commented 3 years ago

Hello everyone, I am the developer of LaserGRBL.

I am trying to make my program able to communicate with a laser engraver (Vigo VG-L7x) on which the manufacturer, which does not release specifications and which does not have a contact even email, has made some changes to the standard "grbl" protocol by inserting some messages that to my eyes they appear "encoded" or perhaps even "encrypted".

This cause that this machine can only talk with their software (which is a piece of junk) so people start asking me to support it in LaserGRBL (if possible).

Look like that when the engraver talks to their standard program, in addition to exchanging a stream of human readable G-Code commands, it exchanges some messages that are not understandable because they are encoded.

The control board has an both an ESP32 chip and an Atmega32. I think that the communication is handled by ESP32 that talk to Atmega32 (where they have the standard grbl firmware).

Here some example (see picture or pastebin) of this encoded communication https://pastebin.com/v3q14rdE

image

These messages are sent regularly on specific action: on connection, before starting to send a job file, at the end of the job stream etc and activate something on ESP32 that make it able to work.

For example, the board does not send an "ok" at each command received but use a sort of status report in the form of <VSta:2|SBuf:5,1,0|LTC:4095> to tell, via Sbuf numbers, how many lines are received, processed etc. The problem is that this report is only activated when you send a special encripted command that say "I am start streaming a job" (and the board make a beep when receive this command).

Between multiple work sessions the messages content is always different, but same lenght. https://pastebin.com/AXz6k3tQ

If I send a previous session message, the engraver recognize it without problem. Understanding if it is simply encoded (and so reversable), or ciphered can really help me not wasting my time.

Any Idea? Thanks to all!

arkypita commented 3 years ago

Here is a picture of the board

image

bdring commented 3 years ago

It does not sound like the the ESP32 is using our firmware. I would suggest making a new controller. That would be easier, give you full control and future upgrades.

MitchBradley commented 3 years ago

My first guess is that the data might be a variant of base64 encoding of binary data. The character set looks like base64 except for the use of : instead of +. But even if you do reverse that encoding, you still have to discover the meaning of the data. I suspect that the messages could be some sort of challenge/response authentication scheme for protecting against unauthorized use of the laser. It could be pretty dangerous if someone took control of a 20W wireless laser and started a fire.

arkypita commented 3 years ago

Thanks both

Yes, I assumed they didn't use your firmware. Since both an ESP32 and an Atmega328 are present on the board, I assume that there is a standard GRBL firmware on the Atmega328 and the ESP simply acts as an interface for Wi-Fi and probably also for serial communication via USB.

So i think that the schema is PC <==> USB/WIFI <==> ESP32 <==> Atmega328

They have implemented a firmware in the ESP32 that partly appears "transparent" (for example the GCODE stream is sent normally, as well as some of the immediate commands and the real-time status message) and partially changes things a bit; eating the "ok" messages, changing error message in a different form of message, adding a new status message <VSta:2|SBuf:5,1,0|LTC:4095> that report streaming reception progress (that could be used instead of the "ok's" as confirm of reception) and with those weird encoded/encripter phrasing.

My first guess is that the data might be a variant of base64 encoding of binary data.

At a glance, I too had this impression, but trying to decode them with base64 leads to unreadable results.

These messages are exchanged on some specific occasions:

I suspect that the messages could be some sort of challenge/response authentication scheme for protecting against unauthorized use of the laser.

It might seem like it, but it isn't. Even without sending the encrypted commands you can still send GCode commands and activate the laser.

Instead, these messages appear to activate "modes". For example what you exchange as "header" activates a sort of "in program" mode and the board make a "beep" and start sending <VSta|Sbuf> report, and stop that modes when receive the "footer"

arkypita commented 3 years ago

PS: even if I know that it has nothing to do with your fw I chose to write here because maybe among you there is someone a little expert in ESP32 who could recognize some similarity with something already seen. I hope it doesn't bother!

MitchBradley commented 3 years ago

It is very unlikely that what they are doing is related to anything specific to the ESP32 processor. It is clearly some sort of protocol chatter. The only ESP-specific protocol that I know of is ESP-Now, and that is for an entirely different use case - things like smart lights.

One possibility is that they invented their own variant of base64 and use it to transmit data structure values directly.

Since transparent sending seems to work, can just just ignore that extra protocol?

If not, are the messages always the same for specific use cases, or do they vary from run to run even when you are doing the exact same thing? If they are the same, then perhaps you could try different use cases and create a map of which message values activate which modes. You have probably already thought of that; I'm just mentioning it for completeness.

MitchBradley commented 3 years ago

Can you snoop on the serial lines between the ESP32 and the AVR to see if there are extra GCode or GRBL messages that result from the funny protocol messages?

arkypita commented 3 years ago

Since transparent sending seems to work, can just just ignore that extra protocol?

It works, in the sense that the commands are executed, but with the lack of "ok's" response it's very difficult (if not impossible) to stream gcode to the board without overfilling the buffer because you can't know when grbl received and managed them so you can send more.

The only way to have a command/streaming feedback from the board (and so being able to implement a character count protocol) is to activate the <VSta:2|SBuf:5,1,0|LTC:4095> report which can only be activated by sending the right encrypted string that the board recognize as "start of a job stream".

It would also be interesting to understand the meaning of these VSta, SBuf, LTC. My guess is:

If not, are the messages always the same for specific use cases, or do they vary from run to run even when you are doing the exact same thing? If they are the same, then perhaps you could try different use cases and create a map of which message values activate which modes.

I did some analysis and this is what I see: 1) Ciphered messages they exchange (from sw to fw and vice versa) are always different, without any similar recognizable sequence/pattern. Only length of the message (of same type) look repetitive. 2) If I send an old known/snooped message the action is acknowledge by the fw and accepted (that's a good news for me!). The board reply with a ciphered message that is different from the previous reply message, even if you keep sending him the same old snooped message. 3) if you try to change some character to the message (respecting length) the board doesn't recognize the message and doesn't reply.

All this makes me think that the messages are encrypted, and that a foo/ignored character/number is added to randomize the result of the encryption.

Luckily it seems that sending known messages, without knowing what they mean, cheats the receiver. I am going to map messages as you suggest.

Can you snoop on the serial lines between the ESP32 and the AVR to see if there are extra GCode or GRBL messages that result from the funny protocol messages?

Not so easy because i should put some wires and maybe cut some path on the PCB.

MitchBradley commented 3 years ago

I downloaded the software for both VG-L7 and VG-L7x from http://www.vigotec.cn/ . In the VG-L7 zip file, I found a readme that says this

Important for using VigoEngraverL7_v2.32:
    1.Please upload the new firmware 'VigoEngraver_Firmware_V1.3_B20200718.hex' to the control board before using the new VigoEngraverL7_v2.32.
    2.Two methods for upload the new firmware, use VigoEngraverL7_v2.32 or XLoader.exe.
    3.Follow the software manual, if use the VigoEngraverL7_v2.32, click connect, and the firmware will upload automatically!
    4.If you have other control software and want to use it, please upload the standard grbl firmware named 'Standard_Grbl_1.1f.hex'. Or if you have the appropriative firmware just for the control software, upload it !

Detailed description:
    The default firmware of engraving machine control main board is VIGOTEC special firmware. You can only use the VigoEngraveL7 laser engraving machine software you just downloaded to control engraving. There are two firmware files in the software directory, which are special firmware and general firmware. If you want to use other engraving machine control softwares, please update the firmware of engraving machine motherboard to general firmware. If you still want to use the VigoEngraveL7 laser engraving machine software after you updated the general firmware, please update the firmware back to the special firmware. The main board firmware update method is as follows: Click "Settings > Model Select", Click "Upload Firmware" at the bottom left of the dialog box, Click "OK". Then select one of the firmware file you want to update and click "Open", and wait for the firmware to update automatically.
    If you fail to update the firmware with VigoEngraveL7, you can also use XLoader to update the firmware of the control board. Please refer to step 8 of the User-Guide for update method.

That makes me think that the ESP32 might be programmed to be a transparent gateway between the USB and the AVR, with special firmware in the AVR chip. The ESP32 probably also has a WiFi mode that gateways from WiFi to AVR.

If that idea is correct, then it might be possible to use XLoader to reprogram the AVR with standard GRBL, and problem solved.

The Vigo app has a screen that will restore the device to factory defaults, which might let you put the special firmware back in the AVR if necessary.

I think my guess is very likely to be correct, based on what I know about the way product development teams work. The simpler VG-L7 version was probably the first product. They developed the special AVR firmware to support their application requirements. Then later, when they wanted to add the new WiFi-capable version, they kept the AVR code the same as before, and added only the minimal ESP functionality needed to support the new features. They first programmed the ESP32 as a transparent gateway, so all of their existing app code and AVR firmware ran unchanged, then they folded in the extra WiFi gateway features.

Note: The following idea is probably obsolete based on information that I have just discovered.

Another possibility would be to reprogram the ESP32 as a truly transparent gateway. You could do it in stages, as follows

If esptool does not work, it could be that the manufacturer tried to make it difficult to reprogram via the USB port. One reason I suspect that is because they have used a CH330N USB-serial chip instead of the more common CH340 or CP2102. The CH330N has too few pins to support the extra RTS and DTR pins that most ESP32 modules use to switch the ESP32 into programming mode. CH330N has RTS but not DTR. They may have a clever way to make it work but you would have to try esptool to see. Fortunately, it is easy to force programming mode by temporarily shorting IO0 to ground then resetting the ESP32.

Alternatively, it might be possible to use ESP32 OTA to change the ESP32 firmware.

MitchBradley commented 3 years ago

Regarding snooping, cutting traces would not be necessary, because you would be adding extra receivers to lines, and that can be done safely. The wires could be soldered to the pins on the ESP32 module. Those pins are large and easy to access.

arkypita commented 3 years ago

The engraver model with which I cannot communicate is the L7x, which is the model with WiFi, which uses the VigoWork software. Neither Atmega nor ESP32 firmware are provided in the download package with VigoWork for L7x.

The L7 model has a standard Atmega328 controller, and use a different software (although the UI is similar) called VigoEngraver. The firmware that comes in the download is a pretty standard grbl, despite what is stated in the readme. Loaded on an Arduino communicates without any encrypted package or notables differences with GRBL.

image

Having a transparent ESP32 is the simplest thing, among other things I also have released a sketch for ESP8266 which acts as a telnet bridge, which with a few modifications could be adapted for use with ESP32. Although the simplest choice, it seems that this is not the path taken by the developer of the VG-L7x

Yes, reprogramming the chip can be a solution, but my goal is not to make the board compatible with LaserGRBL, rather the opposite (to make LaserGRBL compatible with that board). This allows all owners of this model to use LaserGRBL, and not just the "geeks" able to reprogram the fw.

Fortunately, I have good results now. I can send "sniffed" encrypted messages and the board responds as expected. I believe I can make the necessary changes in LaserGRBL to make it compatible with the engraver.

Furthermore, the board I have on hand is not mine. It was sent to me by a LaserGRBL user who bought this engraver. Before I send it back to him, I definitely want to do some of the things you suggested.

1) Snoop on the serial lines between the AVR and ESP to see if the encryption and the VSta/SBuf message is done in esp or avr (i guess in esp because atmega328 has no free program space for implement such feature) but I want to check. 2) Dump the ESP32 firmware and clone to another ESP32 (i have some esp devkit) so I can send back the board and do my test on a test environment.

I have electronic skills so I can use ohmmeter, welder and co.

About point 2. I never dump/programmed an ESP32 chip directly (only used devkit with integrated USB). The chip is connected with u0TXD and u0RXD to USB port via CH330N wired via resistors.

text855-0

So do you thing put IO0 to ground and resetting the ESP32 should be enough to read the esp content via the USB board port? Sorry for the NOOB question, is IO0 the pin with number 23?

image

Tomorrow I will do some tests, I hope to be able to clone the firmware (if not read protected).

MitchBradley commented 3 years ago

Yes, the bootload pin is GPIO0 / pin 23. https://github.com/espressif/esptool/wiki/ESP32-Boot-Mode-Selection.

The connection of the CH330N to u0TxD and U0RxD is exactly as expected, and is compatible with the serial bootloader, so holding GPIO0 low after reset should allow you to connect with esptool.

I suppose that they had problems - just like other senders do - with the standard GRBL ok response protocol under the heavy loads of lots of laser jobs with a lot of short moves and S word changes. Such problems could be especially troublesome if they were exporting the standard GRBL line protocol over WiFi with inconsistent latency. They may be using the ESP32 for extra buffering. The SBuf reports are more definitive than ok counting, especially when you consider the error cases. I wonder if the third number relates to additional buffering in the ESP32? If I were designing an ESP32 front end to an AVR GRBL, I would probably provide a lot more line buffering inside the ESP32. Snooping on the AVR lines and comparing the ok stream to the SBuf stream can give you a clue. One problem with lines-sent/lines-received is that it does not directly give you information about the amount of free space/lines available in the queue. Maybe the queue length is known implicitly and that is compared with the difference between two SBuf numbers. A better protocol design would be to directly report the available space, like TCP does with "window size". Regardless, you can probably figure out what they did with snooping.

Regarding the lack of firmware images in the VG-L7x .zip download: I suspect that they buried the firmware images inside the application. For new users, that is less error-prone, less complicated, and requires less documentation on how to find and select the write firmware file.

One of Bart's ESP32_Grbl boards would make a much better controller for this device than the board shown, so as a thank-you for the support you are receiving here, you might consider passing on that suggestion to your Vigotech "customers".

arkypita commented 3 years ago

Thanks Mitch Your suggestions to dump the ESP32 fw point me out to the right direction and allowed me to create a replica of the system. This way I can do all the tests I want without risk of damaging the original board.

The first test was to put the ESP in communication with an arduino nano with standard grbl firmware from gnea/grbl. Everything is working correctly and the VigoWork software thinks it is talking to its board.

IMG_20201017_120730

This confirm that the arduino firmware is standard and the protocol change (encrypted message, no ok etc) is done only by the esp32 fw.

However I don't think I will go further on trying to decode the coded messages because I think this would necessarily require reverse engineering of the sw / fw to understand the encryption scheme. Once I have verified that the "spied" messages are correctly accepted by the machine in every situation, I think I could be satisfied and I have all the info I need to make LaserGRBL faking VigoWork protocol :-)

Thank you again for all the suggestions, I can close the thread Best regards