Close
0%
0%

Obtaining Control of JXD523 : the $20 drone

Obtaining access to a drone which is currently set to communicate with android application, allowing custom software to be built for it.

Public Chat
Similar projects worth following
Hey guys. thanks for taking the time to look at this project.
I have been challenging myself for the past week to obtain control of a drone I bought from a workmate. However In all my attempts the furthest I have gotten is a stream of data from RSTP which I have not even been able to decode.
I hope that the information I have placed here proves useful for others in their projects.
Enjoy!

P.S I did reference another article for assistance here:
https://hackaday.io/project/19680-controlling-a-jjrc-h37-elfie-quad-from-a-pc

Manufacturer Android App can be found here : https://play.google.com/store/apps/details?id=com.gx_exploration_ufo&hl=en&gl=US

Review Video of Product which displays App and Drone.

In the photos I have added the Blue chip connects the camera and WiFi while the Green chip appears to receive communication from the Blue chip to control the motors

RSTPControl Edit 1.py

Code as of 19 Sept 2021: Currently Returns Coded response from 2 sockets and stops light flickering on device.

x-python - 1.97 kB - 09/19/2021 at 06:42

Download

RSTPcontrol.py

Current Code Which Returns Coded video

x-python - 1.55 kB - 09/18/2021 at 07:17

Download

Data.txt

Byte Value recieved from drone via RSTP stream. ( b' removed.)

plain - 37.63 kB - 09/18/2021 at 04:49

Download

yes.cap

Capture from Microsoft Network Monitor. See conversation between 192.168.1.101(Android Device) and 192.168.1.1(Drone Wifi Card)

cap - 14.99 MB - 09/18/2021 at 04:46

Download

stm32f031k4.pdf

Micro Controller Manufacturer Information Sheet.

Adobe Portable Document Format - 1.77 MB - 09/18/2021 at 04:32

Preview

  • 19 Sept 2021

    Kynan09/19/2021 at 06:37 0 comments

    Continuing on in my quest for control over this device I decided to test whether other methods of controlling the drone will lead to some output on the device itself.

    Theory 1 :

    Packets sent not frequently enough.

    As seen above there a large number of the larger packets being sent as opposed to the smaller packet example (when in reference to the 2 packets mentioned in 18 Sept 2021 Log).

    Theory 2: 

    In my last recording I had picked up a new request which has not come up earlier when trying to scan over a network on my pc while my android device controls the drone.

    After Googling about this protocol I found that this was to do with giving IP addresses as devices joined then I digressed back into testing Theory 1.

    To test this I configured the code slightly so that It will not just pause in the while true loop.

    s2.send(bytes.fromhex('7F'))
    while True:
        data, addr = s1.recvfrom(1500)    
        sys.stdout.write(str(data))
        s2.send(bytes.fromhex('19 FF FF FF FF 7F 7F E6'))
        print("\r\n sent")
        #data = s2.recv(106)
        print(data)

    After testing this on the device on both ports given by the RSTP request 

    I then tested sending both codes in sequence in the while loop.

    s2.send(bytes.fromhex('7F'))
    s2.send(bytes.fromhex('19 FF FF FF FF 7F 7F E6'))
    

    This did not yield results either thus began the test with the most accurate representation to what we see in the live environment.

    This allows for 11 of the more frequent messages to be sent before the smaller one.

    Alas this did not bring about any visible change on the device.

    n = 0
    while True:
        data, addr = s1.recvfrom(1500)
        sys.stdout.write(str(data))
        s2.send(bytes.fromhex('19 FF FF FF FF 7F 7F E6'))
        if n == 10:
            s2.send(bytes.fromhex('7F'))
        print("\r\n sent")
        #data = s2.recv(106)
        print(data)
        n = n+1

    After pondering for some time as to what the difference was between the code that works and my code.

    I then realized that perhaps the port I am communicating using is not recognized because it differs from the one receiving video.

    I then decided to only loop the program once and printout the address and then configured the following code to send from the next port up from the one currently bound to receive packets.

    s1 = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    s1.bind(("",57795))
    
    s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s2.bind(("", 57796))

    [loop code change]

    n=0
    while True:
        data, addr = s1.recvfrom(1500)
        data2, addr2 = s2.recvfrom(1500)
        s2.sendto(bytes.fromhex('19 FF FF FF FF 7F 7F E6'),0,addr2)
        print("\r\n S1 Address = " + str(addr))
        print("\r\n S2 Address = " + str(addr2))
        if n == 10:
            s2.sendto(bytes.fromhex('7F'),0,addr2)
           n = 0
        print("\r\n s2 packet sent")
        #data = s2.recv(106)
        print(data)
        print(data2)
        n = n+1

    Which this appears to be allowing myself to receive packets and also had an interesting effect on the lights on the drone, as it seems to engage them in the same way when you pressed the on button(in the android app) before which the LEDs seem to flash consistently.

    I also receive this in the output console on my code.

    b'OPTIONS rtsp://192.168.1.1:7070/webcam RTSP/1.0\r\nCSeq: 1\r\nUser-Agent: Lavf56.40.101\r\n\r\n'
    package sent
    package recved
    b'RTSP/1.0 200 OK\r\nCSeq: 1\r\nPublic: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE\r\n\r\n'
    b'DESCRIBE rtsp://192.168.1.1:7070/webcam RTSP/1.0\r\nAccept: application/sdp\r\nCSeq: 2\r\nUser-Agent: Lavf56.40.101\r\n\r\n'
    package sent
    package recved
    b'RTSP/1.0 200 OK\r\nCSeq: 2\r\nContent-Base: rtsp://192.168.1.1:7070/webcam/\r\nContent-Type: application/sdp\r\nCo'
    b'SETUP rtsp://192.168.1.1:7070/webcam/track0 RTSP/1.0\r\nTransport: RTP/AVP/UDP;unicast;client_port=57795\r\nCSeq: 3\r\nUser-Agent: Lavf56.40.101\r\n\r\n'
    package sent
    package recved
    b'ntent-Length: 122\r\n\r\nv=0\r\no=- 1 1 IN IP4 127.0.0.1\r\ns=Test\r\na=type:broadcast\r\nt=0 0\r\nc=IN IP4 0.0.0.0\r\nm=v'
    ...
    Read more »

  • 18th Sept 2021

    Kynan09/18/2021 at 08:13 0 comments

    Hello to of you reading this.

    Apologies in advance for a lack of in-code documentation.

    However lets get on with the show.

    ___________________________________________________________________

    To start being able to communicate with this device I determined that I would first need to identify what packets are being consumed by the device itself (JXD 523 Drone).

    This proceeded the opening of Microsoft Network Monitor to obtain the contents shown in yes.cap in the download area and then focusing on the communication between 192.168.1.1(server\drone) and 192.168.1.101(Android\interfacing device).

    As we can see we have an initial SIP request which also refers to an URL which may be the key to communicating with our device.

    Using the details in this packet I then was able to construct these packets in python and began trying to interface with the device.(Format of code was assisted by looking at a similar project by https://hackaday.io/AJF1982.

    ___________________________________________________________________

    import socket
    import time
    import sys
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.1.1', 7070))
    
    package= b'OPTIONS rtsp://192.168.1.1:7070/webcam RTSP/1.0\r\nCSeq: 1\r\nUser-Agent: Lavf56.40.101\r\n\r\n'
    print(package)
    s.send(package)
    print("package sent")
    data = s.recv(106)
    print("package recved")
    print(data)
    

    Once I ran this code I had received a response of the following.

    b'OPTIONS rtsp://192.168.1.1:7070/webcam RTSP/1.0\r\nCSeq: 1\r\nUser-Agent: Lavf56.40.101\r\n\r\n'
    package sent
    package recved
    b'RTSP/1.0 200 OK\r\nCSeq: 1\r\nPublic: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE\r\n\r\n'

    With some more work I was able to then use the sequences above just by replacing the first keyword at the start of every line after the identifier of b'  and incremented the CSeq: number which worked well until I got to the play line which returned Session not found until I added an extra s.recv command and made the package line more modular on line 39. (please see RSTPcontrol.py)

    With my code set to complete the entire output looks like this:

    b'OPTIONS rtsp://192.168.1.1:7070/webcam RTSP/1.0\r\nCSeq: 1\r\nUser-Agent: Lavf56.40.101\r\n\r\n'
    package sent
    package recved
    b'RTSP/1.0 200 OK\r\nCSeq: 1\r\nPublic: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE\r\n\r\n'
    b'DESCRIBE rtsp://192.168.1.1:7070/webcam RTSP/1.0\r\nAccept: application/sdp\r\nCSeq: 2\r\nUser-Agent: Lavf56.40.101\r\n\r\n'
    package sent
    package recved
    b'RTSP/1.0 200 OK\r\nCSeq: 2\r\nContent-Base: rtsp://192.168.1.1:7070/webcam/\r\nContent-Type: application/sdp\r\nCo'
    b'SETUP rtsp://192.168.1.1:7070/webcam/track0 RTSP/1.0\r\nTransport: RTP/AVP/UDP;unicast;client_port=57795\r\nCSeq: 3\r\nUser-Agent: Lavf56.40.101\r\n\r\n'
    package sent
    package recved
    b'ntent-Length: 122\r\n\r\nv=0\r\no=- 1 1 IN IP4 127.0.0.1\r\ns=Test\r\na=type:broadcast\r\nt=0 0\r\nc=IN IP4 0.0.0.0\r\nm=v'
    b'ideo 0 RTP/AVP 26\r\na=control:track0\r\nRTSP/1.0 200 OK\r\nCSeq: 3\r\nTransport: RTP/AVP;unicast;client_port=57795-57796;server_port=55934-55935\r\nSession: 82838485868788898A8B8C8D8E8F90\r\n\r\n'
    Session: 82838485868788898A8B8C8D8E8F90
    ['server_port', '55934-55935']
    b'PLAY rtsp://192.168.1.1:7070/webcam RTSP/1.0\r\nRange: npt=0.000-\r\nCSeq: 4\r\nUser-Agent: Lavf56.40.101\r\nSession: 82838485868788898A8B8C8D8E8F90\r\n\r\n'
    b'RTSP/1.0 200 OK\r\nCSeq: 4\r\nSession: 82838485868788898A8B8C8D8E8F90\r\n\r\n'
    b'\x80\x1a\x81\x80\x7f~\xa0\xa4{zyx\x00\x00\x00\x00A\xffP<\x04\xb9\x81\x00\x00\x00\x00\x80\x17\x10\x11\x14\x11\x0e\x17\x14\x12\x14\x1a\x18\x17\x1b"9%"\x1f\x1f"F25)9RHWUQHPN[f\x83o[a|bNPr\x9bs|\x87\x8b\x92\x94\x92Xm\xa0\xac\x9f\x8e\xaa\x83\x8f\x92\x8d\x18\x1a\x1a"\x1e"C%%C\x8d^P^\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\xbe\xd0\xf3\xd2\x98b\xc7\xadj\x18j6\x84\xfaWj\xa8I\x9ab4\xd3\x11\x15\xa0`>\x95\x19\x83\xfd\x91V\xaa\x0c\xa0P\xfaSJ\x1a\xbeb\xff\x008\xa8\xcc>\xd5j`R*})\xa5O\xa5\\hi\x86\x1fJ\xb54\x05R(\xc5X1z\x81M1\x9fJ|\xc8\x08qF\rK\xb0\xd0P\xd3\xb8\x0c\x02\x8cS\xf6\xd1\x8aW\x02<R\xe2\x9f\x8a1E\xc7a\xa0R\xe2\x8cQ\x9a\x06\x19\xf5\xa6\x93A4\xd2i\xd8.)4\xd2i)*\xac+\x814\x94\xb8\xa3\x14\t\x858RQ@\x87\x03N\xcd34\xb9\xa4\x03\xb3J\rG\x9ap4\xac1\xf9\xa34\xda)X\x05\xa4\xa5\xa5\x02\x80\x10\n]\xbe\xd4\xe0\xb4\xf0\xb4\x9b\x19\x1e\xdar\xadH\x12\xa4X\xea\\\x861S\xda\xa5U4\xe5Oj\x95R\xb3r\x01\xaa\xb5"\xad9V\xa4\x0bY9\x00\xd5Z\x90-(\x14\xe0+6\xc5q\x02\xd1\x8aZ*n\x02b\x93\x14\xb4S\x00\xa2\x8a(\x00\x14\xb4QHAE\x14\xb4\x00R\xd0)i\x00QK\x8a\\R\x01\xb4\xb4\xb8\xa3\x14\x08)q@\x14\xb4\x80)h\xa2\x90\x05\x14Q@\xc2\x8a)i\x00RR\xd1@\x05\x14Q@\xc2\x8a(\xa0\x02\x8a(\xa0\x02\x8a(\xa0\x02\x8a(\xa0\x0f\xff\xd0\xea\xb6\x8aB\x99\xa7\xd1N\xe2\xb1\x11\x8f\xda\x98b\x1e\x95b\x93\x14\xd4\x98\x15LT\xc3\x00\xab\x98\x14\x85A\xabSb(4\x03\xd0~T\xc3\rh\x18\xc54\xc6*\xd5@3\x8c4\xc3\x0f\xa0\xad#\x18\xf4\xa6\x18\xbd\xaa\xd5A\x99\xa6/\xf3\x8a<\xafo\xd2\xaf\x98\xbd\xa9\x86\x1a\xa5Pe\x13\x154\xc7W\x8c5\x1bEV\xa6\x052\x94\xd2\xa7\xd2\xad\x98\xbd)\xa6#\x8e\xff\x00\x95R\x90\xca\xa5H\xedL`j\xd3&*6J\xa5...
    Read more »

View all 2 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates