mirror of
https://github.com/traccar/traccar.git
synced 2025-01-09 04:07:38 +08:00
Add Galileo protocol
This commit is contained in:
parent
d4f33f724b
commit
572dfddfb6
@ -197,4 +197,8 @@
|
||||
<entry key='cellocator.enable'>true</entry>
|
||||
<entry key='cellocator.port'>5033</entry>
|
||||
|
||||
<!-- Galileo server configuration -->
|
||||
<entry key='galileo.enable'>true</entry>
|
||||
<entry key='galileo.port'>5034</entry>
|
||||
|
||||
</properties>
|
||||
|
@ -139,6 +139,7 @@ public class ServerManager {
|
||||
initSyrusServer("syrus");
|
||||
initVt300Server("vt300");
|
||||
initCellocatorServer("cellocator");
|
||||
initGalileoServer("galileo");
|
||||
|
||||
// Initialize web server
|
||||
if (Boolean.valueOf(properties.getProperty("http.enable"))) {
|
||||
@ -732,4 +733,18 @@ public class ServerManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void initGalileoServer(String protocol) throws SQLException {
|
||||
if (isProtocolEnabled(properties, protocol)) {
|
||||
TrackerServer server = new TrackerServer(this, new ServerBootstrap(), protocol) {
|
||||
@Override
|
||||
protected void addSpecificHandlers(ChannelPipeline pipeline) {
|
||||
pipeline.addLast("frameDecoder", new GalileoFrameDecoder());
|
||||
pipeline.addLast("objectDecoder", new GalileoProtocolDecoder(ServerManager.this));
|
||||
}
|
||||
};
|
||||
server.setEndianness(ByteOrder.LITTLE_ENDIAN);
|
||||
serverList.add(server);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
47
src/org/traccar/protocol/GalileoFrameDecoder.java
Normal file
47
src/org/traccar/protocol/GalileoFrameDecoder.java
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2013 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.protocol;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.jboss.netty.channel.Channel;
|
||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||
import org.jboss.netty.handler.codec.frame.FrameDecoder;
|
||||
|
||||
public class GalileoFrameDecoder extends FrameDecoder {
|
||||
|
||||
private static final int MESSAGE_MINIMUM_LENGTH = 5;
|
||||
|
||||
@Override
|
||||
protected Object decode(
|
||||
ChannelHandlerContext ctx,
|
||||
Channel channel,
|
||||
ChannelBuffer buf) throws Exception {
|
||||
|
||||
// Check minimum length
|
||||
if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Read packet
|
||||
int length = buf.getUnsignedShort(buf.readerIndex() + 1) & 0x7fff;
|
||||
if (buf.readableBytes() >= (length + MESSAGE_MINIMUM_LENGTH)) {
|
||||
return buf.readBytes(length + MESSAGE_MINIMUM_LENGTH);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
169
src/org/traccar/protocol/GalileoProtocolDecoder.java
Normal file
169
src/org/traccar/protocol/GalileoProtocolDecoder.java
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2013 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.protocol;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
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.ServerManager;
|
||||
import org.traccar.helper.Log;
|
||||
import org.traccar.model.Position;
|
||||
|
||||
public class GalileoProtocolDecoder extends BaseProtocolDecoder {
|
||||
|
||||
public GalileoProtocolDecoder(ServerManager serverManager) {
|
||||
super(serverManager);
|
||||
}
|
||||
|
||||
private static final Map<Integer, Integer> tagLengthMap = new HashMap<Integer, Integer>();
|
||||
|
||||
static {
|
||||
int[] l1 = {0x01,0x02,0x35,0x43,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd5};
|
||||
int[] l2 = {0x04,0x10,0x34,0x40,0x41,0x42,0x45,0x46,0x50,0x51,0x52,0x53,0x58,0x59,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0xd6,0xd7,0xd8,0xd9,0xda};
|
||||
int[] l4 = {0x20,0x33,0x44,0x90,0xc0,0xc1,0xc2,0xc3,0xd3,0xd4,0xdb,0xdc,0xdd,0xde,0xdf};
|
||||
for (int i : l1) { tagLengthMap.put(i, 1); }
|
||||
for (int i : l2) { tagLengthMap.put(i, 2); }
|
||||
for (int i : l4) { tagLengthMap.put(i, 4); }
|
||||
}
|
||||
|
||||
private static int getTagLength(int tag) {
|
||||
return tagLengthMap.get(tag);
|
||||
}
|
||||
|
||||
private String readImei(ChannelBuffer buf) {
|
||||
int b = buf.readUnsignedByte();
|
||||
StringBuilder imei = new StringBuilder();
|
||||
imei.append(b & 0x0F);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
b = buf.readUnsignedByte();
|
||||
imei.append((b & 0xF0) >> 4);
|
||||
imei.append(b & 0x0F);
|
||||
}
|
||||
return imei.toString();
|
||||
}
|
||||
|
||||
private static final int TAG_IMEI = 0x03;
|
||||
private static final int TAG_DATE = 0x20;
|
||||
private static final int TAG_COORDINATES = 0x30;
|
||||
private static final int TAG_SPEED_COURSE = 0x33;
|
||||
private static final int TAG_ALTITUDE = 0x34;
|
||||
private static final int TAG_STATUS = 0x40;
|
||||
private static final int TAG_POWER = 0x41;
|
||||
private static final int TAG_BATTERY = 0x42;
|
||||
private static final int TAG_MILAGE = 0xd4;
|
||||
|
||||
|
||||
private void sendReply(Channel channel, int checksum) {
|
||||
ChannelBuffer reply = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 3);
|
||||
reply.writeByte(0x02);
|
||||
reply.writeShort((short) checksum);
|
||||
if (channel != null) {
|
||||
channel.write(reply);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object decode(
|
||||
ChannelHandlerContext ctx, Channel channel, Object msg)
|
||||
throws Exception {
|
||||
|
||||
ChannelBuffer buf = (ChannelBuffer) msg;
|
||||
|
||||
buf.readUnsignedByte(); // header
|
||||
int length = buf.readUnsignedShort() & 0x7fff + 3;
|
||||
|
||||
// Create new position
|
||||
Position position = new Position();
|
||||
StringBuilder extendedInfo = new StringBuilder("<protocol>galileo</protocol>");
|
||||
|
||||
while (buf.readerIndex() < length) {
|
||||
int tag = buf.readUnsignedByte();
|
||||
switch (tag) {
|
||||
|
||||
case TAG_IMEI:
|
||||
String imei = buf.toString(buf.readerIndex(), 15, Charset.defaultCharset());
|
||||
buf.skipBytes(imei.length());
|
||||
try {
|
||||
position.setDeviceId(getDataManager().getDeviceByImei(imei).getId());
|
||||
} catch(Exception error) {
|
||||
Log.warning("Unknown device - " + imei);
|
||||
}
|
||||
break;
|
||||
|
||||
case TAG_DATE:
|
||||
position.setTime(new Date(buf.readUnsignedInt() * 1000));
|
||||
break;
|
||||
|
||||
case TAG_COORDINATES:
|
||||
position.setValid((buf.readUnsignedByte() & 0xf0) == 0x00);
|
||||
position.setLatitude(buf.readInt() / 1000000.0);
|
||||
position.setLongitude(buf.readInt() / 1000000.0);
|
||||
break;
|
||||
|
||||
case TAG_SPEED_COURSE:
|
||||
position.setSpeed(buf.readUnsignedShort() * 0.0539957);
|
||||
position.setCourse(buf.readUnsignedShort() * 0.1);
|
||||
break;
|
||||
|
||||
case TAG_ALTITUDE:
|
||||
position.setAltitude((double) buf.readShort());
|
||||
break;
|
||||
|
||||
case TAG_STATUS:
|
||||
extendedInfo.append("<status>");
|
||||
extendedInfo.append(buf.readUnsignedShort());
|
||||
extendedInfo.append("</status>");
|
||||
break;
|
||||
|
||||
case TAG_POWER:
|
||||
position.setPower((double) buf.readUnsignedShort());
|
||||
break;
|
||||
|
||||
case TAG_BATTERY:
|
||||
extendedInfo.append("<battery>");
|
||||
extendedInfo.append(buf.readUnsignedShort());
|
||||
extendedInfo.append("</battery>");
|
||||
break;
|
||||
|
||||
case TAG_MILAGE:
|
||||
extendedInfo.append("<milage>");
|
||||
extendedInfo.append(buf.readUnsignedInt());
|
||||
extendedInfo.append("</milage>");
|
||||
break;
|
||||
|
||||
default:
|
||||
buf.skipBytes(getTagLength(tag));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sendReply(channel, buf.readUnsignedShort());
|
||||
|
||||
position.setExtendedInfo(extendedInfo.toString());
|
||||
return position;
|
||||
}
|
||||
|
||||
}
|
@ -26,14 +26,8 @@ import org.traccar.ServerManager;
|
||||
import org.traccar.helper.Log;
|
||||
import org.traccar.model.Position;
|
||||
|
||||
/**
|
||||
* T55 tracker protocol decoder
|
||||
*/
|
||||
public class Gt02ProtocolDecoder extends BaseProtocolDecoder {
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public Gt02ProtocolDecoder(ServerManager serverManager) {
|
||||
super(serverManager);
|
||||
}
|
||||
@ -53,9 +47,6 @@ public class Gt02ProtocolDecoder extends BaseProtocolDecoder {
|
||||
private static final int MSG_HEARTBEAT = 0x1A;
|
||||
private static final int MSG_DATA = 0x10;
|
||||
|
||||
/**
|
||||
* Decode message
|
||||
*/
|
||||
@Override
|
||||
protected Object decode(
|
||||
ChannelHandlerContext ctx, Channel channel, Object msg)
|
||||
|
20
test/org/traccar/protocol/GalileoProtocolDecoderTest.java
Normal file
20
test/org/traccar/protocol/GalileoProtocolDecoderTest.java
Normal file
@ -0,0 +1,20 @@
|
||||
package org.traccar.protocol;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffers;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import org.junit.Test;
|
||||
|
||||
public class GalileoProtocolDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testDecode() throws Exception {
|
||||
|
||||
GalileoProtocolDecoder decoder = new GalileoProtocolDecoder(null);
|
||||
decoder.setDataManager(new TestDataManager());
|
||||
|
||||
/*byte[] buf1 = {0x00};
|
||||
assertNotNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(buf1)));*/
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user