Protocol Pattern Matching

obby6 years ago

I'm implementing a protocol for a device that is still being in production (testing stage, no proper documentation yet). It sends data via UDP. The data is a comma-delimited string. The current format is as follows.

mm/dd/yy,hh:mm:ss,DEVICE_IMEI,VENDOR_ID,VEHICLE_REGISTRATION,SPEED,LONGITUDE,LATITUDE,POWER_CONNECTION,LIMITER_CONNECTION

e.g.

11/12/18,13.52.40,111111111111111,GVXX,KKK888K,90,51.4337S,0.0478E

I checked out various protocol implementations and came up with the following pattern.

private static final Pattern PATTERN = new PatternBuilder()
            .number("(dd)/(dd)/(dd),")        // date (mm/dd/yy)
            .number("(dd):(dd):(dd),")          // time (hh:mm:ss)
            .number("(d+),")                        // imei
            .text("[a-zA-Z_0-9]{5},")             // vendor id (alphanumeric)
            .text("[a-zA-Z_0-9]{7},")             // vehicle registration (alphanumeric)
            .number("(d+),")                        // speed (km/h)
            .number("(d+)(d+.d+)([NS]),")       // latitude
            .number("(d+)(d+.d+)([EW]),")      // longitude
            .number("(d),")                          // power connection (1-disconnected, 0-okay)
            .number("(d)")                           // limiter connection (1-disconnected, 0-okay)
            .compile();

For the date pattern, I added DateTimeFormat.MDY_HMS in the Parser class.

so far the test for the decoder is failing due to a failed pattern match. Question is, where did i mess up in the pattern builder?

Also, the device sends data as a ASCII string via UDP, will it need a custom frame decoder or new CharacterDelimiterFrameDecoder(1024, "+", "-") will do just fine? Because I can see that the BaseProtocolDecoder checks whether it's TCP/UDP in the getDeviceSession method.

I'll appreciate help in understanding the pattern builder and the UDP situation.

Anton Tananaev6 years ago

Use PatternUtil class to check.

obby6 years ago

I tried using PatternUtil but still I'm facing the same problem. I also tested a different protocol pattern that looked similar to mine, that is TrackboxProtocol, but this also failed using PatternUtil. For TrackBoxProtocol, I used the same test string as used in TrackboxProtocolDecoderTest.

// Trackbox
PatternUtil.checkPattern(
                "(dd)(dd)(dd).(ddd),(dd)(dd.dddd)([NS]),(ddd)(dd.dddd)([EW]),(d+.d),(-?d+.?d*),(d),(d+.d+),d+.d+,(d+.d+),(dd)(dd)(dd),(d+)",
                "183457.999,5126.0247N,00002.8686E,5.2,70.4,3,57.63,32.11,17.32,150507,05");


// For my protocol
PatternUtil.checkPattern(
                "(dd)/(dd)/(dd),(dd):(dd):(dd),(d+),[a-zA-Z_0-9]{5},[a-zA-Z_0-9]{7},(dd),(dd)(dd.dddd)([NS]),(ddd)(dd.dddd)([EW]),(d),(d)",
                "11/12/18,13:52:40,111111111111111,GVXX,KKK888K,90,51.43375S,0.04781E");

Both of them have the same error: WARNING: Pattern matching error java.util.regex.PatternSyntaxException: Unclosed group near index 5
I still can't tell where the issue is. No other code has been changed apart from adding an extra switch case for DateTimeFormat.MDY_HMS in the Parser class. The rest of the code is as per the current master which I pulled today.

Somehow i just can't get my head around it.

Anton Tananaev6 years ago

What do you mean by failed? Pattern util tells you where the problem is.

obby6 years ago

I mean it shows there is an error even for protocol (Trackbox) whose test is passing. Can you give me any pointers as to why the pattern would not match?

Anton Tananaev6 years ago

I think you misunderstand how util works. You need to see the result. It tells you where the issue is exactly.

obby6 years ago

Yes it does, it says WARNING: Pattern matching error java.util.regex.PatternSyntaxException: Unclosed group near index 5. But if I check that specific part of the string, I see no problem. (dd)/(dd)/(dd) this is the beginning of the string, index 5 is the third ( from the start. Where is the unenclosed group? does the forward slash require grouping?

Anton Tananaev6 years ago

It never throws any exceptions:

https://github.com/traccar/traccar/blob/master/src/org/traccar/helper/PatternUtil.java#L73

You are doing something wrong.

obby6 years ago

That's what am asking, where have I gone wrong?

Anton Tananaev6 years ago

I'll repeat it one more time. You need to look at the result that pattern util returns you.

obby6 years ago

maybe i'm not explaining myself properly. That's what i'm checking. I'm checking the results of pattern util. The main thing it shows me is a series of WARNING: Pattern matching error java.util.regex.PatternSyntaxException: Unclosed group near index 5. This continues for several other indices. What i'm trying to say, if there is something wrong with the pattern in my code, one will be able to see it and correct it. Can you see any mistake in the above pattern? If so, I would appreciate the correction.

Anton Tananaev6 years ago

Result is returned from the method. You should NOT be looking in the logs.

obby6 years ago

Okay. Just checked the returned MatchResult object. The same result for both the Trackbox and my protocol decoder classes.

PatternMatch = empty string
PatternTail = full test string
StringMatch = empty string
StringTail = empty string

maybe i'm disturbing you, but if you let me know what's wrong with my pattern builder, i will do the correction. i just want to understand why my pattern is not working. You may ask me to check it again, and i will continue to check on my own, but if you can let me know where i'm going wrong, i'll appreciate.

Anton Tananaev6 years ago

If you get empty match, probably it doesn't match from the very beginning of the string.

obby6 years ago

If you look at both the pattern and the test string without using PatternUtil, just lokking at it character by character. is there any error?