private void send(Channel channel, String message) {
   if (channel != null) {
     channel.write(message + Crc.nmeaChecksum(message) + "\r\n");
   }
 }
示例#2
0
  @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(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {

    String sentence = (String) msg;

    // Heartbeat
    if (sentence.startsWith("$ECHK") && channel != null) {
      channel.write(sentence + "\r\n");
      return null;
    }

    // Parse message
    Matcher parser = pattern.matcher(sentence);
    if (!parser.matches()) {
      return null;
    }

    // Create new position
    Position position = new Position();
    ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter("laipac");
    Integer index = 1;

    // Identification
    String id = parser.group(index++);
    try {
      position.setDeviceId(getDataManager().getDeviceByImei(id).getId());
    } catch (Exception error) {
      Log.warning("Unknown device - " + id);
    }

    // Time
    Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    time.clear();
    time.set(Calendar.HOUR_OF_DAY, Integer.valueOf(parser.group(index++)));
    time.set(Calendar.MINUTE, Integer.valueOf(parser.group(index++)));
    time.set(Calendar.SECOND, Integer.valueOf(parser.group(index++)));

    // Validity
    String status = parser.group(index++);
    position.setValid(status.compareToIgnoreCase("A") == 0);

    // 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 longitude = Double.valueOf(parser.group(index++));
    longitude += Double.valueOf(parser.group(index++)) / 60;
    if (parser.group(index++).compareTo("W") == 0) longitude = -longitude;
    position.setLongitude(longitude);

    // Speed
    position.setSpeed(Double.valueOf(parser.group(index++)));

    // Course
    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());

    // Altitude
    position.setAltitude(0.0);

    // Response
    String type = parser.group(index++);
    String checksum = parser.group(index++);
    String response = null;

    if (type.equals("0") && Character.isLowerCase(status.charAt(0))) {
      response = "$EAVACK,0," + checksum;
      response += Crc.nmeaChecksum(response);
    } else if (type.equals("S") || type.equals("T")) {
      response = "$AVCFG,00000000,t*21";
    } else if (type.equals("3")) {
      response = "$AVCFG,00000000,d*31";
    } else if (type.equals("X") || type.equals("4")) {
      response = "$AVCFG,00000000,x*2D";
    }

    if (response != null && channel != null) {
      channel.write(response + "\r\n");
    }

    position.setExtendedInfo(extendedInfo.toString());
    return position;
  }