almsh / homebridge-livolo-switches

12 stars 6 forks source link

Local server #1

Closed lych closed 5 years ago

lych commented 5 years ago

Hi @almsh. I've glanced at the code of their app. If I'm not mistaken their app doesn't interact with the gateway except that part where they send wifi settings and the server address. I'm going to try to change the address to my local mqtt server. Unlikely it will work, but I think it's worth a try.

almsh commented 5 years ago

Hi @lych, according to this lines from .apk

public static final class WifiConnect {
        public static final String ACTION = "com.google.zxing.client.android.WIFI_CONNECT";
        public static final String PASSWORD = "PASSWORD";
        public static final String SSID = "SSID";
        public static final String TYPE = "TYPE";

        private WifiConnect() {
        }
    }

and

 String reqStr = getJsonString(new String[]{WifiConnect.SSID, WifiConnect.PASSWORD, "DHCP", "SERVICEIP"}, new Object[]{this.wifiSSID, this.wifiPWD, Boolean.valueOf(true), url});
        Log.e("-----post----", "------------------dopost:" + reqStr);
        mOkHttpClient.newCall(new Builder().url("http://10.10.10.1:8000/config-write-uap").post(RequestBody.create(JSON, reqStr)).build()).enqueue(new C07675());

You can turn Livolo bridge into pairing mode by holding it's button for 5 seconds until it starts blinking, then connect to LIVO_GW_xxxx network with password 12345678 and then send POST request to http://10.10.10.1:8000/config-write-uap with body:

{
   "SSID": "%your_wifi_ssid%",
   "PASSWORD": "%your_wifi_password%",
   "DHCP": true,
   "SERVICEIP": "%you_mqtt_server_ip%"
}

I can send you full unpacked apk if needed.

lych commented 5 years ago

Here's what I've found out: After power on, the gateway starts from sending request to pool.ntp.org then some http request then mqtt protocol data. Unfortunately, http and mqtt data are encrypted using TLS. It also possible to send http://10.10.10.1:8000/config-write-uap and the gateway starts to send data to the server from SERVICEIP field. SERVICEIP must be domain name and http server must be https. Probably server should answer a domain name of mqtt server, because after getting the response from http server the gateway starts to try to resolve some data via dns. I haven't been able to find the right answer format yet.

If something wrong the gateway starts from the begining and sends requests to pool.ntp.org, once or twice per second. It's great thing, isn't it? sarcasm :)

almsh commented 5 years ago

Did you record parameters of request to SERVICEIP from gateway, maybe we should try to send same request to https://cn.appnew.livolo.com/ (47.98.102.223) to receive correct answer format?

almsh commented 5 years ago

Here is what i found: if you send custom ip to bridge in SERVICEIP field it will send https request to this ip with

GET /app/setting/mqtt/ip_port?type=device&id=04786311B904
Host: appnew.livolo.com

You can see answer example here: https://appnew.livolo.com/app/setting/mqtt/ip_port?type=device&id=04786311B904

I've send custom response by using simple node.js app and nginx running on maschine which ip i've sended as SERVICEIP

server {
        listen       443 ssl;
        server_name  appnew.livolo.com;

        ssl_certificate /path-to-self-signed-cert.pem;
       #Force weak ciphers to be able to decrypt communication using wireshark
        ssl_ciphers GOST2012256-GOST89-GOST89:GOST2001-GOST89-GOST89:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA256:CAMELLIA256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA256:CAMELLIA128-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC3-SHA:DES-CBC3-SHA:EDH-RSA-DES-CBC-SHA:DES-CBC-SHA;

        ssl_certificate_key /path-to-self-signed-cert-key.pem;

        location / {
            proxy_pass http://127.0.0.1:3000/;
        }
}
const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  Object.assign(ctx.response.headers, {"Content-Type":"application/json;charset=UTF-8"});
  ctx.body = {"data":{"port":"1883","ip":"192.168.8.2","pwd":"livolo123","user":"livolo_device_pub"},"result_code":"000","result_msg":"success"};
});

app.listen(3000);

After that i've start receiving this image

livolo-bridge-attempting-to connect.pcapng.zip

Unfortunately it didn't connect to http://www.mosca.io/ server running on my machine. I'm experiencing lack of MQTT knowledge, so i need help here 😄

Also i've changed id in this url, but seems that it send same response to any id https://appnew.livolo.com/app/setting/mqtt/ip_port?type=device&id=04786311B904 responce:

{"data":{"port":"8883","ip":"47.254.154.71","pwd":"livolo123","user":"livolo_device_pub"},"result_code":"000","result_msg":"success"}

and i were able to connect to 47.254.154.71 as mqtt broker with username and password.

almsh commented 5 years ago

Also i've noticed requests to api.easylink.io from bridge. According to their site http://easylink.io they provide OTA solutions, so maybe bridge can be reflashed over the air.

lych commented 5 years ago

I've got the same result as you. There are strings in my mosquitto log:

1548098123: New connection from 192.168.1.26 on port 1883.
1548098123: Socket error on client <unknown>, disconnecting.

Probably they use their own MQTT protocol as well as they do with zigbee protocol or/and it's encrypted.

Lumbricus commented 5 years ago

Yesterday I've tried to connect the gatewas to an own secured MQTT Server with no success. It seems to me, that the gateway will only connect if the certificate is the right one. The only message in the logs is:

New connection from 192.168.0.80 on port 8883. Socket error on client (null), disconnecting.

@almsh Your adapter works very well with the Homebridge-Adapter for ioBroker. Very nice job! Thank you very much. I'll use it till there is a solution.

Lumbricus commented 5 years ago

Sorry, that I've to write once again, but there is a small problem I have. After half an hour, the state doesn't change if I use the switch directly. If I change the state manually, the switch works like expected. Could that be a problem with the ioBroker bridge or is that an issue of your adapter?

almsh commented 5 years ago

@Lumbricus maybe it's issue with adapter, currently there is no handling and/or logging for error and end events on mqtt client, i will take a look later.