From 5d780d8ce9a36d7217ffb310af07c1b55f888014 Mon Sep 17 00:00:00 2001 From: fernadosilva Date: Fri, 4 Oct 2019 21:52:58 +0100 Subject: [PATCH] 1. The synchronization check between the socket and server now verifies the time further to DST and TZ. 2. The procSync activity now sets the socket clock further to the DST and TZ, since the automatic time synchronization service formerly provided by Orvibo and used by the S20 sockets ceased to operate somewhere in the middle of 2019. See TECHNICAL_DATA.txt for more info. --- README | 8 ++++++++ TECHNICAL_DATA.txt | 25 ++++++++++++++++++------- lib/orvfms/globals.php | 4 +++- lib/orvfms/main_page.php | 4 +++- lib/orvfms/orvfms.php | 29 ++++++++++++++++++++++++++++- lib/orvfms/setup_page.php | 7 +++---- s20/index.php | 2 ++ 7 files changed, 65 insertions(+), 14 deletions(-) diff --git a/README b/README index 1998249..6806158 100755 --- a/README +++ b/README @@ -3,6 +3,14 @@ #************************************************************************* Last update: 13 May 2016 +Reviewed: 4 October 2019 + +PRELIMINARY NOTE: + Unhappily, this code only supports the "old" S20 Orvibo socket. The newer S25 + socket, as well as newer Orvibo devices, use a completely different and encrypted + protocol and, so far it seems to us, much more difficult to reverse engineering to + the level we were able to do with the S20 :-(. However, may be this code still fits + to some of us that use the "old" S20 socket. SUMMARY: This software implements a web interface to control Orvibo S20 diff --git a/TECHNICAL_DATA.txt b/TECHNICAL_DATA.txt index 4307213..ed6167f 100755 --- a/TECHNICAL_DATA.txt +++ b/TECHNICAL_DATA.txt @@ -1,3 +1,11 @@ +Last reviewed: 4 october 2019 + +IMPORTANT NOTICE: unhappily, this code only supports the "old" S20 Orvibo socket. The newer S25 +socket, as well as newer Orvibo devices, use a completely different protocol and, so far it +seems to us, much more difficult to reverse engineering to the level we were able to do with +the S20 :-(. However, may be this code still fits to some of us that still use the old S20 +socket. + As stated in the README file, most of the reverse engineering information required to operate the S20 was obtained from @@ -67,19 +75,14 @@ c) All weekly scheduled timers are represented in Hours Min and Seconds in local time. More aboute these timers below. d) Sockets take care of converting UTC time to local time taking into acount the local timezone (TZ) and Daylight Saving Time (DST). -e) It is possible to initialize the socket UTC time using a specific command. -While the WiWo performs this initialization, our code does not uses it, -since the sockets seem always to automatically synchronize by themselves -using some NTP alike service. - -However, for those interested in this possibility, initialization of the -socket clock in UTC can be done sending to the socket the following +e) To initialize the socket UTC time, send to the socket the following message: 0000 68 64 00 1a 63 73 MM MM MM MM MM MM 20 20 20 20 hd..cs..#5.. 0010 20 20 00 00 00 00 XX XX XX XX ........ where + 68 64 - Magic Key 00 1a - Msg length 63 73 - Init socket clock command @@ -90,6 +93,14 @@ XX XX XX XX - Seconds since 1 Jan 1900 (in UTC), little endian. The socket, as usualy, replies with a message with the same code 63 73 and with a dummy payload. +Up to version 1.1 of Orvfms, we did not use this time initializon since the sockets +were always automatically synchronized by themselves using some Orvibo NTP alike +service. Unhappily, we believe that Orvibo ceased to support this service somewhere +in the middle of 2019 (June/July?), and since then our sockets defaulted to 1 january +1900 each time they were unplugged. Therefore, in 4 october 2019 we updated the code +and now the sync command update both the Time zone, DST and the socket time (up to then, +we just updated the TZ and DST). + 3. As reported in pastebin, timezone information is reported in table 4, byte 164. However, the following details and additional info must be taken into account: a) This byte is an integer offset in hours to GMT (positive values to the east, diff --git a/lib/orvfms/globals.php b/lib/orvfms/globals.php index 9a7a278..36d12c9 100644 --- a/lib/orvfms/globals.php +++ b/lib/orvfms/globals.php @@ -41,7 +41,7 @@ // We strongly advise to use here a permanent working directory in the // line below, (for example, define("TMP_DIR","/mytmp"). See INSTALLATION // for more information on this subject. -define("TMP_DIR",""); +define("TMP_DIR","/tmp2"); define("PORT",10000); define("TWENTIES","202020202020"); @@ -59,11 +59,13 @@ define("BUFFER_SIZE",500); define("WRITE_SOCKET_CODE","746D"); define("SEARCH_IP","7167"); +define("SET_TIME","6373"); define("DEBUG",0); define("NUMBER_OF_NEXT_ACTIONS_DISPLAYED_IN_MAIN_PAGE",0); define("LOCAL_FILE_NAME","orvfms.dat"); define("SCENE_FILE_NAME","scene_orvfms.dat"); define("NULL_MAC","000000000000"); +define("FROM_CENTURY_TO_EPOCH",2208988800); ?> diff --git a/lib/orvfms/main_page.php b/lib/orvfms/main_page.php index ff29e64..1269c4f 100755 --- a/lib/orvfms/main_page.php +++ b/lib/orvfms/main_page.php @@ -137,8 +137,10 @@ function displayMainPage(&$s20Table,$myUrl){ echo $clockButton; // overlay warning button for each button if tz or dst differ between server and socket + $socketTime = $devData['time']; + $serverTime = $devData['serverTime']; if(($devData['timeZone'] != $devData['serverTimeZone']) || - ($devData['dst'] != $devData['serverDst'])){ + ($devData['dst'] != $devData['serverDst']) || (abs($serverTime-$socketTime) > 5)){ $warningButton = ''."\n"; echo $warningButton; diff --git a/lib/orvfms/orvfms.php b/lib/orvfms/orvfms.php index a224c49..36283ec 100755 --- a/lib/orvfms/orvfms.php +++ b/lib/orvfms/orvfms.php @@ -125,7 +125,7 @@ function getNextAction($mac,$s20Table){ function getSocketTime($tab){ $th=invertEndian(padHex(substr($tab,-2*5,8),8)); - $timeStamp = hexdec($th) - 2208988800; + $timeStamp = hexdec($th) - FROM_CENTURY_TO_EPOCH; return $timeStamp; } @@ -893,6 +893,33 @@ function setTimeZone($mac,$tz,$dst,&$s20Table){ return $reply; } +function setSocketTime($mac,$newTime,&$s20Table){ + // + // Sets socket time equal to server time + // This is required due given that Orvibo automatic NTP alike service seems not be working anymore and therefore + // the S20 clocks default to 1 jan 1900 each time they are switch off (further to a slight shifting delay) + // + $socketTime = $newTime + FROM_CENTURY_TO_EPOCH; // adjust to 1 jan 1900 + $socketTime = $socketTime + 1; // compensate for delay (roughly) + $socketTimeHex = dechex($socketTime); + $socketTimeHexLE = invertEndian($socketTimeHex); + + $msg = MAGIC_KEY."XXXX".SET_TIME.$mac.TWENTIES.FOUR_ZEROS.$socketTimeHexLE; + $msg = adjustMsgSize($msg); + + $reply = createSocketSendHexMsgWaitReply($mac,$msg,$s20Table); + if($reply == "") { + $s20Table[$mac]['off'] = time(); + } + else{ + $s20Table[$mac]['time'] = $newTime; + $_SESSION['s20Table']=$s20Table; + writeDataFile($s20Table); + } + +} + + function setSwitchOffTimer($mac,$sec,&$s20Table){ // diff --git a/lib/orvfms/setup_page.php b/lib/orvfms/setup_page.php index f1843cf..6331d2d 100755 --- a/lib/orvfms/setup_page.php +++ b/lib/orvfms/setup_page.php @@ -41,7 +41,6 @@ function displaySetupPage($mac,&$s20Table,$myUrl){ ?>

- @@ -77,7 +76,7 @@ function displaySetupPage($mac,&$s20Table,$myUrl){ $dst = $dev['dst']; // 1 means DST on $serverTz = $dev['serverTimeZone']; $serverDst = $dev['serverDst']; - $isSync = ($serverDst == $dst) && ($tz == $serverTz); + $isSync = ($serverDst == $dst) && ($tz == $serverTz) && (abs($serverTime - $time) < 5); if(!$isSync){ echo '

Warning: clock seems out of sync!

'; } @@ -86,11 +85,11 @@ function displaySetupPage($mac,&$s20Table,$myUrl){ ?>


"; ?> S20 mac address - diff --git a/s20/index.php b/s20/index.php index fb3d581..41b3400 100755 --- a/s20/index.php +++ b/s20/index.php @@ -277,7 +277,9 @@ function getMacAndActionFromPost(&$action,$postVal){ if($actionValue == "procSync"){ // Sync socket TZ to server TZ $serverTz = $s20Table[$mac]['serverTimeZone']; $serverDst = $s20Table[$mac]['serverDst']; + $serverTime = $s20Table[$mac]['serverTime']; setTimeZone($mac,$serverTz,$serverDst,$s20Table); + setSocketTime($mac,time(),$s20Table); } elseif($actionValue=="wake"){ $ip = getIpFromMac($mac,$s20Table);