Closed dlbirch closed 9 years ago
Hi Tim,
Here is what I ended up with for the 'header' portion ... I'm still working through how to get the message length.
require 'iso8583'
module ISO8583
class UmsHeader
attr_accessor :total_message_length, :bhn_signature, :product_category_code, :msg_status_code, :msg_spec_id
def initialize(msg_length)
# 2 byte message length in network byte order, exclusive of itself.
@total_message_length = [ msg_length ].pack "n"
# Fixed length alphanumeric field with ‘X’ characters.
# Left justified with trailing spaces.
# Padding should be done to ensure that field is exactly ‘X’ characters. ASCII encoded.
# Each byte on the wire will represent one character
# an6
bhnums = Array.[]( 'B', 'H', 'N', 'U', 'M', 'S' )
@bhn_signature = bhnums.pack "AAAAAA"
# Numeric data where ‘X’ represents the number of digits. Right justified with leading zeroes.
# Padding should be done to ensure that there is an even number of digits. E.g. if value is ‘009’ then
# this field should be padded to with a 0 to make it ‘0009’.
# If ‘X’ is defined as a odd number the field should still be padded with 0 to make it
# an even number Packed unsigned Binary Coded Decimal (BCD).
# Each byte on the wire will represent 2 digits.
# Product Category Code.
# 01 – Gift Card
@product_category_code = [01.to_s].pack("H*")
# Message Status Code
# Status of message parsing.
# 00 – Success
# 01 – Message parsing failed.
@msg_status_code = [00.to_s].pack("H*")
# Identifies the version of the spec in use.
# This spec has a version of ‘02’.
@msg_spec_id = [02.to_s].pack("H*")
end
def to_b
byte_array = Array.[]
byte_array << @total_message_length
byte_array << @bhn_signature
byte_array << @product_category_code
byte_array << @msg_status_code
byte_array << @msg_spec_id
end
end
end
# my_hdr = ISO8583::UmsHeader.new(1024)
# puts my_hdr.to_b.to_s
# puts my_hdr.to_s
1) How can I get a message length for a message?
Call to_b
on the instance of the subclass of Message
you created, that will be a byte array containing the message, from there it's straightfoward ruby to get the length of the array. (I'm not sure how this will behave in ruby 1.9, be sure that the string handling introduced in 1.9 doesn't interfere with the byte array handling, or if in doubt use 1.8.
It would probably be easiest to override the to_b
message to do this automatically. I'm on the road right now, so no-tested pseudo-code:
class MyMessage < Message
... bla bla all the `bmp` definitions ...
def to_b
bytes = super
length = bytes.length
length_header = encode_length_header_according_to_your_protocol(length)
return length_header + bytes
end
end
2) How can I use the iso8583 code to create the header?
Can't say for sure about the header you're describing without knowing what protocal this is, but it looks as if it's another 8583 message tacked in front of the actual message, in that case I would make it a field in your message.
Again Pseudocode:
class MyHeader < Message
(...)
bmp 1, "Product Category Code", N, length => 2
bmp_alias 1, :product_category_code
(...)
def to_b
... the stuff decribed above ...
end
(...)
end
class MyMessage < Message
... bla bla ...
attr_accessor :header
(...)
def to_b
bytes = super
header_bytes = @header.to_b
return header_bytes+bytes
end
(...)
end
(...)
my_message.header = ...
my_message.header.product_category_code = 1
my_message.header.status_code = 0
my_message.header.spec_id = 2
message_bytes = my_message.to_b
Thank you for providing the iso8583 Ruby Gem. I've begun to explore its usage ... and in my scenario, I need to send a 'message header' to the service I'm consuming (using a TCP/IP Socket). The first field in the header is the message length.
My questions:
1) How can I get a message length for a message?
2) How can I use the iso8583 code to create the header?
Sincerely,
Douglas Birch