Skip to content

Commit 74dcf22

Browse files
committed
cmd_key support added
1 parent 9f3ea8f commit 74dcf22

3 files changed

Lines changed: 51 additions & 12 deletions

File tree

src/Libs/Services/Connect.php

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,31 @@ public static function connect(ZKTeco $self)
4242

4343
// If data is received, process it.
4444
if (strlen($self->_data_recv) > 0) {
45-
// Unpack the received data to extract session ID.
4645
$u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6', substr($self->_data_recv, 0, 8));
4746

48-
// Convert session ID from hex to decimal.
49-
$session = hexdec($u['h6'].$u['h5']);
50-
51-
// If session ID is empty, return false.
47+
$session = hexdec($u['h6'] . $u['h5']);
5248
if (empty($session)) {
5349
return false;
5450
}
55-
56-
// Set the session ID in the ZKTecoPhp instance.
5751
$self->_session_id = $session;
58-
59-
// Check if the received data is valid.
60-
return Util::checkValid($self->_data_recv);
52+
$result = Util::checkValid($self->_data_recv);
53+
if ($result == Util::CMD_ACK_UNAUTH) {
54+
$command_string = Util::makeCommKey($self->_password, $self->_session_id);
55+
$buf = Util::createHeader(Util::CMD_ACK_AUTH, 0, $self->_session_id, $reply_id, $command_string);
56+
socket_sendto($self->_zkclient, $buf, strlen($buf), 0, $self->_ip, $self->_port);
57+
@socket_recvfrom($self->_zkclient, $self->_data_recv, 1024, 0, $self->_ip, $self->_port);
58+
if (strlen($self->_data_recv) > 0) {
59+
$u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6', substr($self->_data_recv, 0, 8));
60+
$session = hexdec($u['h6'].$u['h5']);
61+
if (empty($session)) {
62+
return false;
63+
}
64+
$self->_session_id = $session;
65+
return Util::checkValid($self->_data_recv);
66+
}
67+
}
68+
return $result;
6169
} else {
62-
// If no data is received, return false.
6370
return false;
6471
}
6572
} catch (ErrorException $e) {

src/Libs/Services/Util.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Util
2828
const CMD_ACK_ERROR = 2001; // Return value for order perform failed
2929
const CMD_ACK_DATA = 2002; // Return data
3030
const CMD_ACK_UNAUTH = 2005; // Connection unauthorized
31+
const CMD_ACK_AUTH = 1102; // Connection authorized
3132

3233
const CMD_PREPARE_DATA = 1500; // Prepares to transmit the data
3334
const CMD_DATA = 1501; // Transmit a data packet
@@ -260,6 +261,35 @@ public static function createHeader($command, $chksum, $session_id, $reply_id, $
260261
return $buf.$command_string;
261262
}
262263

264+
public static function makeCommKey(int $key, int $session_id, $ticks= 50) {
265+
266+
$k = 0;
267+
for($i = 0; $i < 32; $i++) {
268+
if ($key & (1 << $i) ) {
269+
$k = ($k << 1 | 1 );
270+
} else {
271+
$k = $k << 1;
272+
}
273+
}
274+
$k += $session_id;
275+
$k = pack("I",$k);
276+
$k = unpack("C4", $k);
277+
278+
$k = pack("C4",
279+
$k[1] ^ ord('Z'),
280+
$k[2] ^ ord('K'),
281+
$k[3] ^ ord('S'),
282+
$k[4] ^ ord('O')
283+
);
284+
285+
$k = unpack('S2', $k); // S , n , v all in php for short int
286+
$k = pack('S2', $k[2], $k[1]);
287+
$B = 0xff & 50;
288+
$k = unpack('C4', $k);
289+
$k = pack('C4', $k[1] ^ $B, $k[2] ^ $B, $B, $k[4]^ $B);
290+
return $k;
291+
}
292+
263293
/**
264294
* Checks a returned packet to see if it returned Util::CMD_ACK_OK,
265295
* indicating success.

src/Libs/ZKTeco.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,20 @@ class ZKTeco
3232
public $_section = '';
3333
public $_requiredPing = false;
3434
public $_silentPing = false;
35+
public $_password = false;
3536

3637
/**
3738
* @param string $ip Device IP address.
3839
* @param int $port Port number. Default: 4370.
3940
* @param bool $shouldPing should ping before device connection
4041
* @param int $timeout timeout in sec
4142
*/
42-
public function __construct(string $ip, int $port = 4370, bool $shouldPing = false, int $timeout = 25)
43+
public function __construct(string $ip, int $port = 4370, bool $shouldPing = false, int $timeout = 25, $password = 0)
4344
{
4445
$this->_ip = $ip;
4546
$this->_port = $port;
4647
$this->_requiredPing = (bool) $shouldPing;
48+
$this->_password = $password;
4749

4850
$this->_zkclient = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
4951

0 commit comments

Comments
 (0)