mirror of
https://github.com/traccar/traccar.git
synced 2026-06-12 19:04:56 -04:00
Support versioned JT808 encoder
This commit is contained in:
@@ -92,7 +92,7 @@ public class Jt808ProtocolDecoder extends BaseProtocolDecoder {
|
||||
return protocolVersion;
|
||||
}
|
||||
|
||||
public ByteBuf formatMessage(int delimiter, int type, ByteBuf id, boolean shortIndex, ByteBuf data) {
|
||||
public ByteBuf formatMessage(int type, ByteBuf id, boolean shortIndex, ByteBuf data) {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
buf.writeByte(delimiter);
|
||||
buf.writeShort(type);
|
||||
@@ -125,7 +125,7 @@ public class Jt808ProtocolDecoder extends BaseProtocolDecoder {
|
||||
response.writeShort(type);
|
||||
response.writeByte(RESULT_SUCCESS);
|
||||
channel.writeAndFlush(new NetworkMessage(
|
||||
formatMessage(delimiter, MSG_GENERAL_RESPONSE, id, false, response), remoteAddress));
|
||||
formatMessage(MSG_GENERAL_RESPONSE, id, false, response), remoteAddress));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ public class Jt808ProtocolDecoder extends BaseProtocolDecoder {
|
||||
response.writeShort(type);
|
||||
response.writeByte(RESULT_SUCCESS);
|
||||
channel.writeAndFlush(new NetworkMessage(
|
||||
formatMessage(delimiter, MSG_GENERAL_RESPONSE_2, id, true, response), remoteAddress));
|
||||
formatMessage(MSG_GENERAL_RESPONSE_2, id, true, response), remoteAddress));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +228,11 @@ public class Jt808ProtocolDecoder extends BaseProtocolDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
static ByteBuf encodeId(String uniqueId) {
|
||||
static ByteBuf encodeId(String uniqueId, int length) {
|
||||
if (length == 10) {
|
||||
return Unpooled.wrappedBuffer(DataConverter.parseHex(
|
||||
String.format("%20s", uniqueId).replace(' ', '0')));
|
||||
}
|
||||
if (uniqueId.length() % 2 == 0) {
|
||||
return Unpooled.wrappedBuffer(DataConverter.parseHex(uniqueId));
|
||||
} else {
|
||||
@@ -335,7 +339,7 @@ public class Jt808ProtocolDecoder extends BaseProtocolDecoder {
|
||||
response.writeByte(RESULT_SUCCESS);
|
||||
response.writeBytes(decodeId(id).getBytes(StandardCharsets.US_ASCII));
|
||||
channel.writeAndFlush(new NetworkMessage(
|
||||
formatMessage(delimiter, MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress));
|
||||
formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress));
|
||||
}
|
||||
|
||||
} else if (type == MSG_REPORT_TEXT_MESSAGE) {
|
||||
@@ -408,7 +412,7 @@ public class Jt808ProtocolDecoder extends BaseProtocolDecoder {
|
||||
response.writeByte(calendar.get(Calendar.MINUTE));
|
||||
response.writeByte(calendar.get(Calendar.SECOND));
|
||||
channel.writeAndFlush(new NetworkMessage(
|
||||
formatMessage(delimiter, MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress));
|
||||
formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress));
|
||||
}
|
||||
|
||||
} else if (type == MSG_ACCELERATION) {
|
||||
|
||||
@@ -17,6 +17,8 @@ package org.traccar.protocol;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import org.traccar.BasePipelineFactory;
|
||||
import org.traccar.BaseProtocol;
|
||||
import org.traccar.BaseProtocolEncoder;
|
||||
import org.traccar.Protocol;
|
||||
@@ -39,32 +41,37 @@ public class Jt808ProtocolEncoder extends BaseProtocolEncoder {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object encodeCommand(Command command) {
|
||||
protected Object encodeCommand(Channel channel, Command command) {
|
||||
|
||||
Jt808ProtocolDecoder decoder = BasePipelineFactory.getHandler(
|
||||
channel.pipeline(), Jt808ProtocolDecoder.class);
|
||||
|
||||
boolean alternative = AttributeUtil.lookup(
|
||||
getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId());
|
||||
|
||||
ByteBuf id = Jt808ProtocolDecoder.encodeId(getUniqueId(command.getDeviceId()));
|
||||
Integer protocolVersion = decoder.getProtocolVersion();
|
||||
ByteBuf id = Jt808ProtocolDecoder.encodeId(
|
||||
getUniqueId(command.getDeviceId()), protocolVersion != null ? 10 : 6);
|
||||
String model = getDeviceModel(command.getDeviceId());
|
||||
try {
|
||||
ByteBuf data = Unpooled.buffer();
|
||||
|
||||
switch (command.getType()) {
|
||||
case Command.TYPE_CUSTOM:
|
||||
String model = getDeviceModel(command.getDeviceId());
|
||||
if (model != null && Set.of("AL300", "GL100", "VL300").contains(model)) {
|
||||
data.writeByte(1); // number of parameters
|
||||
data.writeInt(0xF030); // AT command transparent transmission
|
||||
int length = command.getString(Command.KEY_DATA).length();
|
||||
data.writeByte(length);
|
||||
data.writeCharSequence(command.getString(Command.KEY_DATA), StandardCharsets.US_ASCII);
|
||||
return Jt808ProtocolDecoder.formatMessage(
|
||||
0x7e, Jt808ProtocolDecoder.MSG_CONFIGURATION_PARAMETERS, id, false, data);
|
||||
return decoder.formatMessage(
|
||||
Jt808ProtocolDecoder.MSG_CONFIGURATION_PARAMETERS, id, false, data);
|
||||
} else if ("BSJ".equals(model)) {
|
||||
data.writeByte(1); // flag
|
||||
var charset = Charset.isSupported("GBK") ? Charset.forName("GBK") : StandardCharsets.US_ASCII;
|
||||
data.writeCharSequence(command.getString(Command.KEY_DATA), charset);
|
||||
return Jt808ProtocolDecoder.formatMessage(
|
||||
0x7e, Jt808ProtocolDecoder.MSG_SEND_TEXT_MESSAGE, id, false, data);
|
||||
return decoder.formatMessage(
|
||||
Jt808ProtocolDecoder.MSG_SEND_TEXT_MESSAGE, id, false, data);
|
||||
} else {
|
||||
return Unpooled.wrappedBuffer(DataConverter.parseHex(command.getString(Command.KEY_DATA)));
|
||||
}
|
||||
@@ -73,15 +80,15 @@ public class Jt808ProtocolEncoder extends BaseProtocolEncoder {
|
||||
data.writeByte(0x23); // parameter id
|
||||
data.writeByte(1); // parameter value length
|
||||
data.writeByte(0x03); // restart
|
||||
return Jt808ProtocolDecoder.formatMessage(
|
||||
0x7e, Jt808ProtocolDecoder.MSG_PARAMETER_SETTING, id, false, data);
|
||||
return decoder.formatMessage(
|
||||
Jt808ProtocolDecoder.MSG_PARAMETER_SETTING, id, false, data);
|
||||
case Command.TYPE_POSITION_PERIODIC:
|
||||
data.writeByte(1); // number of parameters
|
||||
data.writeByte(0x06); // parameter id
|
||||
data.writeByte(4); // parameter value length
|
||||
data.writeInt(command.getInteger(Command.KEY_FREQUENCY));
|
||||
return Jt808ProtocolDecoder.formatMessage(
|
||||
0x7e, Jt808ProtocolDecoder.MSG_PARAMETER_SETTING, id, false, data);
|
||||
return decoder.formatMessage(
|
||||
Jt808ProtocolDecoder.MSG_PARAMETER_SETTING, id, false, data);
|
||||
case Command.TYPE_ALARM_ARM:
|
||||
case Command.TYPE_ALARM_DISARM:
|
||||
data.writeByte(1); // number of parameters
|
||||
@@ -90,50 +97,50 @@ public class Jt808ProtocolEncoder extends BaseProtocolEncoder {
|
||||
data.writeByte(1 + username.length()); // parameter value length
|
||||
data.writeByte(command.getType().equals(Command.TYPE_ALARM_ARM) ? 0x01 : 0x00);
|
||||
data.writeCharSequence(username, StandardCharsets.US_ASCII);
|
||||
return Jt808ProtocolDecoder.formatMessage(
|
||||
0x7e, Jt808ProtocolDecoder.MSG_PARAMETER_SETTING, id, false, data);
|
||||
return decoder.formatMessage(
|
||||
Jt808ProtocolDecoder.MSG_PARAMETER_SETTING, id, false, data);
|
||||
case Command.TYPE_ENGINE_STOP:
|
||||
case Command.TYPE_ENGINE_RESUME:
|
||||
if (alternative) {
|
||||
data.writeByte(command.getType().equals(Command.TYPE_ENGINE_STOP) ? 0x01 : 0x00);
|
||||
data.writeBytes(DataConverter.parseHex(
|
||||
new SimpleDateFormat("yyMMddHHmmss").format(new Date())));
|
||||
return Jt808ProtocolDecoder.formatMessage(
|
||||
0x7e, Jt808ProtocolDecoder.MSG_OIL_CONTROL, id, false, data);
|
||||
return decoder.formatMessage(
|
||||
Jt808ProtocolDecoder.MSG_OIL_CONTROL, id, false, data);
|
||||
} else {
|
||||
if ("VL300".equals(getDeviceModel(command.getDeviceId()))) {
|
||||
if ("VL300".equals(model)) {
|
||||
data.writeCharSequence(command.getType().equals(Command.TYPE_ENGINE_STOP) ? "#0;1" : "#0;0",
|
||||
StandardCharsets.US_ASCII);
|
||||
} else if ("W15L".equals(getDeviceModel(command.getDeviceId()))) {
|
||||
} else if ("W15L".equals(model)) {
|
||||
data.writeByte(command.getType().equals(Command.TYPE_ENGINE_STOP) ? 0x64 : 0x65);
|
||||
} else {
|
||||
data.writeByte(command.getType().equals(Command.TYPE_ENGINE_STOP) ? 0xf0 : 0xf1);
|
||||
}
|
||||
return Jt808ProtocolDecoder.formatMessage(
|
||||
0x7e, Jt808ProtocolDecoder.MSG_TERMINAL_CONTROL, id, false, data);
|
||||
return decoder.formatMessage(
|
||||
Jt808ProtocolDecoder.MSG_TERMINAL_CONTROL, id, false, data);
|
||||
}
|
||||
case Command.TYPE_VIDEO_START:
|
||||
var config = getCacheManager().getConfig();
|
||||
String host = URI.create(config.getString(Keys.WEB_URL)).getHost();
|
||||
int port = config.getInteger(
|
||||
Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(Jt1078Protocol.class)));
|
||||
int channel = command.getInteger(Command.KEY_INDEX, 1);
|
||||
int videoChannel = command.getInteger(Command.KEY_INDEX, 1);
|
||||
data.writeByte(host.length());
|
||||
data.writeCharSequence(host, StandardCharsets.US_ASCII);
|
||||
data.writeShort(port); // tcp port
|
||||
data.writeShort(0); // udp port
|
||||
data.writeByte(channel);
|
||||
data.writeByte(videoChannel);
|
||||
data.writeByte(1); // video only
|
||||
data.writeByte(0); // main stream
|
||||
return Jt808ProtocolDecoder.formatMessage(
|
||||
0x7e, Jt808ProtocolDecoder.MSG_VIDEO_REQUEST, id, false, data);
|
||||
return decoder.formatMessage(
|
||||
Jt808ProtocolDecoder.MSG_VIDEO_REQUEST, id, false, data);
|
||||
case Command.TYPE_VIDEO_STOP:
|
||||
data.writeByte(command.getInteger(Command.KEY_INDEX, 1));
|
||||
data.writeByte(0); // close audio/video transmission
|
||||
data.writeByte(0); // close both audio and video
|
||||
data.writeByte(0); // main stream
|
||||
return Jt808ProtocolDecoder.formatMessage(
|
||||
0x7e, Jt808ProtocolDecoder.MSG_VIDEO_CONTROL, id, false, data);
|
||||
return decoder.formatMessage(
|
||||
Jt808ProtocolDecoder.MSG_VIDEO_CONTROL, id, false, data);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user