Communicating with Ruida controller for user restriction

It’s only fun if you release it to the world untested and brick a bunch of controllers… :smiling_imp:

Yeah, but I’m still fairly new around here. I don’t think I want too many people after me with pitchforks and torches just yet.

Don’t worry. You wouldn’t make it out the door.

Forget the primitive weapons, everyone here is ‘armed’ with at least one laser… :crazy_face:

:smile_cat:

Sorry if this is long winded and a bit rambling, but …
Well, I did make some more progress.
Once I was finally back on the network where the laser lives, I couldn’t figure out why I wasn’t get ANY responses from it in answer to even simple queries that the emulator gave me no problems with.
I finally remembered that the other source I found talked about the controller listening on port 50200, but replying on 40200. After a 12-hour day at work, I wasn’t thinking really clearly, so it took me more than an hour to remember how to set things up where I had 2 sockets, each one bound to one of the addresses. Then write to the 50200 socket and read from the 40200 socket. I essentially had two parallel python streams running - one with the utility functions cut out of Meerk40t, the other handling the UDP communications - and copied the binary string data from one to the other. It turned out that binding the two sockets to the relevant ports was important. Below is some of the relevant code.

###  a few extra utility functions which are really added to the RuidaEmulator class
###  code because it was easier
def make_checksum(self,data):
	return sum(data)& 0xFFFF

def create_command(self,command_array):
        out = bytearray()
        for it in self.check_bytes(self.make_checksum(self.swizzle(command_array))):
            out.append(it)
        for it in self.swizzle(command_array):
            out.append(it)
        return out
### 
data = [0xDA,0x00,0x05,0x7E]  # Check mainboard and firmware version
ip='192.168.1.109'
out_port=50200
in_port=40200
s_out = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
s_out.bind(('0.0.0.0',out_port))
s_in = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
s_in.bind(('0.0.0.0',in_port))

command = create_command(data)
barray = bytearray(command) # binary data string after swizzling and adding checksum
s_out.sendto(barray,(ip,port))
(reply)6
data, address = s_in.recvfrom(4096)
print (data)
(reply)b'\xc6'  # unswizzles to 0xCC which is our "checksum correct" code
data, address = s_in.recvfrom(4096)
print (data)
(reply)b'\xd4\t\rw\xdb\xcd\xc5K%\xdf\xb1\xa7\xb99\xa7\xbf?\x89'
## unswizzling this gave b'\xda\x01\x05\x7fRDLC-V8.01.67\x00', which, when dropping the
## first 4 bytes of the response code and the terminating null 0x00, says that we have a
## genuine RDLC running version 8.01.67 firmware.

Yay! More to come.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.