Financial message with stx etx and lrc

1,146 views
Skip to first unread message

wshehab

unread,
Dec 26, 2008, 8:19:54 AM12/26/08
to jpos-...@googlegroups.com

Dear all,
i am trying to send a message from pos teminal connected to jpos server. you
can find attached the message specification and a sample message also.i
tried may channels and packager but i did not find any useful one to my
case. could any one assist me and provide me with the rigth channel and how
it works.

thanks in advance for your help.

Walid.

http://www.nabble.com/file/p21174238/ISOMsg%2Bfrom%2BGemalto%2BPOS.doc
ISOMsg+from+Gemalto+POS.doc
--
View this message in context: http://www.nabble.com/Financial-message-with-stx-etx-and-lrc-tp21174238p21174238.html
Sent from the jPOS - Users mailing list archive at Nabble.com.

Andy Orrock

unread,
Dec 26, 2008, 8:22:27 AM12/26/08
to jpos-...@googlegroups.com
Attachments get stripped by Google Groups. Please put traces in-line.

Andy Orrock

wshehab

unread,
Dec 26, 2008, 8:37:14 AM12/26/08
to jpos-...@googlegroups.com

ok here is the example message:

Example Send to Server:
STX: 02
Length: 008A0000
0x60: 60
TPDU: 00000000
MSGID: 0200
BITMAP: 3220448120E08008 {3,4,7,11,18,22,25,32,35,41,42,43,49,61}
MSG:
3- PCode (6): 000000
4- Amount (12): 000000000900
7- Transaction Date & Time (10): 1226105446
11- Trace (6): 000000
18- Merchant Type (4): 5999
22- POS Entry Mode (3): 0902
25- POS Condition Code (2): 001
32- Acquiring Inst ID (10): 0 0000402974
35- Track II (37): 32 601xxxxxxxxxxxxxDxxxxxxxxxxxxxxx
41- TermID (8): 3030303030313032 (00000102)
42- TermLoc (15): 303030343232303030303031303032 (000422000001002)
43- Merchant Name (40):
4D45524348414E5420544553542053484C554D4245524745414348524146494548202020204C424E
49- Currency Code (3): 0840
61- Terminal Serial Number (10): 30313044363038313030333936 (010 D608100396)
ETX: 03
LRC: F1

where:
posistion 0 : STX
posistion 1-->4 : length
posistion 5 :0x60
posistion 6-->9 : TPDU
posistion 10-->11 : MsgID
posistion 12-->19 : BitMap
posistion 20-->msglen -2 : msg data
posistion msglen -1 : ETX
posistion msglen : LRC.

Please advice

wshehab wrote:
>
> Dear all,
> i am trying to send a message from pos teminal connected to jpos server.
> you can find attached the message specification and a sample message
> also.i tried may channels and packager but i did not find any useful one
> to my case. could any one assist me and provide me with the rigth channel
> and how it works.
>
> thanks in advance for your help.
>
> Walid.
>
> http://www.nabble.com/file/p21174238/ISOMsg%2Bfrom%2BGemalto%2BPOS.doc
> ISOMsg+from+Gemalto+POS.doc
>

--
View this message in context: http://www.nabble.com/Financial-message-with-stx-etx-and-lrc-tp21174238p21174383.html

Mark Salter

unread,
Dec 26, 2008, 5:20:24 PM12/26/08
to jpos-...@googlegroups.com
wshehab wrote:
>
> Dear all, i am trying to send a message from pos teminal connected to
> jpos server.
You are trying to receive a message into a server written using jpos
from a terminal; and perhaps send a response back?

> you can find attached the message specification and a sample message
> also.

Not attached, but the target of a link given(got it).

> i tried may channels and packager but i did not find any useful one


> to my case. could any one assist me and provide me with the rigth
> channel and how it works.

Your Channel will need to absorb everything not truly part of the
message, so that it ma pass the message bytes down to the packager...

So the STX is skipped ahead of reading the length,
the padding bytes following the length are skipped,
I would include the 0x60 + TPDU in the header processing, reading the
whole message an stripping of the ETX +LRC (checking it here) before
passing the message bytes to the ISOMsg/packager to unpack.

Things 'wrong' with your 'example':-

- I can't get the length to match the data.
- Your example data do not match the field lengths (DE22 shows (3), but
holds '0902')
- It is not obvious if your message is character or a binary form, which
might help towards the length abnormality if you have a mix.
- In 61 you have the length repeated in the character representation of
the number, but it is absent from the 42 repeat whereas 32 is missing
the 1 so has a typo?!
- You need to sort out the lengths - DE 35 as an example is not 37
bytes, but perhaps this is the maximum length rather than the actual?

Things you need to ascertain sooner rather than later:-

- What is the format of the length field and does it represent the
length of just the message, or the whole packet (STX->ETX) or something
else.
- What is the algorithm for checking and making the LRC.
- The format of each field (check the specification) - this will help
you pick or make a packager.

So in summary. You will need a custom Channel to handle the packing
around the message, but I would think an existing packager would be a
close fit, once you get the field formats.

Do you have any control of the terminal message format or transport? Is
this the serial conversation sent of TCP/IP? I wonder if the
terminal(s) can be reconfigured?

--
Mark

wshehab

unread,
Dec 27, 2008, 3:07:24 AM12/27/08
to jpos-...@googlegroups.com



Mark Salter-5 wrote:
>
>
> wshehab wrote:
>>
>> Dear all, i am trying to send a message from pos teminal connected to
>> jpos server.
> You are trying to receive a message into a server written using jpos
> from a terminal; and perhaps send a response back?
>
> exactly.
>
>> you can find attached the message specification and a sample message
>> also.
> Not attached, but the target of a link given(got it).
>
>> i tried may channels and packager but i did not find any useful one
>> to my case. could any one assist me and provide me with the rigth
>> channel and how it works.
> Your Channel will need to absorb everything not truly part of the
> message, so that it ma pass the message bytes down to the packager...
>
> So the STX is skipped ahead of reading the length,
> the padding bytes following the length are skipped,
> I would include the 0x60 + TPDU in the header processing, reading the
> whole message an stripping of the ETX +LRC (checking it here) before
> passing the message bytes to the ISOMsg/packager to unpack.
>
> Things 'wrong' with your 'example':-
>
> - I can't get the length to match the data.
> the length includes: 0x60+TPDU+MSGID+BitMap+MSG data which is all equal to
> 138 (8A in hex)
> - Your example data do not match the field lengths (DE22 shows (3), but
> holds '0902')
> actually the value is 902 and it is padded with 0 so it is 4 and not 3.
> - It is not obvious if your message is character or a binary form, which
> might help towards the length abnormality if you have a mix.
> yes it is mixed.
> - In 61 you have the length repeated in the character representation of
> the number, but it is absent from the 42 repeat whereas 32 is missing
> the 1 so has a typo?!
> true because there are some fields with variable length.
> - You need to sort out the lengths - DE 35 as an example is not 37
> bytes, but perhaps this is the maximum length rather than the actual?
> yes the max length is 37 and the 1 byte in the DE35 is the field length.
>
> Things you need to ascertain sooner rather than later:-
>
> - What is the format of the length field and does it represent the
> length of just the message, or the whole packet (STX->ETX) or something
> else.
>
> as i mentioned before the length incude all the message without
> STX,ETX,LRC and length
> - What is the algorithm for checking and making the LRC.
>
> this is the function that i use to make the LRC in my POS application.
> uint8 FormulateLRC(uint8 *s,int16 len)
> {
> // s must start with stx and end with etx
>
> int i;
> uint8 c=0,lrc=0;
>
> for(i=1;i<(len);i++)
> {
> c=s[i] ^ lrc;
> lrc=c;
> }
> return lrc;
> }
>
> - The format of each field (check the specification) - this will help
> you pick or make a packager.
>
> So in summary. You will need a custom Channel to handle the packing
> around the message, but I would think an existing packager would be a
> close fit, once you get the field formats.
>
> Do you have any control of the terminal message format or transport? Is
> this the serial conversation sent of TCP/IP? I wonder if the
> terminal(s) can be reconfigured?
>
> i wrote the terminal application before to send message another interface
> (oasis switch) using the modem dial up, but now im trying to use the
> tcp/ip to send it to jpos server.
>
> --
> Mark
>
> >
>
>

--
View this message in context: http://www.nabble.com/Financial-message-with-stx-etx-and-lrc-tp21174238p21182289.html

wshehab

unread,
Dec 27, 2008, 3:39:15 AM12/27/08
to jpos-...@googlegroups.com

could you please also tel me how to skip the STX and read the length truly
from the channel.
i create my custom channel same as NACChannel and i need to modify some
function in it, so please help if you can.

wshehab wrote:
>
> Dear all,
> i am trying to send a message from pos teminal connected to jpos server.
> you can find attached the message specification and a sample message
> also.i tried may channels and packager but i did not find any useful one
> to my case. could any one assist me and provide me with the rigth channel
> and how it works.
>
> thanks in advance for your help.
>
> Walid.
>
> http://www.nabble.com/file/p21174238/ISOMsg%2Bfrom%2BGemalto%2BPOS.doc
> ISOMsg+from+Gemalto+POS.doc
>

--
View this message in context: http://www.nabble.com/Financial-message-with-stx-etx-and-lrc-tp21174238p21182411.html

Mark Salter

unread,
Dec 27, 2008, 5:02:26 AM12/27/08
to jpos-...@googlegroups.com
wshehab wrote:

>>> Do you have any control of the terminal message format or
>>> transport? Is this the serial conversation sent of TCP/IP? I
>>> wonder if the terminal(s) can be reconfigured?
>>>
>> i wrote the terminal application before to send message another
>> interface (oasis switch) using the modem dial up, but now im trying
>> to use the tcp/ip to send it to jpos server.

TCP/IP does not need the STX,ETX nor LRC.
Do you have the option of throwing them away before the send?
It is easy to modify a Channel to cope with them, but it might be easier
for you if you got rid of them (if you can).
Does the terminal have an option to send over TCP/IP directly itself
(the Gemalto website I looked at suggested that the terminals I skimmed
through probably could).

--
Mark

Mark Salter

unread,
Dec 27, 2008, 5:09:51 AM12/27/08
to jpos-...@googlegroups.com
wshehab wrote:
>
> could you please also tel me how to skip the STX and read the length truly
> from the channel.
Find the code in the Channel that calls the method to pull the length
from the stream...

... where the above code is called is where you need to add the
processing of the STX, ETX etc...

...skipping an STX is as simple as reading a byte from the stream at the
right time. You may not need to keep this byte for later reference, but
it is worth checking it holds the expected value.

--
Mark

Chillum

unread,
Dec 27, 2008, 5:44:00 AM12/27/08
to jpos-...@googlegroups.com
My 2 cents:
We have run into a scenarios where you need to tweak the settings by
physically going to atms but the cost of sending people to the fleet
of atms is not accepted well:). Try to accomodate it at the software
level.

-chhil

Mark Salter

unread,
Dec 27, 2008, 7:39:55 AM12/27/08
to jpos-...@googlegroups.com
Chillum wrote:
> My 2 cents:
> We have run into a scenarios where you need to tweak the settings by
> physically going to atms but the cost of sending people to the fleet
> of atms is not accepted well:). Try to accomodate it at the software
> level.
I'm hopeful that Walid has :-

POS -> modem connected server (with his code) -> jPOS active server...


This way his server code could strip the unnessesary padding to make his
work easier.

If of course it is possible to ask the POS devices to talk straight
TCP/IP, then we loose a couple of middle men and reduce the work.

I understand your point Chhil, but for all we know, Walid might have a
single POS device.

8)

--
Mark

Alejandro Revilla

unread,
Dec 27, 2008, 4:30:28 PM12/27/08
to jpos-...@googlegroups.com
You can override :

protected void sendMessageHeader(ISOMsg m, int len) {
serverOut.write(STX);
}

and

protected void sendMessageTrailler(ISOMsg m, byte[] b) throws IOException {
serverOut.write(ETX);
serverOut.write(calcLRC (b));
}

and

protected int getHeaderLength() {
return 1; // the STX
}

and also getMessageTrailler()

wshehab

unread,
Dec 30, 2008, 2:54:49 AM12/30/08
to jpos-...@googlegroups.com

You are right Mark,
I am trying to send the transaction directlty from the terminal through
tcp/ip connection but in my terminal application that i wrote before i sent
the transaction through the modem and dial up line but now. so it is better
to send the transaction without STX, ETX and LRC. i will try to modify my
code and let you know the result.

thanks for all af you for your support.

Regards,

Walid.
--
View this message in context: http://www.nabble.com/Financial-message-with-stx-etx-and-lrc-tp21174238p21214124.html

JTO

unread,
Dec 30, 2008, 1:53:21 PM12/30/08
to jPOS Users
Walid.

I had a similar problem to yours and resolved by creating my own
channel and overriding the send and receive methods. I uploaded an
example (although different) a while back (on the groups home page -
StxEtxChannel.java). My incoming msg did not have a length but that
could be parsed out easily as well.

The key in the receive portion is

/**
* @return a byte array with the received message
* @exception IOException
*/
protected byte[] streamReceive() throws IOException {
// The meat of it all to capture message data wrapped in STX -
ETX characters
int i;
byte[] buf = new byte[4096];
for (i=0; i<4096; i++) {
int c = -1;
try {
c = serverIn.read();
} catch (SocketException e) { }
if (c == 03) <<<<<<<<<<<<<<<<<<<<<< Look for ETX char
{
buf[i] = (byte) '\034';
i++;
break;
}
else if (c == -1)
throw new EOFException("connection closed");
buf[i] = (byte) c;
}
if (i == 4096)
throw new IOException("packet too long");

byte[] d = new byte[i];
System.arraycopy(buf, 1, d, 0, i-1);
return d;
}

I hope this helps you in some way.

-John

Alejandro Revilla

unread,
Mar 11, 2013, 9:26:34 PM3/11/13
to jpos-...@googlegroups.com
I'm afraid you can't use a standard async serial port, you need to be able to deal with HDLC (this brings good memories of the the 8530 chip...)

--
@apr



On Mon, Mar 11, 2013 at 10:20 PM, D Rajkumar <rajkum...@gmail.com> wrote:
Hi Shehab,

I am trying to use a usb modem and perform ISO8583 transaction with a NAC,
The dial up can connect and call is successful , but
when i send the iso8583 packet as in the given code below, it is not detected by NAC.

Should i use any STX ETX and LRC for the data.

The NAC is taking the data midway , ie; the data captured at NAC starts always from 0x01, why is it so ?

My format of sending data currently is LL1 LL2 0x60 NII1 NII2 NII3 NII4 MTI ......

LL is length bytes,
NII is NII bytes , 
MTI is message type identifier etc..

Please give any inputs.

Thanks,

Code for reference,


import java.io.*;
//import javax.comm.*;
import gnu.io.*;
import java.util.*;

public class PortWriter implements SerialPortEventListener
{
    static Enumeration ports;
    static CommPortIdentifier pID;
    static OutputStream outStream;
    static InputStream inStream;
    SerialPort serPort;
    static String messageToSend = "ATD315";
    static boolean writeFlag = false;
String line;
static BufferedReader bos;
static OutputStream fos = null;
static FileOutputStream output = null;
static DataOutputStream dout = null;

    
    public PortWriter() throws Exception{
        serPort = (SerialPort)pID.open("PortWriter",120000);
        
        serPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
        SerialPort.STOPBITS_1,
        SerialPort.PARITY_NONE
        
        );
inStream = serPort.getInputStream();
outStream = serPort.getOutputStream();

try {
serPort.addEventListener(this);
catch (TooManyListenersException e) {System.out.print(e);}
serPort.notifyOnDataAvailable(true);

serPort.notifyOnCarrierDetect(true);
serPort.notifyOnDataAvailable(true);
serPort.notifyOnBreakInterrupt(true);
serPort.notifyOnCTS(true);
serPort.notifyOnDSR(true);
serPort.notifyOnFramingError(true);
serPort.notifyOnOutputEmpty(true);
serPort.notifyOnOverrunError(true);
serPort.notifyOnParityError(true);
serPort.notifyOnRingIndicator(true);


}
    private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();

    public static String asHex(byte[] buf)
    {
        char[] chars = new char[2 * buf.length];
        for (int i = 0; i < buf.length; ++i)
        {
            chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
            chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
        }
        return new String(chars);
    }
public void portclose()
{
this.serPort.close();
}
public void serialEvent(SerialPortEvent event) {
switch(event.getEventType()) 
{
case SerialPortEvent.DATA_AVAILABLE:
handleData();
System.out.println("handle data event");

break;
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.DSR:
System.out.println("Data set ready.");
break;
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
System.out.println("Ignored event");
break;
case SerialPortEvent.BI:
System.out.println("Break Interrupt");
break;
case SerialPortEvent.CTS:
System.out.println("Clear to send");

break;
case SerialPortEvent.RI:
System.out.println("Pick up the receiver.");
if( event.getNewValue() ) 
{
System.out.println("Ring Indicator On");
}
else 
{ System.out.println("Ring Indicator Off");
} break;
case SerialPortEvent.CD:
if( event.getNewValue() ) {
System.out.println("Connected");


// try to send data iso8583

byte isoreq[] = {0x00,(byte) 0xBA,0x60,0x00,0x08,(byte) 0x80,0x62,0x02,0x00,0x32,0x24,0x05,(byte) 0x80,0x20,(byte) 0xC0,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x11,0x11,0x33,0x34,0x00,0x00,0x04,0x03,0x11,0x00,0x51,0x00,0x08,0x00,0x38,0x45,0x70,0x66,0x37,0x63,0x35,0x50,0x02,(byte) 0xD1,0x40,0x62,0x01,0x15,0x54,0x30,0x30,0x00,0x00,0x0F,0x39,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x35,0x33,0x32,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,(byte) 0x99,(byte) 0x9F,0x26,0x08,(byte) 0xBA,0x53,0x2B,0x11,0x5D,(byte) 0xC7,(byte) 0x86,0x1D,(byte) 0x82,0x02,0x5C,0x00,(byte) 0x9F,0x36,0x02,0x02,(byte) 0xC9,(byte) 0x9F,0x07,0x02,(byte) 0xFF,0x00,(byte) 0x9F,0x27,0x01,(byte) 0x80,(byte) 0x8E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x03,0x02,0x03,0x1F,0x00,(byte) 0x9F,0x34,0x03,0x1E,0x03,0x00,(byte) 0x9F,0x0D,0x05,(byte) 0xD0,0x60,0x04,(byte) 0x88,0x00,(byte) 0x9F,0x0E,0x05,0x00,0x10,0x00,0x00,0x00,(byte) 0x9F,0x0F,0x05,(byte) 0xD0,0x60,0x04,(byte) 0x98,0x00,(byte) 0x9F,0x10,0x07,0x06,0x01,0x0A,0x03,(byte) 0xA0,0x28,0x00,(byte) 0x95,0x05,(byte) 0x80,0x00,0x00,0x00,0x00,(byte) 0x9F,0x37,0x04,(byte) 0x8E,0x4B,0x4D,0x2D,0x00,0x01,0x34};

String isoreqs = asHex(isoreq);
try {
//byte tempb[] = {0x00,0x56};
//this.outStream.write(ts.getBytes());

this.outStream.write(isoreq1);
//this.outStream.write(isoreqs.getBytes());
this.serPort.setRTS( ! this.serPort.isRTS() );
this.serPort.setDTR( ! this.serPort.isDTR() );
this.outStream.flush();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}

    private String asHex(char[] buf) {
// TODO Auto-generated method stub
     char[] chars = new char[2 * buf.length];
          for (int i = 0; i < buf.length; ++i)
          {
              chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
              chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
          }
          return new String(chars);
}
public void handleData()
{// System.out.println(writeFlag);
System.out.print("Inside serial event");
try
{
fos = new FileOutputStream("rmn.txt",true);
bos = new BufferedReader(new FileReader("rmn.txt"));
dout = new DataOutputStream(fos);
int avail = inStream.available();
byte[] response = new byte[avail];
StringBuffer strbuf = new StringBuffer();
inStream.read(response, 0, avail);
for (int i = 0; i < avail; i++) 
{
fos.write((char)response[i]);
System.out.println(response[i]);
}
if(!writeFlag)
{
while((line = bos.readLine())!=null)

{// dout.flush();
if(line.equals("CONNECT 9600"))
{
writeFlag = true;
System.out.println("connect"); break;
} } } if(writeFlag)
{ } }catch(IOException ie1){System.out.println("File " +ie1);}
// catch(InterruptedException ie1){System.out.println("File " +ie1);}
}
    
   

    public static void main(String[] args) throws Exception{
        ports = CommPortIdentifier.getPortIdentifiers();
        
        while(ports.hasMoreElements())
        {
            pID = (CommPortIdentifier)ports.nextElement();
            System.out.println("Port " + pID.getName());
            
            if (pID.getPortType() == CommPortIdentifier.PORT_SERIAL)
            {
                if (pID.getName().equals("COM11")) 
                {
                    PortWriter pWriter = new PortWriter();
                    System.out.println("COM11 found");
                
                    messageToSend = "ATE\r\n";
                    
                   // messageToSend = "ATO\r\n";
                   // try {
                    //outStream.write(messageToSend.getBytes());
                   // } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    //e1.printStackTrace();
                   // }
                  // outStream.write(messageToSend.getBytes());
                   // pWriter.portclose();
                    //0380231886
                    //20703632
                  //  byte rb[] = {'A','T','D','3','1','5','\r','\n'};
                 //  byte rb[] = {'A','T','D','9','8','0','2','3','1','8','8','6','\r','\n'};
                  // byte rb[] = {'A','T','D','9','2','0','7','0','3','6','3','2','\r','\n'};
                    byte rb[] = {'A','T','D','T','9',',','8','0','2','4','8','6','8','4','\r','\n'};
                   messageToSend = "ATD315\r\n";
                     // outStream.write(messageToSend.getBytes());
                   outStream.write(rb);
                 
                  
                 
                      break;

--
--
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: sa...@jpos.org
 
You received this message because you are subscribed to the "jPOS Users" group.
Please see http://jpos.org/wiki/JPOS_Mailing_List_Readme_first
To post to this group, send email to jpos-...@googlegroups.com
To unsubscribe, send email to jpos-users+...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/jpos-users
 
---
You received this message because you are subscribed to the Google Groups "jPOS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

D Rajkumar

unread,
Mar 11, 2013, 9:51:26 PM3/11/13
to jpos-...@googlegroups.com
Thanks for the reply,
Yes I suspected i need to use HDLC, but dont know which modem or device to use it .

Can you suggest any good modems for the same, should the modem support FastPos Hypercom ?
Will the above code work fine if I use synchronous modem or should i change the code ?

D Rajkumar

unread,
Mar 12, 2013, 1:24:45 AM3/12/13
to jpos-...@googlegroups.com

Can someone please help with below query on modem ?
Thanks,

D Rajkumar

unread,
Mar 11, 2013, 9:20:51 PM3/11/13
to jpos-...@googlegroups.com, walid_...@hotmail.com
Reply all
Reply to author
Forward
0 new messages