I'm objective is to build a custom wifi module to be used on a Samsung AC AR24HSFSAWKN. I have such an official module SWL-B70F for which I'm trying to reverse engineer the communication with the main AC board. It's just for the challenge and my first attempt on such hack.
From the AC manual I have identified the following pinout:
CN51 - WI-FI MODULE
#1 : WIFI UART SIGNAL1
#2 : WIFI UART SIGNAL2
#3 : WIFI RESET SIGNAL
#4 : GND
#5 : DC 12V
#6 : N.C
Once module was disassembled, I found inside an arm board and a second one which I identified to be a step-down regulator (12V -> 5V). On the regulator board, I've hooked some wires to the UART lines + GND to 2 ftdi cables on their RX pin, so I can dump the frames in both directions. I've booted the device several times with different tty
baud rates. I think 9600 bauds is the right one as other did not gave nice patterns. Now I end with the exchanges bellow. I found some common patterns. I suppose frames start with d0
(or d0c002
) and ends with e0
. There seems to have a message counter, a fixed separator, a payload, and a checksum: <start> <????> <counter> <sep?> <payload> <CheckSum8 Xor> <end>
. When a message is sent, a similar message is sent on the other line, probably a ack
message.
I can send xml commands via the actual wifi module. As a test, I send a OFF
command, wich resulted in the following exchanges:
OFF
Command:
# try 1
-> d0c002 12 000000000038 fe 1204060201f074010f 5f e0
<- d0c002 12 000000000038 fe 1205060201f074010f 5e e0
# try 2
-> d0c002 12 000000000047 fe 1204060201f074010f 20 e0
<- d0c002 12 000000000047 fe 1205060201f074010f 21 e0
# try 3
-> d0c002 12 000000000058 fe 1204060201f074010f 3f e0
<- d0c002 12 000000000058 fe 1205060201f074010f 3e e0
Another possible command is to get DeviceState
, which return the following XML (but did not triggered any exchange with main board, I suppose the values are stored in the wifi module upon initialization):
?xml version="1.0" encoding="utf-8" ?>
<Response Type="DeviceState" Status="Okay">
<DeviceState>
<Device DUID="F8042ED83EA0" GroupID="AC" ModelID="AC" >
<Attr ID="AC_FUN_ENABLE" Type="RW" Value="Enable"/>
<Attr ID="AC_FUN_POWER" Type="RW" Value="Off"/>
<Attr ID="AC_FUN_OPMODE" Type="RW" Value="Auto"/>
<Attr ID="AC_FUN_TEMPSET" Type="RW" Value="21"/>
<Attr ID="AC_FUN_COMODE" Type="RW" Value="Off"/>
<Attr ID="AC_FUN_ERROR" Type="RW" Value="NULL"/>
<Attr ID="AC_FUN_TEMPNOW" Type="R" Value="23"/>
<Attr ID="AC_FUN_SLEEP" Type="RW" Value="0"/>
<Attr ID="AC_FUN_WINDLEVEL" Type="RW" Value="Auto"/>
<Attr ID="AC_FUN_DIRECTION" Type="RW" Value="Fixed"/>
<Attr ID="AC_ADD_AUTOCLEAN" Type="RW" Value="Off"/>
<Attr ID="AC_ADD_SETKWH" Type="RW" Value="255"/>
<Attr ID="AC_ADD_CLEAR_FILTER_ALARM" Type="RW" Value="240"/>
<Attr ID="AC_ADD_APMODE_END" Type="W" Value="0"/>
<Attr ID="AC_ADD_STARTWPS" Type="RW" Value="Default"/>
<Attr ID="AC_ADD_SPI" Type="RW" Value="Off"/>
<Attr ID="AC_OUTDOOR_TEMP" Type="R" Value="71"/>
<Attr ID="AC_COOL_CAPABILITY" Type="R" Value="68"/>
<Attr ID="AC_WARM_CAPABILITY" Type="R" Value="80"/>
<Attr ID="AC_SG_WIFI" Type="W" Value="Connected"/>
<Attr ID="AC_SG_INTERNET" Type="W" Value="Disconnected"/>
<Attr ID="AC_ADD2_USEDWATT" Type="R" Value="65024"/>
<Attr ID="AC_ADD2_VERSION" Type="RW" Value="65024"/>
<Attr ID="AC_SG_MACHIGH" Type="W" Value="216"/>
<Attr ID="AC_SG_MACMID" Type="W" Value="62"/>
<Attr ID="AC_SG_MACLOW" Type="W" Value="160"/>
<Attr ID="AC_SG_VENDER01" Type="W" Value="248"/>
<Attr ID="AC_SG_VENDER02" Type="W" Value="4"/>
<Attr ID="AC_SG_VENDER03" Type="W" Value="46"/>
<Attr ID="AC_ADD2_PANEL_VERSION" Type="R" Value="150224"/>
<Attr ID="AC_ADD2_OUT_VERSION" Type="R" Value="1246985"/>
<Attr ID="AC_FUN_MODEL" Type="R" Value="5"/>
<Attr ID="AC_ADD2_OPTIONCODE" Type="R" Value="53432"/>
<Attr ID="AC_ADD2_USEDPOWER" Type="R" Value="58933"/>
<Attr ID="AC_ADD2_USEDTIME" Type="R" Value="265675"/>
<Attr ID="AC_ADD2_CLEAR_POWERTIME" Type="RW" Value="254"/>
<Attr ID="AC_ADD2_FILTERTIME" Type="RW" Value="500"/>
<Attr ID="AC_ADD2_FILTER_USE_TIME" Type="R" Value="10000"/>
</Device>
</DeviceState>
</Response>
Some values are present in the boot log, such as AC_ADD2_USEDTIME
, AC_ADD2_OPTIONCODE
, AC_ADD2_USEDPOWER
, AC_ADD2_FILTER_USE_TIME
=>
d0c002 39 000000000009 fe 14032d3201fef601fef403150224f303130709f501053902 d0b8(AC_ADD2_OPTIONCODE) e0040000 e635 e404000 40dcb(AC_ADD2_USEDPOWER) e801fee90103e602 2710(AC_ADD2_FILTER_USE_TIME) 93 e0
The frame may be split as:
14032d3201fef601fef403150224f303130709f50105
3902 d0b8
e004 0000e635
e404 00040dcb
e801 fee90103
e602 2710
e004
, e404
, e602
could probably be some field header?
The checksum is CheckSum8 Xor
of the first bytes: d0c00212000000000047fe1204060201f074010f
-> 20
Also the first exchange (0000
/ 00fc
) never showed again, so it should be some sort of handshake.
Next I'll try to remove the wifi module, and replay the communication with it, simulating the AC.
Questions:
- Are my methodology and assumptions valid?
- What could be the second field in the frame (unique values seems to be
0f 12 18 1c 1e 22 30
)? - Am I splitting the frames correctly?
- Do you have some advises on how to decode the remaining messages and reverse the full protocol?
- Does it looks like something known elsewhere?
- Any other tip :)
Thanks a lot!
The full boot log:
#-> WIFI TO AC
#<- AC TO WIFI
-> 00fc
<- 0000
-> d0c002 12 000000000000 fe 12040601010f7401f0 64 e0
<- d0c002 12 000000000000 fe 12050601010f7401f0 65 e0
-> d0c002 18 000000000001 fe 14040c170115180105190127fd0102 37 e0
<- d0c002 18 000000000001 fe 14050c170115180105190127fd0102 36 e0
-> d0c002 1e 000000000002 fe 140412fa01f8fb0104fc012ef701d8f8013ef901a0 6d e0
<- d0c002 1e 000000000002 fe 140512fa01f8fb0104fc012ef701d8f8013ef901a0 6c e0
-> d0c002 18 000000000003 fe 14040c170115180105190127fd0102 35 e0
<- d0c002 18 000000000003 fe 14050c170115180105190127fd0102 34 e0
-> d0c002 1e 000000000004 fe 140412fa01f8fb0104fc012ef701d8f8013ef901a0 6b e0
<- d0c002 1e 000000000004 fe 140512fa01f8fb0104fc012ef701d8f8013ef901a0 6a e0
-> d0c002 18 000000000005 fe 14040c170115180105190127fd0102 33 e0
<- d0c002 18 000000000005 fe 14050c170115180105190127fd0102 32 e0
-> d0c002 1e 000000000006 fe 140412fa01f8fb0104fc012ef701d8f8013ef901a0 69 e0
<- d0c002 1e 000000000006 fe 140512fa01f8fb0104fc012ef701d8f8013ef901a0 68 e0
-> d0c002 30 000000000006 fe 1207240201f04101324301e24401126201006301c2ea01fe5a01155c0117730100f70400000000 ce e0
<- d0c002 30 000000000006 fe 1206240201f04101324301e24401126201006301c2ea01fe5a01155c0117730100f70400000000 cf e0
-> d0c002 1c 000000000008 fe 13021032004000440043007500760077007800 80 e0
<- d0c002 26 000000000008 fe 13031a3201234001ff4401f043010f7501f07601497702004478020050 3f e0
-> d0c002 22 000000000009 fe 1402163200f600f400f300f5003900 e000e400e800e900e600 2b e0
<- d0c002 39 000000000009 fe 14032d3201fef601fef403150224f303130709f501053902d0b8e0040000e635e40400040dcbe801fee90103e6022710 93 e0
-> d0c002 0f 00000000000a fe 14040337010f c3 e0
<- d0c002 0f 00000000000a fe 14050337010f c2 e0
-> d0c002 18 00000000000b fe 14040c170115180105190127fd0102 3d e0
<- d0c002 18 00000000000b fe 14050c170115180105190127fd0102 3c e0
-> d0c002 22 00000000000c fe 1402163200f600f400f300f5003900 e000e400e800e900e600 2e e0
<- d0c002 39 00000000000c fe 14032d3201fef601fef403150224f303130709f501053902d0b8e0040000e635e40400040dcbe801fee90103e6022710 96 e0
-> d0c002 1e 00000000000d fe 140412fa01f8fb0104fc012ef701d8f8013ef901a0 62 e0
<- d0c002 1e 00000000000d fe 140512fa01f8fb0104fc012ef701d8f8013ef901a0 63 e0
-> d0c002 0f 00000000000e fe 1404033801f0 37 e0
<- d0c002 0f 00000000000e fe 1405033801f0 36 e0
-> d0c002 0f 00000000000f fe 14040337010f c6 e0
<- d0c002 0f 00000000000f fe 14050337010f c7 e0
-> d0c002 0f 000000000010 fe 14040337010f d9 e0
<- d0c002 0f 000000000010 fe 14050337010f d8 e0
-> d0c002 18 000000000011 fe 14040c170115180105190127fd0102 27 e0
<- d0c002 18 000000000011 fe 14050c170115180105190127fd0102 26 e0
-> d0c002 1e 000000000012 fe 140412fa01f8fb0104fc012ef701d8f8013ef901a0 7d e0
<- d0c002 1e 000000000012 fe 140512fa01f8fb0104fc012ef701d8f8013ef901a0 7c e0
-> d0c002 0f 000000000013 fe 1404033801f0 2a e0
<- d0c002 0f 000000000013 fe 1405033801f0 2b e0
-> d0c002 0f 000000000014 fe 14040337010f dd e0
<- d0c002 0f 000000000014 fe 14050337010f dc e0
-> d0c002 0f 000000000015 fe 1404033801f0 2c e0
<- d0c002 0f 000000000015 fe 1405033801f0 2d e0
-> d0c002 0f 000000000016 fe 14040337010f df e0
<- d0c002 0f 000000000016 fe 14050337010f de e0
-> d0c002 0f 000000000017 fe 1404033801f0 2e e0
<- d0c002 0f 000000000017 fe 1405033801f0 2f e0
-> d0c002 0f 000000000018 fe 14040337010f d1 e0
<- d0c002 0f 000000000018 fe 14050337010f d0 e0
-> d0c002 0f 000000000019 fe 1404033801f0 20 e0
<- d0c002 0f 000000000019 fe 1405033801f0 21 e0
-> d0c002 0f 00000000001a fe 14040337010f d3 e0
<- d0c002 0f 00000000001a fe 14050337010f d2 e0