da_funk 0.4.4 → 0.4.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1428a015e59da2c2ba1c5b7db367d3a675d8dc27
4
- data.tar.gz: 9932163afefdab19e28393464f99aeebbc3a450b
3
+ metadata.gz: ec1d9846f46aa2dac82e6aa65bcda41838400d2b
4
+ data.tar.gz: 81335482ebcc090564b03cfeec21434f29fc6be2
5
5
  SHA512:
6
- metadata.gz: 99b76fb9cf5da0fbdc7e1b9c40fd3e687ef5f650facf6b89b228f0680e3e949e9d5ff06e60e8fbe8be8c12de2898689ba66c4592ee3d10e0ef8d78d355ccf80c
7
- data.tar.gz: 39ad52f41a43b49e6c6e053a9a0c1c691a4d4755d37414221678bc4be7533c4b75169fe325d90cc42e31eee2c8e9333c4a8ff680ea1e6bc831ada8a4edf5dc12
6
+ metadata.gz: cf63404ca741cae273ba0c59ab2c88ba9c46b3b211d82faaa41a18f25bec532f8458fc7d4e6db258189a071be125f91e640d240e1ab6242620a9b0c5ea908b44
7
+ data.tar.gz: e9d59a6978b202957fb58e522d1c76835c8649d7dc86545cd9a50ce3f28a502affa7da2b2c39856209a34b41ae4ac89f2a78ebf6b6bc78ef57a9cd1d1b5f6d25
data/README.md CHANGED
@@ -18,34 +18,19 @@ Walk Framework API, responsible for managed compatibility between implemented de
18
18
 
19
19
  ### Steps
20
20
 
21
- 1. Add da_funk as submodule `$ git submodule add git@github.com:cloudwalkio/da_funk.git <path/to/lib/da_funk>`
21
+ 1. Add da_funk as submodule of your platform project, check the sample [here](https://github.com/cloudwalkio/around_the_world) `$ git submodule add git@github.com:cloudwalkio/da_funk.git <path/to/lib/da_funk>`
22
22
 
23
- 2. Develop start method in platform abstraction.
23
+ 2. Develop setup method in platform abstraction.
24
24
 
25
- Start method is responsible for start the runtime in our platform. And should require the da_funk lib(common lib between platforms).
25
+ Setup method will be called in every app execution, should be use to filesystem preparation or any shore needed by the app environment. Check the sample [here](https://github.com/cloudwalkio/mruby-cloudwalk-platform).
26
26
 
27
27
  class PlatformInterface
28
- def self.start(file = "./main.mrb")
29
- begin
30
- require "./da_funk.mrb"
31
- require "./platform.mrb"
32
- require file
33
-
34
- app = Device::Support.path_to_class file
35
-
36
- loop do
37
- app.call
38
- end
39
- rescue => @exception
40
- puts "#{@exception.class}: #{@exception.message}"
41
- puts "#{@exception.backtrace[0..2].join("\n")}"
42
- IO.getc
43
- return nil
44
- end
45
- end
28
+ def self.setup
29
+ # Configuration and initialization before apps execution
30
+ end
46
31
  end
47
32
 
48
- 3. Develop interface required by DaFunk on PlatformInterface, could be the same file you have start method.
33
+ 3. Develop interface required by DaFunk on PlatformInterface, could be the same file you have setup method.
49
34
 
50
35
  class PlatformInterface
51
36
  Network = ::Network # Implemented on C
@@ -66,7 +51,7 @@ Walk Framework API, responsible for managed compatibility between implemented de
66
51
  4. Configure Adapter
67
52
 
68
53
  class Device # Class from DaFunk
69
- self.adapter = PlatformAbstraction
54
+ self.adapter = PlatformInterface
70
55
  end
71
56
 
72
57
  5. Compile da_funk into mrb file `$ rake`.
data/RELEASE_NOTES.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # DaFunk
2
2
 
3
+ ### 0.4.5 - 2015-06-09 - ISO8583, environment and abstraction classes
4
+ - Implementing support to change host environment configuration with Setting.to_production! and Setting.to_staging!.
5
+ - Fix da_funk.mrb out path getting the app name to output da_funk.mrb.
6
+ - Add tests to FileDb and ParamsDat.
7
+ - Improve README adding chapters about AroundTheWorld project.
8
+ - Add return 7 to Device::System.battery, which means power supply connected and has no battery.
9
+ - Support to Network::Ethernet abstraction.
10
+ - Support to Print abstraction.
11
+ - Fix number_to_currency on the 1.1.0 mruby version.
12
+ - Update ISO8583 library.
13
+
3
14
  ### 0.4.4 - 2015-03-27 - Gemspec summary and description.
4
15
  - Fix gemspec summary and description.
5
16
 
data/Rakefile CHANGED
@@ -19,7 +19,7 @@ FILES = FileList[
19
19
  "lib/device/io.rb",
20
20
  "lib/device/network.rb",
21
21
  "lib/device/params_dat.rb",
22
- "lib/device/printer.rb",
22
+ "lib/device/print.rb",
23
23
  "lib/device/runtime.rb",
24
24
  "lib/device/setting.rb",
25
25
  "lib/device/support.rb",
@@ -69,6 +69,16 @@ module DaFunk
69
69
  end
70
70
  end
71
71
 
72
+ def check_gem_out(gem)
73
+ if File.exists?(path = File.join(gem.full_gem_path, "out", gem.name)) && File.file?(path)
74
+ elsif File.exists?(path = File.join(gem.full_gem_path, "out", gem.name, "main.mrb")) && File.file?(path)
75
+ elsif File.exists?(path = File.join(gem.full_gem_path, "out", gem.name, "#{gem.name}.mrb")) && File.file?(path)
76
+ else
77
+ return nil
78
+ end
79
+ return path
80
+ end
81
+
72
82
  def define
73
83
  task :resources do
74
84
  FileUtils.rm_rf File.join(root_path, "out")
@@ -86,7 +96,8 @@ module DaFunk
86
96
  FileUtils.mkdir_p out_path
87
97
 
88
98
  Bundler.load.specs.each do |gem|
89
- sh "cp #{File.join(gem.full_gem_path, "out", gem.name)}.mrb #{out_path}/#{gem.name}.mrb" if File.exists? "#{File.join(gem.full_gem_path, "out", gem.name)}.mrb"
99
+ path = check_gem_out(gem)
100
+ FileUtils.cp(path, File.join(out_path, "#{gem.name}.mrb")) if path
90
101
  end
91
102
 
92
103
  sh "#{mrbc} -g -o #{main_out} #{libs} "
data/lib/da_funk.rb CHANGED
@@ -6,7 +6,7 @@ unless Object.const_defined?(:MTest)
6
6
  require file_path + "/device/display.rb"
7
7
  require file_path + "/device/io.rb"
8
8
  require file_path + "/device/network.rb"
9
- require file_path + "/device/printer.rb"
9
+ require file_path + "/device/print.rb"
10
10
  require file_path + "/device/setting.rb"
11
11
  require file_path + "/device/system.rb"
12
12
  require file_path + "/device/version.rb"
data/lib/device/helper.rb CHANGED
@@ -96,6 +96,7 @@ class Device
96
96
 
97
97
  if value.is_a? Float
98
98
  number, unit = value.to_s.split(".")
99
+ unit = unit.to_s
99
100
  len = number.size + unit.size
100
101
  else
101
102
  len = value.to_s.size
@@ -2,8 +2,9 @@
2
2
  class Device
3
3
  class Network
4
4
 
5
- MEDIA_GPRS = "gprs"
6
- MEDIA_WIFI = "wifi"
5
+ MEDIA_GPRS = "gprs"
6
+ MEDIA_WIFI = "wifi"
7
+ MEDIA_ETHERNET = "ethernet"
7
8
 
8
9
  AUTH_NONE_OPEN = "open"
9
10
  AUTH_NONE_WEP = "wep"
@@ -149,7 +150,7 @@ class Device
149
150
  while(ret == PROCESSING)
150
151
  ret = Device::Network.connected?
151
152
  end
152
- if ret == SUCCESS && wifi?
153
+ if ret == SUCCESS && (wifi? || ethernet?)
153
154
  Device::Network.dhcp_client(20000)
154
155
  end
155
156
  ret
@@ -177,6 +178,8 @@ class Device
177
178
  cipher: Device::Setting.cipher,
178
179
  mode: Device::Setting.mode
179
180
  }
181
+ elsif ethernet?
182
+ Hash.new
180
183
  end
181
184
  end
182
185
 
@@ -187,6 +190,10 @@ class Device
187
190
  def self.wifi?
188
191
  Device::Setting.media == "wifi"
189
192
  end
193
+
194
+ def self.ethernet?
195
+ Device::Setting.media == "ethernet"
196
+ end
190
197
  end
191
198
  end
192
199
 
@@ -13,12 +13,13 @@ class Device
13
13
  # To control if there is any app and parse worked
14
14
  self.status = false
15
15
 
16
+ def self.file
17
+ self.setup unless @file
18
+ @file
19
+ end
20
+
16
21
  def self.setup
17
- if File.exists?(FILE_NAME)
18
- @file = FileDb.new(FILE_NAME)
19
- else
20
- false
21
- end
22
+ @file = FileDb.new(FILE_NAME)
22
23
  end
23
24
 
24
25
  # TODO Scalone: Change after @bmsatierf change the format
@@ -0,0 +1,189 @@
1
+
2
+ class Device
3
+ class Print
4
+ RET_OK = 0
5
+ ERR_PRN_BUSY = -3701 # Printer busy
6
+ ERR_PRN_PAPEROUT = -3702 # Out of paper
7
+ ERR_PRN_WRONG_PACKAGE = -3703 # The format of print data packet error
8
+ ERR_PRN_OVERHEAT = -3704 # Printer over heating
9
+ ERR_PRN_OUTOFMEMORY = -3705 # The print data is too large, and exceeds the buffer length.
10
+ ERR_PRN_OVERVOLTAGE = -3706 # Voltage is too high.
11
+ ERR_INVALID_PARAM = -1003 # Invalid parameter.
12
+ ERR_DEV_NOT_EXIST = -1004 # Device does not exist.
13
+ ERR_DEV_BUSY = -1005 # Device is busy.
14
+ ERR_FONT_NOT_EXIST = -1008 # Font does not exist.
15
+
16
+ DEFAULT_SINGLE_WIDTH = 12
17
+ DEFAULT_SINGLE_HEIGHT = 24
18
+ DEFAULT_MULTI_WIDTH = 24
19
+ DEFAULT_MULTI_HEIGHT = 24
20
+
21
+ def self.adapter
22
+ Device.adapter::Print
23
+ end
24
+
25
+ # Initialize Printer device.
26
+ #
27
+ # @param singlecode_width [Fixnum] The width control of single code font.
28
+ # (For non-monospaced font, width of each character may not meet the settings).
29
+ # The value ranges from 8 to 64.
30
+ # @param singlecode_height [Fixnum] The height control of single code font.
31
+ # The value ranges from 8 to 64.
32
+ # @param multicode_width [Fixnum] The width control of multiple code font.
33
+ # The value ranges from 12 to 64.
34
+ # @param multicode_height [Fixnum] The height control of multiple code font
35
+ # The value ranges from 12 to 64.
36
+ #
37
+ # @retval RET_OK Success.
38
+ # @retval ERR_FONT_NOT_EXIST Font does not exist.
39
+ # @retval ERR_INVALID_PARAM Invalid parameter.
40
+ # @retval ERR_DEV_BUSY Device is busy.
41
+ #
42
+ # @return [Fixnum] Return number.
43
+ def self.start(singlecode_width=DEFAULT_SINGLE_WIDTH,
44
+ singlecode_height=DEFAULT_SINGLE_HEIGHT,
45
+ multicode_width=DEFAULT_MULTI_WIDTH,
46
+ multicode_height=DEFAULT_MULTI_HEIGHT)
47
+ self.adapter.start(singlecode_width, singlecode_height, multicode_width, multicode_height)
48
+ end
49
+
50
+ # Check printer status, useful for paper check.
51
+ #
52
+ # @retval RET_OK Success.
53
+ # @retval ERR_FONT_NOT_EXIST Font does not exist.
54
+ # @retval ERR_INVALID_PARAM Invalid parameter.
55
+ # @retval ERR_DEV_BUSY Device is busy.
56
+ #
57
+ # @return [Fixnum] Return number.
58
+ def self.open
59
+ self.adapter.open
60
+ end
61
+
62
+ # Restore the printer default settings and clear the print buffer data.
63
+ #
64
+ # @return [NilClass] Allways returns nil.
65
+ def self.reset
66
+ self.adapter.reset
67
+ end
68
+
69
+ # Closes the printer.
70
+ #
71
+ # @return [NilClass] Allways returns nil.
72
+ def self.close
73
+ self.adapter.close
74
+ end
75
+
76
+ # Selects print font.
77
+ #
78
+ # @param filename [String] Font filename.
79
+ #
80
+ # @retval RET_OK Success.
81
+ # @retval ERR_FONT_NOT_EXIST Font does not exist.
82
+ # @retval ERR_INVALID_PARAM Invalid parameter.
83
+ def self.font=(path)
84
+ self.adapter.font = path
85
+ end
86
+
87
+ # Sets printing gray level.
88
+ #
89
+ # @param value [Fixnum] Value to define level
90
+ # 􏰀 Level =0, reserved,
91
+ # 􏰀 Level =1, default level, normal print slip,
92
+ # 􏰀 Level =2, reserved,
93
+ # 􏰀 Level =3, two-layer thermal printing,
94
+ # 􏰀 Level =4, two-layer thermal printing, higher gray
95
+ # level than 3,
96
+ # 􏰀 The default level is 1.
97
+ # 􏰀 The illegal value does not change current settings.
98
+ #
99
+ # @return [NilClass] Allways returns nil.
100
+ def self.level=(value)
101
+ self.adapter.level = value
102
+ end
103
+
104
+ # Define size, in pixel, of printing
105
+ #
106
+ # @param singlecode_width [Fixnum] The width control of single code font.
107
+ # (For non-monospaced font, width of each character may not meet the settings).
108
+ # The value ranges from 8 to 64.
109
+ # @param singlecode_height [Fixnum] The height control of single code font.
110
+ # The value ranges from 8 to 64.
111
+ # @param multicode_width [Fixnum] The width control of multiple code font.
112
+ # The value ranges from 12 to 64.
113
+ # @param multicode_height [Fixnum] The height control of multiple code font
114
+ # The value ranges from 12 to 64.
115
+ #
116
+ # @return [NilClass] Allways returns nil.
117
+ def self.size(singlecode_width=DEFAULT_SINGLE_WIDTH,
118
+ singlecode_height=DEFAULT_SINGLE_HEIGHT,
119
+ multicode_width=DEFAULT_MULTI_WIDTH,
120
+ multicode_height=DEFAULT_MULTI_HEIGHT)
121
+ self.adapter.size(singlecode_width, singlecode_height, multicode_width, multicode_height)
122
+ end
123
+
124
+ # Feeds printing paper.
125
+ #
126
+ # @return [NilClass] Allways returns nil.
127
+ def self.paperfeed
128
+ self.adapter.feed
129
+ end
130
+
131
+ # Write text on print buffer.
132
+ #
133
+ # @param string [String] Text to be printed.
134
+ #
135
+ # @return [NilClass] Allways returns nil.
136
+ def self.print(string)
137
+ self.adapter.print(string)
138
+ end
139
+
140
+ # Write text on print buffer.
141
+ #
142
+ # @param string [String] Text to be printed.
143
+ #
144
+ # @return [NilClass] Allways returns nil.
145
+ def self.puts(string)
146
+ self.adapter.puts(string)
147
+ end
148
+
149
+ # Print bmp file.
150
+ #
151
+ # Details:
152
+ # Bitmap data is generated as monochromatic, bmp format.
153
+ # Printing bitmap size limit up to 384 pixels in width, spocket with 180 pixels and the height is unlimited.
154
+ # If the bitmap width is larger than the limit of the printer, then it will be sliced on the right side.
155
+ # If the data packet is too long, then this function will remove the LOGO message.
156
+ #
157
+ # @param path [String] Path to bmp file.
158
+ #
159
+ # @return [NilClass] Allways returns nil.
160
+ def self.print_bmp(path)
161
+ self.adapter.print_bmp(path)
162
+ end
163
+
164
+ # Check printer status, useful for paper check.
165
+ #
166
+ # @retval RET_OK Success.
167
+ # @retval ERR_FONT_NOT_EXIST Font does not exist.
168
+ # @retval ERR_INVALID_PARAM Invalid parameter.
169
+ # @retval ERR_PRN_BUSY Printer is busy.
170
+ # @retval ERR_PRN_PAPEROUT Out of paper.
171
+ # @retval ERR_PRN_OVERHEAT Printer overheating.
172
+ def self.check
173
+ self._check
174
+ end
175
+
176
+ # Check if printer has paper
177
+ #
178
+ # @return [TrueClass] Has paper.
179
+ # @return [FalseClass] No paper.
180
+ def self.paper?
181
+ if self.check == ERR_PRN_PAPEROUT
182
+ false
183
+ else
184
+ true
185
+ end
186
+ end
187
+ end
188
+ end
189
+
@@ -4,10 +4,12 @@ class Device
4
4
  FILE_PATH = "./main/config.dat"
5
5
  HOST_PRODUCTION = "switch.cloudwalk.io"
6
6
  HOST_STAGING = "switch-staging.cloudwalk.io"
7
+ PORT_TCP = "31415"
8
+ PORT_TCP_SSL = "31416"
7
9
 
8
10
  DEFAULT = {
9
- "host" => "switch-staging.cloudwalk.io",
10
- "host_port" => "31416",
11
+ "host" => HOST_PRODUCTION,
12
+ "host_port" => PORT_TCP_SSL,
11
13
  "ssl" => "1",
12
14
  "user" => "",
13
15
  "password" => "", #WIFI
@@ -35,10 +37,18 @@ class Device
35
37
 
36
38
  def self.setup
37
39
  @file = FileDb.new(FILE_PATH, DEFAULT)
38
- self.host = HOST_STAGING if self.staging?
40
+ self.check_environment!
39
41
  @file
40
42
  end
41
43
 
44
+ def self.check_environment!
45
+ if self.staging?
46
+ self.to_staging!
47
+ else
48
+ self.to_production!
49
+ end
50
+ end
51
+
42
52
  def self.production?
43
53
  self.environment == "production"
44
54
  end
@@ -47,6 +57,14 @@ class Device
47
57
  self.environment == "staging"
48
58
  end
49
59
 
60
+ def self.to_production!
61
+ self.host = HOST_PRODUCTION
62
+ end
63
+
64
+ def self.to_staging!
65
+ self.host = HOST_STAGING
66
+ end
67
+
50
68
  def self.method_missing(method, *args, &block)
51
69
  setup unless @file
52
70
  param = method.to_s
data/lib/device/system.rb CHANGED
@@ -37,6 +37,7 @@ class Device
37
37
  # 4 Battery icon displays 4 grids
38
38
  # 5 Powered by external power supply and the battery in charging. Battery icon displays form empty to full cycle. The battery status indicator on the bottom of terminal is displaying red
39
39
  # 6 Powered by external power supply and the battery charging 6 finished. Battery icon displays full grids. The battery status indicator on the bottom of terminal is displaying green.
40
+ # 7 Powered by external power supply and has no battery.
40
41
  def self.battery
41
42
  adapter.battery
42
43
  end
@@ -1,3 +1,6 @@
1
+ # Copyright 2009 by Tim Becker (tim.becker@kuriostaet.de)
2
+ # MIT License, for details, see the LICENSE file accompaning
3
+ # this distribution
1
4
 
2
5
  module ISO8583
3
6
 
@@ -8,24 +11,26 @@ module ISO8583
8
11
  # In all likelyhood, you won't be using this class much, it's used
9
12
  # transparently by the Message class.
10
13
  class Bitmap
11
-
14
+ include Device::Helper
12
15
  # create a new Bitmap object. In case an iso message
13
16
  # is passed in, that messages bitmap will be parsed. If
14
17
  # not, this initializes and empty bitmap.
15
- def initialize(message = nil)
16
- @bmp = Array.new(128, false)
17
- if !message
18
+ def initialize(message = nil, hex_bitmap=false)
19
+ @bmp = Array.new(128, false)
20
+ @hex_bitmap = hex_bitmap
18
21
 
19
- else
20
- initialize_from_message message
21
- end
22
+ message ? initialize_from_message(message) : nil
22
23
  end
23
-
24
+
25
+ def hex_bitmap?
26
+ !!@hex_bitmap
27
+ end
28
+
24
29
  # yield once with the number of each set field.
25
- def each #:yields: each bit set in the bitmap.
26
- @bmp.each_with_index {|set, i| yield i+1 if set}
30
+ def each #:yields: each bit set in the bitmap except the first bit.
31
+ @bmp[1..-1].each_with_index {|set, i| yield i+2 if set}
27
32
  end
28
-
33
+
29
34
  # Returns whether the bit is set or not.
30
35
  def [](i)
31
36
  @bmp[i-1]
@@ -46,7 +51,7 @@ module ISO8583
46
51
  def set(i)
47
52
  self[i] = true
48
53
  end
49
-
54
+
50
55
  # Unsets bit #i
51
56
  def unset(i)
52
57
  self[i] = false
@@ -61,22 +66,22 @@ module ISO8583
61
66
  end
62
67
  alias_method :to_b, :to_bytes
63
68
 
69
+ def to_hex
70
+ "%02x" % self.to_s.to_i(2)
71
+ end
72
+
64
73
  # Generate a String representation of this bitmap in the form:
65
- # 01001100110000011010110110010100100110011000001101011011001010
74
+ # 01001100110000011010110110010100100110011000001101011011001010
66
75
  def to_s
67
76
  #check whether any `high` bits are set
68
- @bmp[0] = false
69
- 65.upto(128) {|i|
70
- if self[i]
71
- # if so, set continuation bit
72
- @bmp[0] = true
73
- break
74
- end
75
- }
77
+ ret = (65..128).one? {|bit| self[bit]}
78
+ high, @bmp[0] = ret ? [128, true] : [64, false]
79
+
76
80
  str = ""
77
- 1.upto(self[1] ? 128 : 64) {|i|
78
- str << (self[i] ? "1" : "0")
79
- }
81
+ 1.upto(high) do|i|
82
+ str << (self[i] ? '1' : '0')
83
+ end
84
+
80
85
  str
81
86
  end
82
87
 
@@ -84,9 +89,18 @@ module ISO8583
84
89
  private
85
90
 
86
91
  def initialize_from_message(message)
87
- bmp = message.to_i(16).to_s(2)
92
+ bmp = if hex_bitmap?
93
+ rjust(message[0..15].to_i(16).to_s(2), 64, '0')
94
+ else
95
+ message.unpack("B64")[0]
96
+ end
97
+
88
98
  if bmp[0,1] == "1"
89
- bmp = message.to_i(16).to_s(2)
99
+ bmp = if hex_bitmap?
100
+ rjust(message[0..31].to_i(16).to_s(2), 128,'0')
101
+ else
102
+ message.unpack("B128")[0]
103
+ end
90
104
  end
91
105
 
92
106
  0.upto(bmp.length-1) do |i|
@@ -97,18 +111,19 @@ module ISO8583
97
111
  class << self
98
112
  # Parse the bytes in string and return the Bitmap and bytes remaining in `str`
99
113
  # after the bitmap is taken away.
100
- def parse(str)
101
- bmp = Bitmap.new(str)
102
- rest = bmp[1] ? str[32, str.length] : str[16, str.length]
114
+ def parse(str, hex_bitmap = false)
115
+ bmp = Bitmap.new(str, hex_bitmap)
116
+
117
+ rest = if bmp.hex_bitmap?
118
+ bmp[1] ? str[32, str.length] : str[16, str.length]
119
+ else
120
+ bmp[1] ? str[16, str.length] : str[8, str.length]
121
+ end
122
+
103
123
  [ bmp, rest ]
104
124
  end
105
125
  end
106
-
126
+
107
127
  end
108
128
  end
109
129
 
110
- if __FILE__==$0
111
- mp = ISO8583::Bitmap.new
112
- 20.step(128,7) {|i| mp.set(i)}
113
- print mp.to_bytes
114
- end
data/lib/iso8583/codec.rb CHANGED
@@ -1,3 +1,7 @@
1
+ # Copyright 2009 by Tim Becker (tim.becker@kuriostaet.de)
2
+ # MIT License, for details, see the LICENSE file accompaning
3
+ # this distribution
4
+
1
5
  #require 'date'
2
6
 
3
7
  module ISO8583
@@ -54,6 +58,9 @@ module ISO8583
54
58
  # [+MMDDhhmmssCodec+] encodes Time, Datetime or String to the described date format, checking
55
59
  # that it is a valid date. Decodes to a DateTime instance, decoding and
56
60
  # encoding perform validity checks!
61
+ # [+MMDDCodec+] encodes Time, Datetime or String to the described date format, checking
62
+ # that it is a valid date. Decodes to a DateTime instance, decoding and
63
+ # encoding perform validity checks!
57
64
  # [+YYMMDDhhmmssCodec+] encodes Time, Datetime or String to the described date format, checking
58
65
  # that it is a valid date. Decodes to a DateTime instance, decoding and
59
66
  # encoding perform validity checks!
@@ -130,7 +137,7 @@ module ISO8583
130
137
 
131
138
  ANS_Codec = Codec.new
132
139
  ANS_Codec.encoder = lambda{|str|
133
- raise ISO8583Exception.new("Invalid value: #{str} must be [\x20-\x7E]") unless str =~ /^[\x20-\x7E]*$/
140
+ raise ISO8583Exception.new("Invalid value: #{str} must be [\\x20-\\x7E]") unless str =~ /^[\x20-\x7E]*$/
134
141
  str
135
142
  }
136
143
  ANS_Codec.decoder = PASS_THROUGH_DECODER
@@ -191,7 +198,7 @@ module ISO8583
191
198
  HhmmssCodec = _date_codec("%H%M%S")
192
199
  YYMMDDhhmmssCodec = _date_codec("%y%m%d%H%M%S")
193
200
  YYMMCodec = _date_codec("%y%m")
194
- MMDDCodec = _date_codec("%m%d")
195
- YYMMDDCodec = _date_codec("%y%m%d")
201
+ MMDDCodec = _date_codec("%m%d")
196
202
 
197
203
  end
204
+
@@ -2,3 +2,4 @@ module ISO8583
2
2
  class ISO8583Exception < Exception; end
3
3
  class ISO8583ParseException < ISO8583Exception; end
4
4
  end
5
+
data/lib/iso8583/field.rb CHANGED
@@ -52,7 +52,11 @@ module ISO8583
52
52
  # special treatment, you may need to override this method alltogether.
53
53
  # In other cases, the padding has to be implemented by the codec, such as BCD with an odd number of nibbles.
54
54
  def encode(value)
55
- encoded_value = codec.encode(value)
55
+ begin
56
+ encoded_value = codec.encode(value)
57
+ rescue ISO8583Exception
58
+ raise ISO8583Exception.new($!.message+" (#{name})")
59
+ end
56
60
 
57
61
  if padding
58
62
  if padding.arity == 1
@@ -88,3 +92,4 @@ module ISO8583
88
92
  end
89
93
 
90
94
  end
95
+
@@ -1,3 +1,9 @@
1
+ #--
2
+ # Copyright 2009 by Tim Becker (tim.becker@kuriostaet.de)
3
+ # MIT License, for details, see the LICENSE file accompaning
4
+ # this distribution
5
+ #++
6
+
1
7
  module ISO8583
2
8
 
3
9
  # This file contains a number of preinstantiated Field definitions. You
@@ -27,6 +33,7 @@ module ISO8583
27
33
  # [+ANS+] fixed length ASCII [\x20-\x7E], padding left, spaces
28
34
  # [+B+] binary data, padding left using nulls (0x00)
29
35
  # [+MMDDhhmmss+] Date, formatted as described in ASCII numerals
36
+ # [+MMDD+] Date, formatted as described in ASCII numerals
30
37
  # [+YYMMDDhhmmss+] Date, formatted as named in ASCII numerals
31
38
  # [+YYMM+] Expiration Date, formatted as named in ASCII numerals
32
39
  # [+Hhmmss+] Date, formatted in ASCII hhmmss
@@ -156,16 +163,13 @@ module ISO8583
156
163
  YYMM = Field.new
157
164
  YYMM.codec = YYMMCodec
158
165
  YYMM.length = 4
159
-
160
- Hhmmss = Field.new
161
- Hhmmss.codec = HhmmssCodec
162
- Hhmmss.length = 6
163
166
 
164
167
  MMDD = Field.new
165
168
  MMDD.codec = MMDDCodec
166
169
  MMDD.length = 4
167
170
 
168
- YYMMDD = Field.new
169
- YYMMDD.codec = YYMMDDCodec
170
- YYMMDD.length = 6
171
+ Hhmmss = Field.new
172
+ Hhmmss.codec = HhmmssCodec
173
+ Hhmmss.length = 6
171
174
  end
175
+
@@ -1,3 +1,6 @@
1
+ # Copyright 2009 by Tim Becker (tim.becker@kuriostaet.de)
2
+ # MIT License, for details, see the LICENSE file accompaning
3
+ # this distribution
1
4
 
2
5
  module ISO8583
3
6
 
@@ -37,7 +40,7 @@ module ISO8583
37
40
  # be accessed later either via their name or value:
38
41
  #
39
42
  # mes = MyMessage.new 1100
40
- #
43
+ #
41
44
  # or
42
45
  # mes = MyMessage.new "Authorization Request Acquirer Gateway"
43
46
  #
@@ -107,44 +110,22 @@ module ISO8583
107
110
  class Message
108
111
 
109
112
  # The value of the MTI (Message Type Indicator) of this message.
110
- attr_reader :mti, :size_endianness
113
+ attr_reader :mti
114
+
115
+ # ISO8583 allows hex or binary bitmap, so it should be configurable
116
+ attr_reader :use_hex_bitmap
111
117
 
112
118
  # Instantiate a new instance of this type of Message
113
119
  # optionally specifying an mti.
114
- def initialize(mti = nil, size_endianness = :little, format = :ascii)
120
+ def initialize(mti = nil, use_hex_bitmap = false)
115
121
  # values is an internal field used to collect all the
116
122
  # bmp number | bmp name | field en/decoders | values
117
123
  # which are set in this message.
118
124
  @values = {}
119
- @size_endianness = size_endianness
120
- @format = :ascii
121
- self.mti = mti if mti
122
- end
123
-
124
- def build
125
- message = self.to_b
126
- message_size = self.size(message)
127
-
128
- if size_endianness == :little
129
- binary_size = [message_size].pack("s")
130
- elsif size_endianness == :big
131
- binary_size = [message_size].pack("s>")
132
- else
133
- raise ISO8583Exception.new "size endianness no recognized"
134
- end
135
125
 
136
- binary_size + message
137
- end
126
+ self.mti = mti if mti
127
+ @use_hex_bitmap = use_hex_bitmap
138
128
 
139
- def size(message)
140
- case format
141
- when :ascii
142
- message.size
143
- when :bcd
144
- (message.size / 2)
145
- else
146
- raise ISO8583Exception.new "format no recognized"
147
- end
148
129
  end
149
130
 
150
131
  # Set the mti of the Message using either the actual value
@@ -172,9 +153,13 @@ module ISO8583
172
153
  # mes[2]=47474747 # bmp 2 is generally the PAN
173
154
  # mes["Primary Account Number"]=47474747 # if thats what you called the field in Message.bmp.
174
155
  def []=(key, value)
175
- bmp_def = _get_definition key
176
- bmp_def.value = value
177
- @values[bmp_def.bmp] = bmp_def
156
+ if value.nil?
157
+ @values.delete(key)
158
+ else
159
+ bmp_def = _get_definition key
160
+ bmp_def.value = value
161
+ @values[bmp_def.bmp] = bmp_def
162
+ end
178
163
  end
179
164
 
180
165
  # Retrieve the decoded value of the contents of a bitmap
@@ -196,14 +181,6 @@ module ISO8583
196
181
  raise ISO8583Exception.new "no MTI set!" unless mti
197
182
  mti_enc = self.class._mti_format.encode(mti)
198
183
  mti_enc << _body.join
199
-
200
- # length = mti_enc.length.to_s(16).rjust(4, '0')
201
-
202
- length_dec = [mti_enc.length]
203
- length_hex = length_dec.pack("s>")
204
- mti_enc = length_hex + mti_enc
205
-
206
- return mti_enc
207
184
  end
208
185
 
209
186
  # Returns a nicely formatted representation of this
@@ -237,7 +214,12 @@ module ISO8583
237
214
  enc_value = @values[bmp_num].encode
238
215
  message << enc_value
239
216
  end
240
- [ bitmap.to_s.to_i(2).to_s(16).upcase, message ]
217
+
218
+ if use_hex_bitmap
219
+ [bitmap.to_hex, message]
220
+ else
221
+ [bitmap.to_bytes, message]
222
+ end
241
223
  end
242
224
 
243
225
  def _get_definition(key) #:nodoc:
@@ -333,7 +315,7 @@ module ISO8583
333
315
  field.bmp = bmp
334
316
  _handle_opts(field, opts) if opts
335
317
 
336
- bmp_def = ISO8583::BMP.new bmp, name, field
318
+ bmp_def = BMP.new bmp, name, field
337
319
 
338
320
  @defs[bmp] = bmp_def
339
321
  @defs[name] = bmp_def
@@ -372,17 +354,22 @@ module ISO8583
372
354
  end
373
355
 
374
356
  # Parse the bytes `str` returning a message of the defined type.
375
- def parse(str)
376
- message = self.new
357
+ def parse(str, use_hex_bitmap = false)
358
+ message = self.new(nil, use_hex_bitmap)
359
+
377
360
  message.mti, rest = _mti_format.parse(str)
378
361
 
379
- bmp,rest = Bitmap.parse(rest)
362
+ bmp, rest = Bitmap.parse(rest, use_hex_bitmap)
363
+
380
364
  bmp.each {|bit|
381
- if bit > 1 && bit <= 128
382
- bmp_def = _definitions[bit]
383
- value, rest = bmp_def.field.parse(rest)
384
- message[bit] = value
365
+ bmp_def = _definitions[bit]
366
+
367
+ unless bmp_def
368
+ raise ISO8583ParseException.new "The message contains fields not defined"
385
369
  end
370
+
371
+ value, rest = bmp_def.field.parse(rest)
372
+ message[bit] = value
386
373
  }
387
374
  message
388
375
  end
@@ -421,7 +408,7 @@ module ISO8583
421
408
  # in through the `bmp` and `mti_format` class methods.
422
409
  #
423
410
  def _handle_opts(field, opts)
424
- opts.each {|key, value|
411
+ opts.each_pair {|key, value|
425
412
  key = (key.to_s+"=").to_sym
426
413
  if field.respond_to?(key)
427
414
  field.send(key, value)
data/lib/iso8583/util.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # Copyright 2009 by Tim Becker (tim.becker@kuriostaet.de)
2
+ # MIT License, for details, see the LICENSE file accompaning
3
+ # this distribution
1
4
 
2
5
  module ISO8583
3
6
 
@@ -87,5 +90,5 @@ module ISO8583
87
90
  0x5c, 0x3f, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
88
91
  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
89
92
  ]
90
-
91
93
  end
94
+
@@ -1,6 +1,4 @@
1
1
  # -*- mode: ruby; encoding: utf-8; tab-width: 2; indent-tabs-mode: nil -*-
2
-
3
2
  module ISO8583
4
- VERSION = "0.1.5.a"
3
+ VERSION = "0.1.6"
5
4
  end
6
-
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  class Device
3
- API_VERSION="0.4.4"
3
+ API_VERSION="0.4.5"
4
4
  end
5
5
 
@@ -0,0 +1,14 @@
1
+
2
+ class FileDbTest < DaFunk::Test.case
3
+ def test_create
4
+ file_name = "test_create.dat"
5
+ assert_equal false, File.exists?(file_name)
6
+ assert FileDb.new(file_name, Hash.new).hash.is_a? Hash
7
+ end
8
+
9
+ def test_define_unset_value
10
+ file = FileDb.new("test_define_unset_value.dat", {})
11
+ file["unknown"] = "any"
12
+ assert_equal "any", file["unknown"]
13
+ end
14
+ end
@@ -0,0 +1,55 @@
1
+
2
+ class WilliamMessage < ISO8583::Message
3
+ include ISO8583
4
+ mti_format N, :length => 4
5
+ mti 200, "Authorization Request Acquirer Gateway"
6
+ bmp 3 , "Processing Code" , N , :length => 6
7
+ bmp 4 , "Amount (Transaction)" , N , :length => 12
8
+ bmp 7 , "Amount (Transaction)" , N , :length => 10
9
+ bmp 11 , "Amount (Transaction)" , N , :length => 6
10
+ bmp 12 , "Amount (Transaction)" , N , :length => 6
11
+ bmp 13 , "Amount (Transaction)" , N , :length => 4
12
+ bmp 22 , "Amount (Transaction)" , N , :length => 3
13
+ bmp 32 , "Amount (Transaction)" , LLVAR_N
14
+ bmp 35 , "Amount (Transaction)" , LLVAR_N
15
+ bmp 41 , "Amount (Transaction)" , ANS , :length => 8
16
+ bmp 42 , "Amount (Transaction)" , ANS , :length => 15
17
+ bmp 45 , "Amount (Transaction)" , LLVAR_ANS
18
+ bmp 48 , "Amount (Transaction)" , LLLVAR_ANS
19
+ bmp 49 , "Amount (Transaction)" , AN , :length => 3
20
+ bmp 55 , "Amount (Transaction)" , LLLVAR_ANS
21
+ bmp 61 , "Amount (Transaction)" , LLLVAR_ANS
22
+ end
23
+
24
+ #004 Amount (Transaction) : 600
25
+ #007 Amount (Transaction) : 608201250
26
+ #011 Amount (Transaction) : 55
27
+ #012 Amount (Transaction) : 171250
28
+
29
+ class DeviceISO8583Test < DaFunk::Test.case
30
+ def setup
31
+ @str = "02003238040120C98208003000000000000600060820125000005517125006080511100000001941379999701163750703=160320100190277164640000061100040000000000448 !'#$%&'()0123456789@ABCDEFGHIPQRSTUVWXY`abcdefg008003002019862705A0899997011637507039F02060000000006009F03060000000000009F1A020076950500804080005F2A0209869A031506089C01009F3704F6164711820258009F360200629F10200FA5F1A078F0000000000000000000010F0108520000000000000000000000009F260881CEEAA12263D32F9F2701809F0607A09900000010109F3403410302102001008EL0107SC002020000000002311315669050040160000000000003.3100500800000611006020000000000000INGENICO"
32
+ @iso = WilliamMessage.parse(@str, true)
33
+ end
34
+
35
+ def test_bmp_3
36
+ assert_equal @iso[3], 3000
37
+ end
38
+
39
+ def test_bmp_4
40
+ assert_equal @iso[4], 600
41
+ end
42
+
43
+ def test_bmp_7
44
+ assert_equal @iso[7], 608201250
45
+ end
46
+
47
+ def test_bmp_11
48
+ assert_equal @iso[11], 55
49
+ end
50
+
51
+ def test_bmp_12
52
+ assert_equal @iso[12], 171250
53
+ end
54
+ end
55
+
@@ -0,0 +1,11 @@
1
+
2
+ class ParamsDatTest < DaFunk::Test.case
3
+ def test_params_dat_not_nil_file
4
+ assert_equal false, Device::ParamsDat.file.nil?
5
+ end
6
+
7
+ def test_params_dat_initialize_calling_file
8
+ assert Device::ParamsDat.file.hash.is_a? Hash
9
+ end
10
+ end
11
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: da_funk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thiago Scalone
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-27 00:00:00.000000000 Z
11
+ date: 2015-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -100,7 +100,7 @@ files:
100
100
  - lib/device/notification_callback.rb
101
101
  - lib/device/notification_event.rb
102
102
  - lib/device/params_dat.rb
103
- - lib/device/printer.rb
103
+ - lib/device/print.rb
104
104
  - lib/device/runtime.rb
105
105
  - lib/device/setting.rb
106
106
  - lib/device/support.rb
@@ -137,6 +137,9 @@ files:
137
137
  - test/unit/device/notification_callback_test.rb
138
138
  - test/unit/device/notification_event_test.rb
139
139
  - test/unit/device/notification_test.rb
140
+ - test/unit/file_db_test.rb
141
+ - test/unit/iso8583_test.rb
142
+ - test/unit/params_dat_test.rb
140
143
  - utils/command_line_platform.rb
141
144
  - utils/test_run.rb
142
145
  homepage: http://github.com/cloudwalkio/da_funk
@@ -174,4 +177,7 @@ test_files:
174
177
  - test/unit/device/notification_callback_test.rb
175
178
  - test/unit/device/notification_event_test.rb
176
179
  - test/unit/device/notification_test.rb
180
+ - test/unit/file_db_test.rb
181
+ - test/unit/iso8583_test.rb
182
+ - test/unit/params_dat_test.rb
177
183
  has_rdoc:
@@ -1,35 +0,0 @@
1
-
2
- class Device
3
- class Printer
4
- def self.adapter
5
- Device.adapter::Printer
6
- end
7
-
8
- # Same as print, but add "\n" at end of print
9
- #
10
- # @param buf [String] Text to be printed.
11
- # @param option [Symbol] :big, :bar_code, :bitmap
12
- # @return [String] buffer read from keyboard
13
- def self.puts(buf, option=nil)
14
- adapter.puts(buf, option)
15
- end
16
-
17
- # Print buffer
18
- #
19
- # @param buf [String] Text to be printed.
20
- # @param option [Symbol] :big, :bar_code, :bitmap
21
- # @return [String] buffer read from keyboard
22
- def self.print(buf, option=nil)
23
- adapter.print(buf, option)
24
- end
25
-
26
- def self.paper?
27
- adapter.paper?
28
- end
29
-
30
- def self.paperfeed
31
- adapter.paperfeed
32
- end
33
- end
34
- end
35
-