-
-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DA 00 XX XX - get XX XX from machine #2
Comments
It's mentioned in Roger Clark's work:
Which suggests the right response is: The issue I'm having is that this it's not enough to trick RDWorks. I added a basic RuidaServer to MeerK40t ( meerk40t/meerk40t@f98bd1a ). 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. |
Figured it out. The required reply is certainly 0x65006500 for 0x05 0x7E. Most of the rest of the values you can just return 0. |
634XG uses 0x11 xor as the swizzle. But all of them fail at: 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. |
@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. |
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. |
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 ) |
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. |
Ohh!!! Camera?? Real time streaming? |
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. |
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. |
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. |
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. |
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? |
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:
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. |
What is "card ID" ? First connection to RUIDA? |
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. |
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. |
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 ... |
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 |
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. |
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: So I changed that to:
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. |
The app has some specialty commands that are not actually seen elsewhere, and a different protocol on UDP 50207.
Also, the Tablet sends |
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. |
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).
So that's enough to replicate the Android App for whatever you are planning to do with that info. |
Ohhh thank you for all work. |
Amazing |
Where are you from? :) |
California, US. NP on the work, I reverse engineer a lot of stuff so it's a bit easy at this point. |
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?
Different UDP protocol? |
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. |
Due to a leftover bug in MeerK40t I updated the version and this weird parsing protocol got added. So the regular 0.6.2 MeerK40t release with Alt + F12, will launch the ruida emulation server and parse the data from the android app. |
The adroid app works 5 stars, you see all the commands. 😉 But the physical RUIDA was not supposed to respond to MeerK40t also? Mine does not answer, it is, the USB is connected and says in operation ... |
I don't have a physical Ruida device. But, you want to emulate what the app is sending to the MeerK40t program. So you would do the same thing as the android app. Send a packet 0xCC to udp:50207 at the given IP address. Then send commands like 0xa55002 then 0xa55102, to the Ruida device. It won't know it's not the normal android app, so it should work perfectly fine just sending those commands. MeerK40t is just talking between the android app and the PC. So I can reverse engineer the protocol. I could likely write up a quick example app in python or something to control the ruida just like the app. It's understood well enough. MeerK40t doesn't talk to Ruida since I don't have one, and can't really troubleshoot it. |
Hi how are you? |
I don't know. At least not for the udp:50207 interface. It's pretty commonly done with the regular 50207 interface. The position is a just information request. However, for the other interface, this information is sent from the Ruida device to the App. I don't have a ruida device and thus I can't snoop on that part of the connection. If you're writing an app to do that, also make sure you log anything sent from the device to the app and look for coordinates. They are often 27 bit numbers in nanometers, but my guess is the ruida device replies the location to the 0xCE keepalive packet. Without a ruida device I don't know what the command would be. |
Hello ... I'm here with a problem ... Something's not right! Maybe it's my mistake, but I don't see why, but maybe because of my misinterpretation of what he told me ... I'm trying to send commands from arduino to RUIDA physical and virtual ... It turns out that on ARDUINO's serial monitor when sending any command to RUIDA, I have the answer F, on the server I get an ACK message ... But on both sides it says that the sending of the arduino packages is 0 ... So I don't know what's going on ... Even sending 0xcc or whatever ... I'm sorry about all these questions, but I'm starting my adventure in the world of programming. 🙂 |
I believe that me, not following the correct steps ... Will it be so? Arduino sends 0xcc RUIDA answers 0xcc ... And then? For example move X axis? Byte .... [] = {0xCC, 0xa5, 0x50, 0x02}? Or do I have to delete the first byte? And SWIZZLING? It is necessary? I am confused as to the correct sequence of commands. Can you help me please? It would be super easy for you! Thank you. [email protected] |
And then answers the rest of the commands with other commands.
You have to delete the first byte. The commands are alway above 0x80. That's how the Ruida command structure works.
It is typically done for the 50200 UDP channel, it is never done for your 50207 channel. Which does entirely different protocols.
There will actually not be much of a sequence. UDP packets can arrive in basically any order so you can't really be quite sure of getting or not getting one. The only thing it should matter for is the 0xA5 0x50 0x02 arriving before the 0xA5 0x51 0x02 which would turn it off. You only need to send a set of identical UDP packets. 0xCC gets a 0xCC reply so you know it's there. The physical ruida device likely has a reply somewhere that gives the current position. That has not been mapped out yet. You send exactly the packet 0xA5 0x50 0x02 then 0xA5 0x51 0x02 and make it stop.
The image for some reason is being sent the value 0, which MeerK40t rightly says is not a command. All commands start above 0x80. And all the other values are always below that value. It's not sending a valid UDP packet from the arduino. But, when you do, MeerK40t will tell you what command you sent. |
https://edutechwiki.unige.ch/en/Ruida |
Magic - 0x88 |
If you're only using the udp port 50207 stuff there is no swizzling. The bytes are transmitted without any encoding changes. The 50207 stuff. Yes, that would use the swizzling on that page. That reminds me I should update that page with the 50207 protocol information. |
Yes I understood... But in this case, as I said before, the interest would be to send through port 50200 directly in the physical RUIDA ... |
Oh, yeah, in that case you'll need swizzling. The code from that site is great. I wrote it, in fact, it does the xor swap for the swizzle. But, yeah, for something more advanced than the connecting on 50207 and controlling it like that app, you'd need swizzling, and also the ability to write some of the common data structures. 14 bit numbers, 35 bit numbers, and the like. The formatting is such that because all commands are above 0x80. No data byte can use the highest bit, they all must be zero. And all the commands are listed in the MeerK40t source as well as on that webpage where I wrote some good documentation. |
You mean 0xA5 not 0x5A. The distinction there is that the 0xA5 is higher than 0x80 and therefore a command. The correct answer is [46, 89, 139] == 2E 59 8B, which is what you got there swizzled. The other issue is that using the swizzled channels, I don't know if that's an actual command. The only place I saw A5 was on 50207. I do not know it is a command at 50200. You can load up a copy of RDWorks and send the output to MeerK40t and look at the commands it uses to move the laser around. It's actually completely different than the commands used from the android app. You're trying to send the app data to the udp:50200 channel, but I've never seen that command set used. And when I decoded all the commands known to exist they weren't there. You'd really want to load up RDWorks and see what jogging to the right requires for that. For that in RDWorks, through the swizzled channel I get:
You sent the command correctly with swizzling. So it didn't respond. Try that given set of command where you do IOEnable, and tell it to move X by 10mm. Also, keep in mind the UDP:50200 command to do that is: d900007f7f7f3170. But, it may take the IOEnable command and some others. I'm not sure the other commands are required. But, that's how RDWorks moves the laser around. So I'd emulate that rather than the app. For the app, I'd send that without swizzling on on the app's UDP:50207 channel. |
Also the wireshark data says 00002e598b and should have a checksum of 274 rather than 0. And should read 01122e598b. Dunno I'd fix the flawed checksum before giving up on the idea of the use of the 0xA5 command. |
Where will my mistake be? |
https://edutechwiki.unige.ch/en/Ruida |
From point 4.3. |
Get the checksum working correctly. You need to correctly give the checksum of the commands you are issuing. The 0xA5 commands might work through the UDP:50200 protocol, but you'd certainly need a correct checksum or it will just be discarded. But, with a working sending data protocol. You should be able to duplicate some RDWorks commands and get some working control of the laser. From there you can add some commands and see what correctly works and what doesn't. |
So as I understand it, the Android app commands for physical RUIDA are "filtered / translated" with a different checksum? Even decompiling the Android app, is it not possible to access this checksun? So, the app has to know how to make this Cheksum so that the physical RUIDA realizes the correct checksum? Did I realize? Thank you. |
The app itself doesn't use a checksum or a swizzle. It transmits the commands without alteration, in plain text. You literally send The app would not need to make a checksum, and would not need to do a swizzle of the bytes. Since the App itself uses a different protocol on UDP:50207 which needs neither a checksum nor a swizzle algorithm. |
@cortesegravacoes Here. I figured it would be easier to see it in code. Here's code that you can run in python (requires pynput, #!/usr/bin/env python
import socket
import sys
import threading
from pynput import keyboard
UDP_IP = "127.0.0.1"
UPD_SEND_PORT = 50207
UPD_RECV_PORT = 40207
print("Ruida IP:")
for line in sys.stdin:
UDP_IP = line.rstrip()
break
class UDPSock(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.bind((UDP_IP, UPD_RECV_PORT))
self.start()
def run(self):
while True:
data, addr = self.sock.recvfrom(1024)
print("Received message: %s" % data)
def upd_send(self,message):
self.sock.sendto(message, (UDP_IP, UPD_SEND_PORT))
class KeyPresses:
def __init__(self, sock):
self.sock = sock
self.down = False
with keyboard.Listener(
on_press=self.on_press,
on_release=self.on_release) as listener:
listener.join()
def on_press(self, keypress):
if self.down:
return
self.down = True
print("Down: %s" % keypress)
try:
key = keypress.char
except AttributeError:
return
if key == 'e':
self.sock.upd_send(b'\xCE') # KeepAlive
elif key == 'a':
self.sock.upd_send(b'\xA5\x50\x01') # -X
elif key == 'd':
self.sock.upd_send(b'\xA5\x50\x02') # +X
elif key == 's':
self.sock.upd_send(b'\xA5\x50\x04') # -Y
elif key == 'w':
self.sock.upd_send(b'\xA5\x50\x03') # +Y
def on_release(self, keypress):
if not self.down:
return
self.down = False
print("Up: %s" % keypress)
try:
key = keypress.char
except AttributeError:
return
if key == 'a':
self.sock.upd_send(b'\xA5\x51\x01') # -X
elif key == 'd':
self.sock.upd_send(b'\xA5\x51\x02') # +X
elif key == 's':
self.sock.upd_send(b'\xA5\x51\x04') # -Y
elif key == 'w':
self.sock.upd_send(b'\xA5\x51\x03') # +Y
KeyPresses(UDPSock()) You should be able to tell from this, that it's just emulating the App. It has no checksum or swizzling done on the input. It's only sending a couple static packets to control the device. I also added a key 'e' to send the |
Hello, thanks! I made a code in C ++ on the Arduino ide ... I happen to be trying to send the bytes 0xda, 0x50, 0x05, 0x7e(first command of comunitation) .... Doing the checksum first and then Swizzling, sending to the 50200 virtual RUIDA port I get f6 saying no is command, but the virtual RUIDA sends c6 ... Wireshark gives a 5 byte udp packet to 0 ... I don't know where I'm failing. Because I read this link that I sent earlier in another message, that the checksum would be done first and then Swizzling. Right? |
The checksum is on the swizzled data. To reverse it you do swizzle and then calculate the checksum. The Ruida device is going to check the if the sum is correct before changing the bytes. There's no reason to process the data if the sum is wrong. |
In python the check is calculated: data = sent_data[2:1472]
checksum_check = (sent_data[0] & 0xFF) << 8 | sent_data[1] & 0xFF
checksum_sum = sum(data) & 0xFFFF The first 2 bytes are cut off the front of the packet, This is combined together to give me a 16 bit number. And the checksum sum is the sum of the swizzled bytes. So if you're on the other side of this and you're making the packet. You need to take the data you are sending to the ruida device, you need to swizzle all the bytes. Then you need to calculate the checksum and append it to the front of the data. And that's your packet. My code for MeerK40t is acting like the Ruida device. If you want to make code that controls the Ruida device you do the commands in reverse order. This means swizzle, sum, then appending the sum to the front of the packet as a header. |
I think Card ID is like serial number or something. I solved all the commands and properties, but I don't actually know what they all mean. I do know that if RDWorks isn't told that that CardID value is 0x6500 (0x65006500 14 bit data is always repeated twice) it says there's a communication problem and dies. It's actually what ghost's original question was asking in the first post of this thread. |
Hi! I know its a bit late but the coordinates are sent regulary so just listen for all UDP-packets beside teh ACK response and there you have your coordinates. |
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?
The text was updated successfully, but these errors were encountered: