private static short checksum(ChannelBuffer buf) {
   short sum = 0;
   for (int i = 0; i < buf.readableBytes(); i++) {
     sum ^= buf.getUnsignedByte(i);
   }
   return sum;
 }
Beispiel #2
0
 /**
  * Read a PeerAddress from a Netty buffer. I did not want to include ChannelBuffer in the class
  * PeerAddress
  *
  * @param buffer The Netty buffer
  * @return A PeerAddress created from the buffer (deserialized)
  */
 private static PeerAddress readPeerAddress(final ChannelBuffer buffer) {
   if (buffer.readableBytes() < 21) return null;
   Number160 id = readID(buffer);
   // peek
   int type = buffer.getUnsignedByte(buffer.readerIndex());
   // now we know the length
   int len = PeerAddress.expectedSocketLength(type);
   if (buffer.readableBytes() < len) return null;
   PeerAddress peerAddress =
       new PeerAddress(id, buffer.array(), buffer.arrayOffset() + buffer.readerIndex());
   buffer.skipBytes(len);
   return peerAddress;
 }
Beispiel #3
0
 /**
  * Simple "content sniffing". May not be a great idea, but will do until this class has a better
  * API.
  *
  * @param buf The content of the reply to send.
  * @return The MIME type guessed from {@code buf}.
  */
 private String guessMimeTypeFromContents(final ChannelBuffer buf) {
   if (!buf.readable()) {
     logWarn("Sending an empty result?! buf=" + buf);
     return "text/plain";
   }
   final int firstbyte = buf.getUnsignedByte(buf.readerIndex());
   switch (firstbyte) {
     case '<': // <html or <!DOCTYPE
       return HTML_CONTENT_TYPE;
     case '{': // JSON object
     case '[': // JSON array
       return "application/json"; // RFC 4627 section 6 mandates this.
     case 0x89: // magic number in PNG files.
       return "image/png";
   }
   return "text/plain"; // Default.
 }
  @Override
  protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf)
      throws Exception {

    // Check minimum length
    if (buf.readableBytes() < 12) {
      return null;
    }

    int length;
    switch (buf.getUnsignedByte(buf.readerIndex())) {
      case AutoFonProtocolDecoder.MSG_LOGIN:
        length = 12;
        break;
      case AutoFonProtocolDecoder.MSG_LOCATION:
        length = 78;
        break;
      case AutoFonProtocolDecoder.MSG_HISTORY:
        length = 257;
        break;
      case AutoFonProtocolDecoder.MSG_45_LOGIN:
        length = 19;
        break;
      case AutoFonProtocolDecoder.MSG_45_LOCATION:
        length = 34;
        break;
      default:
        length = 0;
        break;
    }

    // Check length and return buffer
    if (length != 0 && buf.readableBytes() >= length) {
      return buf.readBytes(length);
    }

    return null;
  }
Beispiel #5
0
  @Override
  protected Object decode(final ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer)
      throws Exception {

    if (buffer.readableBytes() < 5) {
      return null;
    }

    int packetLength = 0;

    // SSLv3 or TLS - Check ContentType
    boolean tls;
    switch (buffer.getUnsignedByte(buffer.readerIndex())) {
      case 20: // change_cipher_spec
      case 21: // alert
      case 22: // handshake
      case 23: // application_data
        tls = true;
        break;
      default:
        // SSLv2 or bad data
        tls = false;
    }

    if (tls) {
      // SSLv3 or TLS - Check ProtocolVersion
      int majorVersion = buffer.getUnsignedByte(buffer.readerIndex() + 1);
      if (majorVersion >= 3 && majorVersion < 10) {
        // SSLv3 or TLS
        packetLength = (buffer.getShort(buffer.readerIndex() + 3) & 0xFFFF) + 5;
        if (packetLength <= 5) {
          // Neither SSLv2 or TLSv1 (i.e. SSLv2 or bad data)
          tls = false;
        }
      } else {
        // Neither SSLv2 or TLSv1 (i.e. SSLv2 or bad data)
        tls = false;
      }
    }

    if (!tls) {
      // SSLv2 or bad data - Check the version
      boolean sslv2 = true;
      int headerLength = (buffer.getUnsignedByte(buffer.readerIndex()) & 0x80) != 0 ? 2 : 3;
      int majorVersion = buffer.getUnsignedByte(buffer.readerIndex() + headerLength + 1);
      if (majorVersion >= 2 && majorVersion < 10) {
        // SSLv2
        if (headerLength == 2) {
          packetLength = (buffer.getShort(buffer.readerIndex()) & 0x7FFF) + 2;
        } else {
          packetLength = (buffer.getShort(buffer.readerIndex()) & 0x3FFF) + 3;
        }
        if (packetLength <= headerLength) {
          sslv2 = false;
        }
      } else {
        sslv2 = false;
      }

      if (!sslv2) {
        // Bad data - discard the buffer and raise an exception.
        SSLException e =
            new SSLException("not an SSL/TLS record: " + ChannelBuffers.hexDump(buffer));
        buffer.skipBytes(buffer.readableBytes());
        throw e;
      }
    }

    assert packetLength > 0;

    if (buffer.readableBytes() < packetLength) {
      return null;
    }

    // We advance the buffer's readerIndex before calling unwrap() because
    // unwrap() can trigger FrameDecoder call decode(), this method, recursively.
    // The recursive call results in decoding the same packet twice if
    // the readerIndex is advanced *after* decode().
    //
    // Here's an example:
    // 1) An SSL packet is received from the wire.
    // 2) SslHandler.decode() deciphers the packet and calls the user code.
    // 3) The user closes the channel in the same thread.
    // 4) The same thread triggers a channelDisconnected() event.
    // 5) FrameDecoder.cleanup() is called, and it calls SslHandler.decode().
    // 6) SslHandler.decode() will feed the same packet with what was
    //    deciphered at the step 2 again if the readerIndex was not advanced
    //    before calling the user code.
    final int packetOffset = buffer.readerIndex();
    buffer.skipBytes(packetLength);
    return unwrap(ctx, channel, buffer, packetOffset, packetLength);
  }
  @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;
  }
  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);
  }
Beispiel #8
0
 @Override
 public int getUnsignedByte() {
   return buffer.getUnsignedByte(buffer.readerIndex());
 }
  @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;
  }