Skip to content

Device pairing

Alberto Geniola edited this page Nov 24, 2018 · 5 revisions

Pairing

The pairing phase is performed via the Meross application. Its objectives are:

  • Configure the Wifi credentials on the switch
  • Configure the remote MQTT server that the switch whould connect to
  • Associate the switch to the user's Meross account

Scanning

Once we put the MSS310 into pairing mode (by simply pressing and holding the front button for 10 seconds), the switch will create an AccessPoint named MEROSS_SW_XXXX. The application will therefore scan all the nearby Wifi networks, and will connect to the first MEROSS_SW_XXXX network.

It appears that the MS310 runs a DHCP server on the network 10.10.10.0/24 binding on 10.10.10.1 and pooling addresses from 10.10.10.100 and upwards to every client. Once our application connects to the AP, it will probably be given the 10.10.10.100 address.

Configuration phase

The next step that the App Performs is to gather details about the Meross device. Such data exchange is performed via HTTP POST messages. All the local communication between the Meross Application and the Meross switch appears to rely to the same data-packets that are exchanged over the MQTT protocol, that is described in section MQTT Topics and Messages. However, it seems that the device does not perform any signature validation check, nor it cares about the messageId/from header parameters of the request. All it takes into account are the namespace, the method and the payload attributes of the request. The rest of the parameters must be present into the message, but can be blank.

Getting device info

The first post message that is issued by the app to the device is the following:

POST /config HTTP/1.1
Host: 10.10.10.1
Content-Type: application/json
Connection: close
Accept-Encoding: gzip
User-Agent: okhttp/3.6.0

{"header":{"from":"","messageId":"","method":"GET","namespace":"Appliance.System.All","payloadVersion":0,"sign":"","timestamp":0},"payload":{}}`

An example of response would be the following:

{
    "header": {
        "messageId": "",
        "namespace": "Appliance.System.All",
        "method": "GETACK",
        "payloadVersion": 1,
        "from": "/appliance/XXXXXXXXXXXXXXXXXXXXXXXXXXXX/publish",
        "timestamp": 585,
        "timestampMs": 250,
        "sign": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    },
    "payload": {
        "all": {
            "system": {
                "hardware": {
                    "type": "mss310",
                    "subType": "us",
                    "version": "1.0.0",
                    "chipType": "MT7688",
                    "uuid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                    "macAddress": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
                },
                "firmware": {
                    "version": "1.1.15",
                    "compileTime": "2018-08-09 09:30:41",
                    "wifiMac": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                    "innerIp": "0.0.0.0",
                    "server": "",
                    "port": 0,
                    "secondServer": "",
                    "secondPort": 0,
                    "userId": 0
                },
                "time": {
                    "timestamp": 585,
                    "timezone": "",
                    "timeRule": []
                },
                "online": {
                    "status": 2
                }
            },
            "control": {
                "toggle": {
                    "onoff": 1,
                    "lmTime": 0
                },
                "trigger": [],
                "timer": []
            }
        }
    }
}

To protect my privacy, I've replaced sensible values with "X" placeholder.

As you can see, the device returns some information about itself. Particularly relevant are the hardware and firmware information, that can be used by the app itself to check if the device is supported or not.

Setting up user/remote endpoint

The next relevant message that is issued by the app to the switch tells the device to which MQTT broker it needs to connect. Moreover, the app will tell to the device what user-id/password to use when connecting to the remote MQTT broker.

POST /config HTTP/1.1
Host: 10.10.10.1
Content-Type: application/json
Connection: close
Accept-Encoding: gzip
User-Agent: okhttp/3.6.0

{
  "header": {
    "from": "",
    "messageId": "",
    "method": "SET",
    "namespace": "Appliance.Config.Key",
    "payloadVersion": 1,
    "sign": "",
    "timestamp": 0
  },
  "payload": {
    "key": {
      "gateway": {
        "host": "iot.meross.com",
        "port": 2001,
        "secondHost": "smart.meross.com",
        "secondPort": 2001
      },
      "key": "XXXX",
      "userId": "XXX"
    }
  }
}

AS you can see, I've once again masquerated my userId and key with the X placeholder. Such data is in fact used by the device in order to connect to the meross MQTT broken (iot.meross.com) on port 2001.

Setting up wifi credentials

The next and final step is to configure the switch network profile so that it can connect to the local Wifi. Once again, the message that the App will send to the switch is simply the following:

POST /config HTTP/1.1
Host: 10.10.10.1
Content-Type: application/json
Connection: close
Accept-Encoding: gzip
User-Agent: okhttp/3.6.0

{
  "header": {
    "from": "",
    "messageId": "",
    "method": "SET",
    "namespace": "Appliance.Config.Wifi",
    "payloadVersion": 0,
    "sign": "",
    "timestamp": 0
  },
  "payload": {
    "wifi": {
      "bssid": "XX-XX-XX-XX-XX-XX",
      "channel": 6,
      "cipher": 3,
      "encryption": 6,
      "password": "XXBASE64PASSXX",
      "ssid": "XXBASE64SSIDXX"
    }
  }
}

As you would imagine, the SSID and Password of the local network are passed to the switch after being Base64 encoded. Once the app issues this command to the smart plug, it will reboot and try to connect to the selected wifi. If it succeeds, the meross app will see the new device connected to the MQTT broker and will assume that the pairing succeeded.