ASCIIChannel not display the correct total length

Skip to first unread message

Venese Lee

Dec 9, 2022, 7:55:52 AM12/9/22
to jPOS Users
Hi all,

I'm integrating my program to UPI (Union Pay International) simulator & seems like the simulator is expecting the total length in ASCII.

I used ASCIIChannel but it seems like the total length for the message only include the length for the ISOMSG & not included header length.

Anyone encountered this issue?
Is there anyway I can modify the total length for the message?

murtuza chhil

Dec 9, 2022, 9:08:04 AM12/9/22
to jPOS Users
You will need to write your own Channel to talk to UnionPay, you cannot use the AsciiChannel as there are specific headers that need to be dealt with.

Take a look at how headers can be parsed

Implement your UnionPayHeader accordingly.

See how the channel uses the BASE1Header 

Implement the your channel accordingly.

And you can copy the AsciiChannel's  get and set MessageLength in your channel implementation


Venese Lee

Dec 13, 2022, 3:10:08 AM12/13/22
to jPOS Users
Hi chhil,

Thanks for your reply.
Yes I had my own procedure to populate UPI Header but it working fine.
In debugging log, my body len =65, header len = 46 so total 111.
But when sending the ISORequest r thru muxUPI, I expect it will populate correct length = 30313131 (ASCII) but it is sent as 30303635 (the length of the body 65).
So I suspect something wrong for muxUPI.

I tried to implement my own ASCIIChannel & change protected getMessageLength() to public getMessageLength_UPI() but I got nullpointerexception at serverIn.readFully(b, 0, lengthDigits);
Appreciate your advise on what can I do further.

public int getMessageLength_UPI() throws IOException, ISOException {

int l = 0;

byte[] b = new byte[lengthDigits];

while (l == 0) {

serverIn.readFully(b, 0, lengthDigits);

try {

if ((l=Integer.parseInt(new String(b))) == 0) {




} catch (NumberFormatException e) {

throw new ISOException ("Invalid message length "+new String(b));



return l;


ISOMsg m = new ISOMsg();

m.set (new ISOField (0,  "0820"));
m.set (new ISOField (7,  F7));
m.set (new ISOField (11, ISOUtil.zeropad(new Integer(ISOUPIServer.seq.get ("traceno") % 1000000).toString(),6)));
m.set (new ISOField (33, "26520458"));
m.set (new ISOField (70,  "071")); // LogOn
ISORequest r = new ISORequest (m);


static ISOChannel UPIchannel;
UPIchannel = new ASCIIChannel(UPIipaddress, UPIlistenport, new GenericPackager("upi.xml")); // connecting to UPI
muxUPI = new ISOMUX (UPIchannel);


public byte [] UPIHeader(int iBodyLen)
                int iTotalLen = iBodyLen + 46; //body len + header len 46

                String s4DigitLen = StringUtils.leftPad(String.valueOf(iTotalLen),4,"0");
                String sASCIILen = "3" + s4DigitLen.substring(0,1) +
                                    "3" + s4DigitLen.substring(1,2) +
                                    "3" + s4DigitLen.substring(2,3) +
                                    "3" + s4DigitLen.substring(3,4); //eg 0095 to 30303935

                ISOUPIServer.MyExceptionFile("UPI Len : " + sASCIILen);

                String HeaderLen = "2E"; //binary(8)                                  
                String HeaderFlagAndVers = "02"; //binary(8)                                        
                String HeaderTotMsgLen = sASCIILen; //numeric(4)                            
                String HeaderDestID = "3030303130333434202020"; //numeric(11)                                
                String HeaderSourceID = "3236353230343538202020"; //numeric(11)        
                String HeaderReserve = "000000"; //binary(24)
                String HeaderBatchNo = "00"; //binary(8)                                            
                String HeaderTrxInfo = "3030303030303030"; //ans8                              
                String HeaderUserInfo = "00"; //binary(8)
                String HeaderRejectCode = "3030303030"; //numeric(5)                              
                String Vheader =    HeaderLen +
                                    HeaderFlagAndVers +
                                    HeaderTotMsgLen +
                                    HeaderDestID +
                                    HeaderSourceID +
                                    HeaderReserve +
                                    HeaderBatchNo +
                                    HeaderTrxInfo +
                                    HeaderUserInfo +
                ISOUPIServer.MyExceptionFile("Vheader : " + Vheader);

                //byte[] h = hexToBuffer(sASCIILen + Vheader);
                byte[] h = hexToBuffer(Vheader);
                ISOUPIServer.MyExceptionFile("header.length : " + h.length);
                return h;
            } catch(Exception e01) {
                StackTraceElement[] ste01 =  e01.getStackTrace();
                for (int i2 =0; i2<ste01.length; i2++){
                    ISOUPIServer.MyExceptionFile("ISOUPIOutgoing -> UPIHeader() -> Exception : " + ste01[i2]);
                return null;

15:17:38| Body msg: 3038323038323230303030303830303030303030303430303030303030303030303030303132313330373137333730303030303130383236353230343538303731
15:17:38| Body len: 65
15:17:38| header : 2E023031313130303031303334342020203236353230343538202020000000003030303030303030003030303030
15:17:38| header.length : 46
15:17:38| UPI Len : 30313131


Dec 13, 2022, 6:59:12 AM12/13/22
This is what I had done when we had implemented it to talk to the UPI Sim.

      public class UnionPayChannel extends BaseChannel
    protected void sendMessageHeader(ISOMsg m, int len) throws IOException {

        ISOHeader h = new UnionPayHeader(srcid, dstid, len);

       if (h instanceof UnionPayHeader)

            ((UnionPayHeader) h)

                    .setTotalMessageLength(UnionPayHeader.LENGTH + len); // <-- You are probably not doing this i.e. header length  46 + length of message



and the UPIHeader

    public void setTotalMessageLength(int totalMessageLength) {
        byte[] temp = ISOUtil.zeropad(totalMessageLength, 4).getBytes();
        System.arraycopy(temp, 0, header, 2, 4); // <-- The header loacation where the message length is placed.


The message length is embedded in the header.

 *         Fld  1: Header Length           1B      (Byte       0)

 *         Fld  2: Header Flag             1B      (Byte       1)

 *         Fld  3: Total Message Length    4B      (Byte   2 - 5)

So when you pack and unpack the message you need to get the length from the right place and know where the message starts from (after the 46 bytes).


jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage. Please support jPOS, contact:
You received this message because you are subscribed to a topic in the Google Groups "jPOS Users" group.
To unsubscribe from this topic, visit
To unsubscribe from this group and all its topics, send an email to
To view this discussion on the web visit

Venese Lee

Dec 14, 2022, 3:13:32 AM12/14/22
to jPOS Users
Wow  sendMessageHeader works for me, thanks for your sharings.
Now I able to send ISOMSG to UPI simulator but the reply I have problem to pack to ISOMSG.
As you mentioned I had to read the msg after 46 bytes, how can I do that because the xml file in the GenericPackager doesn't not have header details rite?



Dec 14, 2022, 4:06:44 AM12/14/22
When the header gets unpacked, it will consume 46 bytes. The offset returned is at the start of the message. Basically, you need to return 46 from the header unpack.
You will need to define your own packager for UPI, generic most likely wont work.

I am not sure, but the message length may also be present after the header, you will need to debug it.

It may be easier if you dump the message using ISOUtil.hexdump and analyse the message bytes for length etc.
If the SIM can send a network message, you can have it send a request, which you can dump.


Venese Lee

Dec 28, 2022, 8:13:14 PM12/28/22
to jPOS Users
Thanks for your info.
I managed to solve the header issue.
Now I have problem packing field 57 in 0110 message from Union Pay.

error unpacking field 57
org.jpos.iso.ISOException: org.jpos.iso.IFA_LLLCHAR: Problem unpacking field 57 (java.lang.ArrayIndexOutOfBoundsException: 278)
        at org.jpos.iso.ISOStringFieldPackager.unpack(
        at org.jpos.iso.ISOBasePackager.unpack(
        at org.jpos.iso.ISOMsg.unpack(
        at ASCIIChannelPBB.receive(
        at org.jpos.iso.ISOMUX$
        at Source)
Nested:java.lang.ArrayIndexOutOfBoundsException: 278
        at org.jpos.iso.AsciiInterpreter.uninterpret(
        at org.jpos.iso.ISOStringFieldPackager.unpack(
        at org.jpos.iso.ISOBasePackager.unpack(
        at org.jpos.iso.ISOMsg.unpack(
        at ASCIIChannelPBB.receive(
        at org.jpos.iso.ISOMUX$
        at Source)

Do you have xml file to share?


Dec 28, 2022, 10:02:22 PM12/28/22
Due to proprietary nature the packager xml cannot be shared.

Basically you need to align your packager go through all the fields prior to 57 and see if they are defined correctly according to spec and the data in the fields match what was sent and expected.


Reply all
Reply to author
0 new messages