Module: Zklib::Helper

Included in:
Zklib
Defined in:
lib/zklib/helper.rb

Instance Method Summary collapse

Instance Method Details

#check_valid(options) ⇒ Object

Check validity of response

param options

|_ data  Data to check validity


7
8
9
# File 'lib/zklib/helper.rb', line 7

def check_valid(options)
  BinData::Uint16le.read(options[:data][0..-1]).snapshot == CMD_ACK_OK
end

#create_checksum(options) ⇒ Object

Create checksum for execution

param options

|_ data  Data to create checksum


15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/zklib/helper.rb', line 15

def create_checksum(options)
  data = options[:data]
  checksum = 0

  (0...data.length).step(2) do |i|
    checksum += (i == data.length - 1) ?
      BinData::Uint8le.read(data[i]).snapshot :
      BinData::Uint16le.read(data[i..-1]).snapshot
    checksum %= USHRT_MAX
  end

  chksum = USHRT_MAX - checksum - 1
  chksum
end

#create_header(options) ⇒ Object

Create header for execution

param options

|_ command         Command value
|_ checksum        Checksum
|_ session_id      Session ID
|_ reply_id        Reply ID
|_ command_string  Command string


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/zklib/helper.rb', line 38

def create_header(options)
  header_buffer = StringIO.new
  binary_writer = BinData::Uint16le.new

  # Write command header
  binary_writer.value = options[:command]
  header_buffer.pos   = 0
  binary_writer.write(header_buffer)

  # Write checksum header
  binary_writer.value = options[:checksum]
  header_buffer.pos   = 2
  binary_writer.write(header_buffer)

  # Write session ID header
  binary_writer.value = options[:session_id]
  header_buffer.pos   = 4
  binary_writer.write(header_buffer)

  # Write reply ID header
  binary_writer.value = options[:reply_id]
  header_buffer.pos   = 6
  binary_writer.write(header_buffer)

  # Write command string header
  header_buffer.pos = 8
  header_buffer.write(options[:command_string])

  # Rewrite checksum header
  binary_writer.value = create_checksum(data: header_buffer.string)
  header_buffer.pos   = 2
  binary_writer.write(header_buffer)

  # Rewrite reply ID header
  binary_writer.value = (options[:reply_id] + 1) % USHRT_MAX
  header_buffer.pos   = 6
  binary_writer.write(header_buffer)

  header_buffer.string
end

#decode_time(options) ⇒ Object

Convert number of seconds to time

param options

|_ seconds  Time in seconds to decode


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/zklib/helper.rb', line 83

def decode_time(options)
  time = options[:seconds]

  # Calculate second value
  second = time % 60
  time = (time - second) / 60

  # Calculate minute value
  minute = time % 60
  time = (time - minute) / 60

  # Calculate hour value
  hour = time % 24
  time = (time - hour) / 24

  # Calculate day value
  day = time % 31 + 1
  time = (time - day + 1) / 31

  # Calculate month value
  month = time % 12 + 1
  time = (time - month + 1) / 12

  # Calculate year value
  year = time + 2000

  Time.new(year, month, day, hour, minute, second)
end

#decode_user_data(options) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/zklib/helper.rb', line 112

def decode_user_data(options)
  data = options[:data]

  {
    uid:      BinData::Uint16be.read(data[0..1]).snapshot,
    role:     BinData::Uint16le.read(data[2..3]).snapshot,
    password: nil,
    name:     nil,
    cardno:   nil,
    userid:   nil
  }
end

#encode_time(options) ⇒ Object

Convert time to number of seconds

param options

|_ time  Time object to encode


129
130
131
132
133
# File 'lib/zklib/helper.rb', line 129

def encode_time(options)
  time = options[:time]

  ((time.year % 100) * 12 * 31 + ((time.mon - 1) * 31) + time.day - 1) * (24 * 60 * 60) + (time.hour * 60 + time.min) * 60 + time.sec
end

#execute_cmd(options) ⇒ Object

Execute command on attendance machine

param options

|_ command         Command to execute
|_ command_string  Command string


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/zklib/helper.rb', line 140

def execute_cmd(options)
  command = options[:command]
  self.reply_id = USHRT_MAX - 1 if command == CMD_CONNECT
  header = create_header(
    command:        command,
    checksum:       0,
    session_id:     session_id,
    reply_id:       reply_id,
    command_string: options[:command_string]
  )

  # Send command
  socket = UDPSocket.new
  socket.bind('0.0.0.0', inport)
  socket.send(header, 0, ip, port)
  self.data_recv = socket.recvfrom(USHRT_MAX)[0] if IO.select([socket], nil, nil, 10)
  socket.close

  # Callback
  if data_recv && data_recv.length > 0
    self.session_id = BinData::Uint16le.read(data_recv[4..-1]).snapshot
    self.reply_id = BinData::Uint16le.read(data_recv[6..-1]).snapshot

    yield(valid: true, data: data_recv) if block_given?
  else
    yield(valid: false, error: 'Empty response') if block_given?
  end
end

#receive_nonblock(options) ⇒ Object

Receive data from non-blocking socket

param options

|_ socket  Socket to receive data from


173
174
175
176
177
178
179
# File 'lib/zklib/helper.rb', line 173

def receive_nonblock(options)
  return options[:socket].recvfrom_nonblock(USHRT_MAX)
rescue IO::WaitReadable
  IO.select([options[:socket]])

  retry
end