sergio
sergio

Reputation: 1046

How to read network stream data in Java (Protocol packets)

Am working on decoding a protocol used by a certain gps device to communicate. Right now, am analyzing the first data packet that it sends. I am able to read it, but am thinking am not reading it properly.

Here is what i got so far:

    public static String toHex(byte[] bytes) {
    BigInteger bi = new BigInteger(1, bytes);
    return String.format("%0" + (bytes.length << 1) + "X", bi);
}

private void ProcessInitialPacket(){
            int port = 1954;
    System.out.println("Listening on port :"+port);
    byte[] data =  new byte[17];
    byte[] ackPacket = new byte[2];
    byte[] dataPacket= new byte[15];
    try {
        ServerSocket sSocket = new ServerSocket(port);
        Socket cSocket = sSocket.accept();          
        DataInputStream dataIN = new DataInputStream(cSocket.getInputStream());
        int packetSize=dataIN.read(data,0,data.length);         
        System.arraycopy(data, 0, ackPacket, 0, 2);
        System.arraycopy(data,2,dataPacket,0,15);

        System.out.println("Total packet size: "+ packetSize);
        System.out.println("ACK PACKET : "+ toHex(ackPacket));
        System.out.println("DATA PACKET: "+ toHex(dataPacket));
        System.out.println("FULL PACKET: "+ toHex(data));
    } catch (IOException e) { 
        e.printStackTrace();
    }
}

the output:

-PARSER()--

-INITSESSION-- Listening on port :1954

Total packet size: 17

ACK PACKET : 000F

DATA PACKET: 333532383438303236323631393534

FULL PACKET: 000F333532383438303236323631393534

------CLOSESESSION------------

Now, my problem:

what is happening here is that the device sends a [0x00][0x0F]xxxxxxxxxxxxxxx where the xxxxxxx is its imei (the data packet). My problem is that there are way too many 3´s on the data packet, so the real valid output is

352848026261954

which you obtain by removing 3´s. my question is: can this behavior come from my code or its part of the protocol? i can correct this programmatically but am wanting to know it there is a way that code can cause these extra 3s.

Upvotes: 0

Views: 6689

Answers (2)

user207421
user207421

Reputation: 310980

This is ASCII numeric encoding. 0 is being transmitted as '0', which is 0x30. 1 is being transmitted as 0x31. Etc. So your understanding of the data format is incorrect.

Upvotes: 2

Peter Lawrey
Peter Lawrey

Reputation: 533680

You are looking at the hex of the ascii values which needs to be decoded as numbers. The character '0' as a decimal is 48 or as hex 0x30, up to '9' is 57 as a decimal or 0x39 as hex.

So a sequence of bytes

33 35 32 38 34 38 30 32 36 32 36 31 39 35 34

is

"352848026261954"

as ASCII characters.

I would change your code like this

dataIN.readFully(data); // always read 17 bytes, not less
String text = new String(data, 0, 2, 13); // decodes 8-bit bytes as a String
long number = Long.parseLong(text);

Upvotes: 3

Related Questions