zklib 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/zklib.rb +124 -0
- data/lib/zklib/attendance_management.rb +119 -0
- data/lib/zklib/connection_management.rb +23 -0
- data/lib/zklib/data_management.rb +37 -0
- data/lib/zklib/device_management.rb +91 -0
- data/lib/zklib/face_management.rb +40 -0
- data/lib/zklib/helper.rb +181 -0
- data/lib/zklib/pin_management.rb +22 -0
- data/lib/zklib/platform_management.rb +22 -0
- data/lib/zklib/serial_management.rb +22 -0
- data/lib/zklib/ssr_management.rb +22 -0
- data/lib/zklib/time_management.rb +47 -0
- data/lib/zklib/user_management.rb +199 -0
- data/lib/zklib/version.rb +3 -0
- data/lib/zklib/version_management.rb +58 -0
- data/lib/zklib/work_code_management.rb +22 -0
- data/zklib.gemspec +27 -0
- metadata +139 -0
@@ -0,0 +1,199 @@
|
|
1
|
+
class Zklib
|
2
|
+
module UserManagement
|
3
|
+
# Clear admins
|
4
|
+
def clear_admins
|
5
|
+
execute_cmd(
|
6
|
+
command: CMD_CLEAR_ADMIN,
|
7
|
+
command_string: ''
|
8
|
+
) do |opts|
|
9
|
+
return puts "ERROR: #{options[:error]}" unless opts[:valid]
|
10
|
+
|
11
|
+
data = opts[:data]
|
12
|
+
if data.length > 7
|
13
|
+
data.split("\u0000").pop
|
14
|
+
else
|
15
|
+
puts 'ERROR: Invalid clear admins response'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Clear users
|
21
|
+
def clear_users
|
22
|
+
execute_cmd(
|
23
|
+
command: CMD_CLEAR_DATA,
|
24
|
+
command_string: ''
|
25
|
+
) do |opts|
|
26
|
+
return puts "ERROR: #{options[:error]}" unless opts[:valid]
|
27
|
+
|
28
|
+
data = opts[:data]
|
29
|
+
if data.length > 7
|
30
|
+
data.split("\u0000").pop
|
31
|
+
else
|
32
|
+
puts 'ERROR: Invalid clear users response'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Create user
|
38
|
+
# param options
|
39
|
+
# |_ uid UID
|
40
|
+
# |_ user_id User ID
|
41
|
+
# |_ name Name
|
42
|
+
# |_ password Password
|
43
|
+
# |_ role Role
|
44
|
+
def create_user(options)
|
45
|
+
# command_string = (options[:uid] % 256).chr
|
46
|
+
# command_string += (options[:uid] >> 8).chr
|
47
|
+
command_string = options[:uid].chr.ljust(2, 0.chr)
|
48
|
+
command_string += options[:role].chr
|
49
|
+
command_string += options[:password].ljust(8, 0.chr)
|
50
|
+
command_string += options[:name].ljust(28, 0.chr)
|
51
|
+
command_string += 1.chr
|
52
|
+
command_string += 0.chr * 8
|
53
|
+
command_string += options[:user_id].ljust(8, 0.chr)
|
54
|
+
command_string += 0.chr * 16
|
55
|
+
|
56
|
+
execute_cmd(
|
57
|
+
command: CMD_SET_USER,
|
58
|
+
command_string: command_string
|
59
|
+
) do |opts|
|
60
|
+
return puts "ERROR: #{options[:error]}" unless opts[:valid]
|
61
|
+
|
62
|
+
data = opts[:data]
|
63
|
+
if data.length > 7
|
64
|
+
data.split("\u0000").pop
|
65
|
+
else
|
66
|
+
puts 'ERROR: Invalid set user response'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Decode user data
|
72
|
+
# param options
|
73
|
+
# |_ data User data to decode
|
74
|
+
def decode_user_data(options)
|
75
|
+
data = options[:data]
|
76
|
+
|
77
|
+
{
|
78
|
+
uid: BinData::Uint16be.read(data[0..1]).snapshot,
|
79
|
+
role: BinData::Uint16be.read(data[2..3]).snapshot,
|
80
|
+
password: data[4..11].split("\0").pop,
|
81
|
+
name: data[12..35].split("\0").pop,
|
82
|
+
card_no: BinData::Uint32le.read(data[36..39]).snapshot,
|
83
|
+
user_id: data[49..71].split("\0").pop
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
# Delete user
|
88
|
+
# param options
|
89
|
+
# |_ uid UID
|
90
|
+
def delete_user(options)
|
91
|
+
command_buffer = StringIO.new
|
92
|
+
binary_writer = BinData::Uint16le.new
|
93
|
+
|
94
|
+
binary_writer.value = options[:uid]
|
95
|
+
command_buffer.pos = 0
|
96
|
+
binary_writer.write(command_buffer)
|
97
|
+
|
98
|
+
command_string = command_buffer.string
|
99
|
+
|
100
|
+
execute_cmd(
|
101
|
+
command: CMD_DELETE_USER,
|
102
|
+
command_string: command_string
|
103
|
+
) do |opts|
|
104
|
+
return puts "ERROR: #{options[:error]}" unless opts[:valid]
|
105
|
+
|
106
|
+
data = opts[:data]
|
107
|
+
if data.length > 7
|
108
|
+
data.split("\u0000").pop
|
109
|
+
else
|
110
|
+
puts 'ERROR: Invalid clear admins response'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Get user list size
|
116
|
+
def get_user_count
|
117
|
+
return 0 if BinData::Uint16le.read(data_recv).snapshot != CMD_PREPARE_DATA
|
118
|
+
|
119
|
+
BinData::Uint32le.read(data_recv[8..-1]).snapshot
|
120
|
+
end
|
121
|
+
|
122
|
+
# Get users
|
123
|
+
def get_users
|
124
|
+
header = create_header(
|
125
|
+
command: CMD_USERTEMP_RRQ,
|
126
|
+
command_string: 5.chr,
|
127
|
+
checksum: 0,
|
128
|
+
session_id: session_id,
|
129
|
+
reply_id: BinData::Uint16le.read(data_recv[6..-1]).snapshot
|
130
|
+
)
|
131
|
+
|
132
|
+
# Send command
|
133
|
+
socket = UDPSocket.new
|
134
|
+
socket.bind('0.0.0.0', inport)
|
135
|
+
socket.send(header, 0, ip, port)
|
136
|
+
|
137
|
+
### START Get response size ###
|
138
|
+
self.data_recv = receive_nonblock(socket: socket)[0]
|
139
|
+
|
140
|
+
return puts 'ERROR: Empty response' unless data_recv && data_recv.length > 0
|
141
|
+
|
142
|
+
self.session_id = BinData::Uint16le.read(data_recv[4..-1]).snapshot
|
143
|
+
total_bytes = get_user_count
|
144
|
+
|
145
|
+
# Stop if user list is empty
|
146
|
+
if total_bytes <= 0
|
147
|
+
socket.close
|
148
|
+
|
149
|
+
return []
|
150
|
+
end
|
151
|
+
### END Get response size ###
|
152
|
+
|
153
|
+
### START Get user list ###
|
154
|
+
bytes_recv = 0
|
155
|
+
rem = nil
|
156
|
+
offset = 0
|
157
|
+
user_data_size = 72
|
158
|
+
trim_first = 11
|
159
|
+
trim_others = 8
|
160
|
+
users = []
|
161
|
+
|
162
|
+
while true
|
163
|
+
data = receive_nonblock(socket: socket)[0]
|
164
|
+
|
165
|
+
if bytes_recv == 0
|
166
|
+
offset = trim_first
|
167
|
+
bytes_recv = 4
|
168
|
+
else
|
169
|
+
offset = trim_others
|
170
|
+
end
|
171
|
+
|
172
|
+
while(data.length - offset >= user_data_size)
|
173
|
+
user_data = data[offset..-1]
|
174
|
+
offset += user_data_size
|
175
|
+
|
176
|
+
if rem && rem.length > 0
|
177
|
+
user_data.prepend(rem)
|
178
|
+
offset -= rem.length
|
179
|
+
rem = nil
|
180
|
+
end
|
181
|
+
|
182
|
+
users << decode_user_data(data: user_data)
|
183
|
+
bytes_recv += user_data_size
|
184
|
+
|
185
|
+
if bytes_recv == total_bytes
|
186
|
+
socket.close
|
187
|
+
|
188
|
+
return users
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
rem = data[offset..-1]
|
193
|
+
end
|
194
|
+
### END Get user list ###
|
195
|
+
|
196
|
+
socket.close
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class Zklib
|
2
|
+
module VersionManagement
|
3
|
+
OS_VERSION_KEYWORD = '~OS'
|
4
|
+
PLATFORM_VERSION_KEYWORD = '~ZKFPVersion'
|
5
|
+
SSR_VERSION_KEYWORD = '~SSR'
|
6
|
+
|
7
|
+
# Get firmware version
|
8
|
+
def get_firmware_version
|
9
|
+
execute_cmd(
|
10
|
+
command: CMD_VERSION,
|
11
|
+
command_string: ''
|
12
|
+
) do |opts|
|
13
|
+
return puts "ERROR: #{options[:error]}" unless opts[:valid]
|
14
|
+
|
15
|
+
data = opts[:data]
|
16
|
+
if data.length > 8
|
17
|
+
data.split("\u0000").pop
|
18
|
+
else
|
19
|
+
puts 'ERROR: Invalid firmware version response'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get OS version
|
25
|
+
def get_os_version
|
26
|
+
execute_cmd(
|
27
|
+
command: CMD_DEVICE,
|
28
|
+
command_string: OS_VERSION_KEYWORD
|
29
|
+
) do |opts|
|
30
|
+
return puts "ERROR: #{options[:error]}" unless opts[:valid]
|
31
|
+
|
32
|
+
data = opts[:data]
|
33
|
+
if data.length > 8
|
34
|
+
data.split("\u0000").pop.tr("#{OS_VERSION_KEYWORD}=", '')
|
35
|
+
else
|
36
|
+
puts 'ERROR: Invalid OS version response'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Get platform version
|
42
|
+
def get_platform_version
|
43
|
+
execute_cmd(
|
44
|
+
command: CMD_DEVICE,
|
45
|
+
command_string: PLATFORM_VERSION_KEYWORD
|
46
|
+
) do |opts|
|
47
|
+
return puts "ERROR: #{options[:error]}" unless opts[:valid]
|
48
|
+
|
49
|
+
data = opts[:data]
|
50
|
+
if data.length > 8
|
51
|
+
data.split("\u0000").pop.tr("#{PLATFORM_VERSION_KEYWORD}=", '')
|
52
|
+
else
|
53
|
+
puts 'ERROR: Invalid platform version response'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Zklib
|
2
|
+
module WorkCodeManagement
|
3
|
+
WORK_CODE_KEYWORD = 'WorkCode'
|
4
|
+
|
5
|
+
# Get work code
|
6
|
+
def get_work_code
|
7
|
+
execute_cmd(
|
8
|
+
command: CMD_DEVICE,
|
9
|
+
command_string: WORK_CODE_KEYWORD
|
10
|
+
) do |opts|
|
11
|
+
return puts "ERROR: #{options[:error]}" unless opts[:valid]
|
12
|
+
|
13
|
+
data = opts[:data]
|
14
|
+
if data.length > 8
|
15
|
+
data.split("\u0000").pop.tr("#{WORK_CODE_KEYWORD}=", '')
|
16
|
+
else
|
17
|
+
puts 'ERROR: Invalid work code response'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/zklib.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'zklib/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'zklib'
|
8
|
+
spec.version = Zklib::VERSION
|
9
|
+
spec.platform = Gem::Platform::RUBY
|
10
|
+
spec.license = 'MIT'
|
11
|
+
|
12
|
+
spec.summary = 'Attendance machine client in Ruby'
|
13
|
+
spec.email = 'anhtrantuan.hcmc@gmail.com'
|
14
|
+
spec.homepage = 'https://github.com/anhtrantuan/zklib-ruby'
|
15
|
+
spec.description = 'Attendance machine client in Ruby'
|
16
|
+
spec.authors = ['Anh Tran']
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'bindata', '~> 2.3'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.12'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
26
|
+
spec.add_development_dependency 'byebug', '~> 9.0'
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zklib
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anh Tran
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bindata
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.12'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '9.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '9.0'
|
83
|
+
description: Attendance machine client in Ruby
|
84
|
+
email: anhtrantuan.hcmc@gmail.com
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- ".gitignore"
|
90
|
+
- ".travis.yml"
|
91
|
+
- CODE_OF_CONDUCT.md
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/console
|
97
|
+
- bin/setup
|
98
|
+
- lib/zklib.rb
|
99
|
+
- lib/zklib/attendance_management.rb
|
100
|
+
- lib/zklib/connection_management.rb
|
101
|
+
- lib/zklib/data_management.rb
|
102
|
+
- lib/zklib/device_management.rb
|
103
|
+
- lib/zklib/face_management.rb
|
104
|
+
- lib/zklib/helper.rb
|
105
|
+
- lib/zklib/pin_management.rb
|
106
|
+
- lib/zklib/platform_management.rb
|
107
|
+
- lib/zklib/serial_management.rb
|
108
|
+
- lib/zklib/ssr_management.rb
|
109
|
+
- lib/zklib/time_management.rb
|
110
|
+
- lib/zklib/user_management.rb
|
111
|
+
- lib/zklib/version.rb
|
112
|
+
- lib/zklib/version_management.rb
|
113
|
+
- lib/zklib/work_code_management.rb
|
114
|
+
- zklib.gemspec
|
115
|
+
homepage: https://github.com/anhtrantuan/zklib-ruby
|
116
|
+
licenses:
|
117
|
+
- MIT
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 2.6.11
|
136
|
+
signing_key:
|
137
|
+
specification_version: 4
|
138
|
+
summary: Attendance machine client in Ruby
|
139
|
+
test_files: []
|