/** * Decode a message header from a Netty buffer * * @param buffer The buffer to decode from * @param sender The sender of the packet, which has been set in the socket class * @return The partial message, only the header fields are filled */ public static Message decodeHeader( final ChannelBuffer buffer, final InetSocketAddress recipient, final InetSocketAddress sender) throws DecoderException { final Message message = new Message(); message.setVersion(buffer.readInt()); message.setMessageId(buffer.readInt()); // final int typeCommand = buffer.readUnsignedByte(); message.setType(Type.values()[typeCommand >>> 4]); message.setCommand(Command.values()[typeCommand & 0xf]); final Number160 senderID = readID(buffer); final int portTCP = buffer.readUnsignedShort(); final int portUDP = buffer.readUnsignedShort(); final Number160 recipientID = readID(buffer); message.setRecipient(new PeerAddress(recipientID, recipient)); final int contentType = buffer.readUnsignedShort(); message.setContentType( Content.values()[contentType & 0xf], Content.values()[(contentType >>> 4) & 0xf], Content.values()[(contentType >>> 8) & 0xf], Content.values()[contentType >>> 12]); // set the address as we see it, important for port forwarding // identification final int senderMessageOptions = buffer.readUnsignedByte(); final int senderOptions = senderMessageOptions >>> 4; final PeerAddress peerAddress = new PeerAddress(senderID, sender.getAddress(), portTCP, portUDP, senderOptions); message.setSender(peerAddress); final int options = senderMessageOptions & 0xf; message.setOptions(options); return message; }
@Override public WindowClickMessage decode(ChannelBuffer buffer) throws IOException { int id = buffer.readUnsignedByte(); int slot = buffer.readUnsignedShort(); boolean rightClick = buffer.readUnsignedByte() != 0; int transaction = buffer.readUnsignedShort(); boolean shift = buffer.readUnsignedByte() != 0; ItemStack item = ChannelBufferUtils.readItemStack(buffer); return new WindowClickMessage(id, slot, rightClick, transaction, shift, item); }
@Override protected Object decode( ChannelHandlerContext chtx, Channel chan, ChannelBuffer in, AuthenticationStage state) throws Exception { switch (state) { case VALIDATION: int bytesLeft = readableBytes(in); if (bytesLeft >= 3) { int type = in.readUnsignedByte(); int size = in.readUnsignedShort(); if (size != readableBytes(in)) { throw new Exception("Mismatched login packet size."); } int version = in.readInt(); if (version != 614) { throw new Exception("Incorrect revision read"); } if (type == 16 || type == 18) { checkpoint(AuthenticationStage.DETAILS); } } break; case DETAILS: in.readUnsignedByte(); int mode = in.readUnsignedByte(); in.readUnsignedShort(); in.readUnsignedShort(); in.readUnsignedByte(); in.skipBytes(24); readRS2String(in); // macaddress! in.readInt(); int size = in.readUnsignedByte(); in.skipBytes(size); in.skipBytes(6 + (33 * 4) + 8 + 2 + 14); if (in.readUnsignedByte() != 10) { throw new Exception("Invalid RSA header."); } in.readLong(); in.readLong(); long l = in.readLong(); String name = longToString(l); String password = readRS2String(in); int left = readableBytes(in); in.skipBytes(left); return new LoginRequest(chan, chtx, name, password, mode); } return null; }
private void decodeEventData(int event, ChannelBuffer buf) { switch (event) { case 2: case 40: buf.readUnsignedByte(); break; case 9: buf.readUnsignedMedium(); break; case 31: case 32: buf.readUnsignedShort(); break; case 38: buf.skipBytes(4 * 9); break; case 113: buf.readUnsignedInt(); buf.readUnsignedByte(); break; case 121: case 142: buf.readLong(); break; case 130: buf.readUnsignedInt(); // incorrect break; default: break; } }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; prefix = buf.toString(buf.readerIndex(), 4, CHARSET); buf.skipBytes(prefix.length()); // prefix @NTC by default serverId = buf.readUnsignedInt(); deviceUniqueId = buf.readUnsignedInt(); int length = buf.readUnsignedShort(); buf.skipBytes(2); // header and data XOR checksum if (length == 0) { return null; // keep alive message } String type = buf.toString(buf.readerIndex(), 3, CHARSET); buf.skipBytes(type.length()); switch (type) { case "*>T": return processSingle(channel, buf); case "*>A": return processArray(channel, buf); case "*>S": return processHandshake(channel, buf); default: Log.warning(new UnsupportedOperationException(type)); break; } return null; }
@Override public BlockActionMessage decode(ChannelBuffer buffer) throws IOException { int x = buffer.readInt(); int y = buffer.readUnsignedShort(); int z = buffer.readInt(); byte firstByte = buffer.readByte(); byte secondByte = buffer.readByte(); short blockId = buffer.readShort(); return new BlockActionMessage(x, y, z, blockId, firstByte, secondByte); }
@Override public PlayerSpawnMessage decode(ChannelBuffer buffer) throws IOException { int id = buffer.readInt(); String name = ChannelBufferUtils.readString(buffer); int x = buffer.readInt(); int y = buffer.readInt(); int z = buffer.readInt(); int rotation = buffer.readUnsignedByte(); int pitch = buffer.readUnsignedByte(); int item = buffer.readUnsignedShort(); List<Parameter<?>> parameters = ChannelBufferUtils.readParameters(buffer); return new PlayerSpawnMessage(id, name, x, y, z, rotation, pitch, item, parameters); }
private String getUtf(ChannelBuffer buffer) { // UTF = short + data; int readableBytes = buffer.readableBytes(); if (readableBytes < 2) { throw new IllegalArgumentException("buffer doesn't contains utf data!"); } // 只有长度 没有内容 if (readableBytes == 2) { return ""; } int dataLen = buffer.readUnsignedShort(); byte[] data = new byte[dataLen]; buffer.readBytes(data); try { return new String(data, "UTF-8"); } catch (UnsupportedEncodingException e) { Log.error("解码UTF错误", e); } return null; }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; buf.skipBytes(2); // header int type = buf.readUnsignedByte(); buf.readUnsignedShort(); // size if (type == MSG_ON_DEMAND || type == MSG_POSITION_UPLOAD || type == MSG_POSITION_REUPLOAD || type == MSG_ALARM || type == MSG_REPLY || type == MSG_PERIPHERAL) { // Create new position Position position = new Position(); position.setProtocol(getProtocolName()); // Device identification if (!identify(readSerialNumber(buf), channel)) { return null; } position.setDeviceId(getDeviceId()); // Date and time Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); time.clear(); time.set(Calendar.YEAR, 2000 + ChannelBufferTools.readHexInteger(buf, 2)); time.set(Calendar.MONTH, ChannelBufferTools.readHexInteger(buf, 2) - 1); time.set(Calendar.DAY_OF_MONTH, ChannelBufferTools.readHexInteger(buf, 2)); time.set(Calendar.HOUR_OF_DAY, ChannelBufferTools.readHexInteger(buf, 2)); time.set(Calendar.MINUTE, ChannelBufferTools.readHexInteger(buf, 2)); time.set(Calendar.SECOND, ChannelBufferTools.readHexInteger(buf, 2)); position.setTime(time.getTime()); // Location position.setLatitude(ChannelBufferTools.readCoordinate(buf)); position.setLongitude(ChannelBufferTools.readCoordinate(buf)); position.setSpeed(UnitsConverter.knotsFromKph(ChannelBufferTools.readHexInteger(buf, 4))); position.setCourse(ChannelBufferTools.readHexInteger(buf, 4)); // Flags int flags = buf.readUnsignedByte(); position.setValid((flags & 0x80) != 0); if (type == MSG_ALARM) { buf.skipBytes(2); } else { // Odometer position.set(Event.KEY_ODOMETER, buf.readUnsignedMedium()); // Status buf.skipBytes(4); // Other buf.skipBytes(8); } // TODO: parse extra data return position; } else if (type == MSG_LOGIN && channel != null) { buf.skipBytes(4); // serial number buf.readByte(); // reserved ChannelBuffer response = ChannelBuffers.dynamicBuffer(); response.writeByte(0x29); response.writeByte(0x29); // header response.writeByte(MSG_CONFIRMATION); response.writeShort(5); // size response.writeByte(buf.readUnsignedByte()); response.writeByte(type); response.writeByte(0); // reserved response.writeByte(Crc.xorChecksum(response.toByteBuffer())); response.writeByte(0x0D); // ending channel.write(response); } return null; }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; buf.skipBytes(2); // header int type = buf.readUnsignedByte(); buf.readUnsignedShort(); // length String id = decodeId( buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); if (type == MSG_HEARTBEAT) { if (channel != null) { ChannelBuffer response = ChannelBuffers.dynamicBuffer(); response.writeByte(0x24); response.writeByte(0x24); // header response.writeByte(MSG_HEARTBEAT); // size response.writeShort(5); response.writeByte(buf.readUnsignedByte()); response.writeByte(0); // main order response.writeByte(0); // slave order response.writeByte(1); // calibration response.writeByte(0x0D); channel.write(response); } } else if (type == MSG_POSITION_DATA || type == MSG_ROLLCALL_RESPONSE || type == MSG_ALARM_DATA || type == MSG_BLIND_AREA) { Position position = new Position(); position.setProtocol(getProtocolName()); if (!identify("1" + id, channel, remoteAddress, false) && !identify(id, channel, remoteAddress)) { return null; } position.setDeviceId(getDeviceId()); DateBuilder dateBuilder = new DateBuilder() .setYear(BcdUtil.readInteger(buf, 2)) .setMonth(BcdUtil.readInteger(buf, 2)) .setDay(BcdUtil.readInteger(buf, 2)) .setHour(BcdUtil.readInteger(buf, 2)) .setMinute(BcdUtil.readInteger(buf, 2)) .setSecond(BcdUtil.readInteger(buf, 2)); position.setTime(dateBuilder.getDate()); position.setLatitude(BcdUtil.readCoordinate(buf)); position.setLongitude(BcdUtil.readCoordinate(buf)); position.setSpeed(UnitsConverter.knotsFromKph(BcdUtil.readInteger(buf, 4))); position.setCourse(BcdUtil.readInteger(buf, 4)); int flags = buf.readUnsignedByte(); position.setValid((flags & 0x80) != 0); position.set(Position.KEY_SATELLITES, flags & 0x0f); position.set(Position.KEY_STATUS, buf.readUnsignedByte()); position.set("key", buf.readUnsignedByte()); position.set("oil", buf.readUnsignedShort() / 10.0); position.set(Position.KEY_POWER, buf.readUnsignedByte() + buf.readUnsignedByte() / 100.0); position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); return position; } return null; }
@Override public int readUnsignedShort() { return buffer.readUnsignedShort(); }
/** * Decodes the payload from a Netty buffer in a big switch * * @param content The content type * @param buffer The buffer to read from * @param message The message to store the results * @throws IndexOutOfBoundsException If a buffer is read beyond its limits * @throws NoSuchAlgorithmException * @throws SignatureException * @throws InvalidKeyException * @throws InvalidKeySpecException * @throws InvalidKeySpecException * @throws IOException * @throws DecoderException * @throws ASN1Exception * @throws UnsupportedEncodingException If UTF-8 is not there */ public static boolean decodePayload( final Content content, final ChannelBuffer buffer, final Message message) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, DecoderException { final int len; byte[] me; switch (content) { case KEY: if (buffer.readableBytes() < 20) return false; message.setKey0(readID(buffer)); return true; case KEY_KEY: if (buffer.readableBytes() < 40) return false; message.setKeyKey0(readID(buffer), readID(buffer)); return true; case MAP_KEY_DATA: if (buffer.readableBytes() < 4) return false; int size = buffer.readInt(); Map<Number160, Data> result = new HashMap<Number160, Data>(size); for (int i = 0; i < size; i++) { if (buffer.readableBytes() < 20) return false; Number160 key = readID(buffer); final Data data = decodeData(new ChannelDecoder(buffer), message.getSender()); if (data == null) return false; if (message.isRequest()) { if (data.isProtectedEntry() && message.getPublicKey() == null) throw new DecoderException( "You indicated that you want to protect the data, but you did not provide or provided too late a public key."); data.setPublicKey(message.getPublicKey()); } result.put(key, data); } message.setDataMap0(result); return true; case MAP_KEY_KEY: if (buffer.readableBytes() < 4) return false; len = buffer.readInt(); if (buffer.readableBytes() < ((20 + 20) * len)) return false; final Map<Number160, Number160> keyMap = new HashMap<Number160, Number160>(); for (int i = 0; i < len; i++) { final Number160 key1 = readID(buffer); final Number160 key2 = readID(buffer); keyMap.put(key1, key2); } message.setKeyMap0(keyMap); return true; case SET_KEYS: // can be 31bit long ~ 2GB if (buffer.readableBytes() < 4) return false; len = buffer.readInt(); if (buffer.readableBytes() < (20 * len)) return false; final Collection<Number160> tmp = new ArrayList<Number160>(len); for (int i = 0; i < len; i++) { Number160 key = readID(buffer); tmp.add(key); } message.setKeys0(tmp); return true; case SET_NEIGHBORS: if (buffer.readableBytes() < 1) return false; len = buffer.readUnsignedByte(); if (buffer.readableBytes() < (len * PeerAddress.SIZE_IPv4)) return false; final Collection<PeerAddress> neighbors = new ArrayList<PeerAddress>(len); for (int i = 0; i < len; i++) { PeerAddress peerAddress = readPeerAddress(buffer); if (peerAddress == null) return false; neighbors.add(peerAddress); } message.setNeighbors0(neighbors); return true; case SET_TRACKER_DATA: if (buffer.readableBytes() < 1) return false; len = buffer.readUnsignedByte(); if (buffer.readableBytes() < (len * (PeerAddress.SIZE_IPv4 + 1))) return false; final Collection<TrackerData> trackerDatas = new ArrayList<TrackerData>(len); for (int i = 0; i < len; i++) { PeerAddress peerAddress = readPeerAddress(buffer); if (peerAddress == null) return false; byte[] attachment = null; int offset = 0; int length = 0; if (buffer.readableBytes() < 1) return false; byte miniHeader = buffer.readByte(); if (miniHeader != 0) { if (buffer.readableBytes() < 4) return false; length = buffer.readInt(); if (buffer.readableBytes() < length) return false; attachment = new byte[length]; buffer.readBytes(attachment); } trackerDatas.add( new TrackerData(peerAddress, message.getSender(), attachment, offset, length)); } message.setTrackerData0(trackerDatas); return true; case CHANNEL_BUFFER: if (buffer.readableBytes() < 4) return false; len = buffer.readInt(); if (buffer.readableBytes() < len) return false; // you can only use slice if no execution handler is in place, // otherwise, you will overwrite stuff final ChannelBuffer tmpBuffer = buffer.slice(buffer.readerIndex(), len); buffer.skipBytes(len); message.setPayload0(tmpBuffer); return true; case LONG: if (buffer.readableBytes() < 8) return false; message.setLong0(buffer.readLong()); return true; case INTEGER: if (buffer.readableBytes() < 4) return false; message.setInteger0(buffer.readInt()); return true; case PUBLIC_KEY: case PUBLIC_KEY_SIGNATURE: if (buffer.readableBytes() < 2) return false; len = buffer.readUnsignedShort(); me = new byte[len]; if (buffer.readableBytes() < len) return false; message.setPublicKey0(decodePublicKey(new ChannelDecoder(buffer), me)); if (content == Content.PUBLIC_KEY_SIGNATURE) { message.setHintSign(true); } return true; case EMPTY: case RESERVED1: case RESERVED2: case RESERVED3: default: return true; } }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; buf.skipBytes(2); // header buf.readUnsignedShort(); // length String imei = ChannelBuffers.hexDump(buf.readBytes(7)); if (!identify(imei, channel, null, false) && !identify(imei + Checksum.luhn(Long.parseLong(imei)), channel)) { return null; } int type = buf.readUnsignedShort(); if (type == MSG_LOCATION_REPORT || type == MSG_LOCATION_REQUEST) { String sentence = buf.toString(buf.readerIndex(), buf.readableBytes() - 8, Charset.defaultCharset()); Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { return null; } Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(getDeviceId()); if (parser.hasNext(15)) { DateBuilder dateBuilder = new DateBuilder() .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setTime(dateBuilder.getDate()); position.setValid(parser.next().equals("A")); position.set(Event.KEY_SATELLITES, parser.next()); position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); position.setSpeed(parser.nextDouble()); position.set(Event.KEY_HDOP, parser.nextDouble()); position.setAltitude(parser.nextDouble()); } else { getLastLocation(position, null); } position.set(Event.KEY_MCC, parser.nextInt()); position.set(Event.KEY_MNC, parser.nextInt()); position.set(Event.KEY_LAC, parser.nextInt()); position.set(Event.KEY_CELL, parser.nextInt()); return position; } return null; }
private Position decodeNormalMessage( ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { Position position = new Position(); position.setProtocol(getProtocolName()); buf.readByte(); // header String id = String.valueOf(Long.parseLong(ChannelBuffers.hexDump(buf.readBytes(5)))); if (!identify(id, channel, remoteAddress)) { return null; } position.setDeviceId(getDeviceId()); int version = ChannelBufferTools.readHexInteger(buf, 1); buf.readUnsignedByte(); // type buf.readBytes(2); // length DateBuilder dateBuilder = new DateBuilder() .setDay(ChannelBufferTools.readHexInteger(buf, 2)) .setMonth(ChannelBufferTools.readHexInteger(buf, 2)) .setYear(ChannelBufferTools.readHexInteger(buf, 2)) .setHour(ChannelBufferTools.readHexInteger(buf, 2)) .setMinute(ChannelBufferTools.readHexInteger(buf, 2)) .setSecond(ChannelBufferTools.readHexInteger(buf, 2)); position.setTime(dateBuilder.getDate()); double latitude = convertCoordinate(ChannelBufferTools.readHexInteger(buf, 8)); double longitude = convertCoordinate(ChannelBufferTools.readHexInteger(buf, 9)); byte flags = buf.readByte(); position.setValid((flags & 0x1) == 0x1); if ((flags & 0x2) == 0) { latitude = -latitude; } position.setLatitude(latitude); if ((flags & 0x4) == 0) { longitude = -longitude; } position.setLongitude(longitude); position.setSpeed(ChannelBufferTools.readHexInteger(buf, 2)); position.setCourse(buf.readUnsignedByte() * 2.0); if (version == 1) { position.set(Event.KEY_SATELLITES, buf.readUnsignedByte()); position.set(Event.KEY_POWER, buf.readUnsignedByte()); buf.readByte(); // other flags and sensors position.setAltitude(buf.readUnsignedShort()); int cid = buf.readUnsignedShort(); int lac = buf.readUnsignedShort(); if (cid != 0 && lac != 0) { position.set(Event.KEY_CID, cid); position.set(Event.KEY_LAC, lac); } position.set(Event.KEY_GSM, buf.readUnsignedByte()); } else if (version == 2) { int fuel = buf.readUnsignedByte() << 8; position.set(Event.KEY_STATUS, buf.readUnsignedInt()); position.set(Event.KEY_ODOMETER, buf.readUnsignedInt()); fuel += buf.readUnsignedByte(); position.set(Event.KEY_FUEL, fuel); } return position; }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; int type = buf.readUnsignedShort(); buf.readUnsignedShort(); // length if (type == MSG_IDENT || type == MSG_IDENT_FULL) { buf.readUnsignedInt(); // id int length = buf.readUnsignedShort(); buf.skipBytes(length); length = buf.readUnsignedShort(); buf.skipBytes(length); length = buf.readUnsignedShort(); String imei = buf.readBytes(length).toString(Charset.defaultCharset()); identify(imei, channel, remoteAddress); } else if (hasDeviceId() && (type == MSG_POINT || type == MSG_ALARM || type == MSG_LOGMSG)) { List<Position> positions = new LinkedList<>(); int recordCount = 1; if (type == MSG_LOGMSG) { recordCount = buf.readUnsignedShort(); } for (int j = 0; j < recordCount; j++) { Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(getDeviceId()); if (type == MSG_LOGMSG) { position.set(Event.KEY_ARCHIVE, true); int subtype = buf.readUnsignedShort(); if (subtype == MSG_ALARM) { position.set(Event.KEY_ALARM, true); } if (buf.readUnsignedShort() > buf.readableBytes()) { lastIndex += 1; break; // workaround for device bug } lastIndex = buf.readUnsignedInt(); position.set(Event.KEY_INDEX, lastIndex); } else { newIndex = buf.readUnsignedInt(); } position.setTime(new Date(buf.readUnsignedInt() * 1000)); position.setLatitude(buf.readInt() * 180.0 / 0x7FFFFFFF); position.setLongitude(buf.readInt() * 180.0 / 0x7FFFFFFF); position.setSpeed(buf.readUnsignedInt() * 0.01); position.setCourse(buf.readUnsignedShort() * 0.01); position.setAltitude(buf.readUnsignedShort() * 0.01); int satellites = buf.readUnsignedByte(); position.setValid(satellites >= 3); position.set(Event.KEY_SATELLITES, satellites); position.set(Event.KEY_GSM, buf.readUnsignedByte()); position.set(Event.KEY_ODOMETER, buf.readUnsignedInt()); long extraFlags = buf.readLong(); if (BitUtil.check(extraFlags, 0)) { int count = buf.readUnsignedShort(); for (int i = 1; i <= count; i++) { position.set(Event.PREFIX_ADC + i, buf.readUnsignedShort()); } } if (BitUtil.check(extraFlags, 1)) { int size = buf.readUnsignedShort(); position.set("can", buf.toString(buf.readerIndex(), size, Charset.defaultCharset())); buf.skipBytes(size); } if (BitUtil.check(extraFlags, 2)) { position.set("passenger", ChannelBuffers.hexDump(buf.readBytes(buf.readUnsignedShort()))); } if (type == MSG_ALARM) { position.set(Event.KEY_ALARM, true); byte[] response = {(byte) 0xC9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; channel.write(ChannelBuffers.wrappedBuffer(response)); } buf.readUnsignedInt(); // crc positions.add(position); } requestArchive(channel); return positions; } return null; }
private ParseResult parsePosition(ChannelBuffer buf) { Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(getDeviceId()); int format; if (buf.getUnsignedByte(buf.readerIndex()) == 0) { format = buf.readUnsignedShort(); } else { format = buf.readUnsignedByte(); } position.set("format", format); long index = buf.readUnsignedInt(); position.set(Event.KEY_INDEX, index); position.set(Event.KEY_EVENT, buf.readUnsignedShort()); buf.skipBytes(6); // event time position.set(Event.KEY_ALARM, buf.readUnsignedByte()); position.set(Event.KEY_STATUS, buf.readUnsignedByte()); position.set(Event.KEY_GSM, buf.readUnsignedByte()); if (isFormat(format, F10, F20, F30)) { position.set(Event.KEY_OUTPUT, buf.readUnsignedShort()); } else if (isFormat(format, F40, F50, F51, F52)) { position.set(Event.KEY_OUTPUT, buf.readUnsignedByte()); } if (isFormat(format, F10, F20, F30, F40)) { position.set(Event.KEY_INPUT, buf.readUnsignedShort()); } else if (isFormat(format, F50, F51, F52)) { position.set(Event.KEY_INPUT, buf.readUnsignedByte()); } position.set(Event.KEY_POWER, buf.readUnsignedShort() * 0.001); position.set(Event.KEY_BATTERY, buf.readUnsignedShort()); if (isFormat(format, F10, F20, F30)) { position.set(Event.PREFIX_TEMP + 1, buf.readShort()); } if (isFormat(format, F10, F20, F50, F52)) { position.set(Event.PREFIX_ADC + 1, buf.readUnsignedShort()); position.set(Event.PREFIX_ADC + 2, buf.readUnsignedShort()); } // Impulse counters if (isFormat(format, F20, F50, F51, F52)) { buf.readUnsignedInt(); buf.readUnsignedInt(); } if (isFormat(format, F20, F50, F51, F52)) { int locationStatus = buf.readUnsignedByte(); position.setValid(BitUtil.check(locationStatus, 1)); DateBuilder dateBuilder = new DateBuilder() .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setDateReverse( buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); position.setTime(dateBuilder.getDate()); position.setLatitude(buf.readFloat() / Math.PI * 180); position.setLongitude(buf.readFloat() / Math.PI * 180); position.setSpeed(buf.readFloat()); position.setCourse(buf.readUnsignedShort()); position.set(Event.KEY_ODOMETER, buf.readFloat()); position.set("segment", buf.readFloat()); // last segment // Segment times buf.readUnsignedShort(); buf.readUnsignedShort(); } // Other if (isFormat(format, F51, F52)) { buf.readUnsignedShort(); buf.readByte(); buf.readUnsignedShort(); buf.readUnsignedShort(); buf.readByte(); buf.readUnsignedShort(); buf.readUnsignedShort(); buf.readByte(); buf.readUnsignedShort(); } // Four temperature sensors if (isFormat(format, F40, F52)) { buf.readByte(); buf.readByte(); buf.readByte(); buf.readByte(); } return new ParseResult(index, position); }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; if (buf.getUnsignedShort(buf.readerIndex()) == 0xfe02) { if (channel != null) { channel.write(buf, remoteAddress); // keep-alive message } return null; } buf.skipBytes(2); // prefix buf.readUnsignedShort(); // checksum buf.readUnsignedShort(); // length int index = buf.readUnsignedShort(); long id = buf.readLong(); if (!identify(String.valueOf(id), channel, remoteAddress)) { return null; } sendResponse(channel, remoteAddress, id, index); List<Position> positions = new LinkedList<>(); while (buf.readableBytes() >= MIN_DATA_LENGTH) { Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(getDeviceId()); if (longDate) { DateBuilder dateBuilder = new DateBuilder() .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); position.setTime(dateBuilder.getDate()); buf.skipBytes(7 + 7); } else { position.setFixTime(new Date(buf.readUnsignedInt() * 1000)); position.setDeviceTime(new Date(buf.readUnsignedInt() * 1000)); buf.readUnsignedInt(); // send time } position.setValid(true); position.setLongitude(buf.readInt() * 0.000001); position.setLatitude(buf.readInt() * 0.000001); position.setCourse(buf.readUnsignedShort()); position.set(Position.KEY_TYPE, buf.readUnsignedByte()); position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 0.1); position.set(Position.KEY_HDOP, buf.readUnsignedShort() * 0.1); position.set(Position.KEY_INPUT, buf.readUnsignedByte()); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.001); position.set("driver", readString(buf)); position.set(Position.PREFIX_TEMP + 1, buf.readShort() * 0.1); position.set(Position.PREFIX_TEMP + 2, buf.readShort() * 0.1); position.set("message", readString(buf)); if (custom) { String form = this.form; if (form == null) { form = readString(buf).substring("%CI".length()); } readCustomData(position, buf, form); } positions.add(position); } return positions; }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; buf.readUnsignedByte(); // marker int version = buf.readUnsignedByte(); String imei; if ((version & 0x80) != 0) { imei = String.valueOf((buf.readUnsignedInt() << (3 * 8)) | buf.readUnsignedMedium()); } else { imei = String.valueOf(imeiFromUnitId(buf.readUnsignedMedium())); } buf.readUnsignedShort(); // length int selector = DEFAULT_SELECTOR; if ((version & 0x40) != 0) { selector = buf.readUnsignedMedium(); } Position position = new Position(); position.setProtocol(getProtocolName()); if (!identify(imei, channel, remoteAddress)) { return null; } position.setDeviceId(getDeviceId()); int event = buf.readUnsignedByte(); position.set(Event.KEY_EVENT, event); position.set("event-info", buf.readUnsignedByte()); if ((selector & 0x0008) != 0) { position.setValid((buf.readUnsignedByte() & 0x40) != 0); } else { return null; // no location data } if ((selector & 0x0004) != 0) { buf.skipBytes(4); // snapshot time } if ((selector & 0x0008) != 0) { position.setTime(new Date(buf.readUnsignedInt() * 1000)); position.setLatitude(buf.readInt() / 1000000.0); position.setLongitude(buf.readInt() / 1000000.0); position.set(Event.KEY_SATELLITES, buf.readUnsignedByte()); } if ((selector & 0x0010) != 0) { position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); buf.readUnsignedByte(); // maximum speed position.setCourse(buf.readUnsignedByte() * 2.0); } if ((selector & 0x0040) != 0) { position.set(Event.KEY_INPUT, buf.readUnsignedByte()); } if ((selector & 0x0020) != 0) { position.set(Event.PREFIX_ADC + 1, 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 ((selector & 0x8000) != 0) { position.set(Event.KEY_POWER, buf.readUnsignedShort() / 1000.0); position.set(Event.KEY_BATTERY, buf.readUnsignedShort()); } // Pulse rate 1 if ((selector & 0x10000) != 0) { buf.readUnsignedShort(); buf.readUnsignedInt(); } // Pulse rate 2 if ((selector & 0x20000) != 0) { buf.readUnsignedShort(); buf.readUnsignedInt(); } if ((selector & 0x0080) != 0) { position.set("trip1", buf.readUnsignedInt()); } if ((selector & 0x0100) != 0) { position.set("trip2", buf.readUnsignedInt()); } if ((selector & 0x0040) != 0) { position.set(Event.KEY_OUTPUT, buf.readUnsignedByte()); } if ((selector & 0x0200) != 0) { position.set( Event.KEY_RFID, (((long) buf.readUnsignedShort()) << 32) + buf.readUnsignedInt()); } if ((selector & 0x0400) != 0) { buf.readUnsignedByte(); // Keypad } if ((selector & 0x0800) != 0) { position.setAltitude(buf.readShort()); } if ((selector & 0x2000) != 0) { buf.readUnsignedShort(); // snapshot counter } if ((selector & 0x4000) != 0) { buf.skipBytes(8); // state flags } if ((selector & 0x80000) != 0) { buf.skipBytes(11); // cell info } if ((selector & 0x1000) != 0) { decodeEventData(event, buf); } if (Context.getConfig().getBoolean(getProtocolName() + ".can") && buf.readable() && (selector & 0x1000) != 0 && event == EVENT_DATA) { decodeCanData(buf, position); } return position; }
private void decodeCanData(ChannelBuffer buf, Position position) { buf.readUnsignedMedium(); // packet identifier buf.readUnsignedByte(); // version int count = buf.readUnsignedByte(); buf.readUnsignedByte(); // batch count buf.readUnsignedShort(); // selector bit buf.readUnsignedInt(); // timestamp buf.skipBytes(8); ArrayList<ChannelBuffer> values = new ArrayList<>(count); for (int i = 0; i < count; i++) { values.add(buf.readBytes(8)); } for (int i = 0; i < count; i++) { ChannelBuffer value = values.get(i); switch (buf.readInt()) { case 0x20D: position.set(Event.KEY_RPM, ChannelBuffers.swapShort(value.readShort())); position.set("diesel-temperature", ChannelBuffers.swapShort(value.readShort()) * 0.1); position.set("battery-voltage", ChannelBuffers.swapShort(value.readShort()) * 0.01); position.set("supply-air-temp-dep1", ChannelBuffers.swapShort(value.readShort()) * 0.1); break; case 0x30D: position.set("active-alarm", ChannelBuffers.hexDump(value)); break; case 0x40C: position.set("air-temp-dep1", ChannelBuffers.swapShort(value.readShort()) * 0.1); position.set("air-temp-dep2", ChannelBuffers.swapShort(value.readShort()) * 0.1); break; case 0x40D: position.set("cold-unit-state", ChannelBuffers.hexDump(value)); break; case 0x50C: position.set("defrost-temp-dep1", ChannelBuffers.swapShort(value.readShort()) * 0.1); position.set("defrost-temp-dep2", ChannelBuffers.swapShort(value.readShort()) * 0.1); break; case 0x50D: position.set("condenser-pressure", ChannelBuffers.swapShort(value.readShort()) * 0.1); position.set("suction-pressure", ChannelBuffers.swapShort(value.readShort()) * 0.1); break; case 0x58C: value.readByte(); value.readShort(); // index switch (value.readByte()) { case 0x01: position.set("setpoint-zone1", ChannelBuffers.swapInt(value.readInt()) * 0.1); break; case 0x02: position.set("setpoint-zone2", ChannelBuffers.swapInt(value.readInt()) * 0.1); break; case 0x05: position.set("unit-type", ChannelBuffers.swapInt(value.readInt())); break; case 0x13: position.set("diesel-hours", ChannelBuffers.swapInt(value.readInt()) / 60 / 60); break; case 0x14: position.set("electric-hours", ChannelBuffers.swapInt(value.readInt()) / 60 / 60); break; case 0x17: position.set("service-indicator", ChannelBuffers.swapInt(value.readInt())); break; case 0x18: position.set("software-version", ChannelBuffers.swapInt(value.readInt()) * 0.01); break; default: break; } break; default: Log.warning(new UnsupportedOperationException()); break; } } }
public static MacAddress read6Bytes(ChannelBuffer c) throws OFParseError { long raw = c.readUnsignedInt() << 16 | c.readUnsignedShort(); return MacAddress.of(raw); }
private void readCustomData(Position position, ChannelBuffer buf, String form) { String[] keys = form.substring(1).split("%"); for (String key : keys) { switch (key) { case "SA": position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; case "MV": position.set(Position.KEY_POWER, buf.readUnsignedShort()); break; case "BV": position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); break; case "GQ": position.set(Position.KEY_GSM, buf.readUnsignedByte()); break; case "CE": position.set(Position.KEY_CID, buf.readUnsignedInt()); break; case "LC": position.set(Position.KEY_LAC, buf.readUnsignedShort()); break; case "CN": buf.readUnsignedInt(); // mcc + mnc break; case "RL": buf.readUnsignedByte(); // rxlev break; case "PC": buf.readUnsignedInt(); // pulse count break; case "AT": position.setAltitude(buf.readUnsignedInt()); break; case "RP": position.set(Position.KEY_RPM, buf.readUnsignedShort()); break; case "GS": buf.readUnsignedByte(); // gsm status break; case "DT": position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() == 1); break; case "VN": position.set(Position.KEY_VIN, readString(buf)); break; case "MF": buf.readUnsignedShort(); // mass air flow rate break; case "EL": buf.readUnsignedByte(); // engine load break; case "TR": position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); break; case "ET": buf.readUnsignedShort(); // engine coolant temp break; case "FL": position.set(Position.KEY_FUEL, buf.readUnsignedByte()); break; case "ML": buf.readUnsignedByte(); // mil status break; case "FC": buf.readUnsignedInt(); // fuel used break; case "CI": readString(buf); // format string break; case "AV1": position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); break; case "NC": readString(buf); // gsm neighbor cell info break; case "SM": buf.readUnsignedShort(); // max speed between reports break; case "GL": readString(buf); // google link break; case "MA": readString(buf); // mac address break; default: break; } } }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; buf.readUnsignedShort(); // device id buf.readUnsignedByte(); // length int type = buf.readUnsignedByte(); DeviceSession deviceSession; if (type == MSG_IMEI) { deviceSession = getDeviceSession( channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); } else { deviceSession = getDeviceSession(channel, remoteAddress); } if (deviceSession == null) { return null; } if (BitUtil.to(type, 2) == 0) { Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); buf.readUnsignedByte(); // firmware version buf.readUnsignedShort(); // index position.set(Position.KEY_STATUS, buf.readUnsignedShort()); position.setValid(true); position.setLatitude(buf.readFloat()); position.setLongitude(buf.readFloat()); position.setCourse(buf.readUnsignedShort() * 0.1); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); buf.readUnsignedByte(); // acceleration position.setAltitude(buf.readUnsignedShort()); position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte() & 0x0f); position.setTime(new Date(buf.readUnsignedInt() * 1000)); position.set(Position.KEY_POWER, buf.readUnsignedShort()); position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); if (BitUtil.check(type, 2)) { buf.skipBytes(4); } if (BitUtil.check(type, 3)) { buf.skipBytes(12); } if (BitUtil.check(type, 4)) { buf.skipBytes(8); } if (BitUtil.check(type, 5)) { buf.skipBytes(9); } if (BitUtil.check(type, 6)) { buf.skipBytes(buf.getUnsignedByte(buf.readerIndex())); } if (BitUtil.check(type, 7)) { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); } return position; } return null; }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; buf.readUnsignedByte(); // header int length = (buf.readUnsignedShort() & 0x7fff) + 3; List<Position> positions = new LinkedList<>(); Set<Integer> tags = new HashSet<>(); boolean hasLocation = false; Position position = new Position(); position.setProtocol(getProtocolName()); while (buf.readerIndex() < length) { // Check if new message started int tag = buf.readUnsignedByte(); if (tags.contains(tag)) { if (hasLocation && position.getFixTime() != null) { positions.add(position); } tags.clear(); hasLocation = false; position = new Position(); } tags.add(tag); switch (tag) { case TAG_IMEI: getDeviceSession( channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); break; case TAG_DATE: position.setTime(new Date(buf.readUnsignedInt() * 1000)); break; case TAG_COORDINATES: hasLocation = true; 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(buf.readShort()); break; case TAG_STATUS: int status = buf.readUnsignedShort(); position.set(Position.KEY_IGNITION, BitUtil.check(status, 9)); position.set(Position.KEY_ALARM, BitUtil.check(status, 15)); position.set(Position.KEY_POWER, BitUtil.check(status, 2)); break; case TAG_DIGITAL_INPUTS: int input = buf.readUnsignedShort(); for (int i = 0; i < 16; i++) { position.set(Position.PREFIX_IO + (i + 1), BitUtil.check(input, i)); } break; case TAG_DIGITAL_OUTPUTS: int output = buf.readUnsignedShort(); for (int i = 0; i < 16; i++) { position.set(Position.PREFIX_IO + (i + 17), BitUtil.check(output, i)); } break; case TAG_INPUT_VOLTAGE1: position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() / 1000.0); break; case TAG_INPUT_VOLTAGE2: position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort() / 1000.0); break; case TAG_INPUT_VOLTAGE3: position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShort() / 1000.0); break; case TAG_INPUT_VOLTAGE4: position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShort() / 1000.0); break; case TAG_XT1: case TAG_XT2: case TAG_XT3: buf.skipBytes(16); break; default: break; } } if (hasLocation && position.getFixTime() != null) { positions.add(position); } DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } sendReply(channel, buf.readUnsignedShort()); for (Position p : positions) { p.setDeviceId(deviceSession.getDeviceId()); } if (positions.isEmpty()) { return null; } return positions; }
private List<Position> decodeBinaryMessage(Channel channel, ChannelBuffer buf) { List<Position> positions = new LinkedList<>(); String flag = buf.toString(2, 1, Charset.defaultCharset()); int index = ChannelBufferTools.find(buf, 0, buf.readableBytes(), ","); // Identification String imei = buf.toString(index + 1, 15, Charset.defaultCharset()); if (!identify(imei, channel)) { return null; } buf.skipBytes(index + 1 + 15 + 1 + 3 + 1 + 2 + 2 + 4); while (buf.readableBytes() >= 0x34) { Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(getDeviceId()); // Event position.set(Event.KEY_EVENT, buf.readUnsignedByte()); // Location position.setLatitude(buf.readInt() * 0.000001); position.setLongitude(buf.readInt() * 0.000001); // Time (946684800 - timestamp for 2000-01-01) position.setTime(new Date((946684800 + buf.readUnsignedInt()) * 1000)); // Validity position.setValid(buf.readUnsignedByte() == 1); // Satellites position.set(Event.KEY_SATELLITES, buf.readUnsignedByte()); // GSM Signal position.set(Event.KEY_GSM, buf.readUnsignedByte()); // Speed position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); // Course position.setCourse(buf.readUnsignedShort()); // HDOP position.set(Event.KEY_HDOP, buf.readUnsignedShort() * 0.1); // Altitude position.setAltitude(buf.readUnsignedShort()); // Other position.set(Event.KEY_ODOMETER, buf.readUnsignedInt()); position.set("runtime", buf.readUnsignedInt()); position.set( Event.KEY_CELL, buf.readUnsignedShort() + "|" + buf.readUnsignedShort() + "|" + buf.readUnsignedShort() + "|" + buf.readUnsignedShort()); position.set(Event.KEY_STATUS, buf.readUnsignedShort()); // ADC position.set(Event.PREFIX_ADC + 1, buf.readUnsignedShort()); position.set(Event.KEY_BATTERY, buf.readUnsignedShort() * 0.01); position.set(Event.KEY_POWER, buf.readUnsignedShort()); buf.readUnsignedInt(); // geo-fence positions.add(position); } // Delete recorded data if (channel != null) { StringBuilder command = new StringBuilder("@@"); command.append(flag).append(27 + positions.size() / 10).append(","); command.append(imei).append(",CCC,").append(positions.size()).append("*"); int checksum = 0; for (int i = 0; i < command.length(); i += 1) checksum += command.charAt(i); command.append(String.format("%02x", checksum & 0xff).toUpperCase()); command.append("\r\n"); channel.write(command.toString()); } return positions; }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; buf.skipBytes(2); // header ChannelBuffer id = buf.readBytes(12); buf.readUnsignedByte(); // separator int type = buf.readUnsignedByte(); buf.readUnsignedShort(); // length if (type == MSG_LOGIN) { int command = buf.readUnsignedByte(); // 0x00 - heartbeat if (command == 0x01) { String imei = buf.toString(buf.readerIndex(), 15, StandardCharsets.US_ASCII); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession != null && channel != null) { ChannelBuffer response = ChannelBuffers.dynamicBuffer(); response.writeByte(0x48); response.writeByte(0x52); // header response.writeBytes(id); response.writeByte(0x2c); // separator response.writeByte(type); response.writeShort(0x0002); // length response.writeShort(0x8000); response.writeShort(0x0000); // checksum channel.write(response); } } } else if (type == MSG_GPS) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.setTime(new Date(buf.readUnsignedInt() * 1000)); int flags = buf.readUnsignedByte(); position.setValid(true); position.setLatitude(convertCoordinate(buf.readUnsignedInt(), !BitUtil.check(flags, 0))); position.setLongitude(convertCoordinate(buf.readUnsignedInt(), !BitUtil.check(flags, 1))); position.setSpeed(buf.readUnsignedByte()); position.setCourse(buf.readUnsignedByte()); position.set(Position.KEY_LAC, buf.readUnsignedShort()); position.set(Position.KEY_CID, buf.readUnsignedShort()); return position; } return null; }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; buf.skipBytes(4); // system code int type = buf.readUnsignedByte(); long deviceUniqueId = buf.readUnsignedInt(); if (type != MSG_CLIENT_SERIAL) { buf.readUnsignedShort(); // communication control } byte packetNumber = buf.readByte(); // Send reply sendReply(channel, deviceUniqueId, packetNumber); // Parse location if (type == MSG_CLIENT_STATUS) { Position position = new Position(); position.setProtocol(getProtocolName()); // Device identifier if (!identify(String.valueOf(deviceUniqueId), channel)) { return null; } position.setDeviceId(getDeviceId()); buf.readUnsignedByte(); // hardware version buf.readUnsignedByte(); // software version buf.readUnsignedByte(); // protocol version // Status position.set(Event.KEY_STATUS, buf.getUnsignedByte(buf.readerIndex()) & 0x0f); int operator = (buf.readUnsignedByte() & 0xf0) << 4; operator += buf.readUnsignedByte(); buf.readUnsignedByte(); // reason data buf.readUnsignedByte(); // reason buf.readUnsignedByte(); // mode buf.readUnsignedInt(); // IO operator <<= 8; operator += buf.readUnsignedByte(); position.set("operator", operator); buf.readUnsignedInt(); // ADC buf.readUnsignedMedium(); // Odometer buf.skipBytes(6); // multi-purpose data buf.readUnsignedShort(); // gps fix buf.readUnsignedByte(); // location status buf.readUnsignedByte(); // mode 1 buf.readUnsignedByte(); // mode 2 position.setValid(buf.readUnsignedByte() >= 3); // satellites // Location data position.setLongitude(buf.readInt() / Math.PI * 180 / 100000000); position.setLatitude(buf.readInt() / Math.PI * 180 / 100000000.0); position.setAltitude(buf.readInt() * 0.01); position.setSpeed(UnitsConverter.knotsFromMps(buf.readInt() * 0.01)); position.setCourse(buf.readUnsignedShort() / Math.PI * 180.0 / 1000.0); // Time Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); time.clear(); time.set(Calendar.SECOND, buf.readUnsignedByte()); time.set(Calendar.MINUTE, buf.readUnsignedByte()); time.set(Calendar.HOUR_OF_DAY, buf.readUnsignedByte()); time.set(Calendar.DAY_OF_MONTH, buf.readUnsignedByte()); time.set(Calendar.MONTH, buf.readUnsignedByte() - 1); time.set(Calendar.YEAR, buf.readUnsignedShort()); position.setTime(time.getTime()); return position; } return null; }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; buf.readUnsignedByte(); // protocol buf.readUnsignedShort(); // length int index = buf.readUnsignedByte() >> 3; if (channel != null) { ChannelBuffer response = ChannelBuffers.copiedBuffer("^" + index, Charset.defaultCharset()); channel.write(response, remoteAddress); } String id = String.valueOf(buf.readUnsignedInt()); if (!identify(id, channel, remoteAddress)) { return null; } List<Position> positions = new LinkedList<>(); while (buf.readableBytes() > 2) { Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(getDeviceId()); int end = buf.readerIndex() + buf.readUnsignedByte(); position.setTime(new Date(buf.readUnsignedInt() * 1000)); int flags = buf.readUnsignedByte(); position.set(Event.KEY_SATELLITES, BitUtil.range(flags, 2)); position.setValid(BitUtil.range(flags, 0, 2) > 0); // Latitude double lat = buf.readUnsignedMedium(); lat = lat * -180 / 16777216 + 90; position.setLatitude(lat); // Longitude double lon = buf.readUnsignedMedium(); lon = lon * 360 / 16777216 - 180; position.setLongitude(lon); // Status flags = buf.readUnsignedByte(); position.set(Event.KEY_IGNITION, BitUtil.check(flags, 0)); position.set(Event.KEY_GSM, BitUtil.range(flags, 2, 3)); position.setCourse((BitUtil.range(flags, 5) * 45 + 180) % 360); // Speed int speed = buf.readUnsignedByte(); if (speed < 250) { position.setSpeed(UnitsConverter.knotsFromKph(speed)); } while (buf.readerIndex() < end) { int type = buf.readUnsignedByte(); int length = buf.readUnsignedByte(); if (length == 255) { length += buf.readUnsignedByte(); } switch (type) { case 2: position.set(Event.KEY_ODOMETER, buf.readUnsignedMedium()); break; case 5: position.set(Event.KEY_INPUT, buf.readUnsignedByte()); break; case 6: { int n = buf.readUnsignedByte() >> 4; if (n < 2) { position.set(Event.PREFIX_ADC + n, readSwappedFloat(buf)); } else { position.set("di" + (n - 2), readSwappedFloat(buf)); } } break; case 7: { int alarm = buf.readUnsignedByte(); buf.readUnsignedByte(); if (BitUtil.check(alarm, 5)) { position.set(Event.KEY_ALARM, BitUtil.range(alarm, 0, 4)); } } break; case 8: position.set("antihijack", buf.readUnsignedByte()); break; case 9: position.set("authorized", ChannelBufferTools.readHexString(buf, 16)); break; case 10: position.set("unauthorized", ChannelBufferTools.readHexString(buf, 16)); break; case 24: { Set<Integer> temps = new LinkedHashSet<>(); int temp = buf.readUnsignedByte(); for (int i = 3; i >= 0; i--) { int n = (temp >> (2 * i)) & 0x03; if (!temps.contains(n)) { temps.add(n); } } for (int n : temps) { position.set(Event.PREFIX_TEMP + n, buf.readUnsignedByte()); } } break; case 28: position.set("weight", buf.readUnsignedShort()); buf.readUnsignedByte(); break; case 90: position.set(Event.KEY_POWER, readSwappedFloat(buf)); break; case 101: position.set(Event.KEY_OBD_SPEED, buf.readUnsignedByte()); break; case 102: position.set(Event.KEY_RPM, buf.readUnsignedByte() * 50); break; case 107: { int fuel = buf.readUnsignedShort(); switch (fuel >> 14) { case 1: position.set(Event.KEY_FUEL, (fuel & 0x3fff) * 0.4 + "%"); break; case 2: position.set(Event.KEY_FUEL, (fuel & 0x3fff) * 0.5 + " l"); break; case 3: position.set(Event.KEY_FUEL, (fuel & 0x3fff) * -0.5 + " l"); break; } } break; case 108: position.set(Event.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 5); break; case 150: position.set("door", buf.readUnsignedByte()); break; default: buf.skipBytes(length); break; } } positions.add(position); } return positions; }