From c2bdb1c0af69739eb7ed3618e72687bc5e1275c4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 29 Dec 2016 05:57:26 +1300 Subject: Finish Smokey protocol implementation --- src/org/traccar/model/WifiAccessPoint.java | 17 ++++ .../traccar/protocol/SmokeyProtocolDecoder.java | 93 +++++++++++++++++++--- test/org/traccar/helper/ChecksumTest.java | 1 - .../protocol/SmokeyProtocolDecoderTest.java | 13 +-- 4 files changed, 101 insertions(+), 23 deletions(-) diff --git a/src/org/traccar/model/WifiAccessPoint.java b/src/org/traccar/model/WifiAccessPoint.java index e4a613e7c..ddb995412 100644 --- a/src/org/traccar/model/WifiAccessPoint.java +++ b/src/org/traccar/model/WifiAccessPoint.java @@ -20,6 +20,13 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) public class WifiAccessPoint { + public static WifiAccessPoint from(String macAddress, int signalStrength) { + WifiAccessPoint wifiAccessPoint = new WifiAccessPoint(); + wifiAccessPoint.setMacAddress(macAddress); + wifiAccessPoint.setSignalStrength(signalStrength); + return wifiAccessPoint; + } + private String macAddress; public String getMacAddress() { @@ -30,4 +37,14 @@ public class WifiAccessPoint { this.macAddress = macAddress; } + private Integer signalStrength; + + public Integer getSignalStrength() { + return signalStrength; + } + + public void setSignalStrength(Integer signalStrength) { + this.signalStrength = signalStrength; + } + } diff --git a/src/org/traccar/protocol/SmokeyProtocolDecoder.java b/src/org/traccar/protocol/SmokeyProtocolDecoder.java index 86496fba6..856c62018 100644 --- a/src/org/traccar/protocol/SmokeyProtocolDecoder.java +++ b/src/org/traccar/protocol/SmokeyProtocolDecoder.java @@ -21,9 +21,13 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; +import org.traccar.model.CellTower; +import org.traccar.model.Network; import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; public class SmokeyProtocolDecoder extends BaseProtocolDecoder { @@ -31,6 +35,32 @@ public class SmokeyProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public static final int MSG_DATE_RECORD = 0; + public static final int MSG_DATE_RECORD_ACK = 1; + + private static void sendResponse( + Channel channel, SocketAddress remoteAddress, ChannelBuffer id, int index, int report) { + + if (channel != null) { + ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + response.writeBytes("SM".getBytes(StandardCharsets.US_ASCII)); + response.writeByte(3); // protocol version + response.writeByte(MSG_DATE_RECORD_ACK); + response.writeBytes(id); + response.writeInt(0); // timestamp + response.writeByte(index); + response.writeByte(report - 0x200); + + short checksum = (short) 0xF5A0; + for (int i = 0; i < response.readableBytes(); i += 2) { + checksum ^= ChannelBuffers.swapShort(response.getShort(i)); + } + response.writeShort(checksum); + + channel.write(response, remoteAddress); + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -42,17 +72,13 @@ public class SmokeyProtocolDecoder extends BaseProtocolDecoder { int type = buf.readUnsignedByte(); - String id = ChannelBuffers.hexDump(buf.readBytes(8)); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); + ChannelBuffer id = buf.readBytes(8); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ChannelBuffers.hexDump(id)); if (deviceSession == null) { return null; } - if (type == 0) { - - /*if (channel != null) { - // TODO send ack - }*/ + if (type == MSG_DATE_RECORD) { buf.readUnsignedShort(); // firmware version @@ -60,20 +86,65 @@ public class SmokeyProtocolDecoder extends BaseProtocolDecoder { position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_STATUS, buf.readUnsignedByte()); + int status = buf.readUnsignedShort(); + position.set(Position.KEY_STATUS, status); DateBuilder dateBuilder = new DateBuilder() .setDate(2000, 1, 1).addSeconds(buf.readUnsignedInt()); getLastLocation(position, dateBuilder.getDate()); - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + int index = buf.readUnsignedByte(); + position.set(Position.KEY_INDEX, index); - buf.readUnsignedShort(); // task / parameter number + int report = buf.readUnsignedShort(); buf.readUnsignedShort(); // length - // data + position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); + + Network network = new Network(); + + if (report != 0x0203) { + + int count = 1; + if (report != 0x0200) { + count = buf.readUnsignedByte(); + } + + for (int i = 0; i < count; i++) { + int mcc = buf.readUnsignedShort(); + int mnc = buf.readUnsignedShort(); + int lac = buf.readUnsignedShort(); + int cid = buf.readUnsignedShort(); + if (i == 0) { + buf.readByte(); // timing advance + } + int rssi = buf.readByte(); + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); + } + + } + + if (report == 0x0202 || report == 0x0203) { + + int count = buf.readUnsignedByte(); + + for (int i = 0; i < count; i++) { + buf.readerIndex(buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0) + 1); // ssid + + String mac = String.format("%02x:%02x:%02x:%02x:%02x:%02x", + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + + network.addWifiAccessPoint(WifiAccessPoint.from(mac, buf.readByte())); + } + + } + + position.setNetwork(network); + + sendResponse(channel, remoteAddress, id, index, report); return position; diff --git a/test/org/traccar/helper/ChecksumTest.java b/test/org/traccar/helper/ChecksumTest.java index 82bae7346..c37eda88d 100644 --- a/test/org/traccar/helper/ChecksumTest.java +++ b/test/org/traccar/helper/ChecksumTest.java @@ -5,7 +5,6 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.junit.Assert; import org.junit.Test; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; public class ChecksumTest { diff --git a/test/org/traccar/protocol/SmokeyProtocolDecoderTest.java b/test/org/traccar/protocol/SmokeyProtocolDecoderTest.java index fd862b437..d3e268992 100644 --- a/test/org/traccar/protocol/SmokeyProtocolDecoderTest.java +++ b/test/org/traccar/protocol/SmokeyProtocolDecoderTest.java @@ -11,19 +11,10 @@ public class SmokeyProtocolDecoderTest extends ProtocolTest { SmokeyProtocolDecoder decoder = new SmokeyProtocolDecoder(new SmokeyProtocol()); verifyAttributes(decoder, binary( - "534D0300865628025161227F030100000000029E03020200A4021405028F0007010658300200028F0007010625F21D028F00070106000027028F00070106584E19028F000701065DCF2707537265696C6C69634E657400E8DE27400DF0A80084C9B2D85A1DB7537265696C6C69634E657400E8DE27401048D44350455F44423745393900A8A668DB7E99A94D794E6574776F726B4E616D6500002675ED6D70AB74686170616E6500002675F4DA3CA94D75666173610088CEFA735AFCA9C524")); + "534d0300865101019383025f0403000000000b86250200000c0000028f000102f8cc0900127f08")); verifyAttributes(decoder, binary( - "534d0300865628025163272f031400000000001c000200000c0168028f000102c9f93a011f538d")); - - verifyAttributes(decoder, binary( - "534d0300865628025163272f031400000000001f000200000c0167028f000102c9f93a011f5082")); - - verifyAttributes(decoder, binary( - "534d0300865628025163272f031400000000001d000200000c0167028f000102c9f93a011f5282")); - - verifyAttributes(decoder, binary( - "534d0300865628025163272f031400000000001e000200000c0167028f000102c9f93a011f5182")); + "534d0300865101019383025f0403000000000bcf260200000c0000028f000102f8cc090012360b")); } -- cgit v1.2.3