Few days ago I’ve bought Broadlink RM 3 Mini IR controller and found out that the 3rd party software that works with other Broadlink IR controllers doesn’t support RM 3 Mini (Tasker plug-in and RM Bridge - both an Android applications that serve as a way of communicating with a device without using official Broadlink application). I’ve contacted Broadlink and they’ve said they don’t have intention of making some kind of API for easier communication and integration of the device, and they don’t even support this device in their official SDK yet, so there is no way of making any way of interaction outside an official application. Then I’ve decided to sniff the traffic between their application and the device and try to replicate the behavior. I’ve managed to find an UDP packet that contains already learned command in payload, but replicating it works only first time after using their application. After that, it stops working, until you use their application again - then it works - but just once. The application itself has a lot of TCP traffic, but I can’t determine what is it used for (beside some ads it receives). It also broadcasts on 255.255.255.255 and 241.0.0.251 UDP every 3 seconds (both addresses have the same payload), but even with replicating that payloads it doesn’t allow me to send a command more than once. I was wondering if there is someone with more knowledge in network protocols that could help me with this, so I could make some kind of simple app (python or something like that) that would send already learned and sniffed commands without usage of the official app?
Hi, I guess that sniffing packets is not enough. I’M not an expert though.
Both the RM bridge and the Tasker plug in are based on a compiled library that works in android.
No sources are available. It may be possible to see if a newer version of that library can be extracted from the official app.
As you are able to sniff packets, I would compare udp packets sent by the tasker plug in with the ones sent by the official app: are they completely different, or do they differ only in some part?
Are the packets being sent by the app and by the tasker plug in different even when sending the same code?
I can’t sniff packets from the Tasker plug-in or RM Bridge application, because they don’t support RM 3 Mini. Using them is not the best solution, but I would use it anyway, if that was an option. I can try to extract compiled library (I think that’s libBLNetwork.so, if I’m not mistaken), but since I don’t know the structure of the library, I’m not sure I could use it properly. I will try and see if the functions are the same as they were in earlier version. Thank you for your advice and help.
Hello, actually I tested the tasker plugin http server: if it runs on the same android phone as the broadlink app it can import the mac address and the IR codes stored into the phone. It reads from the phone memory the informations packed for exporting to other phones with the share command of the broadlink app.
The http server answers to the /devices and /codes queries (because they do not require to communicate with the mini) showing the MAC and IP address and other info. When trying to execute a remote code on the mini with /send?deviceMac=… it returns an error saying that the device does not exist. My guess is that the http server sends an udp packet to the mini 3 (encoded in a way that a RM2 would accept) but the mini does not respond.
I hope that this may help,
PS. Another question. Is the UDP packet generated by the broadlink app for simulating a given remote key always the same? I noticed that it is not possible to repeat the same keypress more than once (as when you press the arrow key multiple times to navigate a menu), which is very annoying: the app actually vibrates every time I touch the key on the screen but I see the effect only the first time. Isn’t this related to your observation that the UDP packet works only the first time? What happens if you send a sequence of UDP packets related to different keys? Are they still ignored?
Since I’m at work at the moment, I’m going to try Tasker plug-in http server tonight. I’ve tried to share codes, but I couldn’t get any - nothing happened when using that function. Regarding your second question. I’ve tested it with just one intercepted command (volume up), but I haven’t noticed that it stops working from the official app - don’t know about arrow keys, but volume up works every time I press it in their application. I will try to navigate the menu to see if consecutively pressing an arrow key works. Your findings with official application are exactly the same as my findings while sending intercepted UDP payload. The strange thing is that using intercepted UDP packet for the first time works, then it stops, but the same packet works again after using their application - so, I guess there is no difference in the UDP payload. I will have to try intercepting another key press, and try sending them alternately.
Actually also in my case the volume up works correctly in the App even when I repeatedly press it.
The fact that the same packet works after using the application is interesting: are you using the application to send exactly the same remote command or it does not matter? I’ve read somewhere that a payload for a wifi smart plug was sent followed by a random number which was always different and I was wondering why. Maybe the RM 3 mini keeps a cached copy of the last IR command received and accepts the following one only if it is different: as in the UDP protocol there’s no way to know that the packet has been received, maybe the client sends multiple times the same packet and the RM mini3 executes it only once. The next command needs to be different so that the RM 3 mini can recognize it as a new one and not as a broadcast copy of the old one.
Maybe, when the arrow key is encoded in the client app, for some bug the udp packet is the same and the RM 3 mini does not recognize it as a new command. I admit that it looks too simple to be true but I think it may be worth trying.
I’m curious to know about your tests tonight
When I was testing it, I’ve used to start Broadlink application, use it to set volume to some value that is easy to remember (10 for example), then test sending UDP payload. After that, since UDP payload was Volume Up command, I used Volume down on Broadlink app, so it would remain on the same value, and I would know if it worked when sent more then once (I was testing it from the PC that’s placed in another room). As far as I can tell, it does not send same command multiple times, because pcap capture shows only one UDP packet from cellphone to RM 3, and after that one UDP packet from RM 3 to cellphone. At first I was suspecting that RM 3 somehow sends a port that will be used in the next transmission, but it wasn’t the case. In some of the packets (I don’t remember which packets, to or from RM 3), it sends date and time in little endian, MAC address of the device (RM 3) and there is some part of the packet that looks like a year in little endian, plus some kind of counter (it’s different in every packet), but again, it works for the first time even with old timestamp and counter. I will test other things you’ve reported tonight. and I will post my findings here.
I just replicated your tests by intercepting the UDP traffic from the phone to the Mini and then sending back the packets from a PC to the Mini. It appears that it is possible to send commands to the Mini, provided that two consecutive commands are not the same packet.
At this point, I’m a little bit concerned about security, though. What happens if I give a command with the App when I’m ouside my LAN and someone sniffs that packet?
After the learning process, that requires some connection with broadlink servers, I will close all inbound and outbound traffic to the MAC/IP address of the Mini.
By the way, I’ve read in a russian forum that the developer of the android tasker plugin is trying to support the Mini even though he does not know if it will be possible.
I’m sorry I haven’t posted my findings earlier, but I haven’t had any free time. Regarding your tests, I’ve tried using arrow keys consecutively, and it works for me. Actually, I’ve tried all the keys I have programmed in the Broadlink application to use twice in a row, and they all work. Speaking of Tasker plug-in, I’ve contacted both, the Tasker plug-in and RM Bridge authors. Tasker plug-in author said he’s trying to implement it, but wasn’t sure when or if it will be done. RM Bridge author said he does not have a device, so he will not try implementing it in the near future. Now, to the point. I’ve managed to make RM 3 work from Python script using not very optimized method, but at least, it works. I’ve learned a command from the remote of an old satellite receiver I’m not using, and then I send that command prior to the real command. For now, it looks like it’s working well. I will have to test it tomorrow, or day after tomorrow, to see if the date and time part of the payload will make any difference. I’m posting a Python script I’m using in the attachment. First payload is “dummy” (I’m not sure if you’ll be able to use this payload, or it has to be a payload that RM 3 already has saved as a button). The second payload is Volume up command, also retrieved from packet capture. Thank you for your help in, at least partially, solving this.
Edit: I just found out I can’t send .py files in the attachment. If you want, you can contact me via private message, so I can send it to your mail.
I’m glad that you confirmed that finding. I’ve managed to switch on and off my airconditioner. I’ve also switched the mini off several times and the captured packet are still working. I will contact you via private message and I will also try the OpenHAB TCP/UDP binding.
In order to follow this path to integrate the mini on openHAB you will need to get your packets going to your device.
Wireshark needs to run on a Linux machine if you want to see all the traffic, not only the one directed to or originated by the Windows laptop.
I actually installed Wireshark for root on the android phone where the broadlink app was installed. I was using a galaxy nexus with a custom Rom with root access. Captured packets were stored in a file that I analyzed on the Windows version of wireshark.
In principle yes, but it is not as straightforward as it seems (at least for me) because the udp packet payload is a relatively long sequence of binary data (a few hundreds of bytes), while the udp binding is designed to send strings.
Once this first problem is solved, the second one is that every command is composed by two udp packets. Therefore some items and rules need to be developed in order for this to work, because AFAIK the tcp/udp binding sends only one packet per command.
The python way is easier but need to be integrated with the exec binding.
Fair enough, I’ll go grab a linux laptop to try with. Never bothered rooting my phone since the old zte 7" one - can do without the risk of bricking it (esp since this Oppo came from now defunct Dick Smith store). Could the rule to trigger the RM do 2 sendCommand calls for the 2 udp, or would they be too separated that way?
The tcp binding is designed for ASCII traffic, therefore it adds lf + cr at the end of the packets, according to the wiki.
I’m going to use packetsender for windows (It is freeware). I used it to test the packets. It includes the possibility to send through the command line the same packets that have been previously saved in the gui. This seems to me the easiest solution.
@benhelps if the dns320 is based on Linux it may be that you can find a similar packet sending functionality
The separation does not matter. The point is that consecutive packets need to be different, otherwise the mini won’t issue the ir command a second time.
The unlocking of the dns320 hints that it uses Linux under the bonnet, but it doesn’t have build tools or a package manager(or graphical output or a ui for that matter). No surprise given its just a NAS.
So you couldn’t define ON, OFF, and OTHER packets in the mapping file, then have consecutive lines like
Yes, you are right, one command per udp packet can be defined. The problem of the lf+cr characters being added at the end of the payload remains, though, even if a solution for properly inserting the packets in openhab is found.
I think that some change in the binding would be required (which is way beyond my capabilities).
I’ve made some improvements to the initial Python script and uploaded it to Github. You can find it here:
There is BlackBeanControl.ini file which consists of General and Commands section. General section should contain:
IPAddress: IP address of the RM 3 mini device
Port: Port of the RM 3 mini device - usually 80
DummyCommand: Hex dump of the UDP payload that will be sent before every other command - it should be already learned IR command that is not used, for example, IR command from an old, unused remote control. RM 3 mini does not want to trigger commands if they are sent over UDP more then once consecutively, so, this command is used to bypass this problem
Commands section should contain list of command names (only letters, without blanks) followed by column and a hex dump of the actual command. For example:
TVVolumeUp: [HEX DUMP]
ACTempUp: [HEX DUMP]
A syntax for calling a script is:
BlackBeanControl -c [-i IP Address] [-p Port]
Command name parameter is the name of command already stored in an .ini file
IP Address and Port are optional parameters - used in case there is a need for sending UDP payload to a multiple RM 3 minis in the same network. If value is not assigned to these parameters, values from an .ini file will be used.
I’m not very friendly with java, so I’m not able to make this into regular OpenHAB binding - if that is possible at all. If someone is willing to do that, I’ll help as much as I can.