0

I have the following code. I can do the reading all well and convert data into hex. The issue is when I send back String replyMessage = "7E81";, the device receives it as "3745". What is wrong? Is it due to my encoding, or do I need to do some conversion before I send back?

w =  new BufferedWriter(new OutputStreamWriter(receivedSocketConn1.getOutputStream(),"ISO-8859-15")); //
r = new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream(),"ISO-8859-15"));
int nextChar=0;
while ((nextChar=r.read()) != -1) {               
    StringBuilder sb = new StringBuilder();
    sb.append(Integer.toHexString(nextChar));
    if (sb.length() < 2) {
        sb.insert(0, '0'); // pad with leading zero if needed
    }
    String hexChar = sb.toString();
    System.out.println("\n\n hex value is "+Integer.toHexString(nextChar).toUpperCase()+"   "+"Int value is:"+nextChar);          
    message = message+hexChar; 
    String messageID=message.substring(2,6);
    System.out.println("messageId is :"+messageID);
    if(messageID.equals("0100")){
        String replyMessage = "7E81";
        w.write(replyMessage+"\r\n");
        w.flush();
    }
}
7
  • 1
    37 is the hex value of the 7 character, and 45 is the hex value of the E character. So, you are sending the string "7E81" and the receiver is converting the first two characters (or all of them?) to their hex values. Why are you dealing with hex values at all? This is a very unusual protocol. Commented Sep 27, 2016 at 19:03
  • So before I send should I convert the for e.g. 7E into integer first then? So that when it converts it get the right data? Commented Sep 27, 2016 at 19:05
  • 1
    You need to explain this communication protocol first, and what you are attempting to accomplish with it. Using hex values in this manner is not how network communications should be handled. What exactly is this protocol you are trying to implement? Commented Sep 27, 2016 at 19:05
  • Ok the communication protocol states that it will send in hex value and I reply in hex format. That is why I do Integer.toHexString(nextChar).toUpperCase() which so far the receiving process is working fine. Commented Sep 27, 2016 at 19:09
  • 1
    IF (and I stress IF) the device is sending hex-formatted strings, you should NOT be converting the characters you receive to hex yourself, as it is ALREADY in a hex format. You would be double-encoding the data and thus corrupting it. I doubt the protocol is actually sending real hex strings, though. But you did not show the actual data. Please edit your question to show some real data example, and include the relevant documentation. I suspect you are misinterpreting it. Commented Sep 27, 2016 at 19:16

1 Answer 1

2

Based on comments in chat:

the documentation say

Start Byte (1 Byte) 7e
Message ID (2 Byte) 01 00
Message Body Nature (2 Byte) 00 19
Phone no. of Device (6 Byte) 09 40 27 84 94 70
Message Serial number (2 Byte) 00 01
Message Body (N Byte) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 09 40 27 84 94 70 00
Check Code (1Byte) 19
End Byte (1Byte) 7E

so the start and termination is 7E

for outgoing

Start Byte (1 Byte) 7e
Message ID (2 Byte) 81 00
Message Body Nature (2 Byte) 00 13
Phone no. of Device (6 Byte) 09 40 27 84 94 70
Message Serial number (2 Byte) 00 01
Message Body (N Byte) 00 01 00 32 30 31 31 31 31 30 38 31 31 33 33 32 31 39 36
Check Code (1Byte) 9A
End Byte (1Byte) 7e

This means the protocol in question is a binary protocol, not a textual protocol that sends hex strings, like you thought. As such, your use of OutputStreamWriter, InputStreamReader, StringBuilder, toHexString(), etc are all completely wrong for this protocol.

Each message received and sent begins with a fixed 13-byte header, followed by a variable-length body (the header specifies the body length), and terminated by a fixed 2-byte footer.

With that in mind, try something more like this instead:

final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

...

w = new DataOutputStream(new BufferedOutputStream(receivedSocketConn1.getOutputStream()));
r = new DataInputStream(new BufferedInputStream(receivedSocketConn1.getInputStream()));

...

if (r.readByte() != 0x7E) // start byte
{
    // ah oh, something went wrong!!
    receivedSocketConn1.close();
    return;
}

int messageID = r.readUnsignedShort();     // message ID
int bodyLen = r.readUnsignedShort();       // message body nature (body length)
byte[] phoneNum = new byte[6];
r.readFully(phoneNum);                     // device phone number
int serialNum = r.readUnsignedShort();     // message serial number
byte[] messageBody = new byte[bodyLen];    // message body
r.readFully(messageBody);
byte checkCode = r.readByte();             // check code

if (r.readByte() != 0x7E) // end byte
{
    // ah oh, something went wrong!!
    receivedSocketConn1.close();
    return;
}

// TODO: validate checkCode if needed...

System.out.println("messageId is : 0x" + Integer.toHexString(messageID));
System.out.println("phoneNum is : " + bytesToHex(phoneNum));
System.out.println("serialNum is : 0x" + Integer.toHexString(serialNum));
System.out.println("messageBody is : " + bytesToHex(messageBody));

// process message data as needed...

switch (messageID)
{
    case 0x100:
    {
        // ...

        byte[] replyBody = new byte[19];
        replyBody[0] = 0x00;
        replyBody[1] = 0x01;
        replyBody[2] = 0x00;
        replyBody[3] = 0x32;
        // and so on...

        checkCode = 0x9A; // calculate as needed...

        w.writeByte(0x7e);               // start byte
        w.writeShort(0x8100);            // message ID
        w.writeShort(replyBody.length);  // message body nature (body length)
        w.write(phoneNum);               // device phone number
        w.writeShort(0x0001);            // message serial number
        w.write(replyBody);              // message body
        w.writeByte(checkCode);          // check code
        w.writeByte(0x7e);               // end byte

        break;
    }

    // other message IDs as needed...
}

w.flush();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.