Success!
Thanks for the link to the Android app. I connected to my network via a wireguard tunnel and used tcpdump to capture the traffic between the app and the controller. Long story short:
- 0xCC is basically a “connect” handshake. Send it first.
- 0xCD is apparently a “disconnect” packet the app sends when it disconnects. (I don’t know whether it has actual effects.)
- 0xCE is apparently also sent sometimes, possibly useful as a keepalive packet.
- You must send the UDP packets to the controller’s port 50207 from source port 40207 – in python, you bind the sending socket to the port (and IP, if desired) after you create the socket.
- You can actually ignore the responses entirely and still send commands, but they do have data. (The 0xA568… packets have coordinates of some kind. I made a quick controller impersonator and connected the app to it, and I could change the coords the app displays, although I didn’t bother trying to figure out the encoding and data.)
Here’s some quick and dirty python that successfully “connected” and sent some test key signals:
import socket
from time import sleep
#Source IP and port for sending UDP packets.
ip = '192.168.105.222'
port = 40207
#Ruida IP and port for receiving UDP packets.
co2 = '192.168.105.100'
cport = 50207
#Create the UDP socket...
out = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#...then bind it so the source of the UDP packets is port 40207.
out.bind((ip,port))
#Send a UDP packet.
def sendUDP(hexes):
out.sendto(bytearray.fromhex(hexes),(co2,cport))
def test():
#First, send the handshake to connect.
sendUDP('cc')
#Now send five half-second -X presses.
for _ in range(5):
sendUDP('a55001') #-X keydown
sleep(0.5)
sendUDP('a55101') #-X keyup
sleep(0.5)
test() #Yay! It works!