Cloud protocol dissection - gardena-smart-reverse-engineering/gateway-19000 GitHub Wiki
The gateway (GW) is connected via vpn to its cloud servers (CS). The protocol is based on JSON RPC 2.0 with embedded XMLs as payload via tcpip. The namespace of the XMLs is seluxit bastard. There is a nice seluxit github account. The device identifies itself via its gateway id, which is printed on a sticker on the bottom of the device and is written to its uboot enviroment variables. I will use 13371337-1337-1337-1337-133713371337 as replacement
At the beginning the connection is initialized. More details about the magic values TDB.
GW
ff00000000000000257f
CS
ff00000000000000017f
GW
03
CS
03
GW
0000 00 4e 55 4c 4c 00 00 00 00 00 00 00 00 00 00 00 .NULL...........
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030 00 00 00 00 00 .....
CS
0000 00 4e 55 4c 4c 00 00 00 00 00 00 00 00 00 00 00 .NULL...........
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030 00 00 00 00 00 .....
GW
0000 04 4a 05 52 45 41 44 59 0b 53 6f 63 6b 65 74 2d .J.READY.Socket-
0010 54 79 70 65 00 00 00 03 52 45 51 08 49 64 65 6e Type....REQ.Iden
0020 74 69 74 79 00 00 00 tity...
$13371337-1337-1337-1337-133713371337
CS
0000 04 29 05 52 45 41 44 59 0b 53 6f 63 6b 65 74 2d .).READY.Socket-
0010 54 79 70 65 00 00 00 06 52 4f 55 54 45 52 08 49 Type....ROUTER.I
0020 64 65 6e 74 69 74 79 00 00 00 00 dentity....
As said basicly a JSON RPC 2.0 is used. But there is a small length header at the begin of the TCP data before the JSON data. I will skip this header later on.
Short Header starts with 01 00 00. Data length is 0x3A bytes. It may be used if the payload size is up to 0xFF bytes.
0000 01 00 00 3a 7b 22 6a 73 6f 6e 72 70 63 22 3a 22 ...:{"jsonrpc":"
[...]
0030 22 72 65 73 75 6c 74 22 3a 74 72 75 65 7d "result":true}
Short Header starts with 01 00 02 00 00 00 00. Data length is 0x018E59 bytes
0000 01 00 02 00 00 00 00 00 01 8e 59 5b 7b 22 69 64 ..........Y[{"id
[...]
There may be send multiple request within on request, so there is just a list of those requests.
{
"id": "[type]-[random-number]",
"jsonrpc": "2.0",
"method": "POST",
"params": {
"data": "[xml-payload]",
"meta": {
"receive_time": "2019-05-13T12:23:51.761Z",
"send_time": "2019-05-13T12:23:51.760Z"
},
"url": "[path]"
}
}
The id will be the same as in the request.
{
"jsonrpc": "2.0",
"id": "[type]-[random-number]",
"result": true
}
Type: Network_POST
Path: /network/
<?xml version="1.0"?>
<network xmlns="urn:seluxit:xml:bastard:network-1.0" id="13371337-1337-1337-1337-133713371337" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:seluxit:xml:bastard:network-1.0 network.xsd" />
Type: POST-DEVICE
Path: /network/[gateway-id]/device/
Device-Id: 13371337-1337-1337-1337-133713371338
<device xmlns="urn:seluxit:xml:bastard:device-1.0" id="13371337-1337-1337-1337-133713371338" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:seluxit:xml:bastard:device-1.0 device.xsd">
<name>Husqvarna Automower</name>
<manufacturer>Gardena</manufacturer>
<product>3-DEVICE</product>
<version>3.0.0-2.5.2-1.2.6-1.5.3</version>
<serial>133713371337133713371337</serial>
<protocol>Lemonbeat</protocol>
<communication>Always Online</communication>
<included>1</included>
<inclusion_status>INCLUDED</inclusion_status>
<firmware_status>UP_TO_DATE</firmware_status>
<connection_status>online</connection_status>
<firmware_upload_progress>0</firmware_upload_progress>
<firmware_available_version></firmware_available_version>
<command>idle</command>
</device>
Type: POST-SERVICE
Path: /network/[gateway-id]/device/[device-id]/service/
Service-Id: 13371337-1337-1337-1337-133713371339
<service xmlns="urn:seluxit:xml:bastard:service-1.0" id="13371337-1337-1337-1337-133713371339" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:seluxit:xml:bastard:service-1.0 service.xsd">
<name>charging_cycles</name>
<permission>r</permission>
<type>General Purpose</type>
<virtual>false</virtual>
<number>
<min>0.000000</min>
<max>65535.000000</max>
<step>1.000000</step>
<unit>no unit</unit>
</number>
<status>ok</status>
</service>
Type: POST-VALUE
Path: /network/[gateway-id]/device/[device-id]/service/[service-id]/value/
<value xmlns="urn:seluxit:xml:bastard:value-1.0" id="13371337-1337-1337-1337-133713371339" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:seluxit:xml:bastard:value-1.0 value.xsd">
<type>Report</type>
<timestamp>2019-04-22T14:57:44.246Z</timestamp>
<data>4.000000</data>
</value>
Type: POST-CONFIGURATION
Path: /network/[gateway-id]/device/[device-id]/configuration/
Cfg-Id: 13371337-1337-1337-1337-13371337133a
<configuration xmlns="urn:seluxit:xml:bastard:configuration-1.0" id="13371337-1337-1337-1337-13371337133a" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:seluxit:xml:bastard:configuration-1.0 configuration.xsd">
<status>active</status>
<limits>
<partner>1</partner>
<action>20</action>
<calendar>1</calendar>
<calculation>20</calculation>
<timer>1</timer>
<statemachine>1</statemachine>
<transactions>20</transactions>
</limits>
</configuration>
Type: POST-PARTNER
Path: /network/[gateway-id]/device/[device-id]/configuration/[cfg-id]/partner/
<partner xmlns="urn:seluxit:xml:bastard:partner-1.0" id="261935d9-022d-4fb5-ae68-4736d217198f" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:seluxit:xml:bastard:partner-1.0 partner.xsd">
<device_id>[device-id]</device_id>
</partner>
Type: POST-ACTION
Path: /network/[gateway-id]/device/[device-id]/configuration/[cfg-id]/action/
Action-Id: 13371337-1337-1337-1337-13371337133b
TDB
Type: POST-CALCULATION
Path: /network/[gateway-id]/device/[device-id]/configuration/[cfg-id]/calculation/
Timer-Id: 13371337-1337-1337-1337-13371337133c
TBD
Type: POST-TIMER
Path: /network/[gateway-id]/device/[device-id]/configuration/[cfg-id]/timer/
TBD
Type: POST-STATEMACHINE
Path: /network/[gateway-id]/device/[device-id]/configuration/[cfg-id]/statemachine/
TBD
Type: POST-GATEWAY
Path: /gateway/
TBD
Type: POST-STATUS
Path: /network/[gateway-id]/device/[device-id]/status
TBD
Type: PUT-DEVICE
Path: /network/[gateway-id]/device/[device-id]
TBD