diff options
-rw-r--r-- | src/org/traccar/protocol/CastelProtocolDecoder.java | 221 |
1 files changed, 120 insertions, 101 deletions
diff --git a/src/org/traccar/protocol/CastelProtocolDecoder.java b/src/org/traccar/protocol/CastelProtocolDecoder.java index 0beca4070..994c66ea6 100644 --- a/src/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/org/traccar/protocol/CastelProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 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. @@ -132,156 +132,175 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private Object decodeSc( + Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, + int version, ChannelBuffer id, int type, DeviceSession deviceSession) { - ChannelBuffer buf = (ChannelBuffer) msg; + if (type == MSG_SC_HEARTBEAT) { - int header = buf.readUnsignedShort(); - buf.readUnsignedShort(); // length + sendResponse(channel, remoteAddress, version, id, MSG_SC_HEARTBEAT_RESPONSE, null); - int version = -1; - if (header == 0x4040) { - version = buf.readUnsignedByte(); - } + } else if (type == MSG_SC_LOGIN || type == MSG_SC_LOGOUT || type == MSG_SC_GPS + || type == MSG_SC_ALARM || type == MSG_SC_CURRENT_LOCATION) { - ChannelBuffer id = buf.readBytes(20); - int type = ChannelBuffers.swapShort(buf.readShort()); + if (type == MSG_SC_LOGIN) { + ChannelBuffer response = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 10); + response.writeInt(0xFFFFFFFF); + response.writeShort(0); + response.writeInt((int) (System.currentTimeMillis() / 1000)); + sendResponse(channel, remoteAddress, version, id, MSG_SC_LOGIN_RESPONSE, response); + } - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, id.toString(StandardCharsets.US_ASCII).trim()); - if (deviceSession == null) { - return null; - } + if (type == MSG_SC_GPS) { + buf.readUnsignedByte(); // historical + } else if (type == MSG_SC_ALARM) { + buf.readUnsignedInt(); // alarm + } else if (type == MSG_SC_CURRENT_LOCATION) { + buf.readUnsignedShort(); + } - if (version == -1) { + buf.readUnsignedInt(); // ACC ON time + buf.readUnsignedInt(); // UTC time + long odometer = buf.readUnsignedInt(); + buf.readUnsignedInt(); // trip odometer + buf.readUnsignedInt(); // total fuel consumption + buf.readUnsignedShort(); // current fuel consumption + long status = buf.readUnsignedInt(); + buf.skipBytes(8); - if (type == 0x2001) { + int count = buf.readUnsignedByte(); - sendResponse(channel, remoteAddress, id, (short) 0x1001); + List<Position> positions = new LinkedList<>(); - buf.readUnsignedInt(); // index - buf.readUnsignedInt(); // unix time - buf.readUnsignedByte(); - - return readPosition(deviceSession, buf); + for (int i = 0; i < count; i++) { + Position position = readPosition(deviceSession, buf); + position.set(Position.KEY_ODOMETER, odometer); + position.set(Position.KEY_STATUS, status); + positions.add(position); + } + if (!positions.isEmpty()) { + return positions; } - } else if (version == 4) { + } else if (type == MSG_SC_GPS_SLEEP) { - if (type == MSG_SC_HEARTBEAT) { + buf.readUnsignedInt(); // device time - sendResponse(channel, remoteAddress, version, id, MSG_SC_HEARTBEAT_RESPONSE, null); + return readPosition(deviceSession, buf); - } else if (type == MSG_SC_LOGIN || type == MSG_SC_LOGOUT || type == MSG_SC_GPS - || type == MSG_SC_ALARM || type == MSG_SC_CURRENT_LOCATION) { + } else if (type == MSG_SC_AGPS_REQUEST) { - if (type == MSG_SC_LOGIN) { - ChannelBuffer response = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 10); - response.writeInt(0xFFFFFFFF); - response.writeShort(0); - response.writeInt((int) (System.currentTimeMillis() / 1000)); - sendResponse(channel, remoteAddress, version, id, MSG_SC_LOGIN_RESPONSE, response); - } + return readPosition(deviceSession, buf); - if (type == MSG_SC_GPS) { - buf.readUnsignedByte(); // historical - } else if (type == MSG_SC_ALARM) { - buf.readUnsignedInt(); // alarm - } else if (type == MSG_SC_CURRENT_LOCATION) { - buf.readUnsignedShort(); - } + } + + return null; + } - buf.readUnsignedInt(); // ACC ON time - buf.readUnsignedInt(); // UTC time - long odometer = buf.readUnsignedInt(); - buf.readUnsignedInt(); // trip odometer - buf.readUnsignedInt(); // total fuel consumption - buf.readUnsignedShort(); // current fuel consumption - long status = buf.readUnsignedInt(); - buf.skipBytes(8); - int count = buf.readUnsignedByte(); + private Object decodeCc( + Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, + int version, ChannelBuffer id, int type, DeviceSession deviceSession) { - List<Position> positions = new LinkedList<>(); + if (type == MSG_CC_HEARTBEAT) { - for (int i = 0; i < count; i++) { - Position position = readPosition(deviceSession, buf); - position.set(Position.KEY_ODOMETER, odometer); - position.set(Position.KEY_STATUS, status); - positions.add(position); - } + sendResponse(channel, remoteAddress, version, id, MSG_CC_HEARTBEAT_RESPONSE, null); - if (!positions.isEmpty()) { - return positions; - } + buf.readUnsignedByte(); // 0x01 for history + int count = buf.readUnsignedByte(); - } else if (type == MSG_SC_GPS_SLEEP) { + List<Position> positions = new LinkedList<>(); - buf.readUnsignedInt(); // device time + for (int i = 0; i < count; i++) { + Position position = readPosition(deviceSession, buf); - return readPosition(deviceSession, buf); + position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } else if (type == MSG_SC_AGPS_REQUEST) { + buf.readUnsignedByte(); // geo-fencing id + buf.readUnsignedByte(); // geo-fencing flags + buf.readUnsignedByte(); // additional flags - return readPosition(deviceSession, buf); + position.set(Position.KEY_LAC, buf.readUnsignedShort()); + position.set(Position.KEY_CID, buf.readUnsignedShort()); + positions.add(position); } - } else { + return positions; - if (type == MSG_CC_HEARTBEAT) { + } else if (type == MSG_CC_LOGIN) { - sendResponse(channel, remoteAddress, version, id, MSG_CC_HEARTBEAT_RESPONSE, null); + sendResponse(channel, remoteAddress, version, id, MSG_CC_LOGIN_RESPONSE, null); - buf.readUnsignedByte(); // 0x01 for history - int count = buf.readUnsignedByte(); + Position position = readPosition(deviceSession, buf); - List<Position> positions = new LinkedList<>(); + position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - for (int i = 0; i < count; i++) { - Position position = readPosition(deviceSession, buf); + buf.readUnsignedByte(); // geo-fencing id + buf.readUnsignedByte(); // geo-fencing flags + buf.readUnsignedByte(); // additional flags - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); - position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + // GSM_CELL_CODE + // STR_Z - firmware version + // STR_Z - hardware version - buf.readUnsignedByte(); // geo-fencing id - buf.readUnsignedByte(); // geo-fencing flags - buf.readUnsignedByte(); // additional flags + return position; - position.set(Position.KEY_LAC, buf.readUnsignedShort()); - position.set(Position.KEY_CID, buf.readUnsignedShort()); + } - positions.add(position); - } + return null; + } - return positions; + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - } else if (type == MSG_CC_LOGIN) { + ChannelBuffer buf = (ChannelBuffer) msg; - sendResponse(channel, remoteAddress, version, id, MSG_CC_LOGIN_RESPONSE, null); + int header = buf.readUnsignedShort(); + buf.readUnsignedShort(); // length - Position position = readPosition(deviceSession, buf); + int version = -1; + if (header == 0x4040) { + version = buf.readUnsignedByte(); + } - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); - position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + ChannelBuffer id = buf.readBytes(20); + int type = ChannelBuffers.swapShort(buf.readShort()); - buf.readUnsignedByte(); // geo-fencing id - buf.readUnsignedByte(); // geo-fencing flags - buf.readUnsignedByte(); // additional flags + DeviceSession deviceSession = getDeviceSession( + channel, remoteAddress, id.toString(StandardCharsets.US_ASCII).trim()); + if (deviceSession == null) { + return null; + } + + if (version == -1) { + + if (type == 0x2001) { + + sendResponse(channel, remoteAddress, id, (short) 0x1001); - // GSM_CELL_CODE - // STR_Z - firmware version - // STR_Z - hardware version + buf.readUnsignedInt(); // index + buf.readUnsignedInt(); // unix time + buf.readUnsignedByte(); - return position; + return readPosition(deviceSession, buf); } + } else if (version == 4) { + + return decodeSc(channel, remoteAddress, buf, version, id, type, deviceSession); + + } else { + + return decodeCc(channel, remoteAddress, buf, version, id, type, deviceSession); + } return null; |