SourceForge has been redesigned. Learn more.
Close

Binary Messages

Help
2010-04-25
2012-09-19
  • Gonzalo Fernández

    Hi. I´m currently using your excellent port. But now I need to send and
    receive messages binary coded. I see that sending messages like this is
    supported with a property in the IsoMessage class, but is not implemented in
    the MessageFactory (ParseMessage method). I will try to do it myself because
    I´m almost desperate. But I would appreciate if you could do the port of the
    binary section of the method, I don´t have experience in binary calculations.

    Thank you.

    (do you speak in spanish?)

     
  • Enrique Zamudio Lopez

    You can check out the Java version which has some support for binary messages
    and even though I haven't used it personally, I've been told by others that it
    works.

    Yes I do speak Spanish, it's my native language, but I write everything here
    in English to be more inclusive.

     
  • Gonzalo Fernández

    Thanks for your response. I have ported the java version funcions tha tare
    missing, but no success so far. I´m reading all I can about bit wise
    operations in C# so I can understand better your code. One problem I will have
    is with the BigInteger class you use in java, but I´m not there yet.

    Do you know if the iso header is also binary coded when using this
    codification? I mean, beside the numeric fields, should I code the numbers in
    teh header? header example: ISO123456789012. What sould I do whit the "ISO"
    word?

     
  • Enrique Zamudio Lopez

    ISO header is just a stream of bytes, you don't have to encode anything.

    bitwise operations in C# should be almost the same as they are in Java, with
    the exception that you do have unsigned types in C# so the code can even be
    easier (you can have a byte going from 0..255 instead of -128..127, for
    instance). The operators are the same:

    << bitshift left

    bitshift right

    & bitwise AND

    | bitwise OR

    ^ bitwise XOR

    and I think you also have unsigned bitshifts which are <<< and >>> (just one
    extra bracket).

     
  • Gonzalo Fernández

    Ok, I´ll see if I can do it. Just one more question, in the IsoMessage class
    you implemented the binary coding option. Should I trust in that, or it
    requires some cheking?

     
  • Enrique Zamudio Lopez

    You should check that it's implemented similar to j8583.

     
  • Gonzalo Fernández

    When writing the bitmap to the stream, you are using the following code to
    convert de BitArray to an array of bytes ( byte ):

    ba.CopyTo(by, 0);

    For example, if I have fileds 1, 2, and 7 set, I get this bitArray: 11000010,
    which is 0xC2. But when that line copies the BitArray to the byte array, I get
    the bits reversed. I mean, I get the byte 0x43, which translates to a 01000011
    BitArray when receiving.

    Is correct the way CopyTo is working and should I change the code when
    receiving, or should I use another way to translate the BitArray to a byte
    array?

     
  • Anonymous

    Anonymous - 2010-05-10

    Hi! Gonzalorf, I am doing exactly the same thing as you are doing right now.

    Please note there is a serious bug here in the encoding of the bitmap of the
    message in binary mode. CopyTo reverses the bits in .NET which means the
    binary bitmap is corrupted. (Took me almost two days to figure that out, I am
    a newbie with ISO 8583!)

    I have made some changes to make the packet sending work, but I am now about
    to work on the receiving of the binary packets. If you like, I can work with
    you on that. Let me know if you are interested.

    @Chochos -- Thanks for the great port. Can I contribute my fixes to the
    project to address the binary bitmap issue? BitArray.CopyTo() works
    differently in Java and .NET.

    Thanks and regards,

    Johan

    skype: jvnoordwyk

     
  • Gonzalo Fernández

    Hello Johan. I´m glad that someone else is working on the same problem.

    What I did is to change de "receiver" side of the code (reverse reading of the
    bits), wich works between MY apps, but wont work with an external service. So,
    I´d like to see how you solved.

    I have implemented the encoding and parsing of fields, using de java code with
    almost no change. It seems to work, except for the LLVAR and LLLVAR types. But
    I didn´t have time see what is happening.

    And of course, I´m interested in help or get helped on this. Let me know.

     
  • Enrique Zamudio Lopez

    I'll check the problem this week, hopefully today. Gonzalo, if you already
    have a fix, you can post it here; I'll verify it and patch the code.

     
  • Anonymous

    Anonymous - 2010-05-10

    Hi guys... Yes, the comms between your receiver and sender will work, as both
    will use the same (incorrect) algorithm to encode/decode the bitmap. Other
    parties will not be able to use it like that.

    My e-mail address is johan.vannoordwyk@archsoftware.co.za.

    @Chochos -- did you get my mail regarding the usage of this component in our
    application? I am happy to contribute my fixes to the project if we are indeed
    able to use this component in our commercial project. (Understand that is OK
    under LGPL?)

    Thanks and kind regards,

    Johan

     
  • Anonymous

    Anonymous - 2010-05-10

    Hi guys... OK, here are my changes that I made to get the component to work in
    our evaluation test system:

    protected byte WriteInternal() {

    MemoryStream ms = new MemoryStream(16);

    byte buf = null;

    if (isoHeader != null) {

    buf = Encoding.ASCII.GetBytes(isoHeader);

    ms.Write(buf, 0, buf.Length);

    }

    if (binary) {

    //ms.WriteByte((byte)((type & 0xff00) >> 8));
    //ms.WriteByte((byte)(type & 0xff));

    } else {

    String x = type.ToString("x4");

    ms.Write(Encoding.ASCII.GetBytes(x), 0, 4);

    }

    //TODO write the bitmap

    Dictionary<int, IsoValue="">.KeyCollection keys = fields.Keys;

    BitArray bits = new BitArray(64);

    foreach (int i in keys)

    if (i > 64)

    {

    bits.Length = 128;

    bits.Set(0, true);

    }

    foreach (int i in keys)

    bits.Set(i - 1, true);

    if (binary)

    {

    buf = new byte;

    buf = ToByteArray(bits); // Removed CopyTo!!
    } else {

    buf = new byte;

    int pos = 0;

    int lim = bits.Length / 4;

    for (int i = 0; i < lim; i++) {

    int nibble = 0;

    if (bits.Get(pos++))

    nibble += 8;

    if (bits.Get(pos++))

    nibble += 4;

    if (bits.Get(pos++))

    nibble += 2;

    if (bits.Get(pos++))

    nibble++;

    Encoding.ASCII.GetBytes(HEX, nibble, 1, buf, i);

    }

    }

    ms.Write(buf, 0, buf.Length);

    //Write each field

    for (int i = 1; i < bits.Length; i++) {

    if (fields.ContainsKey(i)) {

    IsoValue v = fields_;

    v.Write(ms);

    }

    }

    return ms.ToArray();

    }

    //byte ConvertToByte(BitArray bits)

    //{

    // if (bits.Count != 8)

    // {

    // throw new ArgumentException("bits");

    // }

    // byte bytes = new byte;

    // bits.CopyTo(bytes, 0);

    // return bytes;

    //}

    ** public byte ToByteArray(BitArray bits)
    {

    int numBytes = bits.Count / 8;

    if (bits.Count % 8 != 0) numBytes++;

    byte bytes = new byte;

    int byteIndex = 0, bitIndex = 0;

    for (int i = 0; i < bits.Count; i++)

    {

    if (bits_)

    bytes |= (byte)(1 << (7 - bitIndex));

    bitIndex++;

    if (bitIndex == 8)

    {

    bitIndex = 0;

    byteIndex++;

    }

    }

    return bytes;

    }**

    Thus there were two unnecessary bites written (I am not 100% sure about that
    fix) and then the function to correctly pack the bits into bytes. I must still
    do the other way around (bytes to bits) But I think this indicates what needs
    to be done.

    Let me know if I should send the source in another format.

    Kind regards,

    Johan

    __

     
  • Enrique Zamudio Lopez

    Johan, yes the project is LGPL so you can use it in commercial applications as
    long as you include the source code for the library (or the link to the
    project so users can download it from here).

    Did you use the binary encoding also? I'll be happy to review the changes and
    patch the faulty code. This may be the excuse I need to make the first
    release.

     
  • Gonzalo Fernández

    I don´t have a fix to the bitmap problem. But I added the binary format to the
    encoding and decoding funcionss (in the IsoMessage and MessageFactory, and
    others as well LLVAR and LLLVAR types. If you want, I can send the changes. I
    think is too much code to paste it here.

     
  • Gonzalo Fernández

    Johan, I don´t understand why you removed the lines that writes the message
    type, like this:

    if (binary) {

    //ms.WriteByte((byte)((type & 0xff00) >> 8));

    //ms.WriteByte((byte)(type & 0xff));

    How is it written to the stream?

    To unpack the bitmap, just use the code in the Java version. It "worked" for
    me, except for the bit order issue. But if your ToByteArray function works
    properly, it will be compatible.

     
  • Gonzalo Fernández

    I have tested your ToByteArray function. It worked correctly. I´m successfully
    sending and receiving 0800 type messages, because they don´t use LLVAR or
    LLLVAR fields.

     
  • Anonymous

    Anonymous - 2010-05-10

    Hi guys

    @gonzalorf: The code is very messy at this stage, and I had to remove that in
    order to make my test case work with an external vendor. I am not very sure if
    that is correct, but with those lines removed it conformed correctly to the
    spec. We can investigate this further.

    @Chocos: I can send my code as I have it at present, but I would like to
    "clean it up" a little first. It would be great if you can incorporate the
    changes. (This feels good, first time I have contributed to open source --
    yeah!)

    Would you be able to merge gonzalorf and my changes?

    Thanks again guys, I am so glad we can work together and make this work!

    Kind regards,

    Johan

     
  • Enrique Zamudio Lopez

    I opened the project today, it's been a while since I last worked on it. There
    is no binary parsing code whatsoever; so... how are you guys parsing binary
    messages? Shouldn't work at all (there isn't even a ParseBinary method in the
    MessageFactory class).

     
  • Enrique Zamudio Lopez

    Hi guys. I got a chance to work on this today. I have modified MessageFactory,
    IsoMessage, IsoValue and FieldParseInfo in order to support binary message
    encoding. I tested it by generating a binary message from niso and parsing it
    with j8583, ir worked OK, so at least the bitmap problem has been solved and
    it looks like the fields are being correctly encoded in binary messages.

    Please test these changes and tell me if they work for you (it wasn't that
    much code, so maybe you want to backup your mods and get a fresh copy from the
    repo).

     
  • Gonzalo Fernández

    Cool. I think that today I could do some test. I have the code modified
    because I needed at some point to serialize IsoMessages, so I made some
    changes to the class. I´ll add your modifications to it.

     
  • Gonzalo Fernández

    It seems to work. I only had problems with DateTime values. I tried DATE4, and
    noticed that the resultant parsed value was diferent in the month part. The
    code is this:

    **else if (type == IsoType.DATE4)
    {

    dt = new DateTime(dt.Year, tens - 1, tens);

    **
    I removed the "-1" and worked correctly. What was that for? Maybe something
    about java? I asmune the other DateTime types have the same problem, I´ll try
    them later.

     
  • Enrique Zamudio Lopez

    The java.util.Calendar object counts months from 0 to 11. I guess .NET
    DateTime object counts them from 1 to 12, so there's no need to subtract 1.
    I'll fix the rest of the dates and commit changes briefly.

     

Log in to post a comment.