vodvud / php_zklib

GNU General Public License v2.0
23 stars 19 forks source link

setting RFID - CardNo of the user! #2

Closed bezhanSalleh closed 4 years ago

bezhanSalleh commented 6 years ago

Hi there! How would you update the set method in user model to set the user RFID also? Thanks.

vodvud commented 5 years ago

Hi! By user data structure the 'CardNo' follow the 'Name', then you should use this line:

https://github.com/vodvud/php_zklib/blob/98f4f59e22d12aa3fac5f0f4a6be6b6e25585e83/zklib/src/User.php#L41

replace 'chr (1)' to your variable that you pass into the method.

WebFikirleri commented 5 years ago

Hi, it's not working for me... Could you please update the main code please? Added to User.php

public function set_with_card(ZKLib $self, $uid, $userid, $name, $card, $password, $role = Util::LEVEL_USER)
    {
        $self->_section = __METHOD__;

        if (
            (int)$uid === 0 ||
            (int)$uid > Util::USHRT_MAX ||
            strlen($userid) > 9 ||
            strlen($name) > 24 ||
            strlen($password) > 8
        ) {
            return false;
        }

        $command = Util::CMD_SET_USER;
        $byte1 = chr((int)($uid % 256));
        $byte2 = chr((int)($uid >> 8));
        $command_string = implode('', [
            $byte1,
            $byte2,
            chr($role),
            str_pad($password, 8, chr(0)),
            str_pad($name, 28, chr(0)),
            str_pad($card, 9, chr(0)),
            str_pad($userid, 9, chr(0)),
            str_repeat(chr(0), 15)
        ]);

        return $self->_command($command, $command_string);
    }

Added to ZKLib.php

public function setUserWC($uid, $userid, $name, $card, $password, $role = Util::LEVEL_USER)
    {
        return (new ZK\User())->set_with_card($this, $uid, $userid, $name, $card, $password, $role);
    }

PS: on activex library sending card number is more like sending fingerprint data, first set card number and then set userdata, then upload...

vodvud commented 5 years ago

Hi, it's not working for me... Could you please update the main code please?

Hi @WebFikirleri Sorry, but I do not have a device that supports the card code.

If you have such a device, you can try to modify this library and test.

WebFikirleri commented 5 years ago

If you have such a device, you can try to modify this library and test.

Sure, i'll love to but i need to find out a way to capture port requests. I create a windows executable with delphi but i need to do it with php. this is my first time playing with ports if i analyse the data which sended/received on my exe maybe i should find to way out

vodvud commented 5 years ago

PS: on activex library sending card number is more like sending fingerprint data, first set card number and then set userdata, then upload...

I think it is inside User Info same like Password.

ZK communication protocol manual You can look the user structure on page 15.

Also see how it work for decode, reverse by pair https://github.com/vodvud/php_zklib/blob/98f4f59e22d12aa3fac5f0f4a6be6b6e25585e83/zklib/src/User.php#L79

WebFikirleri commented 5 years ago

When receiving user data, yes! it's belong to user info. But on the set section; it's like a fingerprint data. Let me show you the delphi code:

        begin
          // setting card number as string
          zk.SetStrCardNumber(dsUsers.DataSet.FieldByName('zk_card').AsWideString);
         // sending user info
          if (zk.SSR_SetUserInfo(1,dsUsers.DataSet.FieldByName('zk_uid').AsWideString,dsUsers.DataSet.FieldByName('zk_name').AsWideString,dsUsers.DataSet.FieldByName('zk_password').AsString,dsUsers.DataSet.FieldByName('zk_role').AsInteger,True)) then
          begin
            Writeln('User: '+dsUsers.DataSet.FieldByName('zk_name').AsString+' with ID: '+dsUsers.DataSet.FieldByName('zk_uid').AsString+' CardN: '+dsUsers.DataSet.FieldByName('zk_card').AsString);
            log.Add('User: '+dsUsers.DataSet.FieldByName('zk_name').AsString+' with ID: '+dsUsers.DataSet.FieldByName('zk_uid').AsString+' CardN: '+dsUsers.DataSet.FieldByName('zk_card').AsString);
          end else begin
            Writeln('Cannot Update User: '+dsUsers.DataSet.FieldByName('zk_name').AsString+' with ID: '+dsUsers.DataSet.FieldByName('zk_uid').AsString+' CardN: '+dsUsers.DataSet.FieldByName('zk_card').AsString);
            log.Add('Cannot Update User: '+dsUsers.DataSet.FieldByName('zk_name').AsString+' with ID: '+dsUsers.DataSet.FieldByName('zk_uid').AsString+' CardN: '+dsUsers.DataSet.FieldByName('zk_card').AsString);
          end;
          dsUsers.DataSet.Next;
        end;

explanation:

SetStrCardNumber(CardNumberAsWideString);
SSR_SetUserInfo(deviceID,UserIDAsWideString,UserNameAsWideString,UserPasswordAsString,UserRoleAsInteger,PrivilegeAsBoolean);

on the manual, as you mentioned before, which located php_zklib/zklib/docs/ZK_Communication_protocol_manual_CMD.pdf

CMD_WRITE_MIFARE Inform machine to write Mifare card. Only the machine with Mifare card to reader is able to support this function. fill the data part 1-4 byte of the transmission packet with user serial number, and 12 bytes with templates information, the first 3 bytes of these 12 bytes, fill the 1-2nd byte with template length, and the 3rd byte with template index (corresponding user some fingerprint), for this 12 bytes, the fist 1-3 byte cannot be empty, there must be template in these bytes. May write 4 fingerprints templates, the following 9 bytes separately is filled with other three fingerprints length and the index, to fill every three bytes methods is same with before filling 3 bytes packing. May refer to the following structure. 4th Bytes | [ 1-2bytes (fingerprint 1 template length), 3rd bytes (fingerprint index) ], [ 4-6... .. ] | The user numbers 4 bytes | fingerprints templates information 12 bytes | 1-4 fingerprint template data

but i couldn't reverse the decoding. 🙃

vodvud commented 5 years ago

So data structure like this

4th Bytes | [ 1-2bytes (fingerprint 1 template length), 3rd bytes (fingerprint index) ], [ 4-6... .. ] | The user numbers 4 bytes | fingerprints templates information 12 bytes | 1-4 fingerprint template data

where we have user numbers 4 bytes - $uid

WebFikirleri commented 5 years ago

I couldn't get, sorry. Mifare number is 10 digit (which leading zeroes) Code must be like this (i guess)

    public function setMIFARE(ZKLib $self, $uid, $cardno) {
        $command = Util::CMD_WRITE_MIFARE;
        $byte1 = chr((int)($uid % 256));
        $byte2 = chr((int)($uid >> 8));
        $command_string = implode('', [
            $byte1,
            $byte2,
            str_pad($cardno, 10, chr(0))
        ]);

        return $self->_command($command, $command_string);
    }

could you please express me like expressing to idiot please. I'm not good at bytes. There must be 1 card number, not much than 1.

vodvud commented 5 years ago

Hi! For leading zeros you should use the option STR_PAD_LEFT, for example:

str_pad($cardno, 10, chr(0), STR_PAD_LEFT)

Also for CMD_WRITE_MIFARE I see difference command string structure.

ZK communication protocol manual (page 14)

May refer to the following structure.

4th Bytes | [ 1-2bytes (fingerprint 1 template length), 3rd bytes (fingerprint index) ], [ 4-6... .. ] | The user numbers 4 bytes | fingerprints templates information 12 bytes | 1-4 fingerprint template data

but in your code just

4th Bytes | fingerprints templates information 12 bytes

tehceen commented 5 years ago

Hi sir i am using carlosang2's libarary https://github.com/carlosang2/ZKLibrary This library is modifies for TCP protocol.all functionalities are same the except the Rfid read and write. Can you please add these functionalists thanks

vodvud commented 5 years ago

@Tehsseen Thank you, I will check this library and write you back.

vodvud commented 5 years ago

@Tehsseen Thank you for your link, I checked already that library. But I didn't see the function for write RFID, also writing fingerprint didn't working.

hasanbayrakci commented 4 years ago

I couldn't get, sorry. Mifare number is 10 digit (which leading zeroes) Code must be like this (i guess)

    public function setMIFARE(ZKLib $self, $uid, $cardno) {
      $command = Util::CMD_WRITE_MIFARE;
      $byte1 = chr((int)($uid % 256));
        $byte2 = chr((int)($uid >> 8));
        $command_string = implode('', [
            $byte1,
            $byte2,
            str_pad($cardno, 10, chr(0))
        ]);

        return $self->_command($command, $command_string);
    }

could you please express me like expressing to idiot please. I'm not good at bytes. There must be 1 card number, not much than 1.

Hi Murat,

Have you been able to come up with a solution?

Mahfuz2811 commented 4 years ago

I am able to solve this issue.

   $cardno = hex2bin(Util::reverseHex(dechex("1254107"))); //add card number

    $command_string = $byte1.$byte2.chr($role).str_pad($password, 8, chr(0)).str_pad($name, 24, chr(0)).str_pad($cardno, 4, chr(0)).str_pad(chr(1), 9, chr(0)).str_pad($userid, 8, chr(0)).str_repeat(chr(0),16);
hasanbayrakci commented 4 years ago

Hi Mahfuz, thanks for solution...

vodvud commented 4 years ago

@Mahfuz2811 Thank you for solution, it works properly.

Changes added in commit e277b4bbe3bc93d11d2aacb773bf188770d78fd8