aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/org/traccar/helper/BitUtil.java35
-rw-r--r--src/org/traccar/protocol/BceProtocolDecoder.java25
-rw-r--r--src/org/traccar/protocol/Mta6ProtocolDecoder.java48
-rw-r--r--src/org/traccar/protocol/SkypatrolProtocolDecoder.java58
-rw-r--r--src/org/traccar/protocol/TeltonikaProtocolDecoder.java32
-rw-r--r--test/org/traccar/helper/BitUtilTest.java23
6 files changed, 129 insertions, 92 deletions
diff --git a/src/org/traccar/helper/BitUtil.java b/src/org/traccar/helper/BitUtil.java
new file mode 100644
index 000000000..6e03e6d2a
--- /dev/null
+++ b/src/org/traccar/helper/BitUtil.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.helper;
+
+/**
+ * Useful functions to work with bits
+ */
+public class BitUtil {
+
+ public static boolean check(long number, int index) {
+ return (number & (1 << index)) != 0;
+ }
+
+ public static int range(int number, int index, int length) {
+ return (number >> index) & ((1 << length) - 1);
+ }
+
+ public static long range(long number, int index, int length) {
+ return (number >> index) & ((1l << length) - 1);
+ }
+
+}
diff --git a/src/org/traccar/protocol/BceProtocolDecoder.java b/src/org/traccar/protocol/BceProtocolDecoder.java
index fa951e21d..189cad754 100644
--- a/src/org/traccar/protocol/BceProtocolDecoder.java
+++ b/src/org/traccar/protocol/BceProtocolDecoder.java
@@ -24,6 +24,7 @@ import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.traccar.BaseProtocolDecoder;
+import org.traccar.helper.BitUtil;
import org.traccar.model.Event;
import org.traccar.model.Position;
@@ -41,10 +42,6 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
private static final int MSG_OUTPUT_CONTROL = 0x41;
private static final int MSG_OUTPUT_CONTROL_ACK = 0xC1;
- private static boolean checkBit(int mask, int bit) {
- return (mask & (1 << bit)) != 0;
- }
-
@Override
protected Object decode(
ChannelHandlerContext ctx, Channel channel, Object msg)
@@ -86,11 +83,11 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
do {
mask = buf.readUnsignedShort();
masks.add(mask);
- } while (checkBit(mask, 15));
+ } while (BitUtil.check(mask, 15));
mask = masks.get(0);
- if (checkBit(mask, 0)) {
+ if (BitUtil.check(mask, 0)) {
position.setValid(true);
position.setLongitude(buf.readFloat());
position.setLatitude(buf.readFloat());
@@ -106,22 +103,22 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
position.set(Event.KEY_ODOMETER, buf.readUnsignedInt());
}
- if (checkBit(mask, 1)) {
+ if (BitUtil.check(mask, 1)) {
position.set(Event.KEY_INPUT, buf.readUnsignedShort());
}
for (int i = 1; i <= 8; i++) {
- if (checkBit(mask, i + 1)) {
+ if (BitUtil.check(mask, i + 1)) {
position.set(Event.PREFIX_ADC + i, buf.readUnsignedShort());
}
}
- if (checkBit(mask, 10)) buf.skipBytes(4);
- if (checkBit(mask, 11)) buf.skipBytes(4);
- if (checkBit(mask, 12)) buf.skipBytes(2);
- if (checkBit(mask, 13)) buf.skipBytes(2);
+ if (BitUtil.check(mask, 10)) buf.skipBytes(4);
+ if (BitUtil.check(mask, 11)) buf.skipBytes(4);
+ if (BitUtil.check(mask, 12)) buf.skipBytes(2);
+ if (BitUtil.check(mask, 13)) buf.skipBytes(2);
- if (checkBit(mask, 14)) {
+ if (BitUtil.check(mask, 14)) {
position.set(Event.KEY_MCC, buf.readUnsignedShort());
position.set(Event.KEY_MNC, buf.readUnsignedByte());
position.set(Event.KEY_LAC, buf.readUnsignedShort());
@@ -130,7 +127,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte();
}
- if (checkBit(mask, 0)) {
+ if (BitUtil.check(mask, 0)) {
positions.add(position);
}
}
diff --git a/src/org/traccar/protocol/Mta6ProtocolDecoder.java b/src/org/traccar/protocol/Mta6ProtocolDecoder.java
index 7d4ead62c..459b8bcb8 100644
--- a/src/org/traccar/protocol/Mta6ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Mta6ProtocolDecoder.java
@@ -21,7 +21,6 @@ import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.TimeZone;
-
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
@@ -31,8 +30,8 @@ import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
-
import org.traccar.BaseProtocolDecoder;
+import org.traccar.helper.BitUtil;
import org.traccar.helper.ChannelBufferTools;
import org.traccar.model.Event;
import org.traccar.model.Position;
@@ -66,11 +65,6 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder {
channel.write(response);
}
- private static boolean checkBit(long mask, int bit) {
- long checkMask = 1 << bit;
- return (mask & checkMask) == checkMask;
- }
-
private static class FloatReader {
private int previousFloat;
@@ -135,11 +129,11 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder {
// Skip events
short event = buf.readUnsignedByte();
- if (checkBit(event, 7)) {
- if (checkBit(event, 6)) {
+ if (BitUtil.check(event, 7)) {
+ if (BitUtil.check(event, 6)) {
buf.skipBytes(8);
} else {
- while (checkBit(event, 7)) {
+ while (BitUtil.check(event, 7)) {
event = buf.readUnsignedByte();
}
}
@@ -149,44 +143,44 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder {
position.setLongitude(longitudeReader.readFloat(buf) / Math.PI * 180);
position.setTime(timeReader.readTime(buf));
- if (checkBit(flags, 0)) {
+ if (BitUtil.check(flags, 0)) {
buf.readUnsignedByte(); // status
}
- if (checkBit(flags, 1)) {
+ if (BitUtil.check(flags, 1)) {
position.setAltitude(buf.readUnsignedShort());
}
- if (checkBit(flags, 2)) {
+ if (BitUtil.check(flags, 2)) {
position.setSpeed(buf.readUnsignedShort() & 0x03ff);
position.setCourse(buf.readUnsignedByte());
}
- if (checkBit(flags, 3)) {
+ if (BitUtil.check(flags, 3)) {
position.set(Event.KEY_ODOMETER, buf.readUnsignedShort());
}
- if (checkBit(flags, 4)) {
+ if (BitUtil.check(flags, 4)) {
position.set(Event.KEY_FUEL, buf.readUnsignedInt() + "|" + buf.readUnsignedInt());
position.set("hours1", buf.readUnsignedShort());
position.set("hours2", buf.readUnsignedShort());
}
- if (checkBit(flags, 5)) {
+ if (BitUtil.check(flags, 5)) {
position.set(Event.PREFIX_ADC + 1, buf.readUnsignedShort() & 0x03ff);
position.set(Event.PREFIX_ADC + 2, buf.readUnsignedShort() & 0x03ff);
position.set(Event.PREFIX_ADC + 3, buf.readUnsignedShort() & 0x03ff);
position.set(Event.PREFIX_ADC + 4, buf.readUnsignedShort() & 0x03ff);
}
- if (checkBit(flags, 6)) {
+ if (BitUtil.check(flags, 6)) {
position.set(Event.PREFIX_TEMP + 1, buf.readByte());
buf.getUnsignedByte(buf.readerIndex()); // control (>> 4)
position.set(Event.KEY_INPUT, buf.readUnsignedShort() & 0x0fff);
buf.readUnsignedShort(); // old sensor state (& 0x0fff)
}
- if (checkBit(flags, 7)) {
+ if (BitUtil.check(flags, 7)) {
position.set(Event.KEY_BATTERY, buf.getUnsignedByte(buf.readerIndex()) >> 2);
position.set(Event.KEY_POWER, buf.readUnsignedShort() & 0x03ff);
buf.readByte(); // microcontroller temperature
@@ -214,11 +208,11 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder {
// Skip events
short event = buf.readUnsignedByte();
- if (checkBit(event, 7)) {
- if (checkBit(event, 6)) {
+ if (BitUtil.check(event, 7)) {
+ if (BitUtil.check(event, 6)) {
buf.skipBytes(8);
} else {
- while (checkBit(event, 7)) {
+ while (BitUtil.check(event, 7)) {
event = buf.readUnsignedByte();
}
}
@@ -230,41 +224,41 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte(); // status
- if (checkBit(flags, 0)) {
+ if (BitUtil.check(flags, 0)) {
position.setAltitude(buf.readUnsignedShort());
position.setSpeed(buf.readUnsignedByte());
position.setCourse(buf.readByte());
position.set(Event.KEY_ODOMETER, new FloatReader().readFloat(buf));
}
- if (checkBit(flags, 1)) {
+ if (BitUtil.check(flags, 1)) {
new FloatReader().readFloat(buf); // fuel consumtion
position.set("hours", new FloatReader().readFloat(buf));
position.set("tank", buf.readUnsignedByte() * 0.4);
}
- if (checkBit(flags, 2)) {
+ if (BitUtil.check(flags, 2)) {
position.set("engine", buf.readUnsignedShort() * 0.125);
position.set("pedals", buf.readUnsignedByte());
position.set(Event.PREFIX_TEMP + 1, buf.readUnsignedByte() - 40);
buf.readUnsignedShort(); // service odometer
}
- if (checkBit(flags, 3)) {
+ if (BitUtil.check(flags, 3)) {
position.set(Event.KEY_FUEL, buf.readUnsignedShort());
position.set(Event.PREFIX_ADC + 2, buf.readUnsignedShort());
position.set(Event.PREFIX_ADC + 3, buf.readUnsignedShort());
position.set(Event.PREFIX_ADC + 4, buf.readUnsignedShort());
}
- if (checkBit(flags, 4)) {
+ if (BitUtil.check(flags, 4)) {
position.set(Event.PREFIX_TEMP + 1, buf.readByte());
buf.getUnsignedByte(buf.readerIndex()); // control (>> 4)
position.set(Event.KEY_INPUT, buf.readUnsignedShort() & 0x0fff);
buf.readUnsignedShort(); // old sensor state (& 0x0fff)
}
- if (checkBit(flags, 5)) {
+ if (BitUtil.check(flags, 5)) {
position.set(Event.KEY_BATTERY, buf.getUnsignedByte(buf.readerIndex()) >> 2);
position.set(Event.KEY_POWER, buf.readUnsignedShort() & 0x03ff);
buf.readByte(); // microcontroller temperature
diff --git a/src/org/traccar/protocol/SkypatrolProtocolDecoder.java b/src/org/traccar/protocol/SkypatrolProtocolDecoder.java
index acb4fa5ec..5521502f6 100644
--- a/src/org/traccar/protocol/SkypatrolProtocolDecoder.java
+++ b/src/org/traccar/protocol/SkypatrolProtocolDecoder.java
@@ -18,12 +18,11 @@ package org.traccar.protocol;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.TimeZone;
-
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
-
import org.traccar.BaseProtocolDecoder;
+import org.traccar.helper.BitUtil;
import org.traccar.helper.Log;
import org.traccar.model.Event;
import org.traccar.model.Position;
@@ -34,11 +33,6 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
- private static boolean checkBit(long mask, int bit) {
- long checkMask = 1 << bit;
- return (mask & checkMask) == checkMask;
- }
-
private static double convertCoordinate(long coordinate) {
int sign = 1;
if (coordinate > 0x7fffffffl) {
@@ -73,23 +67,23 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder {
if (apiNumber == 5 &&
commandType == 2 &&
messageType == 1 &&
- checkBit(mask, 0)) {
+ BitUtil.check(mask, 0)) {
// Create new position
Position position = new Position();
position.setProtocol(getProtocol());
// Status code
- if (checkBit(mask, 1)) {
+ if (BitUtil.check(mask, 1)) {
position.set(Event.KEY_STATUS, buf.readUnsignedInt());
}
// Device id
String id = null;
- if (checkBit(mask, 23)) {
+ if (BitUtil.check(mask, 23)) {
id = buf.toString(buf.readerIndex(), 8, Charset.defaultCharset()).trim();
buf.skipBytes(8);
- } else if (checkBit(mask, 2)) {
+ } else if (BitUtil.check(mask, 2)) {
id = buf.toString(buf.readerIndex(), 22, Charset.defaultCharset()).trim();
buf.skipBytes(22);
} else {
@@ -102,22 +96,22 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder {
position.setDeviceId(getDeviceId());
// IO data
- if (checkBit(mask, 3)) {
+ if (BitUtil.check(mask, 3)) {
buf.readUnsignedShort();
}
// ADC 1
- if (checkBit(mask, 4)) {
+ if (BitUtil.check(mask, 4)) {
buf.readUnsignedShort();
}
// ADC 2
- if (checkBit(mask, 5)) {
+ if (BitUtil.check(mask, 5)) {
buf.readUnsignedShort();
}
// Function category
- if (checkBit(mask, 7)) {
+ if (BitUtil.check(mask, 7)) {
buf.readUnsignedByte();
}
@@ -125,39 +119,39 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder {
time.clear();
// Date
- if (checkBit(mask, 8)) {
+ if (BitUtil.check(mask, 8)) {
time.set(Calendar.DAY_OF_MONTH, buf.readUnsignedByte());
time.set(Calendar.MONTH, buf.readUnsignedByte() - 1);
time.set(Calendar.YEAR, 2000 + buf.readUnsignedByte());
}
// GPS status
- if (checkBit(mask, 9)) {
+ if (BitUtil.check(mask, 9)) {
position.setValid(buf.readUnsignedByte() == 1);
}
// Latitude
- if (checkBit(mask, 10)) {
+ if (BitUtil.check(mask, 10)) {
position.setLatitude(convertCoordinate(buf.readUnsignedInt()));
}
// Longitude
- if (checkBit(mask, 11)) {
+ if (BitUtil.check(mask, 11)) {
position.setLongitude(convertCoordinate(buf.readUnsignedInt()));
}
// Speed
- if (checkBit(mask, 12)) {
+ if (BitUtil.check(mask, 12)) {
position.setSpeed(buf.readUnsignedShort() / 10.0);
}
// Course
- if (checkBit(mask, 13)) {
+ if (BitUtil.check(mask, 13)) {
position.setCourse(buf.readUnsignedShort() / 10.0);
}
// Time
- if (checkBit(mask, 14)) {
+ if (BitUtil.check(mask, 14)) {
time.set(Calendar.HOUR_OF_DAY, buf.readUnsignedByte());
time.set(Calendar.MINUTE, buf.readUnsignedByte());
time.set(Calendar.SECOND, buf.readUnsignedByte());
@@ -166,52 +160,52 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder {
position.setTime(time.getTime());
// Altitude
- if (checkBit(mask, 15)) {
+ if (BitUtil.check(mask, 15)) {
position.setAltitude(buf.readMedium());
}
// Satellites
- if (checkBit(mask, 16)) {
+ if (BitUtil.check(mask, 16)) {
position.set(Event.KEY_SATELLITES, buf.readUnsignedByte());
}
// Battery percentage
- if (checkBit(mask, 17)) {
+ if (BitUtil.check(mask, 17)) {
buf.readUnsignedShort();
}
// Trip odometer
- if (checkBit(mask, 20)) {
+ if (BitUtil.check(mask, 20)) {
position.set("trip", buf.readUnsignedInt());
}
// Odometer
- if (checkBit(mask, 21)) {
+ if (BitUtil.check(mask, 21)) {
position.set(Event.KEY_ODOMETER, buf.readUnsignedInt());
}
// Time of message generation
- if (checkBit(mask, 22)) {
+ if (BitUtil.check(mask, 22)) {
buf.skipBytes(6);
}
// Battery level
- if (checkBit(mask, 24)) {
+ if (BitUtil.check(mask, 24)) {
position.set(Event.KEY_POWER, buf.readUnsignedShort() / 1000.0);
}
// GPS overspeed
- if (checkBit(mask, 25)) {
+ if (BitUtil.check(mask, 25)) {
buf.skipBytes(18);
}
// Cell information
- if (checkBit(mask, 26)) {
+ if (BitUtil.check(mask, 26)) {
buf.skipBytes(54);
}
// Sequence number
- if (checkBit(mask, 28)) {
+ if (BitUtil.check(mask, 28)) {
position.set(Event.KEY_INDEX, buf.readUnsignedShort());
}
diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
index d3e946f69..792a64b79 100644
--- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
+++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
@@ -19,13 +19,12 @@ import java.nio.charset.Charset;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
-
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
-
import org.traccar.BaseProtocolDecoder;
+import org.traccar.helper.BitUtil;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Event;
import org.traccar.model.Position;
@@ -49,11 +48,6 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
}
}
- private static boolean checkBit(long mask, int bit) {
- long checkMask = 1 << bit;
- return (mask & checkMask) == checkMask;
- }
-
private static final int CODEC_GH3000 = 0x07;
private static final int CODEC_FM4X00 = 0x08;
private static final int CODEC_12 = 0x0C;
@@ -87,45 +81,45 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
position.setTime(new Date(time * 1000));
globalMask = buf.readUnsignedByte();
- if (!checkBit(globalMask, 0)) {
+ if (!BitUtil.check(globalMask, 0)) {
return null;
}
int locationMask = buf.readUnsignedByte();
- if (checkBit(locationMask, 0)) {
+ if (BitUtil.check(locationMask, 0)) {
position.setLatitude(buf.readFloat());
position.setLongitude(buf.readFloat());
}
- if (checkBit(locationMask, 1)) {
+ if (BitUtil.check(locationMask, 1)) {
position.setAltitude(buf.readUnsignedShort());
}
- if (checkBit(locationMask, 2)) {
+ if (BitUtil.check(locationMask, 2)) {
position.setCourse(buf.readUnsignedByte() * 360.0 / 256);
}
- if (checkBit(locationMask, 3)) {
+ if (BitUtil.check(locationMask, 3)) {
position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
}
- if (checkBit(locationMask, 4)) {
+ if (BitUtil.check(locationMask, 4)) {
int satellites = buf.readUnsignedByte();
position.set(Event.KEY_SATELLITES, satellites);
position.setValid(satellites >= 3);
}
- if (checkBit(locationMask, 5)) {
+ if (BitUtil.check(locationMask, 5)) {
position.set("area", buf.readUnsignedShort());
position.set(Event.KEY_CELL, buf.readUnsignedShort());
}
- if (checkBit(locationMask, 6)) {
+ if (BitUtil.check(locationMask, 6)) {
position.set(Event.KEY_GSM, buf.readUnsignedByte());
}
- if (checkBit(locationMask, 7)) {
+ if (BitUtil.check(locationMask, 7)) {
position.set("operator", buf.readUnsignedInt());
}
@@ -154,7 +148,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
}
// Read 1 byte data
- if (checkBit(globalMask, 1)) {
+ if (BitUtil.check(globalMask, 1)) {
int cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
int id = buf.readUnsignedByte();
@@ -168,7 +162,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
// Read 2 byte data
- if (checkBit(globalMask, 2)) {
+ if (BitUtil.check(globalMask, 2)) {
int cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
position.set(Event.PREFIX_IO + buf.readUnsignedByte(), buf.readUnsignedShort());
@@ -176,7 +170,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
}
// Read 4 byte data
- if (checkBit(globalMask, 3)) {
+ if (BitUtil.check(globalMask, 3)) {
int cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
position.set(Event.PREFIX_IO + buf.readUnsignedByte(), buf.readUnsignedInt());
diff --git a/test/org/traccar/helper/BitUtilTest.java b/test/org/traccar/helper/BitUtilTest.java
new file mode 100644
index 000000000..dbe3852b7
--- /dev/null
+++ b/test/org/traccar/helper/BitUtilTest.java
@@ -0,0 +1,23 @@
+package org.traccar.helper;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class BitUtilTest {
+
+ @Test
+ public void testCheck() {
+ Assert.assertFalse(BitUtil.check(0, 0));
+ Assert.assertTrue(BitUtil.check(1, 0));
+ Assert.assertFalse(BitUtil.check(2, 0));
+ }
+
+ @Test
+ public void testRange() {
+ Assert.assertEquals(0, BitUtil.range(0, 0, 0));
+ Assert.assertEquals(1, BitUtil.range(1, 0, 1));
+ Assert.assertEquals(2, BitUtil.range(2, 0, 2));
+ Assert.assertEquals(2, BitUtil.range(6, 0, 2));
+ }
+
+}