I'm working on a way to directly connect to an AnViz biometric device(TC550, which uses TC400.dll methods) by TCP from Linux/PHP, however and thus I managed to get some strings for reading out of the device, I'm having a hard time to figure out the checksum which appears on the last 2 bytes of each code to send my own instructions to the device.
An example of a working code might be:
function get_device_clock(){
if(!$this->ip) return;
if(!$this->open_socket()) return;
$bytes = "A5";
$bytes .= $this->fill_hex($this->id,8);
$bytes .= "380000C4B8";
$o = $this->comm($bytes);
if(!trim($o)) return;
$split = array();
for($l = 0; $l < strlen($o); $l+=2){
$split[] = substr($o,$l,2);
}
$year = hexdec($split[9]);
if($year < 10) $year = "0" . $year;
$year = "20$year";
$month = hexdec($split[10]);
if($month < 10) $month = "0$month";
$day = hexdec($split[11]);
if($day < 10) $day = "0$day";
$hour = hexdec($split[12]);
if($hour < 10) $hour = "0$hour";
$min = hexdec($split[13]);
if($min < 10) $min = "0$min";
$sec = hexdec($split[14]);
if($sec < 10) $sec = "0$sec";
fclose($this->socket);
return "$year-$month-$day $hour:$min:$sec\r\n";
}
This will be sending A5 00 00 05 38 00 00 C4 B8 to the device at port 5010 causing it to reply with its time and date.
As this would enable realtime:
A5 00 00 00 05 33 00 0F FF FF FF FF 01 FF FF FF FF FF FF FF FF FF FF 4E 37
This would list the last entries:
A5 00 00 00 05 40 00 02 01 19 FA FA
A5 00 00 00 06 3C 00 00 68 FE
A5 00 00 00 05 3C 00 00 A5 DB
Now the issue is, the last 2 bytes, C4 B8 at the first example, 4E 37 at the second, FA FA at the third, 68 FE and A5 DB on that where the ID is changed from 5 to 6, seams to be some sort of checksum. I'd tried all variants of common algorithms, even used Fsum Frontend, with all variants of byte ordering without success so far.
Also appears to have some variance in longer instructions, like these:
a5 00 00 00 05 73 00 29 01 00 00 00 00 17 ff ff ff 00 12 d6 93 00 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 6e 57
a5 00 00 00 05 73 00 29 01 00 00 00 00 01 10 00 01 3e eb 18 08 00 54 00 65 00 73 00 74 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 50 6f 54
Where in this case the checksum appears to be 40 6E 57 and 50 6F 54
Notes:
Requests seams to be composed of:
A5 + 4 bytes Serial# of the device + 1 byte Instruction code + variable length Content + 16/24 bits Checksum
You can get the SDK which generates this codes, tc400.dll, at SDK BIO-OFFICE
Any help to sort this out would be appreciated. TY in advance.
*UPDATE - Solved thanks to the Anviz Support Team *
Working code:
<?php
$crc_table = [
0x0000,0x1189,0x2312,0x329B,0x4624,0x57AD,0x6536,0x74BF,0x8C48,0x9DC1,0xAF5A,0xBED3,0xCA6C,0xDBE5,0xE97E,0xF8F7,
0x1081,0x0108,0x3393,0x221A,0x56A5,0x472C,0x75B7,0x643E,0x9CC9,0x8D40,0xBFDB,0xAE52,0xDAED,0xCB64,0xF9FF,0xE876,
0x2102,0x308B,0x0210,0x1399,0x6726,0x76AF,0x4434,0x55BD,0xAD4A,0xBCC3,0x8E58,0x9FD1,0xEB6E,0xFAE7,0xC87C,0xD9F5,
0x3183,0x200A,0x1291,0x0318,0x77A7,0x662E,0x54B5,0x453C,0xBDCB,0xAC42,0x9ED9,0x8F50,0xFBEF,0xEA66,0xD8FD,0xC974,
0x4204,0x538D,0x6116,0x709F,0x0420,0x15A9,0x2732,0x36BB,0xCE4C,0xDFC5,0xED5E,0xFCD7,0x8868,0x99E1,0xAB7A,0xBAF3,
0x5285,0x430C,0x7197,0x601E,0x14A1,0x0528,0x37B3,0x263A,0xDECD,0xCF44,0xFDDF,0xEC56,0x98E9,0x8960,0xBBFB,0xAA72,
0x6306,0x728F,0x4014,0x519D,0x2522,0x34AB,0x0630,0x17B9,0xEF4E,0xFEC7,0xCC5C,0xDDD5,0xA96A,0xB8E3,0x8A78,0x9BF1,
0x7387,0x620E,0x5095,0x411C,0x35A3,0x242A,0x16B1,0x0738,0xFFCF,0xEE46,0xDCDD,0xCD54,0xB9EB,0xA862,0x9AF9,0x8B70,
0x8408,0x9581,0xA71A,0xB693,0xC22C,0xD3A5,0xE13E,0xF0B7,0x0840,0x19C9,0x2B52,0x3ADB,0x4E64,0x5FED,0x6D76,0x7CFF,
0x9489,0x8500,0xB79B,0xA612,0xD2AD,0xC324,0xF1BF,0xE036,0x18C1,0x0948,0x3BD3,0x2A5A,0x5EE5,0x4F6C,0x7DF7,0x6C7E,
0xA50A,0xB483,0x8618,0x9791,0xE32E,0xF2A7,0xC03C,0xD1B5,0x2942,0x38CB,0x0A50,0x1BD9,0x6F66,0x7EEF,0x4C74,0x5DFD,
0xB58B,0xA402,0x9699,0x8710,0xF3AF,0xE226,0xD0BD,0xC134,0x39C3,0x284A,0x1AD1,0x0B58,0x7FE7,0x6E6E,0x5CF5,0x4D7C,
0xC60C,0xD785,0xE51E,0xF497,0x8028,0x91A1,0xA33A,0xB2B3,0x4A44,0x5BCD,0x6956,0x78DF,0x0C60,0x1DE9,0x2F72,0x3EFB,
0xD68D,0xC704,0xF59F,0xE416,0x90A9,0x8120,0xB3BB,0xA232,0x5AC5,0x4B4C,0x79D7,0x685E,0x1CE1,0x0D68,0x3FF3,0x2E7A,
0xE70E,0xF687,0xC41C,0xD595,0xA12A,0xB0A3,0x8238,0x93B1,0x6B46,0x7ACF,0x4854,0x59DD,0x2D62,0x3CEB,0x0E70,0x1FF9,
0xF78F,0xE606,0xD49D,0xC514,0xB1AB,0xA022,0x92B9,0x8330,0x7BC7,0x6A4E,0x58D5,0x495C,0x3DE3,0x2C6A,0x1EF1,0x0F78
];
/*************************************************
* Calc CRC16 for Anviz TC-300,TC-400,TC-500,TC-550
*
* @param binary $b
*/
function tc_crc16($b){
global $crc_table;
$crc = 0xFFFF;
for($l = 0; $l < strlen($b); $l++){
$crc ^= ord($b[$l]);
$crc = ($crc >> 8) ^ $crc_table[$crc & 255];
}
$res = strtoupper( dechex($crc) );
return($res[2].$res[3].$res[0].$res[1]);
}
/*****TEST AREA*****/
//$x = "A5000000033C0000"; //A5000000033C00003F90
$x = "A5000000057300290100000000011000013EEB180800540065007300740000000000000000000000000001000000000050"; //A5000000057300290100000000011000013EEB1808005400650073007400000000000000000000000000010000000000506F54
echo tc_crc16(hex2bin($x));
?>