-1

I am trying to parse TLV string:

24 00 35 E1 31 9F 08 02 38 30 9F 37 04 4A 66 6B 69 DF AE 05 01 41 9F 26 08 73 30 35 76 4F 6A 36 4E DF AE 06 0C 33 34 71 76 69 70 6B 4D 53 63 66 55 9F 36 02 00 01 90 00 7B

In this case 9F08 is tag followed by length field and data. I am able to get the required fields with the current input string i have, but there could be a scenario where the tag ("9F08") could also be in the data part of another field. I am confused as to how to proceed on this.

public void bleToPos(String hex) {
    sb=new StringBuilder();
    tlv=new TLVData();
    int noOfCharacters=0,src=0,dest=0;
    String epiolgue="",epligueData="";

    String [] hexArray=hex.split(" ");
    //Extract 1st 3 bytes and last 3 bytes. last 3 bytes should contain 90 00 otherwise not valid string
    epiolgue=hexArray[hexArray.length-3];
    epiolgue= epiolgue + hexArray[hexArray.length-2];
    epligueData = hexArray[hexArray.length-1];
    if(!epiolgue.equals("9000")) {
        System.out.println(" Not a valid tlv no need to process");
        return;
    }
    tlv.setEpilogue(epligueData);
    int arrayLength=hexArray.length;
    if(hexArray!=null && hexArray.length>0) {
        for(int i=0;i<hexArray.length;i++) {
            try {
                if(hexArray[i].equals("9F")) {
                    if((i+1)<arrayLength &&  hexArray[i+1].equals("08")) {
                        noOfCharacters= (char)Integer.parseInt(hexArray[i+2], 16);
                        src=i+3;
                        dest=src+noOfCharacters;
                        copyArrayElementsIntoString(src, dest, hexArray);
                        tlv.setVersion(sb.toString());
                        sb.setLength(0);
                    }
                    else if((i+1)<arrayLength && hexArray[i+1].equals("37")) {
                        noOfCharacters= (char)Integer.parseInt(hexArray[i+2], 16);
                        src=i+3;
                        dest=src+noOfCharacters;
                        copyArrayElementsIntoString(src, dest, hexArray);
                        tlv.setDssid(sb.toString());
                        sb.setLength(0);
                    }
                    else if((i+1)<arrayLength && hexArray[i+1].equals("26")) {
                        noOfCharacters= (char)Integer.parseInt(hexArray[i+2], 16);
                        src=i+3;
                        dest=src+noOfCharacters;
                        copyArrayElementsIntoString(src, dest, hexArray);
                        tlv.setMac(sb.toString());
                        sb.setLength(0);
                    }
                    else if((i+1)<arrayLength && hexArray[i+1].equals("36")) {
                        noOfCharacters= (char)Integer.parseInt(hexArray[i+2], 16);
                        src=i+3;
                        dest=src+noOfCharacters;
                        copyArrayElementsIntoString(src, dest, hexArray);
                        tlv.setAtc(sb.toString());
                        sb.setLength(0);
                    }
                    i=dest-1;
                    src=0;
                    dest=0;
                    continue;

                }
                if(hexArray[i].equals("DF")) {
                    if((i+1)<arrayLength && hexArray[i+1].equals("AE")) {

                        if((i+2)<arrayLength && hexArray[i+2].equals("05")) {
                            noOfCharacters= (char)Integer.parseInt(hexArray[i+3], 16);
                            src=i+4;
                            dest=src+noOfCharacters;
                            copyArrayElementsIntoString(src, dest, hexArray);
                            tlv.setCvb(sb.toString());
                            sb.setLength(0);
                        }
                        else if((i+2)<arrayLength && hexArray[i+2].equals("06")) {
                            noOfCharacters= (char)Integer.parseInt(hexArray[i+3], 16);
                            src=i+4;
                            dest=src+noOfCharacters;
                            copyArrayElementsIntoString(src, dest, hexArray);
                            tlv.setToken(sb.toString());
                            sb.setLength(0);
                        }

                    }
                    i=dest-1;
                    src=0;
                    dest=0;
                    continue;
                }
                /*if(hexArray[i].equals("90")) {
                    if((i+1)<arrayLength && hexArray[i+1].equals("00")) {

                    }
                }*/

            }catch(Exception e) {

            }

        }
    }
}
Kaka
  • 1
  • 3
  • First, you should parse the input hex string into a `byte[]`. Anyway, if input is really 114 hex digits, then `split(" ")` will not split anything, but simply return a `String[]` of one element, i.e. the entire input, and `hexArray[hexArray.length-3]` will then throw exception, and none of your code will run. Try again! – Andreas Mar 12 '18 at 17:16
  • Sorry about the input string i pasted the one which has no spaces in it. Actual string has spaces after every byte and i am able to split it. – Kaka Mar 12 '18 at 17:51
  • Then you should edit the question and show the version of the data that actually matches the code. – Andreas Mar 12 '18 at 20:41
  • TLV Decode from cryptomathic at http://extranet.cryptomathic.com/tlvutils/index Sorry, there were some errors encountered while decoding: Short value for tag 35, expected length 8397414651929375767755279014127412078567821808600920015574545401688638293030691230202797230783982154840628529348657308868018299, got 0 24 Unknown tag 35 Unknown tag – Orlay Garcia Duconge Dec 10 '19 at 16:21

1 Answers1

1

If I understood your question right. When you parse the Length of the data after you have found your Tag, you can ignore a duplicate Tag that occurs within the Data for next Length number of bytes. Only consider the tag that you find outside the Length of Data bytes.

Sam
  • 2,935
  • 1
  • 19
  • 26
  • Say for example this string "240035E1319F080238309F370454363449DFAE0501419F260861742F754D6E4956DFAE060C3334726C5A6E6C6B75796B649F36020001900071". TAG "9F08" is followed by byte 02 which specifies next two bytes as data , now there maybe a case where this TAG will also be part of Another TAG's data how will i distinguish in this case even if i read the next byte. I am a bit confused. – Kaka Mar 13 '18 at 19:20
  • you read a tag, then you read length of data, now you know that how many bytes of data is there for this particular tag. Just consider next `length` number of bytes as data. Even if there is a `tag` within this data you know that you dont have to consider it because now you are just reading data. Once you are done with reading the data, proceed with the next tag. – Sam Mar 13 '18 at 19:58
  • I created one enum map which will have the tags i am interested in, then i loop over the string taking one byte two characters at a time and i check if it is a tag and if so is it the last byte of the tag if not then continue to next byte or next two characters. I have a boolean variable to see if its tag or length just in case to prevent tag checking i n case of length. – Kaka Mar 16 '18 at 19:54
  • So when you find your tag, you read the next 2 bytes for the data length right ? So after reading the length say it is x, so now the next x bytes will be data. Set a boolean flag to true and and start traversing the string for x bytes, and while the boolean flag is true don't look for tags, in the end set boolean flag to false, and look for next tag. – Sam Mar 16 '18 at 21:45