ruida-laser icon indicating copy to clipboard operation
ruida-laser copied to clipboard

DA 00 XX XX - get XX XX from machine

Open ghost opened this issue 6 years ago • 61 comments

I dream make my own hardware compatible with RDWorks. Reading RD-file from SD-card is not a problem. But communication with RDWorks software is a problem. I noticed that I should response in the following way DA 01 XX XX <VALUE>. For example, when I press any button in RDWorks it's first send DA 00 05 7E. But I don't found information about this commands, anyone has decoded this?

ghost avatar Aug 01 '19 07:08 ghost

It's mentioned in Roger Clark's work: http://www.rogerclark.net/network-aware-laser-cutter-security/

e.g. This seems to be the initial packet that is always sent by RDWorks 02:61:d4:89:0d:f7 to which the RDC6442G responds with c6 and then sends a reply packet e.g. d4:09:0d:f7:8f:a1:09:c3:89

Which suggests the right response is: swizzled is: b'\xd4\x09\x0d\xf7\x8f\xa1\x09\xc3\x89' And unswizzled: b'\xDA\x01' + bytearray(array[2:4]) + b'\x06\x28\x01\x4a\x00'

The issue I'm having is that this it's not enough to trick RDWorks.

I added a basic RuidaServer to MeerK40t ( https://github.com/meerk40t/meerk40t/commit/f98bd1ae088865f32e6e4b1c6a045c0d2aca907c ). The idea being I can tell MeerK40t to open that port, pretend to be a RuidaServer then control my M2 Nano with RDWorks for whatever reason you'd have for doing that. But, RDWorks says that that answer is wrong, quickly shutting down with "connection error". @jnweiger can you post a full exchange of the the devices babbling through a ruidaproxy? At least enough to figure out this handshake.

tatarize avatar May 09 '20 14:05 tatarize

Figured it out. The required reply is certainly 0x65006500 for 0x05 0x7E. Most of the rest of the values you can just return 0.

tatarize avatar May 25 '20 03:05 tatarize

634XG uses 0x11 xor as the swizzle. But all of them fail at: --> da000004 <-- da0100040000000000

Responding that 00 04 is equal to zero causes the program to terminate the connection. Goes through with 644XG, where it accepts 0 for that value. I have meerk40ts new version fully pretending to be a ruida device.

tatarize avatar May 27 '20 13:05 tatarize

@ghost I've decoded all the commands. Literally 100% of them. That command actually is Get Parameter "Card ID". Also decoded all the parameters, some of them I can't even get RDWorks to bother asking for. Most of them even weird ones just dutifully get put into the boxes. I told it my machine main board version was "MEERK40T" and it thought that was fine.

I can't, however, know what a good response to Get Machine Status should be for the other controllers and I don't know any other Card IDs that do not raise any objections.

https://edutechwiki.unige.ch/en/Ruida

tatarize avatar May 29 '20 00:05 tatarize

Hello, how are you? I have a laser RUIDA ... Can you help me to "decode" the RUIDA ACS android app? Thank you. Bruno Santos. Portugal.

cortesegravacoes avatar Jul 13 '20 22:07 cortesegravacoes

The link I gave there gives all the commands. The app there is just controlling the laser through the UDP packets. It's just doing what any program controlling the Ruida would do. MeerK40t now allows for a ruida server, which will decode all the commands. If you really wanted to see exactly the commands the app is using. Download a copy of the app, and MeerK40t. Tell the app your Ruida laser is located at the computer running the MeerK40t ruidaserver and it'll tell you exactly the commands it's using. D9 00 and D9 01 are the main commands for moving the x and y. But, it'll let you see all the various other commands its using, since MeerK40t interprets all that stuff.

Then you'd make a similar app that just sends the same commands over UDP to the Ruida device. Basically writing your own Ruida controller software. Which isn't too hard to do. But, mostly you could interpret the app info with MeerK40t. ( https://github.com/meerk40t/meerk40t )

tatarize avatar Jul 14 '20 20:07 tatarize

Thanks for your reply, I am very grateful! But I take the opportunity to expose some doubts ... I am trying to communicate with RUIDA and ARDUINO , sending udp packages to RUIDA. The wireshark software says it does not recognize the IP RUIDA being broadcast. Can you explain why? Will I have to send a hexadecimal to get communication? I can't find my RUIDA's IP and Mac address anywhere on my LAN ... I wonder why? Thank you.

cortesegravacoes avatar Jul 14 '20 21:07 cortesegravacoes

Ohh!!! Camera?? Real time streaming? How does it work?

cortesegravacoes avatar Jul 14 '20 21:07 cortesegravacoes

Basically in MeerK40t hit alt+F12 it'll start up the ruidaserver. Then you say whatever computer running it is a ruida device. It'll take any UDP data sent and parse out the hex into the data commands.

tatarize avatar Jul 14 '20 22:07 tatarize

It's built to control an Lhystudios M2 Nano controller. But, one of the things to do is to interpret other boards so I could use RDWorks or Lightburn to control the M2 device. So it does all the parsing for the Ruida device to make that easier.

tatarize avatar Jul 14 '20 22:07 tatarize

Basicamente, no MeerK40t, pressione alt + F12 e iniciará o ruidaserver. Então você diz que qualquer computador que esteja executando é um dispositivo ruida. Ele pega todos os dados UDP enviados e analisa o hexadecimal nos comandos de dados.

Sorry, I don't understand, or I didn't make myself understood. Can you tell how to communicate with RUIDA through ARDUINO? Directly from the arduino, not going through your RUIDA Server ... I loved your idea. Thanks, but as I've been doing this for 3 days, I didn't want to drop it, I would like to finally finish the communication, to really see how it is. How does RUIDA accept UDP? Because wireshark does not recognize the RUIDA IP ... Thank you.

cortesegravacoes avatar Jul 14 '20 22:07 cortesegravacoes

With an arduino you'd have to connect through the COM port it has. Which would also work. Ruida devices have a internet connection and process UDP. You would wireshark when you connect to the Ruida device with RDWorks or Lightburn. If not over the net, the other connection method is COM port.

https://stefan.schuermans.info/rdcam/pc_conn.html

Unlike the UDP since I can fake it and do the research I don't have much info on how you'd do arduino com port connection stuff.

tatarize avatar Jul 14 '20 23:07 tatarize

The interest would be to connect the arduino via Ethernet ... But for example, what is the 1 command sent to "activate" the RUIDA, that is, if you move the axes manually, in addition to the hex of the axes, first you have to go a hex to "activate" RUIDA, what is the hex that tells RUIDA that someone (arduino, PC, rpi) wants to connect to RUIDA?

cortesegravacoes avatar Jul 14 '20 23:07 cortesegravacoes

There's not actually much to activation. You can see the handshaking when connecting RDWorks to a the fake server. Mostly you don't need most of that handshake stuff. You can generally just tell it to move. Here's a typical jog command:

--> da00057e	(Get 05 7e (Card ID))
<-- b'\xda\x01\x05~\x06(\x01J\x00'     (Respond 05 7e (Card ID) = 1694524672 (0x65006500))
<-- cc     (checksum match)
--> da00057e	(Get 05 7e (Card ID))
<-- b'\xda\x01\x05~\x06(\x01J\x00'     (Respond 05 7e (Card ID) = 1694524672 (0x65006500))
<-- cc     (checksum match)
--> da000004	(Get 00 04 (IOEnable))
<-- b'\xda\x01\x00\x04\x00\x00\x00\x00\x00'     (Respond 00 04 (IOEnable) = 0 (0x00000000))
<-- cc     (checksum match)
--> da00057e	(Get 05 7e (Card ID))
<-- b'\xda\x01\x05~\x06(\x01J\x00'     (Respond 05 7e (Card ID) = 1694524672 (0x65006500))
<-- cc     (checksum match)
--> da000400	(Get 04 00 (Machine Status))
<-- b'\xda\x01\x04\x00\x00\x00\x00\x00\x16'     (Respond 04 00 (Machine Status) = 22 (0x00000016))
<-- cc     (checksum match)
--> da000026	(Get 00 26 (Axis Range 1, Get Frame X))
<-- b'\xda\x01\x00&\x00\x00\x13D\x00'     (Respond 00 26 (Axis Range 1, Get Frame X) = 320000 (0x0004e200))
<-- cc     (checksum match)
--> da000036	(Get 00 36 (Axis Range 2, Get Frame Y))
<-- b'\xda\x01\x006\x00\x00\r6`'     (Respond 00 36 (Axis Range 2, Get Frame Y) = 220000 (0x00035b60))
<-- cc     (checksum match)
--> da000021	(Get 00 21 (Axis Precision 1))
<-- b'\xda\x01\x00!\x00\x00\x00\x00\x00'     (Respond 00 21 (Axis Precision 1) = 0 (0x00000000))
<-- cc     (checksum match)
--> da000031	(Get 00 31 (Axis Precision 2))
<-- b'\xda\x01\x001\x00\x00\x00\x00\x00'     (Respond 00 31 (Axis Precision 2) = 0 (0x00000000))
<-- cc     (checksum match)
--> da00057e	(Get 05 7e (Card ID))
<-- b'\xda\x01\x05~\x06(\x01J\x00'     (Respond 05 7e (Card ID) = 1694524672 (0x65006500))
<-- cc     (checksum match)
--> da00057e	(Get 05 7e (Card ID))
<-- b'\xda\x01\x05~\x06(\x01J\x00'     (Respond 05 7e (Card ID) = 1694524672 (0x65006500))
<-- cc     (checksum match)
--> da000004	(Get 00 04 (IOEnable))
<-- b'\xda\x01\x00\x04\x00\x00\x00\x00\x00'     (Respond 00 04 (IOEnable) = 0 (0x00000000))
<-- cc     (checksum match)
--> da000020	(Get 00 20 (Axis Control Para 1))
<-- b'\xda\x01\x00 \x00\x00\x01\x00\x00'     (Respond 00 20 (Axis Control Para 1) = 16384 (0x00004000))
<-- cc     (checksum match)
--> c9020000030650	(Speed Laser 1 50.000000mm/s)
<-- cc     (checksum match)
--> c6017f7f	(Power 1 min=99.993896)
<-- cc     (checksum match)
--> c6217f7f	(Power 2 min=99.993896)
<-- cc     (checksum match)
--> c6027f7f	(Power 1 max=99.993896)
<-- cc     (checksum match)
--> c6227f7f	(Power 2 max=99.993896)
<-- cc     (checksum match)
--> d900007f7f7f3170	(Move Origin X: -10000.000000 (-20000.000000,0.000000))

Most of the rest of that stuff can be dropped. Maybe not the laser speed but the laser power stuff. That's just syncing it with RDWorks.

tatarize avatar Jul 14 '20 23:07 tatarize

What is "card ID" ? First connection to RUIDA? Enable connection to RUIDA? Does the raspberry pi 3 + handle 2 servers working? This and the other in java? How to find out the IP address and Mac address of RUIDA on the lan?

cortesegravacoes avatar Jul 15 '20 00:07 cortesegravacoes

CardID is something or other. If RDWorks doesn't get 0x65006500 back which is the same as it writes 6500 it will disconnect and refuse to continue. It's actually what this thread originally was asking. What is the proper response to that query. It's called CardID and the correct response is 6500 with that you can also return zero for most of the rest of the stuff and it doesn't worry too much about it. Ghost's original question was the reply to DA 00 05 7E which is really DA 01 65 00 65 00. I'm not actually sure what it means other than the listing as CardID.

tatarize avatar Jul 15 '20 00:07 tatarize

I think Ruida device itself gives you the IP address, somewhere. (I do not own a ruida device). You couldn't run MeerK40t's mock server and this one on the same IP because, by necessity, they use the same UDP port.

tatarize avatar Jul 15 '20 01:07 tatarize

But think with me ... RUIDA receives 057e asks for communication, then RUIDA responds 0400 to say it is waiting for something? It is? As for the raspberry pi, I have a Java server running on it 24 hours a day, I was thinking of adding your server more, the IP of the RPI being different from RUIDA, of course.! I don't know if the 2 will work at the same time ... Obs... After hex, i used scramble and uncramble in ARDUINO code...

cortesegravacoes avatar Jul 15 '20 06:07 cortesegravacoes

Hello, I already installed your software on Windows, very good ... Congratulations ... Opening the server, you really see the commands, :), but in reality I can't get the machine to work with your software as shown on YouTube ... Like the Android app, you cannot connect to the virtual RUIDA IP. I wonder why? Thank you

cortesegravacoes avatar Jul 15 '20 19:07 cortesegravacoes

I wonder that too. I got a copy of the software for Android and I ran it and it didn't seem to even try to connect. It has my correct IP address and everything. There may be something different in the protocol like it's connecting to a different port somehow or doing something else, I might have to eavesdrop on the connection to figure out what's going on there. It should have been really easy, but somehow it's not connecting correctly. RDWorks works fine. The android app doesn't seem to do that.

tatarize avatar Jul 16 '20 08:07 tatarize

I ran wireshark on the PC connection for data from the tablet to catch the incoming packets and the only thing from the right location was:

615 26.034262 192.168.1.118 192.168.1.167 UDP 60 40207 → 50207 Len=1 0xC

In console.py the line 1653: port = 50200

So I changed that to:

port = 50207

And... it crashed. Since it's sending 0xCC which is an ACK packet it, but over UDP packets always tended to require checksums.

Also, 0xCC is ACK in the clear, without any swizzling. I replied 0xCC to it, and it said "Success!". So that's apparently the login sequence there. But, the protocol for the UDP here is a bit different than elsewhere.

tatarize avatar Jul 16 '20 08:07 tatarize

The app has some specialty commands that are not actually seen elsewhere, and a different protocol on UDP 50207.

  • +X key down
    • \xa5P\x02
  • +X key up
    • \xa5Q\x02
  • -X key down
    • \xa5P\x01
  • -X key up
    • \xa5Q\x01
  • +Y key down
    • \xa5P\x03
  • +Y key up
    • \xa5Q\x03
  • -Y key down
    • \xa5P\x04
  • -Y key up
    • \xa5Q\x04
  • +Z key down
    • \xa5P\n
  • +Z key up
    • \xa5P\n
  • -Z key down
    • \xa5P\x0b
  • -Z key up
    • \xa5Q\x0b
  • +U key down
    • \xa5P\x0c
  • +U key up
    • \xa5Q\x0c
  • -U key down
    • \xa5P\r
  • -U key up
    • \xa5P\r
  • Speed
    • \xa5P\x11
  • Start/Pause
    • \xa5P\x06
  • Stop
    • \xa5P\t
  • Reset
    • \xa5PZ
  • Trace On/Off
    • \xa5P\x0f
  • ESC
    • \xa5P\x07
  • Laser Gate
    • \xa5P\x12
  • Pulse key down
    • \xa5P\x05
  • Pulse key down
    • \xa5Q\x05
  • Origin
    • \xa5P\x08
  • Frame
    • \xa5S\x00

Also, the Tablet sends \xce on regular intervals. I'm guessing it's a keep alive.

tatarize avatar Jul 16 '20 08:07 tatarize

The 0xA5 command sends doesn't have a known meaning since it's wasn't registered in the code for the PC version rdworks.

The commands are typically P (0x50), except for some commands which have a key-up command too which is Q (0x51). Except for "Frame" which is 0xA5 S (0x53) It then has a command index.

So if you sent your Ruida over UDP on port 50207 0xA5 0x50 0x01 then 0xA5 0x51 0x01 it would start moving +X then stop. 0x02 is -X. 0x03 is +Y, 0x04 is -Y. Etc.

There is also a blank spot for current location of the laser in the app since I never sent back the right data. To get that correct it might require actually snooping on traffic between the tablet and the the controller.

tatarize avatar Jul 16 '20 09:07 tatarize

Alright. Reverse Engineered most of that. Get a copy of the program circa 0.6.2 and the ruida server will also have a Ruida Jog Server which takes in those jog commands that the app sends out on port 50207. There's still an option on the Android device screen that says location and without capturing the app talking with the laser control, I'm not sure how that gets the information.

https://github.com/meerk40t/meerk40t/tree/0.6.2 (Added the jog server in just that branch).

--> a55006	(Interface Start/Pause)
<-- cc	(ACK)
--> a55009	(Interface Stop)
<-- cc	(ACK)
--> a5505a	(Interface Reset)
<-- cc	(ACK)
--> a5500f	(Interface Trace On/Off)
<-- cc	(ACK)
--> a55007	(Interface ESC)
<-- cc	(ACK)
--> a55012	(Interface Laser Gate)
<-- cc	(ACK)
--> a55005	(Interface Pulse Down)
<-- cc	(ACK)
--> a55105	(Interface Pulse Up)
<-- cc	(ACK)
--> a55008	(Interface Origin)
<-- cc	(ACK)
--> a55300	(Interface Frame)
<-- cc	(ACK)
--> a5500c	(Interface +U Down)
<-- cc	(ACK)
--> a5510c	(Interface +U Up)
<-- cc	(ACK)
--> a55003	(Interface +Y Down)
<-- cc	(ACK)
--> a55103	(Interface +Y Up)
<-- cc	(ACK)
--> a5500a	(Interface +Z Down)
<-- cc	(ACK)
--> a5510a	(Interface +Z Up)
<-- cc	(ACK)
--> a55001	(Interface -X Down)
<-- cc	(ACK)
--> a55101	(Interface -X Up)
<-- cc	(ACK)
--> a55011	(Interface Speed)
<-- cc	(ACK)
--> a55002	(Interface +X Down)
<-- cc	(ACK)
--> a55102	(Interface +X Up)
<-- cc	(ACK)
--> a5500d	(Interface -U Down)
<-- cc	(ACK)
--> a5510d	(Interface -U Up)
<-- cc	(ACK)
--> a55004	(Interface -Y Down)
<-- cc	(ACK)
--> a55104	(Interface -Y Up)
<-- cc	(ACK)
--> a5500b	(Interface -Z Down)
<-- cc	(ACK)
--> a5510b	(Interface -Z Up)
<-- cc	(ACK)

So that's enough to replicate the Android App for whatever you are planning to do with that info.

tatarize avatar Jul 16 '20 10:07 tatarize

Ohhh thank you for all work.

cortesegravacoes avatar Jul 16 '20 10:07 cortesegravacoes

Amazing

cortesegravacoes avatar Jul 16 '20 10:07 cortesegravacoes

Where are you from? :)

cortesegravacoes avatar Jul 16 '20 11:07 cortesegravacoes

California, US.

NP on the work, I reverse engineer a lot of stuff so it's a bit easy at this point.

tatarize avatar Jul 16 '20 12:07 tatarize

Corri o wireshark na conexão do PC para obter dados do tablet para capturar os pacotes recebidos e a única coisa no local certo era:

615 26.034262 192.168.1.118 192.168.1.167 UDP 60 40207 → 50207 Len = 1 0xC

No console.py da linha 1653: port = 50200

Então eu mudei isso para:

port = 50207

E ... caiu. Como está enviando 0xCC, que é um pacote ACK, mas os pacotes UDP sempre tendem a exigir somas de verificação.

Além disso, 0xCC é ACK claro, sem qualquer swizzling. Eu respondi 0xCC e disse "Sucesso!". Então essa é aparentemente a sequência de login lá. Mas, o protocolo para o UDP aqui é um pouco diferente do que em outros lugares.

I understood that I don't need to swizzle on the Arduino and that the commands to be sent to RUIDA are without swizzling, do you agree?

O aplicativo possui alguns comandos especiais que na verdade não são vistos em outros lugares e um protocolo diferente no UDP 50207.

  • Tecla + X pressionada

    • \ xa5P \ x02
  • Tecla + X acima

    • \ xa5Q \ x02
  • Tecla -X pressionada

    • \ xa5P \ x01
  • Tecla -X

    • \ xa5Q \ x01
  • Tecla + Y pressionada

    • \ xa5P \ x03
  • Tecla + Y para cima

    • \ xa5Q \ x03
  • -Y tecla pressionada

    • \ xa5P \ x04
  • Tecla -Y

    • \ xa5Q \ x04
  • Tecla Z + pressionada

    • \ xa5P \ n
    • Tecla Z para cima
    • \ xa5P \ n
  • -Z tecla pressionada

    • \ xa5P \ x0b
  • Tecla -Z

    • \ xa5Q \ x0b
    • Tecla U pressionada
    • \ xa5P \ x0c
    • Tecla U para cima
    • \ xa5Q \ x0c
  • -U tecla para baixo

    • \ xa5P \ r
  • Tecla -U

    • \ xa5P \ r
  • Rapidez

    • \ xa5P \ x11
  • Iniciar / Pausar

    • \ xa5P \ x06
  • Pare

    • \ xa5P \ t
  • Redefinir

    • \ xa5PZ
  • Rastreamento ativado / desativado

    • \ xa5P \ x0f
  • ESC

    • \ xa5P \ x07
  • Laser Gate

    • \ xa5P \ x12
  • Tecla de pulso pressionada

    • \ xa5P \ x05
  • Tecla de pulso pressionada

    • \ xa5Q \ x05
  • Origem

    • \ xa5P \ x08
  • Quadro, Armação

    • \ xa5S \ x00

Além disso, o Tablet envia \xceregularmente. Eu estou supondo que é manter vivo.

Different UDP protocol? As well?

cortesegravacoes avatar Jul 16 '20 16:07 cortesegravacoes

Yeah, the UDP is in the clear without checksum and without swizzle. It's also on port 50207 and replies are made to the sending port on port 40207.

If you make an app that sends a UDP from port 40207 to 50207 on the Ruida device and send one of those preset packets, it should duplicate the app functionality.

tatarize avatar Jul 16 '20 22:07 tatarize