├── LICENSE.txt ├── README.md ├── deleting_user.php ├── storing_user.php ├── test.php ├── test2.php ├── test3.php ├── zk.sql └── zklibrary.php /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZKLibrary 2 | ZKLibrary is PHP Library for ZK Time & Attendance Devices. This library is design to reading and writing data to attendance device (fingerprint, face recognition or RFID) using UDP and TCP protocol. This library is useful to comunicate between web server and attendance device directly without any addition program. This library is implemented in the form of class. So that you can create an object and use it functions. 3 | 4 | Web server must be connected to the attendance device via Local Area Network (LAN). The UDP port that is used in this communication is 4370. You can not change this port without changing firmware of the attendance device. So, you just use it. 5 | For model K14 TCP port 4370 is used. 6 | 7 | The format of the data are: binary, string, and number. The length of the parameter and return value must be vary. 8 | 9 | ## Example 10 | ```php 11 | connect(); 15 | $zk->disableDevice(); 16 | $zk->testVoice(); 17 | $zk->enableDevice(); 18 | $zk->disconnect(); 19 | ?> 20 | ``` 21 | 22 | 23 | --- 24 | 25 | 26 | ## Data Structrure 27 | ```php 28 | Class ZKLibrary{ 29 | String ip; 30 | Unsigned Short port; 31 | Unsigned Long socket; 32 | Unigned Long session_id; 33 | String received_data; 34 | String user_data[][]; 35 | String attendance_data[][]; 36 | Unsigned Long timeout_sec; 37 | Unsigned Long timeout_usec; 38 | } 39 | ``` 40 | ## Functions 41 | ```php 42 | __construct([$ip[, $port[, $protocol]]]) 43 | ``` 44 | Object constructor. 45 | ### Parameters 46 | $ip 47 | 48 | IP address of device. 49 | 50 | $port 51 | 52 | UDP or TCP port of device. 53 | 54 | $protocol 55 | 56 | 'UDP' or 'TCP'. 57 | 58 | ```php 59 | __destruct() 60 | ``` 61 | Object destructor. 62 | 63 | ```php 64 | connect([$ip[, $port[, $protocol]]]) 65 | ``` 66 | Function to make a connection to the device. If IP address and port is not defined yet, this function must take it. Else, this function return FALSE and does not make any connection. 67 | ### Parameters 68 | $ip 69 | 70 | IP address of the device. 71 | 72 | $port 73 | 74 | UDP or TCP port of device. 75 | 76 | $protocol 77 | 78 | 'UDP' or 'TCP'. 79 | 80 | ```php 81 | disconnect() 82 | ``` 83 | Function to disconnect from the device. If ip address and port is not defined yet, this function must take it. Else, this function return FALSE and does not make any changes. 84 | ```php 85 | setTimeout([$sec[, $usec]]) 86 | ``` 87 | Set timeout for socket connection. 88 | ### Parameters 89 | $sec 90 | 91 | Timeout in second. 92 | 93 | $usec 94 | 95 | Timeout in micro second. 96 | ```php 97 | reverseHex($input) 98 | ``` 99 | Reverse hexadecimal digits. 100 | ```php 101 | encodeTime($time) 102 | ``` 103 | Encode time to binary data. 104 | ### Paramaters 105 | $time 106 | 107 | String time in format YYYY-MM-DD HH:II:SS 108 | ### Return Value 109 | Encoded time in binary format. 110 | 111 | ```php 112 | decodeTime($data) 113 | ``` 114 | Decode binary data to time. 115 | ### Parameters 116 | $data 117 | 118 | Binary data from device. 119 | ### Return Value 120 | Dedoded time in string format. 121 | 122 | ```php 123 | checkSum($p) 124 | ``` 125 | This function calculates the chksum of the packet to be sent to the time clock. 126 | ### Parameters 127 | $p 128 | 129 | Packet to be checked. 130 | ```php 131 | createHeader($command, $chksum, $session_id, $reply_id, $command_string) 132 | ``` 133 | Create data header to be sent to the device. 134 | ### Parameters 135 | $command 136 | 137 | Command to the device in integer. 138 | ### Return Value 139 | Data header in binary format. 140 | 141 | ```php 142 | $checksum 143 | ``` 144 | Checksum of packet. 145 | 146 | $session_id 147 | 148 | Session ID of the connection. 149 | 150 | $command_string 151 | 152 | Data to be sent to the device. 153 | ### Return Value 154 | Sum of data to be checked. 155 | ```php 156 | checkValid($reply) 157 | ``` 158 | Check wether reply is valid or not. 159 | ### Parameters 160 | $reply 161 | 162 | Reply data to be checked. 163 | ```php 164 | execCommand($command, $command_string = '', $offset_data = 8) 165 | ``` 166 | Send command and data packet to the device and receive some data if any. 167 | ### Parameters 168 | $command 169 | 170 | Command to the device in integer. 171 | 172 | $command_string 173 | 174 | Data to be sent to the device. 175 | 176 | $offset_data 177 | 178 | Offset data to be returned. The default offset is 8. 179 | ```php 180 | getSizeUser() 181 | ``` 182 | Get number of user. 183 | ### Return Value 184 | Number of registered user in the device. 185 | ```php 186 | getSizeAttendance() 187 | ``` 188 | Get number of attendance log. 189 | ### Return Value 190 | Number of attendance recorded in the device. 191 | ```php 192 | restartDevice() 193 | ``` 194 | Restart the device. 195 | ```php 196 | shutdownDevice() 197 | ``` 198 | Shutdown the device. 199 | ```php 200 | sleepDevice() 201 | ``` 202 | Sleep the device. 203 | ```php 204 | resumeDevice() 205 | ``` 206 | Resume the device. 207 | ```php 208 | changeSpeed($speed = 0) 209 | ``` 210 | Change transfer speed of the device. 0 = slower. 1 = faster. 211 | ### Parameters 212 | $speed 213 | 214 | Transfer speed of packet when the device comunicate to other device, i.e server. 215 | 216 | Note: some device may be not supported fast speed. 217 | ```php 218 | writeLCD($rank, $text) 219 | ``` 220 | Write text on LCD. This order transmit character to demonstrate on LCD, the data part 1, 2 bytes of the packet transmit the rank value which start to demonstrate, the 3rd byte setting is 0 , follows close the filling character which want to be transmit. May work in CMD_CLEAR_LCD when use this function. 221 | ### Parameters 222 | $rank 223 | 224 | Line number. 225 | 226 | $text 227 | 228 | Text to be demonstrated to LCD of the device. 229 | ```php 230 | clearLCD() 231 | ``` 232 | Clear text from LCD. 233 | ```php 234 | testVoice() 235 | ``` 236 | Test voice of the device. 237 | ```php 238 | getVersion() 239 | ``` 240 | Get device version. 241 | ### Return Value 242 | Version of the device in string format. 243 | ```php 244 | getOSVersion($net = true) 245 | ``` 246 | Get OS version. 247 | ### Parameters 248 | $net 249 | 250 | If net set to true, function will return netto data without parameter name. 251 | ```php 252 | setOSVersion($osVersion) 253 | ``` 254 | Set OS version 255 | ### Parameters 256 | $osVersion 257 | 258 | Version of operating version. 259 | ```php 260 | getPlatform($net = true) 261 | ``` 262 | Get OS version. 263 | ### Parameters 264 | $net 265 | If net set to true, function will return netto data without parameter name. 266 | ```php 267 | setPlatform($patform) 268 | ``` 269 | Set platform. 270 | ### Parameters 271 | $platform 272 | 273 | Platform name. 274 | ```php 275 | getFirmwareVersion($net = true) 276 | ``` 277 | Get firmware version. 278 | ### Parameters 279 | $net 280 | 281 | If net set to true, function will return netto data without parameter name. 282 | ```php 283 | setFirmwareVersion ($firmwareVersion) 284 | ``` 285 | Set firmware version. 286 | ### Parameters 287 | $firmwareVersion 288 | 289 | The version of firmware. 290 | ```php 291 | getWorkCode($net = true) 292 | ``` 293 | Get work code. 294 | ### Parameters 295 | $net 296 | If net set to true, function will return netto data without parameter name. 297 | ```php 298 | setWorkCode($workCode) 299 | ``` 300 | Set work code. 301 | ### Parameters 302 | $workCode 303 | 304 | Work code. 305 | 306 | ```php 307 | getSSR($net = true) 308 | ``` 309 | Get SSR 310 | ### Parameters 311 | $net 312 | 313 | If net set to true, function will return netto data without parameter name. 314 | ```php 315 | setSSR($ssr) 316 | ``` 317 | Set SSR. 318 | ### Parameters 319 | $ssr 320 | 321 | SSR. 322 | ```php 323 | getPinWidth($net = true) 324 | ``` 325 | Get pin width. 326 | ### Parameters 327 | $net 328 | 329 | If net set to true, function will return netto data without parameter name. 330 | ```php 331 | setPinWidth($pinWidth) 332 | ``` 333 | Set pin width. 334 | ### Parameters 335 | $pinWidth 336 | 337 | Pin width 338 | ```php 339 | getFaceFunctionOn($net = true) 340 | ``` 341 | Check wether face detection function is available or not. 342 | ### Parameters 343 | $net 344 | 345 | If net set to true, function will return netto data without parameter name. 346 | ```php 347 | setFaceFunctionOn ($faceFunction) 348 | ``` 349 | Set wether face detection function is available or not. 350 | ### Parameters 351 | $faceFunction 352 | 353 | Face function. 1 = available; 2 = not available. 354 | ```php 355 | getSerialNumber($net = true) 356 | ``` 357 | get serial number of the device. 358 | ### Parameters 359 | $net 360 | 361 | If net set to true, function will return netto data without parameter name. 362 | ```php 363 | setSerialNumber($serialNumber) 364 | ``` 365 | Set serial number of the device. 366 | ### Parameters 367 | $serialNumber 368 | 369 | Serial number of the device. 370 | ```php 371 | getDeviceName($net = true) 372 | ``` 373 | Get device name. 374 | ### Parameters 375 | $net 376 | 377 | If net set to true, function will return netto data without parameter name. 378 | ```php 379 | setDeviceName($deviceName) 380 | ``` 381 | Set device name. 382 | ### Parameters 383 | $deviceName 384 | 385 | The device name. 386 | ```php 387 | getTime() 388 | ``` 389 | Get time of device from real time clock (RTC). The time resolution is one minute. 390 | ### Return Value 391 | getTime return time as string with format YYYY-MM-DD HH:II:SS. 392 | ```php 393 | setTime($t) 394 | ``` 395 | Set time of the device. 396 | ### Parameters 397 | Time to be set with format YYYY-MM-DD HH:II:SS. 398 | ```php 399 | enableDevice() 400 | ``` 401 | Ensure the machine to be at in the normal work condition, generally when data communication shields the machine auxiliary equipment (keyboard, LCD, sensor), this order restores the auxiliary equipment to be at the normal work condition. 402 | ```php 403 | disableDevice() 404 | ``` 405 | Shield machine periphery keyboard, LCD, sensor, if perform successfully, there are showing “working” on LCD. 406 | ```php 407 | enableClock() 408 | ``` 409 | Set the LCD dot (to glitter ‘:’) the packet data part transmit 0 to stop glittering, 1 start to glitter. After this order carries out successfully, the firmware will refresh LCD. 410 | ```php 411 | getUser() 412 | ``` 413 | Retrive the user list from the device. 414 | ### Return Value 415 | getUser return array 2 dimension. The key of array is serial number of user. The value of array is array containing: 416 | * serial number of the user 417 | * user name 418 | * user role 419 | * user password 420 | ```php 421 | setUser($uid, $userid, $name, $password, $role) 422 | ``` 423 | Write user to the device. 424 | ### Parameters 425 | $uid 426 | 427 | Serial number of the user. This is the unsigned short number (2 bytes). 428 | 429 | $userid 430 | 431 | User ID of the application. The maximum length of $userid is 8 characters containing numeric whithout zero on the beginning. 432 | 433 | $name 434 | 435 | User name. The maximum length of $name is 28 characters containing alpha numeic and some (not all) punctuation. 436 | 437 | $role 438 | 439 | The role of user. The length of $role is 1 byte. Possible value of $role are: 440 | ``` 441 | 0 = LEVEL_USER 442 | 2 = LEVEL_ENROLLER 443 | 12 = LEVEL_MANAGER 444 | 14 = LEVEL_SUPERMANAGER 445 | ``` 446 | 447 | ```php 448 | setUserTemplate($template) 449 | ``` 450 | 451 | Upload finger print template to the device. 452 | The precondition to successfully upload the fingerprint template which is, the user must exist, the user, whose the fingerprint will be uploaded, must be empty. 453 | 454 | ### Parameter 455 | 456 | $template 457 | 458 | $template is binary data which the structure is shown bellow: 459 | 460 | ```c 461 | typedef struct _Template_{ 462 | U16 Size; // the length of fingerprint template 463 | U16 PIN; // corresponds with the user data structure PIN 464 | char FingerID; // fingerprint 465 | char Valid; // fingerprint is valid or invalid 466 | char *Template; // fingerprint template 467 | } TTemplate, *PTemplate; 468 | ``` 469 | 470 | ```php 471 | getUserTemplate($uid, $finger) 472 | ``` 473 | 474 | Get finger print data from the device. 475 | 476 | ### Parametes 477 | 478 | $uid 479 | 480 | Serial number of the user (2 bytes) 481 | 482 | $finger 483 | 484 | The finger on which the template will be taken (0-9). 485 | 486 | ### Return Value 487 | 488 | getUserTemplate will return an array contains: 489 | - length of template (2 bytes) 490 | - serial number of the user (2 bytes) 491 | - finger (1 byte, 0 to 9) 492 | - valid (1 byte) 493 | - template 494 | 495 | Template is binary data which the structure is shown bellow: 496 | 497 | ```c 498 | typedef struct _Template_{ 499 | U16 Size; // the length of fingerprint template 500 | U16 PIN; // corresponds with the user data structure PIN 501 | char FingerID; // fingerprint 502 | char Valid; // fingerprint is valid or invalid 503 | char *Template; // fingerprint template 504 | } TTemplate, *PTemplate; 505 | ``` 506 | 507 | ```php 508 | clearData() 509 | ``` 510 | Clear some kind of data, if do not assign the data type, then deletes all data, otherwise depending on the assigned type to delete data. 511 | ```php 512 | clearUser() 513 | ``` 514 | Same with clearData. 515 | ```php 516 | deleteUser($uid) 517 | ``` 518 | Delete some user from the device. 519 | ### Parameters 520 | $uid 521 | 522 | Serial number of the user (2 bytes). 523 | ```php 524 | deleteUserTemp($uid, $finger) 525 | ``` 526 | Delete finger template of the user from the device. 527 | ### Parameters 528 | $uid 529 | 530 | Serial number of the user (2 bytes). 531 | 532 | $finger 533 | 534 | The number of finger (0-9). 535 | ```php 536 | clearAdmin() 537 | ``` 538 | Delete all admin from the device. 539 | ```php 540 | getAttendance() 541 | ``` 542 | Retrieve the attendance log. 543 | ### Return Value 544 | getAttendance return array 2 dimension. The value of array is array containing. 545 | * serial number of the user 546 | * user id of the application 547 | * state 548 | * time of attendance in format YYYY-MM-DD HH:II:SS 549 | ```php 550 | clearAttendance() 551 | ``` 552 | Delete all attendance log from the device. 553 | -------------------------------------------------------------------------------- /deleting_user.php: -------------------------------------------------------------------------------- 1 | connect_error) { 14 | die("Connection failed: " . $conn->connect_error); 15 | } 16 | echo 'connected
'; 17 | 18 | 19 | //----------------------------- 20 | //The socket functions described here are part of an extension to PHP which must be enabled at compile time by giving the --enable-sockets option to configure. 21 | //Add extension=php_sockets.dll in php.ini and remove ; from extension=sockets statement 22 | include "zklibrary.php"; 23 | //Library Loaded 24 | $zk = new ZKLibrary('192.168.0.103', 4370, 'TCP'); 25 | //Requesting for connection 26 | $zk->connect(); 27 | //Connected 28 | $zk->disableDevice(); 29 | //disabling device 30 | echo '
All Set

'; 31 | 32 | if(isset($_REQUEST['delete_user'])) 33 | { 34 | $user_id=$_REQUEST['user_id']; 35 | $sql = "SELECT * FROM user where user_id='$user_id'"; 36 | $result = mysqli_query($conn, $sql); 37 | if (mysqli_num_rows($result) == 1) { 38 | $zk->deleteUser($user_id); //Give the user_id no 39 | $sql2="delete from user where user_id='$user_id' "; 40 | mysqli_query($conn,$sql2); 41 | $sql3="delete from user_template where uid='$user_id' "; 42 | mysqli_query($conn,$sql3); 43 | } 44 | echo 'Deleted Successfully.'; 45 | } 46 | 47 | ?> 48 | 49 |

50 |
51 | Delete a user by selecting user ID:
52 | getUser(); 54 | foreach($users as $key=>$user) 55 | { 56 | $user_id=$user[0]; 57 | $name=$user[1]; 58 | 59 | ?> 60 |
61 | 64 |
65 | 66 |
67 | 68 | 69 | enableDevice(); 74 | $zk->disconnect(); 75 | ?> -------------------------------------------------------------------------------- /storing_user.php: -------------------------------------------------------------------------------- 1 | connect_error) { 14 | die("Connection failed: " . $conn->connect_error); 15 | } 16 | if (!mysqli_set_charset($conn, "utf8")) { 17 | printf("Error loading character set utf8: %s\n", mysqli_error($conn)); 18 | exit(); 19 | } else { 20 | printf("Current character set: %s\n", mysqli_character_set_name($conn)); 21 | } 22 | echo 'connected'; 23 | 24 | 25 | //----------------------------- 26 | //The socket functions described here are part of an extension to PHP which must be enabled at compile time by giving the --enable-sockets option to configure. 27 | //Add extension=php_sockets.dll in php.ini and remove ; from extension=sockets statement 28 | include "zklibrary.php"; 29 | //Library Loaded 30 | $zk = new ZKLibrary('192.168.0.103', 4370, 'TCP'); 31 | //Requesting for connection 32 | $zk->connect(); 33 | //Connected 34 | $zk->disableDevice(); 35 | //disabling device 36 | echo '
All Set
'; 37 | 38 | $users = $zk->getUser(); 39 | foreach($users as $key=>$user) 40 | { 41 | $uid=$key; 42 | $user_id=$user[0]; 43 | $name=$user[1]; 44 | $role=$user[2]; 45 | $password=$user[3]; 46 | echo $user_id.' --- '; 47 | $sql = "SELECT * FROM user where uid='$uid' and user_id='$user_id' and name='$name' and role='$role' and password='$password' "; 48 | $result = mysqli_query($conn, $sql); 49 | if (mysqli_num_rows($result) == 0) { //new id 50 | 51 | $sql2="insert into user values('$uid','$user_id','$name','$role','$password')"; 52 | mysqli_query($conn,$sql2); 53 | } 54 | } 55 | echo '
User stored
'; 56 | 57 | //Getting all the users template(fingerprint) data 58 | foreach($users as $key=>$user) 59 | { 60 | $user_id=$user[0]; 61 | $finger_id=6; //by default 62 | $sql = "SELECT * FROM user where user_id='$user_id' "; 63 | $result = mysqli_query($conn, $sql); 64 | if (mysqli_num_rows($result) == 1) { //ID exists in user table 65 | 66 | $sql2 = "SELECT * FROM user_template where uid='$user_id' and fno='$finger_id' "; 67 | $result2 = mysqli_query($conn, $sql2); 68 | if (mysqli_num_rows($result2) == 0) { //New Finger ID 69 | $f = $zk->getUserTemplate($user_id,$finger_id); //user id and finger print no(by defaut 6) 70 | $fp_length=$f[0]; 71 | $valid=$f[3]; 72 | $template=$f[4]; 73 | 74 | echo $fp_length.' ---- '.$user_id.' ---- '.$finger_id.' --- '.$valid.'
'; 75 | 76 | 77 | $stmt = $conn->prepare("INSERT INTO user_template (fp_length,uid,fno,valid,template) VALUES('$fp_length','$user_id','$finger_id','$valid',?)"); 78 | $null = NULL; 79 | $stmt->bind_param("b", $null); 80 | $stmt->send_long_data(0, $template); 81 | $stmt->execute(); 82 | 83 | } 84 | } 85 | } 86 | echo '
Fingerprint stored
'; 87 | 88 | $zk->enableDevice(); 89 | $zk->disconnect(); 90 | ?> -------------------------------------------------------------------------------- /test.php: -------------------------------------------------------------------------------- 1 | '; 9 | $zk = new ZKLibrary('192.168.0.103', 4370, 'TCP'); 10 | echo 'Requesting for connection
'; 11 | $zk->connect(); 12 | echo 'Connected
'; 13 | $zk->disableDevice(); 14 | echo 'disabling device
'; 15 | $users = $zk->getUser(); 16 | 17 | 18 | $attendace = $zk->getAttendance(); 19 | ?> 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | $user) 36 | { 37 | $no++; 38 | ?> 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 52 | 53 | 54 |
NoUIDIDNameRolePassword
55 |

56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | $at) 71 | { 72 | $no++; 73 | ?> 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 |
NoUIDIDStateDate/Time
89 | deleteUser(2); 92 | 93 | //$zk->clearAttendance(); 94 | //setUser($uid, $userid, $name, $password, $role) 95 | //Reading fingerprint data 96 | //for($i=0;$i<=9;$i++){ 97 | //$f = $zk->getUserTemplate(1,6); echo '
-----'; print_r($f); echo '
'; 98 | /* 99 | echo 'FP length: '.$f[0].'
'; 100 | echo 'UID: '.$f[1].'
'; 101 | echo 'Finger ID: '.$f[2].'
'; 102 | echo 'Valid: '.$f[3].'
'; 103 | echo 'template: '.$f[4].'
'; 104 | */ 105 | 106 | $zk->enableDevice(); 107 | $zk->disconnect(); 108 | 109 | ?> 110 | -------------------------------------------------------------------------------- /test2.php: -------------------------------------------------------------------------------- 1 | '; 5 | $zk = new ZKLibrary('192.168.0.103', 4370, 'TCP'); 6 | echo 'Requesting for connection
'; 7 | $zk->connect(); 8 | echo 'Connected
'; 9 | $zk->disableDevice(); 10 | echo 'disabling device
'; 11 | 12 | //$zk->deleteUser(1); 13 | 14 | //Set new user or update 15 | //super admin 14 16 | //normal user 0 17 | //$zk->setUser(2,2,'Ahmed Ali','0000',0); 18 | //echo 'Setting user with new data'; 19 | 20 | $zk->setUser(2,2,'Karim Ali','0000',0); 21 | echo 'Setting user with new data'; 22 | 23 | $zk->enableDevice(); 24 | $zk->disconnect(); 25 | ?> -------------------------------------------------------------------------------- /test3.php: -------------------------------------------------------------------------------- 1 | connect_error) { 12 | die("Connection failed: " . $conn->connect_error); 13 | } 14 | if (!mysqli_set_charset($conn, "utf8")) { 15 | printf("Error loading character set utf8: %s\n", mysqli_error($conn)); 16 | exit(); 17 | } else { 18 | printf("Current character set: %s\n", mysqli_character_set_name($conn)); 19 | } 20 | echo 'connected'; 21 | 22 | 23 | //----------------------------- 24 | //The socket functions described here are part of an extension to PHP which must be enabled at compile time by giving the --enable-sockets option to configure. 25 | //Add extension=php_sockets.dll in php.ini and remove ; from extension=sockets statement 26 | include "zklibrary.php"; 27 | //Library Loaded 28 | $zk = new ZKLibrary('192.168.0.103', 4370, 'TCP'); 29 | //Requesting for connection 30 | $zk->connect(); 31 | //Connected 32 | $zk->disableDevice(); 33 | //disabling device 34 | echo '
All Set
'; 35 | 36 | $sql = "SELECT * FROM user_template where uid='2'"; 37 | $result = mysqli_query($conn, $sql); 38 | $arr=mysqli_fetch_array($result); 39 | $x=$arr[0].$arr[1].$arr[2].$arr[3].$arr[4]; 40 | $zk->setUserTemplate($x,2); 41 | 42 | 43 | $zk->enableDevice(); 44 | $zk->disconnect(); 45 | ?> 46 | -------------------------------------------------------------------------------- /zk.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.9.1 3 | -- https://www.phpmyadmin.net/ 4 | -- 5 | -- Host: 127.0.0.1 6 | -- Generation Time: Dec 09, 2019 at 07:59 PM 7 | -- Server version: 10.4.8-MariaDB 8 | -- PHP Version: 7.3.11 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | SET AUTOCOMMIT = 0; 12 | START TRANSACTION; 13 | SET time_zone = "+00:00"; 14 | 15 | 16 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 17 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 18 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 19 | /*!40101 SET NAMES utf8mb4 */; 20 | 21 | -- 22 | -- Database: `zk` 23 | -- 24 | 25 | -- -------------------------------------------------------- 26 | 27 | -- 28 | -- Table structure for table `user` 29 | -- 30 | 31 | CREATE TABLE `user` ( 32 | `uid` int(11) NOT NULL, 33 | `user_id` int(11) NOT NULL, 34 | `name` varchar(200) NOT NULL, 35 | `role` int(11) NOT NULL, 36 | `password` varchar(100) NOT NULL 37 | ) ENGINE=InnoDB DEFAULT CHARSET=utf32; 38 | 39 | -- -------------------------------------------------------- 40 | 41 | -- 42 | -- Table structure for table `user_template` 43 | -- 44 | 45 | CREATE TABLE `user_template` ( 46 | `fp_length` int(11) NOT NULL, 47 | `uid` int(11) NOT NULL, 48 | `fno` int(11) NOT NULL, 49 | `valid` int(11) NOT NULL, 50 | `template` blob NOT NULL 51 | ) ENGINE=InnoDB DEFAULT CHARSET=utf32; 52 | 53 | -- 54 | -- Indexes for dumped tables 55 | -- 56 | 57 | -- 58 | -- Indexes for table `user` 59 | -- 60 | ALTER TABLE `user` 61 | ADD PRIMARY KEY (`user_id`); 62 | 63 | -- 64 | -- Indexes for table `user_template` 65 | -- 66 | ALTER TABLE `user_template` 67 | ADD PRIMARY KEY (`uid`,`fno`); 68 | COMMIT; 69 | 70 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 71 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 72 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 73 | -------------------------------------------------------------------------------- /zklibrary.php: -------------------------------------------------------------------------------- 1 | ip = $ip; 71 | } 72 | if($port != null) 73 | { 74 | $this->port = $port; 75 | } 76 | $this->protocol = $protocol; 77 | if ($protocol == 'TCP') { 78 | $this->start_data = 8; 79 | $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 80 | //$this->setTimeout($this->sec, $this->usec); 81 | socket_connect($this->socket, $ip, $port); 82 | } 83 | else { 84 | $this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 85 | $this->setTimeout($this->sec, $this->usec); 86 | } 87 | } 88 | public function __destruct() 89 | { 90 | unset($this->received_data); 91 | unset($this->user_data); 92 | unset($this->attendance_data); 93 | } 94 | public function send($buf) { 95 | if ($this->protocol == 'TCP') { 96 | socket_write($this->socket, $buf, strlen($buf)); 97 | } 98 | else { 99 | socket_sendto($this->socket, $buf, strlen($buf), 0, $this->ip, $this->port); 100 | } 101 | } 102 | public function recv($length = 1024) { 103 | $data = ''; 104 | if ($this->protocol == 'TCP') { 105 | $data = socket_read($this->socket, $length); 106 | } 107 | else { 108 | socket_recvfrom($this->socket, $data, $length, 0, $this->ip, $this->port); 109 | } 110 | return $data; 111 | } 112 | public function connect($ip = null, $port = 4370) 113 | { 114 | if($ip != null) 115 | { 116 | $this->ip = $ip; 117 | } 118 | if($port != null) 119 | { 120 | $this->port = $port; 121 | } 122 | if($this->ip == null || $this->port == null) 123 | { 124 | return false; 125 | } 126 | $command = CMD_CONNECT; 127 | $command_string = ''; 128 | $chksum = 0; 129 | $session_id = 0; 130 | $reply_id = -1 + USHRT_MAX; 131 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 132 | $this->send($buf); 133 | try 134 | { 135 | $this->received_data = $this->recv(); 136 | if(strlen($this->received_data)>0) 137 | { 138 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6', substr($this->received_data, $this->start_data, 8)); 139 | $this->session_id = hexdec($u['h6'].$u['h5']); 140 | return $this->checkValid($this->received_data); 141 | } 142 | else 143 | { 144 | return FALSE; 145 | } 146 | } 147 | catch(ErrorException $e) 148 | { 149 | return FALSE; 150 | } 151 | catch(exception $e) 152 | { 153 | return FALSE; 154 | } 155 | } 156 | public function disconnect() 157 | { 158 | if($this->ip == null || $this->port == null) 159 | { 160 | return false; 161 | } 162 | $command = CMD_EXIT; 163 | $command_string = ''; 164 | $chksum = 0; 165 | $session_id = $this->session_id; 166 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 167 | $reply_id = hexdec( $u['h8'].$u['h7'] ); 168 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 169 | $this->send($buf); 170 | try 171 | { 172 | $this->received_data = $this->recv(); 173 | return $this->checkValid($this->received_data); 174 | } 175 | catch(ErrorException $e) 176 | { 177 | return FALSE; 178 | } 179 | catch(Exception $e) 180 | { 181 | return FALSE; 182 | } 183 | } 184 | public function setTimeout($sec = 0, $usec = 0) 185 | { 186 | if($sec != 0) 187 | { 188 | $this->timeout_sec = $sec; 189 | } 190 | if($usec != 0) 191 | { 192 | $this->timeout_usec = $usec; 193 | } 194 | $timeout = array('sec'=>$this->timeout_sec, 'usec'=>$this->timeout_usec); 195 | socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, $timeout); 196 | } 197 | public function ping($timeout = 1) 198 | { 199 | $time1 = microtime(true); 200 | $pfile = fsockopen($this->ip, $this->port, $errno, $errstr, $timeout); 201 | if(!$pfile) 202 | { 203 | return 'down'; 204 | } 205 | $time2 = microtime(true); 206 | fclose($pfile); 207 | return round((($time2 - $time1) * 1000), 0); 208 | } 209 | private function reverseHex($input) 210 | { 211 | $output = ''; 212 | for($i=strlen($input); $i>=0; $i--) 213 | { 214 | $output .= substr($input, $i, 2); 215 | $i--; 216 | } 217 | return $output; 218 | } 219 | private function encodeTime($time) 220 | { 221 | $str = str_replace(array(":", " "), array("-", "-"), $time); 222 | $arr = explode("-", $str); 223 | $year = @$arr[0]*1; 224 | $month = ltrim(@$arr[1], '0')*1; 225 | $day = ltrim(@$arr[2], '0')*1; 226 | $hour = ltrim(@$arr[3], '0')*1; 227 | $minute = ltrim(@$arr[4], '0')*1; 228 | $second = ltrim(@$arr[5], '0')*1; 229 | $data = (($year % 100) * 12 * 31 + (($month - 1) * 31) + $day - 1) * (24 * 60 * 60) + ($hour * 60 + $minute) * 60 + $second; 230 | return $data; 231 | } 232 | private function decodeTime($data) 233 | { 234 | $second = $data % 60; 235 | $data = $data / 60; 236 | $minute = $data % 60; 237 | $data = $data / 60; 238 | $hour = $data % 24; 239 | $data = $data / 24; 240 | $day = $data % 31+1; 241 | $data = $data / 31; 242 | $month = $data % 12+1; 243 | $data = $data / 12; 244 | $year = floor( $data + 2000 ); 245 | $d = date("Y-m-d H:i:s", strtotime($year.'-'.$month.'-'.$day.' '.$hour.':'.$minute.':'.$second)); 246 | return $d; 247 | 248 | } 249 | private function checkSum($p) 250 | { 251 | /* This function calculates the chksum of the packet to be sent to the time clock */ 252 | $l = count($p); 253 | $chksum = 0; 254 | $i = $l; 255 | $j = 1; 256 | while($i > 1) 257 | { 258 | $u = unpack('S', pack('C2', $p['c'.$j], $p['c'.($j+1)])); 259 | $chksum += $u[1]; 260 | if($chksum > USHRT_MAX) 261 | { 262 | $chksum -= USHRT_MAX; 263 | } 264 | $i-=2; 265 | $j+=2; 266 | } 267 | if($i) 268 | { 269 | $chksum = $chksum + $p['c'.strval(count($p))]; 270 | } 271 | while ($chksum > USHRT_MAX) 272 | { 273 | $chksum -= USHRT_MAX; 274 | } 275 | if ( $chksum > 0 ) 276 | { 277 | $chksum = -($chksum); 278 | } 279 | else 280 | { 281 | $chksum = abs($chksum); 282 | } 283 | $chksum -= 1; 284 | while ($chksum < 0) 285 | { 286 | $chksum += USHRT_MAX; 287 | } 288 | return pack('S', $chksum); 289 | } 290 | function createHeader($command, $chksum, $session_id, $reply_id, $command_string) 291 | { 292 | $buf = pack('SSSS', $command, $chksum, $session_id, $reply_id).$command_string; 293 | $len = strlen($buf); 294 | $buf = unpack('C'.(8+strlen($command_string)).'c', $buf); 295 | $u = unpack('S', $this->checkSum($buf)); 296 | if(is_array($u)) 297 | { 298 | while(list($key) = each($u)) 299 | { 300 | $u = $u[$key]; 301 | break; 302 | } 303 | } 304 | $chksum = $u; 305 | $reply_id += 1; 306 | if($reply_id >= USHRT_MAX) 307 | { 308 | $reply_id -= USHRT_MAX; 309 | } 310 | if ($this->protocol == 'TCP') { 311 | $buf = pack('SSLSSSS', 20560, 32130, $len, $command, $chksum, $session_id, $reply_id); 312 | } 313 | else { 314 | $buf = pack('SSSS', $command, $chksum, $session_id, $reply_id); 315 | } 316 | return $buf.$command_string; 317 | } 318 | private function checkValid($reply) 319 | { 320 | $u = unpack('H2h1/H2h2', substr($reply, $this->start_data, 8)); 321 | $command = hexdec( $u['h2'].$u['h1'] ); 322 | if ($command == CMD_ACK_OK) 323 | { 324 | return TRUE; 325 | } 326 | else 327 | { 328 | return FALSE; 329 | } 330 | } 331 | function execCommand($command, $command_string = '', $offset_data = 8) 332 | { 333 | $chksum = 0; 334 | $offset_data += $this->start_data; 335 | $session_id = $this->session_id; 336 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr( $this->received_data, $this->start_data, 8) ); 337 | $reply_id = hexdec( $u['h8'].$u['h7'] ); 338 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 339 | $this->send($buf); 340 | try 341 | { 342 | $this->received_data = $this->recv(); 343 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6', substr( $this->received_data, $this->start_data, 8 ) ); 344 | $this->session_id = hexdec( $u['h6'].$u['h5'] ); 345 | return substr($this->received_data, $offset_data); 346 | } 347 | catch(ErrorException $e) 348 | { 349 | return FALSE; 350 | } 351 | catch(exception $e) 352 | { 353 | return FALSE; 354 | } 355 | } 356 | private function getSizeUser() 357 | { 358 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 359 | $command = hexdec($u['h2'].$u['h1']); 360 | if($command == CMD_PREPARE_DATA) 361 | { 362 | $u = unpack('H2h1/H2h2/H2h3/H2h4', substr($this->received_data, $this->start_data + 8, 4)); 363 | $size = hexdec($u['h4'].$u['h3'].$u['h2'].$u['h1']); 364 | return $size; 365 | } 366 | else 367 | { 368 | return FALSE; 369 | } 370 | } 371 | private function getSizeAttendance() 372 | { 373 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 374 | $command = hexdec($u['h2'].$u['h1'] ); 375 | if($command == CMD_PREPARE_DATA) 376 | { 377 | $u = unpack('H2h1/H2h2/H2h3/H2h4', substr( $this->received_data, $this->start_data + 8, 4)); 378 | $size = hexdec($u['h4'].$u['h3'].$u['h2'].$u['h1']); 379 | return $size; 380 | } 381 | else 382 | { 383 | return FALSE; 384 | } 385 | } 386 | private function getSizeTemplate() 387 | { 388 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 389 | $command = hexdec($u['h2'].$u['h1'] ); 390 | if($command == CMD_PREPARE_DATA) 391 | { 392 | $u = unpack('H2h1/H2h2/H2h3/H2h4', substr( $this->received_data, $this->start_data + 8, 4)); 393 | $size = hexdec($u['h4'].$u['h3'].$u['h2'].$u['h1']); 394 | return $size; 395 | } 396 | else 397 | { 398 | return FALSE; 399 | } 400 | } 401 | public function restartDevice() 402 | { 403 | $command = CMD_RESTART; 404 | $command_string = chr(0).chr(0); 405 | return $this->execCommand($command, $command_string); 406 | } 407 | public function shutdownDevice() 408 | { 409 | $command = CMD_POWEROFF; 410 | $command_string = chr(0).chr(0); 411 | return $this->execCommand($command, $command_string); 412 | } 413 | public function sleepDevice() 414 | { 415 | $command = CMD_SLEEP; 416 | $command_string = chr(0).chr(0); 417 | return $this->execCommand($command, $command_string); 418 | } 419 | public function resumeDevice() 420 | { 421 | $command = CMD_RESUME; 422 | $command_string = chr(0).chr(0); 423 | return $this->execCommand($command, $command_string); 424 | } 425 | public function changeSpeed($speed = 0) 426 | { 427 | if($speed != 0) 428 | { 429 | $speed = 1; 430 | } 431 | $command = CMD_CHANGE_SPEED; 432 | $byte = chr($speed); 433 | $command_string = $byte; 434 | return $this->execCommand($command, $command_string); 435 | } 436 | public function writeLCD($rank, $text) 437 | { 438 | $command = CMD_WRITE_LCD; 439 | $byte1 = chr((int)($rank % 256)); 440 | $byte2 = chr((int)($rank >> 8)); 441 | $byte3 = chr(0); 442 | $command_string = $byte1.$byte2.$byte3.' '.$text; 443 | return $this->execCommand($command, $command_string); 444 | } 445 | public function clearLCD() 446 | { 447 | $command = CMD_CLEAR_LCD; 448 | return $this->execCommand($command); 449 | } 450 | public function testVoice() 451 | { 452 | $command = CMD_TESTVOICE; 453 | $command_string = chr(0).chr(0); 454 | return $this->execCommand($command, $command_string); 455 | } 456 | public function getVersion() 457 | { 458 | $command = CMD_VERSION; 459 | return $this->execCommand($command); 460 | } 461 | public function getOSVersion($net = true) 462 | { 463 | $command = CMD_OPTIONS_RRQ; 464 | $command_string = '~OS'; 465 | $return = $this->execCommand($command, $command_string); 466 | if($net) 467 | { 468 | $arr = explode("=", $return, 2); 469 | return $arr[1]; 470 | } 471 | else 472 | { 473 | return $return; 474 | } 475 | } 476 | public function setOSVersion($osVersion) 477 | { 478 | $command = CMD_OPTIONS_WRQ; 479 | $command_string = '~OS='.$osVersion; 480 | return $this->execCommand($command, $command_string); 481 | } 482 | public function getPlatform($net = true) 483 | { 484 | $command = CMD_OPTIONS_RRQ; 485 | $command_string = '~Platform'; 486 | $return = $this->execCommand($command, $command_string); 487 | if($net) 488 | { 489 | $arr = explode("=", $return, 2); 490 | return $arr[1]; 491 | } 492 | else 493 | { 494 | return $return; 495 | } 496 | } 497 | public function setPlatform($patform) 498 | { 499 | $command = CMD_OPTIONS_RRQ; 500 | $command_string = '~Platform='.$patform; 501 | return $this->execCommand($command, $command_string); 502 | } 503 | public function getFirmwareVersion($net = true) 504 | { 505 | $command = CMD_OPTIONS_RRQ; 506 | $command_string = '~ZKFPVersion'; 507 | $return = $this->execCommand($command, $command_string); 508 | if($net) 509 | { 510 | $arr = explode("=", $return, 2); 511 | return $arr[1]; 512 | } 513 | else 514 | { 515 | return $return; 516 | } 517 | } 518 | public function setFirmwareVersion($firmwareVersion) 519 | { 520 | $command = CMD_OPTIONS_WRQ; 521 | $command_string = '~ZKFPVersion='.$firmwareVersion; 522 | return $this->execCommand($command, $command_string); 523 | } 524 | public function getWorkCode($net = true) 525 | { 526 | $command = CMD_OPTIONS_RRQ; 527 | $command_string = 'WorkCode'; 528 | $return = $this->execCommand($command, $command_string); 529 | if($net) 530 | { 531 | $arr = explode("=", $return, 2); 532 | return $arr[1]; 533 | } 534 | else 535 | { 536 | return $return; 537 | } 538 | } 539 | public function setWorkCode($workCode) 540 | { 541 | $command = CMD_OPTIONS_WRQ; 542 | $command_string = 'WorkCode='.$workCode; 543 | return $this->execCommand($command, $command_string); 544 | } 545 | public function getSSR($net = true) 546 | { 547 | $command = CMD_OPTIONS_PRQ; 548 | $command_string = '~SSR'; 549 | $return = $this->execCommand($command, $command_string); 550 | if($net) 551 | { 552 | $arr = explode("=", $return, 2); 553 | return $arr[1]; 554 | } 555 | else 556 | { 557 | return $return; 558 | } 559 | } 560 | public function setSSR($ssr) 561 | { 562 | $command = CMD_OPTIONS_WRQ; 563 | $command_string = '~SSR='.$ssr; 564 | return $this->execCommand($command, $command_string); 565 | } 566 | public function getPinWidth() 567 | { 568 | $command = CMD_GET_PINWIDTH; 569 | $command = CMD_OPTIONS_PRQ; 570 | $command_string = '~PIN2Width'; 571 | $return = $this->execCommand($command, $command_string); 572 | if($net) 573 | { 574 | $arr = explode("=", $return, 2); 575 | return $arr[1]; 576 | } 577 | else 578 | { 579 | return $return; 580 | } 581 | } 582 | public function setPinWidth($pinWidth) 583 | { 584 | $command = CMD_OPTIONS_WRQ; 585 | $command_string = '~PIN2Width='.$pinWidth; 586 | return $this->execCommand($command, $command_string); 587 | } 588 | public function getFaceFunctionOn($net = true) 589 | { 590 | $command = CMD_OPTIONS_RRQ; 591 | $command_string = 'FaceFunOn'; 592 | $return = $this->execCommand($command, $command_string); 593 | if($net) 594 | { 595 | $arr = explode("=", $return, 2); 596 | return $arr[1]; 597 | } 598 | else 599 | { 600 | return $return; 601 | } 602 | } 603 | public function setFaceFunctionOn($faceFunctionOn) 604 | { 605 | $command = CMD_OPTIONS_WRQ; 606 | $command_string = 'FaceFunOn='.$faceFunctionOn; 607 | return $this->execCommand($command, $command_string); 608 | } 609 | public function getSerialNumber($net = true) 610 | { 611 | $command = CMD_OPTIONS_RRQ; 612 | $command_string = '~SerialNumber'; 613 | $return = $this->execCommand($command, $command_string); 614 | if($net) 615 | { 616 | $arr = explode("=", $return, 2); 617 | return $arr[1]; 618 | } 619 | else 620 | { 621 | return $return; 622 | } 623 | } 624 | public function setSerialNumber($serialNumber) 625 | { 626 | $command = CMD_OPTIONS_WRQ; 627 | $command_string = '~SerialNumber='.$serialNumber; 628 | return $this->execCommand($command, $command_string); 629 | } 630 | public function getDeviceName($net = true) 631 | { 632 | $command = CMD_OPTIONS_RRQ; 633 | $command_string = '~DeviceName'; 634 | $return = $this->execCommand($command, $command_string); 635 | if($net) 636 | { 637 | $arr = explode("=", $return, 2); 638 | return $arr[1]; 639 | } 640 | else 641 | { 642 | return $return; 643 | } 644 | } 645 | public function setDeviceName($deviceName) 646 | { 647 | $command = CMD_OPTIONS_WRQ; 648 | $command_string = '~DeviceName='.$deviceName; 649 | return $this->execCommand($command, $command_string); 650 | } 651 | public function getTime() 652 | { 653 | // resolution = 1 minute 654 | $command = CMD_GET_TIME; 655 | return $this->decodeTime(hexdec($this->reverseHex(bin2hex($this->execCommand($command))))); 656 | } 657 | public function setTime($t) 658 | { 659 | // resolution = 1 second 660 | $command = CMD_SET_TIME; 661 | $command_string = pack('I', $this->encodeTime($t)); 662 | return $this->execCommand($command, $command_string); 663 | } 664 | public function enableDevice() 665 | { 666 | $command = CMD_ENABLEDEVICE; 667 | return $this->execCommand($command); 668 | } 669 | public function disableDevice() 670 | { 671 | $command = CMD_DISABLEDEVICE; 672 | $command_string = chr(0).chr(0); 673 | return $this->execCommand($command, $command_string); 674 | } 675 | public function enableClock($mode = 0) 676 | { 677 | $command = CMD_ENABLE_CLOCK; 678 | $command_string = chr($mode); 679 | return $this->execCommand($command, $command_string); 680 | } 681 | public function getSelectedUser($uid, $finger) 682 | { 683 | $command = CMD_USERTEMP_RRQ; 684 | $byte1 = chr((int)($uid % 256)); 685 | $byte2 = chr((int)($uid >> 8)); 686 | $command_string = $byte1.$byte2.chr($finger); 687 | return $this->execCommand($command, $command_string); 688 | } 689 | public function getUser() 690 | { 691 | if ($this->protocol == 'TCP') { 692 | $command = 1503; 693 | $command_string = pack('CCLLC', 1, 9, 1280, 0, 0); 694 | $chksum = 0; 695 | $session_id = $this->session_id; 696 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 697 | $ucs = unpack('H' . (strlen($command_string) * 2), substr($command_string, 0)); 698 | $udat = unpack('H' . (strlen($this->received_data) * 2), substr($this->received_data, 0)); 699 | $reply_id = hexdec($u['h8'] . $u['h7']); 700 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 701 | $this->send($buf); 702 | $this->received_data = $this->recv(); 703 | $udat = unpack('H' . (strlen($this->received_data) * 2), substr($this->received_data, 0)); 704 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 705 | $reply_id = hexdec($u['h8'] . $u['h7']); 706 | $comando = hexdec($u['h2'] . $u['h1']); 707 | 708 | if ($comando == CMD_ACK_OK) { 709 | $u = unpack('H2h1/H2h2', substr($this->received_data, 17, 2)); 710 | $size = hexdec($u['h2'] . $u['h1']); 711 | } else { 712 | $u = unpack('H2h1/H2h2', substr($this->received_data, 16, 2)); 713 | $size = hexdec($u['h2'] . $u['h1']); 714 | } 715 | 716 | if ($size > 1024) { 717 | $buf = $this->createHeader(1504, $chksum, $session_id, $reply_id, pack('LL', 0, $size)); 718 | $this->send($buf); 719 | } 720 | } 721 | else { 722 | $command = CMD_USERTEMP_RRQ; 723 | $command_string = chr(5); 724 | $chksum = 0; 725 | $session_id = $this->session_id; 726 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr( $this->received_data, $this->start_data, 8) ); 727 | $reply_id = hexdec( $u['h8'].$u['h7'] ); 728 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 729 | $this->send($buf); 730 | } 731 | 732 | try 733 | { 734 | if ($this->protocol == 'TCP') { 735 | if ($size > 1024) { 736 | $this->received_data = $this->recv(); 737 | $bytes = $size; 738 | $bytes2 = 0; 739 | $tembytes = $bytes; 740 | 741 | if ($bytes) { 742 | 743 | array_push($this->user_data, substr($this->received_data, 16)); 744 | $bytes -= strlen($this->received_data); 745 | 746 | while ($bytes > 0) { 747 | $received_data = $this->recv(); 748 | $bytes2 += strlen($received_data); 749 | $longitud = strlen($received_data); 750 | if ($bytes2 > 1024) { 751 | if (substr($received_data, 0, 2) == 'PP') { 752 | $received_data = substr($received_data, 16); 753 | $bytes2 -= 1024; 754 | } else { 755 | $received_data = substr($received_data, 0, $longitud - ($bytes2 - 1024)) . substr($received_data, $longitud - ($bytes2 - 1024) + 16); 756 | $bytes2 -= 1024; 757 | } 758 | } 759 | array_push($this->user_data, substr($received_data, 0)); 760 | $bytes -= strlen($received_data); 761 | 762 | if (strlen($received_data) == 0) { 763 | $bytes = 0; 764 | } 765 | } 766 | $this->session_id = hexdec($u['h6'] . $u['h5']); 767 | $received_data = $this->recv(); 768 | } 769 | 770 | array_push($this->user_data, substr($this->user_data, 0)); 771 | if (count($this->user_data) > 0) { 772 | $this->user_data[0] = substr($this->user_data[0], 8); 773 | $this->user_data[1] = substr($this->user_data[1], 8); 774 | } 775 | } else { 776 | array_push($this->user_data, substr($this->received_data, 0)); 777 | $u = unpack('H' . (strlen($this->received_data) * 2), substr($this->received_data, 0)); 778 | $size -= strlen($this->received_data); 779 | if ($size > 0) { 780 | $size += 12; 781 | } 782 | 783 | while ($size > 0) { 784 | $received_data = $this->recv(); 785 | $u = unpack('H' . (strlen($received_data) * 2), substr($received_data, 0)); 786 | array_push($this->user_data, substr($received_data, 0)); 787 | $size -= strlen($received_data); 788 | 789 | if (strlen($received_data) == 0) { 790 | $size = 0; 791 | } 792 | } 793 | 794 | $this->user_data[0] = substr($this->user_data[0], 8); 795 | } 796 | } 797 | else { 798 | $this->received_data = $this->recv(); 799 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6', substr( $this->received_data, $this->start_data, 8 ) ); 800 | $bytes = $this->getSizeUser(); 801 | if($bytes) 802 | { 803 | while($bytes > 0) 804 | { 805 | $received_data = $this->recv(1032); 806 | array_push( $this->user_data, $received_data); 807 | $bytes -= 1024; 808 | } 809 | $this->session_id = hexdec( $u['h6'].$u['h5'] ); 810 | $received_data = $this->recv(); 811 | } 812 | } 813 | 814 | $users = array(); 815 | if(count($this->user_data) > 0) 816 | { 817 | if ($this->protocol != 'TCP') { 818 | for($x=0; $xuser_data); $x++) 819 | { 820 | if ($x > 0) 821 | { 822 | $this->user_data[$x] = substr($this->user_data[$x], 8); 823 | } 824 | } 825 | } 826 | $user_data = implode('', $this->user_data); 827 | 828 | $user_data = substr($user_data, 11); 829 | 830 | while(strlen($user_data) > 72) 831 | { 832 | $u = unpack('H144', substr($user_data, 0, 72)); 833 | $u1 = hexdec(substr($u[1], 2, 2)); 834 | $u2 = hexdec(substr($u[1], 4, 2)); 835 | $uid = $u1+($u2*256); // 2 byte 836 | $role = hexdec(substr($u[1], 6, 2)).' '; // 1 byte 837 | $password = hex2bin(substr( $u[1], 8, 16 )).' '; // 8 byte 838 | $name = hex2bin(substr($u[1], 24, 74 )). ' '; // 37 byte 839 | $userid = hex2bin(substr($u[1], 98, 72)).' '; // 36 byte 840 | $passwordArr = explode(chr(0), $password, 2); // explode to array 841 | $password = $passwordArr[0]; // get password 842 | $useridArr = explode(chr(0), $userid, 2); // explode to array 843 | $userid = $useridArr[0]; // get user ID 844 | $nameArr = explode(chr(0), $name, 3); // explode to array 845 | $name = $nameArr[0]; // get name 846 | if($name == "") 847 | { 848 | $name = $uid; 849 | } 850 | $users[$uid] = array($userid, $name, intval($role), $password); 851 | $user_data = substr($user_data, 72); 852 | } 853 | } 854 | return $users; 855 | 856 | } 857 | catch(ErrorException $e) 858 | { 859 | return FALSE; 860 | } 861 | catch(exception $e) 862 | { 863 | return FALSE; 864 | } 865 | } 866 | public function getUserTemplateAll($uid) 867 | { 868 | $template = array(); 869 | $j = 0; 870 | for($i = 5; $i<10; $i++, $j++) 871 | { 872 | $template[$j] = $this->getUserTemplate($uid, $i); 873 | } 874 | for($i = 4; $i>=0; $i--, $j++) 875 | { 876 | $template[$j] = $this->getUserTemplate($uid, $i); 877 | } 878 | return $template; 879 | } 880 | public function getUserTemplate($uid, $finger) 881 | { 882 | 883 | $template_data = ''; 884 | $this->user_data = array(); 885 | $command = CMD_USERTEMP_RRQ; 886 | $byte1 = chr((int)($uid % 256)); 887 | $byte2 = chr((int)($uid >> 8)); 888 | $command_string = $byte1.$byte2.chr($finger); 889 | $chksum = 0; 890 | $session_id = $this->session_id; 891 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr( $this->received_data, $this->start_data, 8) ); 892 | $reply_id = hexdec( $u['h8'].$u['h7'] ); 893 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 894 | $this->send($buf); 895 | try 896 | { 897 | $this->received_data = $this->recv(); 898 | 899 | 900 | 901 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6', substr( $this->received_data, $this->start_data, 8 ) ); 902 | $bytes = $this->getSizeTemplate(); 903 | 904 | 905 | if($bytes) 906 | { 907 | while($bytes > 0) 908 | { 909 | $received_data = $this->recv(1032); 910 | 911 | 912 | array_push( $this->user_data, $received_data); 913 | $bytes -= 1024; 914 | } 915 | $this->session_id = hexdec( $u['h6'].$u['h5'] ); 916 | //$received_data = $this->recv(); 917 | } 918 | 919 | $template_data = array(); 920 | if(count($this->user_data) > 0) 921 | { 922 | 923 | for($x=0; $xuser_data); $x++) 924 | { 925 | if ($x == 0) 926 | { 927 | $this->user_data[$x] = substr($this->user_data[$x], 8); 928 | } 929 | else 930 | { 931 | $this->user_data[$x] = substr($this->user_data[$x], 8); 932 | } 933 | } 934 | $user_data = implode('', $this->user_data); 935 | $template_size = strlen($user_data)+6; 936 | $prefix = chr($template_size%256).chr(round($template_size/256)).$byte1.$byte2.chr($finger).chr(1); 937 | $user_data = $prefix.$user_data; 938 | if(strlen($user_data) > 6) 939 | { 940 | $valid = 1; 941 | $template_data = array($template_size, $uid, $finger, $valid, $user_data); 942 | } 943 | } 944 | return $template_data; 945 | 946 | } 947 | catch(ErrorException $e) 948 | { 949 | return FALSE; 950 | } 951 | catch(exception $e) 952 | { 953 | return FALSE; 954 | } 955 | } 956 | public function getUserData() 957 | { 958 | $uid = 1; 959 | $command = CMD_USERTEMP_RRQ; 960 | $command_string = chr(5); 961 | $chksum = 0; 962 | $session_id = $this->session_id; 963 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 964 | $reply_id = hexdec( $u['h8'].$u['h7'] ); 965 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 966 | $this->send($buf); 967 | try 968 | { 969 | $this->received_data = $this->recv(); 970 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6', substr($this->received_data, $this->start_data, 8)); 971 | $bytes = $this->getSizeUser(); 972 | if($bytes) 973 | { 974 | while($bytes > 0) 975 | { 976 | $received_data = $this->recv(1032); 977 | array_push($this->user_data, $received_data); 978 | $bytes -= 1024; 979 | } 980 | $this->session_id = hexdec($u['h6'].$u['h5']); 981 | $received_data = $this->recv(); 982 | } 983 | $users = array(); 984 | $retdata = ""; 985 | if(count($this->user_data) > 0) 986 | { 987 | for($x=0; $xuser_data); $x++) 988 | { 989 | if ($x > 0) 990 | { 991 | $this->user_data[$x] = substr($this->user_data[$x], 8); 992 | } 993 | if($x > 0) 994 | { 995 | $retdata .= substr($this->user_data[$x], 0); 996 | } 997 | else 998 | { 999 | $retdata .= substr($this->user_data[$x], 12); 1000 | } 1001 | } 1002 | } 1003 | return $retdata; 1004 | } 1005 | catch(ErrorException $e) 1006 | { 1007 | return FALSE; 1008 | } 1009 | catch(exception $e) 1010 | { 1011 | return FALSE; 1012 | } 1013 | } 1014 | public function setUser($uid, $userid, $name, $password, $role) 1015 | { 1016 | $uid = (int) $uid; 1017 | $role = (int) $role; 1018 | if($uid > USHRT_MAX) 1019 | { 1020 | return FALSE; 1021 | } 1022 | if($role > 255) $role = 255; 1023 | $name = substr($name, 0, 28); 1024 | $command = CMD_USER_WRQ; 1025 | $byte1 = chr((int)($uid % 256)); 1026 | $byte2 = chr((int)($uid >> 8)); 1027 | $command_string = $byte1.$byte2.chr($role).str_pad($password, 8, chr(0)).str_pad($name, 28, chr(0)).str_pad(chr(1), 9, chr(0)).str_pad($userid, 8, chr(0)).str_repeat(chr(0),16); 1028 | return $this->execCommand($command, $command_string); 1029 | } 1030 | public function setUserTemplate($data,$uid) 1031 | { 1032 | $command = CMD_USERTEMP_WRQ; 1033 | $command_string = $data; 1034 | //$length = ord(substr($command_string, 0, 1)) + ord(substr($command_string, 1, 1))*256; 1035 | $byte1 = chr((int)($uid % 256)); 1036 | $byte2 = chr((int)($uid >> 8)); 1037 | //$command_string = $byte1.$byte2.chr($role).str_pad($password, 8, chr(0)).str_pad($name, 28, chr(0)).str_pad(chr(1), 9, chr(0)).str_pad($userid, 8, chr(0)).str_repeat(chr(0),16); 1038 | 1039 | return $this->execCommand($command, $command_string); 1040 | /* 1041 | $chksum = 0; 1042 | $session_id = $this->session_id; 1043 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr( $this->received_data, $this->start_data, 8) ); 1044 | $reply_id = hexdec( $u['h8'].$u['h7'] ); 1045 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 1046 | $this->send($buf); 1047 | try 1048 | { 1049 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6', substr( $this->received_data, $this->start_data, 8 ) ); 1050 | $this->session_id = hexdec( $u['h6'].$u['h5'] ); 1051 | return substr( $this->received_data, 8 ); 1052 | } 1053 | catch(ErrorException $e) 1054 | { 1055 | return FALSE; 1056 | } 1057 | catch(exception $e) 1058 | { 1059 | return FALSE; 1060 | } 1061 | */ 1062 | } 1063 | public function clearData() 1064 | { 1065 | $command = CMD_CLEAR_DATA; 1066 | return $this->execCommand($command); 1067 | } 1068 | public function clearUser() 1069 | { 1070 | $command = CMD_CLEAR_DATA; 1071 | return $this->execCommand($command); 1072 | } 1073 | public function deleteUser($uid) 1074 | { 1075 | $command = CMD_DELETE_USER; 1076 | $byte1 = chr((int)($uid % 256)); 1077 | $byte2 = chr((int)($uid >> 8)); 1078 | $command_string = $byte1.$byte2; 1079 | return $this->execCommand($command, $command_string); 1080 | } 1081 | public function deleteUserTemp($uid, $finger) 1082 | { 1083 | $command = CMD_DELETE_USERTEMP; 1084 | $byte1 = chr((int)($uid % 256)); 1085 | $byte2 = chr((int)($uid >> 8)); 1086 | $command_string = $byte1.$byte2.chr($finger); 1087 | return $this->execCommand($command, $command_string); 1088 | } 1089 | public function clearAdmin() 1090 | { 1091 | $command = CMD_CLEAR_ADMIN; 1092 | return $this->execCommand($command); 1093 | } 1094 | public function testUserTemplate($uid, $finger) 1095 | { 1096 | $command = CMD_TEST_TEMP; 1097 | $byte1 = chr((int)($uid % 256)); 1098 | $byte2 = chr((int)($uid >> 8)); 1099 | $command_string = $byte1.$byte2.chr($finger); 1100 | $u = unpack('H2h1/H2h2', $this->execCommand($command, $command_string)); 1101 | $ret = hexdec( $u['h2'].$u['h1'] ); 1102 | return ($ret == CMD_ACK_OK)?1:0; 1103 | } 1104 | public function startVerify($uid) 1105 | { 1106 | $command = CMD_STARTVERIFY; 1107 | $byte1 = chr((int)($uid % 256)); 1108 | $byte2 = chr((int)($uid >> 8)); 1109 | $command_string = $byte1.$byte2; 1110 | return $this->execCommand($command, $command_string); 1111 | } 1112 | public function startEnroll($uid, $finger) 1113 | { 1114 | $command = CMD_STARTENROLL; 1115 | $byte1 = chr((int)($uid % 256)); 1116 | $byte2 = chr((int)($uid >> 8)); 1117 | $command_string = $byte1.$byte2.chr($finger); 1118 | return $this->execCommand($command, $command_string); 1119 | } 1120 | public function cancelCapture() 1121 | { 1122 | $command = CMD_CANCELCAPTURE; 1123 | return $this->execCommand($command); 1124 | } 1125 | public function getAttendance() 1126 | { 1127 | if ($this->protocol == 'TCP') { 1128 | $command = 1503; 1129 | $command_string = pack('CCLLC', 1, 13, 0, 0, 0); 1130 | $chksum = 0; 1131 | $session_id = $this->session_id; 1132 | $patron = ""; 1133 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 1134 | $ucs = unpack('H' . (strlen($command_string) * 2), substr($command_string, 0)); 1135 | $udat = unpack('H' . (strlen($this->received_data) * 2), substr($this->received_data, 0)); 1136 | $reply_id = hexdec($u['h8'] . $u['h7']); 1137 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 1138 | $this->send($buf); 1139 | $this->received_data = $this->recv(); 1140 | $udat = unpack('H' . (strlen($this->received_data) * 2), substr($this->received_data, 0)); 1141 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 1142 | $reply_id = hexdec($u['h8'] . $u['h7']); 1143 | $comando = hexdec($u['h2'] . $u['h1']); 1144 | 1145 | if ($comando == CMD_ACK_OK) { 1146 | $u = unpack('H2h1/H2h2/H2h3/H2h4', substr($this->received_data, 17, 4)); 1147 | $size = hexdec($u['h4'] . $u['h3'] . $u['h2'] . $u['h1']); 1148 | } else { 1149 | $u = unpack('H2h1/H2h2/H2h3/H2h4', substr($this->received_data, 16, 4)); 1150 | $size = hexdec($u['h4'] . $u['h3'] . $u['h2'] . $u['h1']); 1151 | } 1152 | 1153 | if ($size > 1024) { 1154 | $buf = $this->createHeader(1504, $chksum, $session_id, $reply_id, pack('LL', 0, $size)); 1155 | $this->send($buf); 1156 | } 1157 | } 1158 | else { 1159 | $command = CMD_ATTLOG_RRQ; 1160 | $command_string = ''; 1161 | $chksum = 0; 1162 | $session_id = $this->session_id; 1163 | $u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, $this->start_data, 8)); 1164 | $reply_id = hexdec($u['h8'].$u['h7']); 1165 | $buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string); 1166 | $this->send($buf); 1167 | } 1168 | 1169 | try 1170 | { 1171 | if ($this->protocol == 'TCP') { 1172 | if ($size > 1024) { 1173 | $this->received_data = $this->recv(); 1174 | $bytes = $this->getSizeAttendance(); 1175 | $lonreceived_data = strlen($this->received_data); 1176 | $bytes2 = 0; 1177 | $tembytes = $bytes; 1178 | 1179 | if ($lonreceived_data > 24) { 1180 | array_push($this->attendance_data, substr($this->received_data, 24)); 1181 | $bytes3 = ($lonreceived_data - 24); 1182 | $bytes2 = $lonreceived_data - 24; 1183 | $bytes -= $bytes3; 1184 | } 1185 | 1186 | if ($bytes) { 1187 | while ($bytes > 0) { 1188 | $received_data = $this->recv(); 1189 | $bytes2 += strlen($received_data); 1190 | $longitud = strlen($received_data); 1191 | if ($bytes2 > 1024) { 1192 | if (substr($received_data, 0, 2) == 'PP') { 1193 | $received_data = substr($received_data, 16); 1194 | $bytes2 -= 1024; 1195 | } else { 1196 | $received_data = substr($received_data, 0, $longitud - ($bytes2 - 1024)) . substr($received_data, $longitud - ($bytes2 - 1024) + 16); 1197 | $bytes2 -= 1024; 1198 | } 1199 | } 1200 | array_push($this->attendance_data, substr($received_data, 0)); 1201 | $bytes -= strlen($received_data); 1202 | 1203 | if (strlen($received_data) == 0) { 1204 | $bytes = 0; 1205 | } 1206 | } 1207 | $this->session_id = hexdec($u['h6'] . $u['h5']); 1208 | $received_data = $this->recv(); 1209 | } 1210 | if ($lonreceived_data > 24) { 1211 | array_push($this->attendance_data, substr($this->received_data, 0, 24)); 1212 | } else { 1213 | array_push($this->attendance_data, substr($this->received_data, 0)); 1214 | } 1215 | if (count($this->attendance_data) > 0) { 1216 | $this->attendance_data[0] = substr($this->attendance_data[0], 8); 1217 | } 1218 | } else { 1219 | 1220 | $ssize = $size; 1221 | 1222 | $sizerecibido = 0; 1223 | 1224 | array_push($this->attendance_data, substr($this->received_data, 8)); 1225 | 1226 | if ($size > 0) { 1227 | $u = unpack('H' . (strlen($this->received_data) * 2), substr($this->received_data, 0)); 1228 | $size -= strlen($this->received_data); 1229 | 1230 | $sizerecibido += strlen($this->received_data); 1231 | 1232 | while ($size > 0) { 1233 | $received_data = $this->recv(); 1234 | $u = unpack('H' . (strlen($received_data) * 2), substr($received_data, 0)); 1235 | array_push($this->attendance_data, substr($received_data, 0)); 1236 | $size -= strlen($received_data); 1237 | 1238 | $sizerecibido += strlen($received_data); 1239 | 1240 | if (strlen($received_data) == 0) { 1241 | $size = 0; 1242 | } 1243 | } 1244 | 1245 | if ($sizerecibido <> ($ssize + 20)) { 1246 | $received_data = $this->recv(); 1247 | $u = unpack('H' . (strlen($received_data) * 2), substr($received_data, 0)); 1248 | array_push($this->attendance_data, substr($received_data, 0)); 1249 | 1250 | $sizerecibido += strlen($received_data); 1251 | } 1252 | } 1253 | } 1254 | } 1255 | else { 1256 | $this->received_data = $this->recv(); 1257 | $bytes = $this->getSizeAttendance(); 1258 | if($bytes) 1259 | { 1260 | while($bytes > 0) 1261 | { 1262 | $received_data = $this->recv(1032); 1263 | array_push($this->attendance_data, $received_data); 1264 | $bytes -= 1024; 1265 | } 1266 | $this->session_id = hexdec($u['h6'].$u['h5']); 1267 | $received_data = $this->recv(); 1268 | } 1269 | } 1270 | 1271 | $attendance = array(); 1272 | if(count($this->attendance_data) > 0) 1273 | { 1274 | if ($this->protocol != 'TCP') { 1275 | for($x=0; $xattendance_data); $x++) 1276 | { 1277 | if($x > 0) 1278 | { 1279 | $this->attendance_data[$x] = substr($this->attendance_data[$x], 8); 1280 | } 1281 | } 1282 | } 1283 | $attendance_data = implode('', $this->attendance_data); 1284 | $attendance_data = substr($attendance_data, 10); 1285 | while(strlen($attendance_data) > 40) 1286 | { 1287 | $u = unpack('H80', substr($attendance_data, 0, 40)); 1288 | $u1 = hexdec(substr($u[1], 4, 2)); 1289 | $u2 = hexdec(substr($u[1], 6, 2)); 1290 | $uid = $u1+($u2*256); 1291 | $id = str_replace("\0", '', hex2bin(substr($u[1], 8, 16))); 1292 | $state = hexdec(substr( $u[1], 56, 2 ) ); 1293 | $timestamp = $this->decodeTime(hexdec($this->reverseHex(substr($u[1], 58, 8)))); 1294 | array_push($attendance, array($uid, $id, $state, $timestamp)); 1295 | $attendance_data = substr($attendance_data, 40 ); 1296 | } 1297 | } 1298 | return $attendance; 1299 | } 1300 | catch(ErrorException $e) 1301 | { 1302 | return FALSE; 1303 | } 1304 | catch(exception $e) 1305 | { 1306 | return FALSE; 1307 | } 1308 | 1309 | } 1310 | public function clearAttendance() 1311 | { 1312 | $command = CMD_CLEAR_ATTLOG; 1313 | return $this->execCommand($command); 1314 | } 1315 | 1316 | } 1317 | ?> 1318 | --------------------------------------------------------------------------------