diff options
Diffstat (limited to 'src/net/sourceforge/opentracking/protocol/xexun')
-rw-r--r-- | src/net/sourceforge/opentracking/protocol/xexun/XexunFrameDecoder.java | 105 | ||||
-rw-r--r-- | src/net/sourceforge/opentracking/protocol/xexun/XexunProtocolDecoder.java | 153 |
2 files changed, 258 insertions, 0 deletions
diff --git a/src/net/sourceforge/opentracking/protocol/xexun/XexunFrameDecoder.java b/src/net/sourceforge/opentracking/protocol/xexun/XexunFrameDecoder.java new file mode 100644 index 000000000..338c7bec9 --- /dev/null +++ b/src/net/sourceforge/opentracking/protocol/xexun/XexunFrameDecoder.java @@ -0,0 +1,105 @@ +/* + * Минимум - 100 + * Начало - (10 цифр) + ',' + * Длина 16 x ',' + */ + +package net.sourceforge.opentracking.protocol.xexun; + +import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.buffer.ChannelBuffer; + +/** + * + */ +public class XexunFrameDecoder extends FrameDecoder { + + protected Object decode( + ChannelHandlerContext ctx, + Channel channel, + ChannelBuffer buf) throws Exception { + + System.out.println("read: " + buf.readableBytes()); + + // Check minimum length + int length = buf.readableBytes(); + if (length < 100) { + return null; + } + + // Find identifier + int index = 0; + int countDigit = 0; + for (; index < length; index++) { + + // Check byte + char c = (char) buf.getByte(index); + if (Character.isDigit(c)) { + countDigit++; + } + + // Check count + if (countDigit == 10) { + break; + } + } + + if (countDigit < 10) { + return null; + } + + // Find begin + int beginIndex = 0; + for (; index < length; index++) { + + char c = (char) buf.getByte(index); + if (c == ',') { + beginIndex = index; + break; + } + } + + if (beginIndex == 0) { + return null; + } + + // Find imei + int imeiIndex = 0; + for (; index < length; index++) { + + char c = (char) buf.getByte(index); + if (c == ':') { + imeiIndex = index; + break; + } + } + + if (imeiIndex == 0) { + return null; + } + + // Find end + int endIndex = 0; + for (; index < length; index++) { + + char c = (char) buf.getByte(index); + if (c == ',') { + endIndex = index; + break; + } + } + + if (endIndex == 0) { + return null; + } + + // Read buffer + buf.skipBytes(beginIndex); + ChannelBuffer frame = buf.readBytes(endIndex - beginIndex + 1); + + return frame; + } + +} diff --git a/src/net/sourceforge/opentracking/protocol/xexun/XexunProtocolDecoder.java b/src/net/sourceforge/opentracking/protocol/xexun/XexunProtocolDecoder.java new file mode 100644 index 000000000..cfd88fe6e --- /dev/null +++ b/src/net/sourceforge/opentracking/protocol/xexun/XexunProtocolDecoder.java @@ -0,0 +1,153 @@ +/* + * Copyright 2010 Anton Tananaev (anton@tananaev.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 net.sourceforge.opentracking.protocol.xexun; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.text.ParseException; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; +import org.jboss.netty.channel.ChannelPipelineCoverage; +import net.sourceforge.opentracking.Position; +import net.sourceforge.opentracking.Device; +import net.sourceforge.opentracking.DataManager; +import java.sql.SQLException; + +/** + * Xexun tracker protocol decoder + */ +@ChannelPipelineCoverage("all") +public class XexunProtocolDecoder extends OneToOneDecoder { + + /** + * Init device table + */ + public XexunProtocolDecoder(DataManager dataManager) throws SQLException { + + // Create map + setDevices(new HashMap()); + + if (dataManager != null) { + List deviceList = dataManager.readDevice(); + + for (Object device: deviceList) { + getDevices().put(((Device) device).getImei(), device); + } + } + } + + /** + * Devices + */ + private Map devices; + + public Map getDevices() { + return devices; + } + + private void setDevices(Map newDevices) { + devices = newDevices; + } + + /** + * Regular expressions pattern + */ + static private Pattern pattern = Pattern.compile( + "," + // Old: [\\d]+, + "\\+?[\\d]+," + // Trusted phone number + "GPRMC," + + "([\\d]{2})([\\d]{2})([\\d]{2}).([\\d]{3})," + // Time (HHMMSS.SSS) + "([AV])," + // Validity + "([\\d]{2})([\\d]{2}.[\\d]{4})," + // Latitude (DDMM.MMMM) + "([NS])," + + "([\\d]{3})([\\d]{2}.[\\d]{4})," + // Longitude (DDDMM.MMMM) + "([EW])," + + "([\\d]+.[\\d]{2})," + // Speed + "([\\d]+.[\\d]{2})," + // Course + "([\\d]{2})([\\d]{2})([\\d]{2})," + // Date (DDMMYY) + ".*imei:" + + "([\\d]+)," + // IMEI + ".*"); + + /** + * Decode message + */ + protected Object decode( + ChannelHandlerContext ctx, Channel channel, Object msg) + throws ParseException { + + // Parse message + String sentence = (String) msg; + System.out.println("parse: " + sentence); + Matcher parser = pattern.matcher(sentence); + if (!parser.matches()) { + throw new ParseException(null, 0); + } + + // Create new position + Position position = new Position(); + + Integer index = 1; + + // Time + Calendar time = new GregorianCalendar(); + time.clear(); + time.set(Calendar.HOUR, Integer.valueOf(parser.group(index++))); + time.set(Calendar.MINUTE, Integer.valueOf(parser.group(index++))); + time.set(Calendar.SECOND, Integer.valueOf(parser.group(index++))); + time.set(Calendar.MILLISECOND, Integer.valueOf(parser.group(index++))); + + // Validity + position.setValid(parser.group(index++).compareTo("A") == 0 ? true : false); + + // Latitude + Double latitude = Double.valueOf(parser.group(index++)); + latitude += Double.valueOf(parser.group(index++)) / 60; + if (parser.group(index++).compareTo("S") == 0) latitude = -latitude; + position.setLatitude(latitude); + + // Longitude + Double lonlitude = Double.valueOf(parser.group(index++)); + lonlitude += Double.valueOf(parser.group(index++)) / 60; + if (parser.group(index++).compareTo("W") == 0) lonlitude = -lonlitude; + position.setLongitude(lonlitude); + + // Speed and course + position.setSpeed(Double.valueOf(parser.group(index++))); + position.setCourse(Double.valueOf(parser.group(index++))); + + // Date + time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++))); + time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1); + time.set(Calendar.YEAR, 2000 + Integer.valueOf(parser.group(index++))); + position.setTime(time.getTime()); + + // Get device by IMEI + String imei = parser.group(index++); + position.setDeviceId(((Device) getDevices().get(imei)).getId()); + + return position; + } + +} |