mob41 / broadlink-java-api

A clean Broadlink API for Java
MIT License
22 stars 25 forks source link

Not working on command packets #1

Closed mob41 closed 7 years ago

mob41 commented 7 years ago

The following code authenticates and tell RM to enter learning mode.

However, this code does work in discovery but fails at dev.auth() (evidence downstairs)

BLDevice[] devs = BLDevice.discoverDevices(0);
System.out.println(devs.length);

BLDevice dev = devs[0];

System.out.println(dev.getMac().getMacString());

dev.auth();

RM2Device rm = (RM2Device) dev;
rm.enterLearning();

Python code for testing:

import broadlink

devs = broadlink.discover(timeout=5)

devs[0].auth()

devs[0].enter_learning()

The executable to be tested

Please run in a console. This does not show any GUI.

java -jar example.jar

Source code to see what it runs

[Download example.jar]

Capture data

mob41 commented 7 years ago

Comparing Packet 2,7 at line 0060, third byte to the end, it is confirmed the code generating the Auth payload or encrypting the payload cause the problem.

There are difference of algorithm of AES-CBC encryption between Java and pycrypto? That's weird.

gerg7 commented 7 years ago

Hi, have a look at your DiscoveryPacket: timezone, weekday, month seem to be wrong. Is your Broadlink devices discovery really working with what you have now?

int rawOffset = tz.getRawOffset() / 1000; int tzOffset = rawOffset / 3600; //inversed sign compared to python

int dayOfWk = cal.get(Calendar.DAY_OF_WEEK) - 1; //Day of week int dayOfMn = cal.get(Calendar.DAY_OF_MONTH); //Day of month int month = cal.get(Calendar.MONTH) + 1; //Month

//This is directly "copied" from the python-broadlink source code if (tzOffset < 0){ data[0x08] = (byte) (0xff + tzOffset - 1); data[0x09] = (byte) 0xff; data[0x0a] = (byte) 0xff; data[0x0b] = (byte) 0xff; } else { data[0x08] = (byte) tzOffset; data[0x09] = (byte) 0x00; data[0x0a] = (byte) 0x00; data[0x0b] = (byte) 0x00; }

data[0x10] = (byte) (year - 2000); // year WITHOUT century

data[0x11] = (byte) dayOfWk;

and for the checksum: checksum += (int) (data[i] & 0x00ff); //add unsigned byte value

mob41 commented 7 years ago

@gerg7 Thank for figuring out these! I haven't found these code problems. But, the discovery is really working without the above code, may be I am lucky 😄.

I will try the code these few days. The Auth packet may be also affected by the checksum problem. Thanks!

gerg7 commented 7 years ago

@mob41 One more obstacle: In CmdPacket.java you have AES aes = new AES(key, iv); instead of AES aes = new AES(iv, key);

mob41 commented 7 years ago

@gerg7 Wow, where? that's weird that I wrote that thing wrong! I will quickly go through it this week. Thanks for your help!

gerg7 commented 7 years ago

@mob41 line 122 in broadlink-java-api/blob/master/src/main/java/com/github/mob41/blapi/pkt/CmdPacket.java

mob41 commented 7 years ago

Wow, thanks! All commands are working right now.

mob41 commented 7 years ago

But I haven't changed your recommended code (like the checksum problem, discovery problem). Things still go all right.

Are they just "lucky" to run? Using your code can stable the code.

gerg7 commented 7 years ago

Maybe it depends on the device or the firmware in use. My target is a spMini2 smart plug (0x2728) and it did not want to be discovered until I made the code changes as mentioned.

mob41 commented 7 years ago

In your code:

int dayOfWk = cal.get(Calendar.DAY_OF_WEEK) - 1; //Day of week

It seems this is wrong. See https://docs.python.org/2/library/datetime.html#datetime.date.isoweekday

Sunday the value should be 7. But your code will result 0

mob41 commented 7 years ago

So I made a quite dirty function called dayOfWeekConv(int fieldVal)

mob41 commented 7 years ago

And the python code it states:

subyear = str(year)[2:]

which gets from the index 2 to the last. Assume 2017 is the year, it gets 17

Your code might be incorrect or unstable (compared to python library) that if now is 2117, but it doesn't matter... 100 years to go that this library breaks

gerg7 commented 7 years ago

dayOfWeek: We are Sunday - the discovery and auth works fine. So for my purpose I leave it with the 0. 2117: You are right - I was lazy to do it correctly, accepting further generations being confonted with a 22nd century bug ;-)