smartware 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,6 +5,13 @@ interfaces:
5
5
  - name: Modem
6
6
  uri: druby://localhost:6002
7
7
  driver: Dummy
8
+ - name: Watchdog
9
+ uri: druby://localhost:6003
10
+ driver: Dummy
11
+ - name: CardReader
12
+ uri: druby://localhost:6004
13
+ driver: Dummy
8
14
  - name: Printer
9
15
  uri: druby://localhost:6005
10
16
  driver: Dummy
17
+ connection_timeout: 60
@@ -0,0 +1,60 @@
1
+ require 'drb'
2
+
3
+ module Smartware
4
+ module Client
5
+
6
+ module CardReader
7
+
8
+ DRb.start_service
9
+ @device = DRbObject.new_with_uri('druby://localhost:6004')
10
+
11
+ def self.open(limit_min = nil, limit_max = nil)
12
+ @device.open_session(limit_min, limit_max)
13
+ end
14
+
15
+ def self.close
16
+ @device.close_session
17
+ end
18
+
19
+ def self.status
20
+ @device.status
21
+ end
22
+
23
+ def self.error
24
+ @device.error
25
+ end
26
+
27
+ def self.model
28
+ @device.model
29
+ end
30
+
31
+ def self.version
32
+ @device.version
33
+ end
34
+
35
+ def self.card_inserted?
36
+ @device.card_inserted?
37
+ end
38
+
39
+ def self.start_accepting
40
+ @device.start_accepting
41
+ end
42
+
43
+ def self.stop_accepting
44
+ @device.stop_accepting
45
+ end
46
+
47
+ def self.eject
48
+ @device.eject
49
+ end
50
+
51
+ def self.capture
52
+ @device.capture
53
+ end
54
+
55
+ def self.read_magstrip
56
+ @device.read_magstrip
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,71 @@
1
+ module Smartware
2
+ module Driver
3
+ module CardReader
4
+ class Dummy
5
+ def initialize(config)
6
+ @accepting = false
7
+ @state = nil
8
+ end
9
+
10
+ def model
11
+ "Dummy card reader"
12
+ end
13
+
14
+ def version
15
+ ""
16
+ end
17
+
18
+ def ready?
19
+ true
20
+ end
21
+
22
+ def accepting?
23
+ @accepting
24
+ end
25
+
26
+ def accepting=(accepting)
27
+ @state = :accepting if accepting
28
+ @accepting = accepting
29
+ end
30
+
31
+ def eject
32
+ @state = :eject
33
+
34
+ self
35
+ end
36
+
37
+ def capture
38
+ @state = :eject
39
+ self
40
+ end
41
+
42
+ def status
43
+ case @state
44
+ when nil
45
+ :ready
46
+
47
+ when :accepting
48
+ @state = :inserted
49
+ :card_at_gate
50
+
51
+ when :inserted
52
+ :card_inserted
53
+
54
+ when :eject
55
+ @state = nil
56
+ :card_at_gate
57
+ end
58
+ end
59
+
60
+ def read_magstrip
61
+ [
62
+ "B4154000000000000^IVANOV/IVAN^1501101000",
63
+ "4154000000000000=1501101000",
64
+ nil,
65
+ nil
66
+ ]
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,466 @@
1
+ require "serialport"
2
+ require "digest/crc16_ccitt"
3
+
4
+ module Smartware
5
+
6
+ module Driver
7
+ module CardReader
8
+ class ICT3K5
9
+ ERRORS = {
10
+ 0x00 => Interface::CardReader::COMMUNICATION_ERROR, # A given command code is unidentified
11
+ 0x01 => Interface::CardReader::COMMUNICATION_ERROR, # Parameter is not correct
12
+ 0x02 => Interface::CardReader::COMMUNICATION_ERROR, # Command execution is impossible
13
+ 0x03 => Interface::CardReader::COMMUNICATION_ERROR, # Function is not implemented
14
+ 0x04 => Interface::CardReader::COMMUNICATION_ERROR, # Command data error
15
+ 0x06 => Interface::CardReader::COMMUNICATION_ERROR, # Key for decrypting is not received
16
+ 0x10 => Interface::CardReader::CARD_JAM_ERROR,
17
+ 0x11 => Interface::CardReader::CARD_ERROR, # Shutter error
18
+ 0x13 => Interface::CardReader::CARD_ERROR, # Long card
19
+ 0x14 => Interface::CardReader::CARD_ERROR, # Short card
20
+ 0x15 => Interface::CardReader::HARDWARE_ERROR, # Flash Memory Parameter Area CRC error
21
+ 0x16 => Interface::CardReader::CARD_ERROR, # Card position move
22
+ 0x17 => Interface::CardReader::CARD_JAM_ERROR, # Jam error at retrieve
23
+ 0x18 => Interface::CardReader::CARD_ERROR, # Two card error
24
+ 0x20 => Interface::CardReader::MAG_READ_ERROR, # Parity error
25
+ 0x21 => Interface::CardReader::MAG_READ_ERROR, # Sentinel error
26
+ 0x23 => Interface::CardReader::MAG_READ_ERROR, # No data contents
27
+ 0x24 => Interface::CardReader::MAG_READ_ERROR, # No stripe
28
+ 0x30 => Interface::CardReader::HARDWARE_ERROR, # Power loss
29
+ 0x31 => Interface::CardReader::COMMUNICATION_ERROR, # DTR low
30
+ 0x39 => Interface::CardReader::HARDWARE_ERROR, # Fan failure
31
+ 0x40 => Interface::CardReader::CARD_ERROR, # Pull out error
32
+ 0x43 => Interface::CardReader::CARD_ERROR, # IC positioning error
33
+ 0x50 => Interface::CardReader::HARDWARE_ERROR, # Capture counter overflow
34
+ 0x60 => Interface::CardReader::ICC_ERROR, # Abnormal VCC condition
35
+ 0x61 => Interface::CardReader::ICC_ERROR, # ATR error
36
+ 0x62 => Interface::CardReader::ICC_ERROR, # Invalid ATR error
37
+ 0x63 => Interface::CardReader::ICC_ERROR, # No response
38
+ 0x64 => Interface::CardReader::ICC_ERROR, # Communication error
39
+ 0x65 => Interface::CardReader::ICC_ERROR, # Not activated
40
+ 0x66 => Interface::CardReader::ICC_ERROR, # Unsupported card
41
+ 0x69 => Interface::CardReader::ICC_ERROR, # Unsupported card
42
+ 0x73 => Interface::CardReader::HARDWARE_ERROR, # EEPROM error
43
+ 0xB0 => Interface::CardReader::COMMUNICATION_ERROR # Not received initialize
44
+ }
45
+
46
+ class CRC < Digest::CRC16CCITT
47
+ INIT_CRC = 0x0000
48
+ end
49
+
50
+ class CommandResponse
51
+ def initialize(response)
52
+ @response = response
53
+ end
54
+
55
+ def error?
56
+ @response.nil? || (@response[0] != "P" && @response[0] != "N")
57
+ end
58
+
59
+ def positive?
60
+ @response[0] == "P"
61
+ end
62
+
63
+ def negative?
64
+ @response[0] == "N"
65
+ end
66
+
67
+ def response
68
+ @response[1..-1]
69
+ end
70
+ end
71
+
72
+ STX = 0xF2
73
+ ACK = 0x06
74
+ NAK = 0x15
75
+
76
+ def initialize(config)
77
+ @config = config
78
+
79
+ @port = SerialPort.new(config["port"], 115200, 8, 1, SerialPort::EVEN)
80
+
81
+ @state = :not_ready
82
+ @event_read, @event_write = IO.pipe
83
+ @read_buf = ""
84
+ @write_buf = ""
85
+ @command_queue = Queue.new
86
+ @status_mutex = Mutex.new
87
+ @active_command = nil
88
+ @active_block = nil
89
+ @start_time = nil
90
+ @retries = nil
91
+ @ready = false
92
+ @accepting = false
93
+
94
+ Thread.new &method(:dispatch)
95
+ end
96
+
97
+ def model
98
+ "ICT3K5"
99
+ end
100
+
101
+ def version
102
+ ""
103
+ end
104
+
105
+ def ready?
106
+ @status_mutex.synchronize { @ready }
107
+ end
108
+
109
+ def accepting?
110
+ @status_mutex.synchronize { @accepting }
111
+ end
112
+
113
+ def accepting=(accepting)
114
+ if accepting
115
+ set_led :green
116
+ resp = command 0x3A, 0x30
117
+ else
118
+ set_led :red
119
+ resp = command 0x3A, 0x31
120
+ end
121
+
122
+ translate_response resp
123
+
124
+ @status_mutex.synchronize { @accepting = accepting }
125
+ end
126
+
127
+ def eject
128
+ resp = command 0x33, 0x30
129
+ translate_response resp
130
+
131
+ self
132
+ end
133
+
134
+ def capture
135
+ resp = command 0x33, 0x31
136
+ translate_response resp
137
+
138
+ self
139
+ end
140
+
141
+ def status
142
+ return :not_ready if !ready?
143
+
144
+ resp = command 0x31, 0x30
145
+ translate_response resp
146
+
147
+ case resp.response[2..3]
148
+ when "00"
149
+ :ready
150
+
151
+ when "01"
152
+ :card_at_gate
153
+
154
+ when "02"
155
+ :card_inserted
156
+
157
+ else
158
+ :not_ready
159
+ end
160
+ end
161
+
162
+ def read_magstrip
163
+ [ 0x31, 0x32, 0x33, 0x34 ].map! do |track|
164
+ resp = command 0x36, track
165
+ translate_response resp if resp.error?
166
+
167
+ if resp.positive?
168
+ resp.response[4..-1]
169
+ else
170
+ nil
171
+ end
172
+ end
173
+ end
174
+
175
+ private
176
+
177
+ def command(*args, &block)
178
+ if block_given?
179
+ @command_queue.push [ args, block ]
180
+ @event_write.write "\x01"
181
+ else
182
+ queue = Queue.new
183
+ command(*args) { |response| queue.push response }
184
+ queue.pop
185
+ end
186
+ end
187
+
188
+ def translate_response(response)
189
+ if response.error?
190
+ raise Interface::CardReader::CardReaderError.new(
191
+ "communication error",
192
+ Interface::CardReader::COMMUNICATION_ERROR
193
+ )
194
+ elsif response.negative?
195
+ error = response.response[0..1].to_i(16)
196
+ if ERRORS.include? error
197
+ translated_error = ERRORS[error]
198
+ else
199
+ translated_error = Interface::CardReader::HARDWARE_ERROR
200
+ end
201
+
202
+ raise Interface::CardReader::CardReaderError.new(
203
+ "command failed: #{error}",
204
+ translated_error
205
+ )
206
+ end
207
+ end
208
+
209
+ def set_led(color)
210
+ code = nil
211
+
212
+ case color
213
+ when :off
214
+ code = 0x30
215
+
216
+ when :green
217
+ code = 0x31
218
+
219
+ when :red
220
+ code = 0x32
221
+
222
+ when :orange
223
+ code = 0x33
224
+ end
225
+
226
+ command(0x35, code) do |resp|
227
+
228
+ end
229
+ end
230
+
231
+ def complete_init(response)
232
+ if response.error?
233
+ Smartware::Logging.logger.info "ICT3K5: initialization error"
234
+ elsif response.negative?
235
+ Smartware::Logging.logger.info "ICT3K5: initialization negative: #{response.response}"
236
+ else
237
+ Smartware::Logging.logger.info "ICT3K5: initialization: #{response.response}"
238
+ @status_mutex.synchronize { @ready = true }
239
+ set_led :red
240
+ end
241
+ end
242
+
243
+ def run_periodic
244
+ if @start_time.nil?
245
+ elapsed = nil
246
+ else
247
+ elapsed = Time.now - @start_time
248
+ end
249
+
250
+ case @state
251
+ when :not_ready
252
+ if @port.dsr == 1
253
+
254
+ Smartware::Logging.logger.info "ICT3K5: DSR active, initializing"
255
+
256
+ @state = :accepting
257
+
258
+ flushed = []
259
+
260
+ command 0x30, # Initialize
261
+ 0x30, # Eject card,
262
+ 0x33, 0x32, 0x34, 0x31, 0x30, # Compatibility nonsense
263
+ 0x30, # Power down card
264
+ 0x31, # Identify reader
265
+ 0x30, # Eject card on DTR low
266
+ 0x30, # Turn off capture counter
267
+ &method(:complete_init)
268
+
269
+ flushed.each do |(command, block)|
270
+ block.call CommandResponse.new(error: "timeout")
271
+ end
272
+ end
273
+
274
+ when :waiting_ack
275
+ if elapsed > 0.3
276
+ Smartware::Logging.logger.info "ICT3K5: ACK timeout"
277
+ retry_or_fail
278
+ end
279
+
280
+ when :reading_response
281
+ if elapsed > 20
282
+ Smartware::Logging.logger.info "ICT3K5: command timeout"
283
+ retry_or_fail
284
+ end
285
+ end
286
+
287
+ if @port.dsr == 0
288
+ @status_mutex.synchronize do
289
+ @ready = false
290
+ @accepting = false
291
+ end
292
+
293
+ if !@active_command.nil?
294
+ Smartware::Logging.logger.info "ICT3K5: DSR fall"
295
+
296
+ fail_command
297
+ end
298
+
299
+ until @command_queue.empty?
300
+ unpacked, block = @command_queue.pop(true)
301
+
302
+ block.call CommandResponse.new(nil)
303
+ end
304
+ end
305
+ end
306
+
307
+ def start_execution
308
+ @event_read.readbyte
309
+
310
+ unpacked, @active_block = @command_queue.pop
311
+ @active_command = frame_command(unpacked)
312
+
313
+ @write_buf << @active_command
314
+ @start_time = Time.now
315
+ @state = :waiting_ack
316
+ @retries = 8
317
+ end
318
+
319
+ def complete_command(response)
320
+ block = @active_block
321
+
322
+ @state = :accepting
323
+ @active_command = nil
324
+ @active_block = nil
325
+
326
+ Smartware::Logging.logger.info "ICT3K5: completing command"
327
+
328
+ block.call CommandResponse.new(response)
329
+ end
330
+
331
+ def fail_command
332
+ block = @active_block
333
+
334
+ @state = :accepting
335
+ @active_command = nil
336
+ @active_block = nil
337
+
338
+ Smartware::Logging.logger.info "ICT3K5: failing command"
339
+
340
+ block.call CommandResponse.new(nil)
341
+ end
342
+
343
+ def retry_or_fail
344
+ if @retries == 0
345
+ fail_command
346
+ else
347
+ @retries -= 1
348
+ @start_time = Time.now
349
+ @state = :waiting_ack
350
+ @write_buf << @active_command
351
+ end
352
+ end
353
+
354
+ def frame_command(bytes)
355
+ data = [ STX, bytes.length + 1 ].pack("Cn")
356
+ data << "C"
357
+ data << bytes.pack("C*")
358
+
359
+ crc = CRC.new
360
+ crc << data
361
+ data << [ crc.checksum ].pack("n")
362
+
363
+ data
364
+ end
365
+
366
+ def read_chunk
367
+ @read_buf << @port.read_nonblock(8192)
368
+ rescue IO::WaitReadable
369
+ end
370
+
371
+ def write_chunk
372
+ bytes = @port.write_nonblock @write_buf
373
+ @write_buf.slice! 0, bytes
374
+
375
+ rescue IO::WaitWritable
376
+ end
377
+
378
+ def handle_input
379
+ until @read_buf.empty? do
380
+ case @state
381
+ when :waiting_ack
382
+ initial_byte = @read_buf.slice!(0, 1).ord
383
+
384
+ case initial_byte
385
+ when ACK
386
+ Smartware::Logging.logger.info "ICT3K5: ACK"
387
+
388
+ @state = :reading_response
389
+ @start_time = Time.now
390
+
391
+ when NAK
392
+ Smartware::Logging.logger.info "ICT3K5: NAK"
393
+
394
+ retry_or_fail
395
+
396
+ else
397
+ Smartware::Logging.logger.info "ICT3K5: garbage on line: #{initial_byte}"
398
+ end
399
+
400
+ when :reading_response
401
+ break if @read_buf.length < 5
402
+
403
+ leading_byte, length = @read_buf[0..2].unpack("Cn")
404
+ if leading_byte != STX
405
+ Smartware::Logging.logger.info "ICT3K5: garbage on line: #{leading_byte}"
406
+
407
+ @read_buf.slice! 0, 1
408
+ next
409
+ end
410
+
411
+ full_length = 5 + length
412
+
413
+ break if @read_buf.length < full_length
414
+
415
+ message = @read_buf.slice! 0, full_length
416
+ sum, = message.slice!(full_length - 2, 2).unpack("n")
417
+ crc = CRC.new
418
+ crc << message
419
+ if sum == crc.checksum
420
+ Smartware::Logging.logger.info "ICT3K5: message checksum ok, ACK and process"
421
+ @write_buf << ACK.chr
422
+ complete_command message[3..-1]
423
+ else
424
+ Smartware::Logging.logger.info "ICT3K5: message checksum invalid, NAK"
425
+ @write_buf << NAK.chr
426
+ end
427
+
428
+ else
429
+ break
430
+ end
431
+ end
432
+ end
433
+
434
+ def dispatch
435
+ loop do
436
+ begin
437
+ run_periodic
438
+
439
+ read_set = [ @port ]
440
+ write_set = []
441
+
442
+ read_set << @event_read if @state == :accepting
443
+ write_set << @port unless @write_buf.empty?
444
+
445
+ read_set, write_set, = IO.select read_set, write_set, [], 1
446
+
447
+ unless read_set.nil?
448
+ start_execution if read_set.include? @event_read
449
+ read_chunk if read_set.include? @port
450
+ write_chunk if write_set.include? @port
451
+ end
452
+
453
+ handle_input
454
+ rescue => e
455
+ Smartware::Logging.logger.error "Error in ICT3K5 dispatch:"
456
+ Smartware::Logging.logger.error e.to_s
457
+ e.backtrace.each do |line|
458
+ Smartware::Logging.logger.error line
459
+ end
460
+ end
461
+ end
462
+ end
463
+ end
464
+ end
465
+ end
466
+ end
@@ -9,7 +9,14 @@ module Smartware
9
9
  attr_reader :error, :model, :balance, :version
10
10
 
11
11
  def initialize(config)
12
- @config = config
12
+ @port = config["port"]
13
+ @balance_ussd = config["balance_ussd"]
14
+ @status_channel_id = config["status_channel"].to_i
15
+ @ppp_channel_id = config["ppp_channel"].to_i
16
+ @poll_interval = config["poll_interval"].to_i
17
+ @balance_interval = config["balance_interval"].to_i
18
+ @apn = config["apn"]
19
+
13
20
  @state = :closed
14
21
  @error = Interface::Modem::MODEM_NOT_AVAILABLE
15
22
  @mux = nil
@@ -18,7 +25,7 @@ module Smartware
18
25
  @model = "GSM modem"
19
26
  @version = ""
20
27
  @signal = "+CSQ: 99,99"
21
- @ussd_interval = 0
28
+ @balance_timer = 0
22
29
  @balance = nil
23
30
  @ppp_state = :stopped
24
31
  @ppp_pid = nil
@@ -70,13 +77,13 @@ module Smartware
70
77
  Smartware::Logging.logger.info "trying to open modem"
71
78
 
72
79
  begin
73
- @mux = CMUX::MUX.new @config["port"]
80
+ @mux = CMUX::MUX.new @port
74
81
  @state = :open
75
- @status_channel = @mux.allocate(@config["status_channel"]).open
82
+ @status_channel = @mux.allocate(@status_channel_id).open
76
83
  @chatter = CMUX::ModemChatter.new @status_channel
77
84
  @chatter.subscribe "CUSD", self
78
85
  @error = nil
79
- @ussd_interval = 0
86
+ @balance_timer = 0
80
87
  Smartware::Logging.logger.info "modem ready"
81
88
  rescue => e
82
89
  close_modem "unable to open modem: #{e}"
@@ -103,15 +110,15 @@ module Smartware
103
110
  end
104
111
 
105
112
  if modem_works
106
- if @config.include?("balance_ussd") && @ussd_interval == 0
107
- @ussd_interval = @config["balance_interval"]
113
+ if !@balance_ussd.nil? && @balance_timer == 0
114
+ @balance_timer = @balance_interval
108
115
  begin
109
- @chatter.command("+CUSD=1,\"#{@config["balance_ussd"]}\",15", 1)
116
+ @chatter.command("+CUSD=1,\"#{@balance_ussd}\",15", 1)
110
117
  rescue => e
111
118
  close_modem "USSD request failed: #{e}"
112
119
  end
113
120
  else
114
- @ussd_interval -= 1
121
+ @balance_timer -= 1
115
122
  end
116
123
  else
117
124
  close_modem "modem is not responding"
@@ -125,11 +132,11 @@ module Smartware
125
132
  if @state == :open
126
133
  Smartware::Logging.logger.info "trying to start pppd"
127
134
  begin
128
- @ppp_channel = @mux.allocate @config["ppp_channel"]
135
+ @ppp_channel = @mux.allocate @ppp_channel_id
129
136
 
130
137
  @ppp_pid = Process.spawn "smartware-ppp-helper",
131
138
  @ppp_channel.device,
132
- @config["apn"]
139
+ @apn
133
140
  @ppp_state = :running
134
141
 
135
142
  Smartware::Logging.logger.info "started pppd, PID #{@ppp_pid}"
@@ -171,12 +178,12 @@ module Smartware
171
178
  def wait_for_event
172
179
  if @state == :open
173
180
  begin
174
- CMUX::ModemChatter.poll [ @chatter ], @config["poll_interval"]
181
+ CMUX::ModemChatter.poll [ @chatter ], @poll_interval
175
182
  rescue => e
176
183
  close_modem "modem poll failed: #{e}"
177
184
  end
178
185
  else
179
- sleep @config["poll_interval"]
186
+ sleep @poll_interval
180
187
  end
181
188
 
182
189
  end
@@ -25,6 +25,13 @@ module Smartware
25
25
  end
26
26
 
27
27
  def print(data)
28
+ name = "smartwareprint_#{Time.now.strftime("%Y-%m-%d-%H:%M:%S")}.txt"
29
+ pathname = File.join(Dir.home, name)
30
+
31
+ File.open(pathname, 'w') { |io| io.write data }
32
+
33
+ Logging.logger.info "Created #{pathname}"
34
+
28
35
  true
29
36
  end
30
37
 
@@ -33,10 +40,23 @@ module Smartware
33
40
  end
34
41
 
35
42
  def new_render
36
- Redcarpet::Render::HTML.new
43
+ DummyRender.new
37
44
  end
38
45
  end
39
46
 
47
+ class DummyRender < Redcarpet::Render::Base
48
+ def linebreak
49
+ "\n"
50
+ end
51
+
52
+ def normal_text(text, keep_newlines = false)
53
+ unless keep_newlines
54
+ text.gsub! "\n", " "
55
+ end
56
+
57
+ text
58
+ end
59
+ end
40
60
  end
41
61
  end
42
62
  end
@@ -0,0 +1,83 @@
1
+ module Smartware
2
+ module Interface
3
+ class CardReader < Interface
4
+ COMMUNICATION_ERROR = 1
5
+ HARDWARE_ERROR = 2
6
+ CARD_JAM_ERROR = 3
7
+ CARD_ERROR = 4
8
+ MAG_READ_ERROR = 5
9
+ ICC_ERROR = 6
10
+
11
+ class CardReaderError < RuntimeError
12
+ attr_reader :code
13
+
14
+ def initialize(message, code)
15
+ super(message)
16
+
17
+ @code = code
18
+ end
19
+ end
20
+
21
+ def initialize(config)
22
+ super
23
+
24
+ @status[:model] = @device.model
25
+ @status[:version] = @device.version
26
+ end
27
+
28
+ def card_inserted?
29
+ @device.status == :card_inserted
30
+ rescue CardReaderError => e
31
+ @status[:error] = e.code
32
+ nil
33
+ end
34
+
35
+ def start_accepting
36
+ @device.accepting = true
37
+ @status[:error] = nil
38
+ true
39
+ rescue CardReaderError => e
40
+ @status[:error] = e.code
41
+ false
42
+ end
43
+
44
+ def stop_accepting
45
+ @device.accepting = false
46
+ @status[:error] = nil
47
+ true
48
+ rescue CardReaderError => e
49
+ @status[:error] = e.code
50
+ false
51
+ end
52
+
53
+ def eject
54
+ @device.eject
55
+
56
+ sleep 0.5 while @device.status == :card_at_gate
57
+
58
+ @status[:error] = nil
59
+ true
60
+ rescue CardReaderError => e
61
+ @status[:error] = e.code
62
+ false
63
+ end
64
+
65
+ def capture
66
+ @device.capture
67
+ @status[:error] = nil
68
+ true
69
+ rescue CardReaderError => e
70
+ @status[:error] = e.code
71
+ false
72
+ end
73
+
74
+ def read_magstrip
75
+ @device.read_magstrip
76
+
77
+ rescue CardReaderError => e
78
+ @status[:error] = e.code
79
+ nil
80
+ end
81
+ end
82
+ end
83
+ end
@@ -17,7 +17,7 @@ module Smartware
17
17
  unless @config["connection_timeout"].nil?
18
18
  Thread.new do
19
19
  begin
20
- monitor = ConnectionMonitor.new @config["connection_timeout"]
20
+ monitor = ConnectionMonitor.new @config["connection_timeout"].to_i
21
21
 
22
22
  monitor.run
23
23
  rescue => e
@@ -1,3 +1,3 @@
1
1
  module Smartware
2
- VERSION = "0.2.7"
2
+ VERSION = "0.2.8"
3
3
  end
data/lib/smartware.rb CHANGED
@@ -3,6 +3,7 @@ require 'yaml'
3
3
  require 'active_support/core_ext/string/inflections'
4
4
  require 'drb'
5
5
  require 'redcarpet'
6
+ require 'stringio'
6
7
 
7
8
  require 'smartkiosk/common'
8
9
 
@@ -14,11 +15,13 @@ require 'smartware/clients/cash_acceptor'
14
15
  require 'smartware/clients/printer'
15
16
  require 'smartware/clients/modem'
16
17
  require 'smartware/clients/watchdog'
18
+ require 'smartware/clients/card_reader'
17
19
  require 'smartware/interfaces/interface'
18
20
  require 'smartware/interfaces/cash_acceptor'
19
21
  require 'smartware/interfaces/modem'
20
22
  require 'smartware/interfaces/printer'
21
23
  require 'smartware/interfaces/watchdog'
24
+ require 'smartware/interfaces/card_reader'
22
25
  require 'smartware/connection_monitor'
23
26
 
24
27
  module Smartware
data/smartware.gemspec CHANGED
@@ -23,4 +23,5 @@ Gem::Specification.new do |gem|
23
23
  gem.add_dependency 'trollop'
24
24
  gem.add_dependency 'activesupport'
25
25
  gem.add_dependency 'redcarpet'
26
+ gem.add_dependency 'digest-crc'
26
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartware
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-21 00:00:00.000000000 Z
13
+ date: 2013-01-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: smartkiosk-common
@@ -108,6 +108,22 @@ dependencies:
108
108
  - - ! '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: digest-crc
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
111
127
  description: Smartware is the Smartkiosk hardware control daemon
112
128
  email:
113
129
  - e.sudarchikov@roundlake.ru
@@ -127,11 +143,14 @@ files:
127
143
  - bin/smartware-ppp-helper
128
144
  - config/smartware.yml.sample
129
145
  - lib/smartware.rb
146
+ - lib/smartware/clients/card_reader.rb
130
147
  - lib/smartware/clients/cash_acceptor.rb
131
148
  - lib/smartware/clients/modem.rb
132
149
  - lib/smartware/clients/printer.rb
133
150
  - lib/smartware/clients/watchdog.rb
134
151
  - lib/smartware/connection_monitor.rb
152
+ - lib/smartware/drivers/card_reader/dummy.rb
153
+ - lib/smartware/drivers/card_reader/ict3_k5.rb
135
154
  - lib/smartware/drivers/cash_acceptor/ccnet.rb
136
155
  - lib/smartware/drivers/cash_acceptor/dummy.rb
137
156
  - lib/smartware/drivers/modem/dummy.rb
@@ -140,6 +159,7 @@ files:
140
159
  - lib/smartware/drivers/printer/esc_pos.rb
141
160
  - lib/smartware/drivers/watchdog/dummy.rb
142
161
  - lib/smartware/drivers/watchdog/watchdog_daemon.rb
162
+ - lib/smartware/interfaces/card_reader.rb
143
163
  - lib/smartware/interfaces/cash_acceptor.rb
144
164
  - lib/smartware/interfaces/interface.rb
145
165
  - lib/smartware/interfaces/modem.rb