Beispiel #1
0
 protected static IdAllocation readIdAllocation(ChannelBuffer buffer) {
   int numberOfDefragIds = buffer.readInt();
   long[] defragIds = new long[numberOfDefragIds];
   for (int i = 0; i < numberOfDefragIds; i++) {
     defragIds[i] = buffer.readLong();
   }
   long rangeStart = buffer.readLong();
   int rangeLength = buffer.readInt();
   long highId = buffer.readLong();
   long defragCount = buffer.readLong();
   return new IdAllocation(new IdRange(defragIds, rangeStart, rangeLength), highId, defragCount);
 }
Beispiel #2
0
 @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
    public OFUint64 readFrom(ChannelBuffer bb) throws OFParseError {
      U64 value = U64.ofRaw(bb.readLong());

      OFUint64Ver14 uint64Ver14 = new OFUint64Ver14(value);
      if (logger.isTraceEnabled()) logger.trace("readFrom - read={}", uint64Ver14);
      return uint64Ver14;
    }
 /**
  * Read long from this packet buffer.
  *
  * @return long
  */
 protected final long readQ() {
   try {
     return buf.readLong();
   } catch (Exception e) {
     log.error("Missing Q for: " + this);
   }
   return 0;
 }
Beispiel #6
0
  protected RequestContext readContext(ChannelBuffer buffer) {
    long sessionId = buffer.readLong();
    int machineId = buffer.readInt();
    int eventIdentifier = buffer.readInt();
    long neoTx = buffer.readLong();
    int masterId = buffer.readInt();
    long checksum = buffer.readLong();

    RequestContext readRequestContext =
        new RequestContext(sessionId, machineId, eventIdentifier, neoTx, masterId, checksum);
    // Only perform checksum checks on the neo data source. If there's none in the request
    // then don't perform any such check.
    if (neoTx > 0) {
      txVerifier.assertMatch(neoTx, masterId, checksum);
    }
    return readRequestContext;
  }
Beispiel #7
0
 @Override
 public Response<LockResult> call(
     Master master, RequestContext context, ChannelBuffer input, ChannelBuffer target) {
   long[] ids = new long[input.readInt()];
   for (int i = 0; i < ids.length; i++) {
     ids[i] = input.readLong();
   }
   return lock(master, context, ids);
 }
Beispiel #8
0
  /**
   * Returns Linked list of PCEP Value Type.
   *
   * @param cb of channel buffer
   * @return Linked list of PCEP Value Type
   * @throws PcepParseException if mandatory fields are missing
   */
  protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb)
      throws PcepParseException {

    LinkedList<PcepValueType> llOutOptionalTlv;

    llOutOptionalTlv = new LinkedList<PcepValueType>();

    while (MINIMUM_TLV_HEADER_LENGTH <= cb.readableBytes()) {

      PcepValueType tlv;
      short hType = cb.readShort();
      short hLength = cb.readShort();
      long lValue = 0;

      switch (hType) {
        case RoutingUniverseTlv.TYPE:
          lValue = cb.readLong();
          tlv = new RoutingUniverseTlv(lValue);
          break;
        case LocalTENodeDescriptorsTlv.TYPE:
          tlv = LocalTENodeDescriptorsTlv.read(cb, hLength);
          break;
        case RemoteTENodeDescriptorsTlv.TYPE:
          tlv = RemoteTENodeDescriptorsTlv.read(cb, hLength);
          break;
        case TELinkDescriptorsTlv.TYPE:
          tlv = TELinkDescriptorsTlv.read(cb, hLength);
          break;
        case TENodeAttributesTlv.TYPE:
          tlv = TENodeAttributesTlv.read(cb, hLength);
          break;
        case TELinkAttributesTlv.TYPE:
          tlv = TELinkAttributesTlv.read(cb, hLength);
          break;
        default:
          throw new PcepParseException("Unsupported TLV type :" + hType);
      }

      // Check for the padding
      int pad = hLength % 4;
      if (0 < pad) {
        pad = 4 - pad;
        if (pad <= cb.readableBytes()) {
          cb.skipBytes(pad);
        }
      }

      llOutOptionalTlv.add(tlv);
    }

    if (0 < cb.readableBytes()) {

      throw new PcepParseException("Optional Tlv parsing error. Extra bytes received.");
    }
    return llOutOptionalTlv;
  }
 @Override
 public void deserialize(ChannelBuffer buffer) {
   int currentSize = size;
   if (currentSize < 0) {
     currentSize = buffer.readInt();
   }
   value = new long[currentSize];
   for (int i = 0; i < currentSize; i++) {
     value[i] = buffer.readLong();
   }
 }
  @Override
  public void decode(ChannelBuffer buffer) throws IOException {
    super.decode(buffer);

    responseFlags = buffer.readInt();
    cursorID = buffer.readLong();
    startingFrom = buffer.readInt();
    numberReturned = buffer.readInt();

    while (buffer.readable()) {
      documents.add(BSONUtils.decoder().readObject(new ChannelBufferInputStream(buffer)));
    }
  }
  @Override
  protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer)
      throws Exception {
    MemcachedRestRequest request = this.request;
    if (request == null) {
      buffer.markReaderIndex();

      if (buffer.readableBytes() < 1) {
        return null;
      }
      short magic = buffer.readUnsignedByte();
      if (magic == 0x80) {
        if (buffer.readableBytes() < 23) return null;
        short opcode = buffer.readUnsignedByte();
        short keyLength = buffer.readShort();
        short extraLength = buffer.readUnsignedByte();
        short dataType = buffer.readUnsignedByte(); // unused
        short reserved = buffer.readShort(); // unused
        int totalBodyLength = buffer.readInt();
        int opaque = buffer.readInt();
        long cas = buffer.readLong();

        // we want the whole of totalBodyLength; otherwise, keep waiting.
        if (buffer.readableBytes() < totalBodyLength) {
          buffer.resetReaderIndex();
          return null;
        }

        buffer.skipBytes(extraLength); // get extras, can be empty

        if (keyLength != 0) {
          byte[] key = new byte[keyLength];
          buffer.readBytes(key);
          String uri = Unicode.fromBytes(key);
          if (opcode == 0x00) { // GET
            request = new MemcachedRestRequest(RestRequest.Method.GET, uri, key, -1, true);
            request.setOpaque(opaque);
            return request;
          } else if (opcode == 0x04) { // DELETE
            request = new MemcachedRestRequest(RestRequest.Method.DELETE, uri, key, -1, true);
            request.setOpaque(opaque);
            return request;
          } else if (opcode == 0x01) { // SET
            // the remainder of the message -- that is, totalLength - (keyLength + extraLength)
            // should be the payload
            int size = totalBodyLength - keyLength - extraLength;
            request = new MemcachedRestRequest(RestRequest.Method.POST, uri, key, size, true);
            request.setOpaque(opaque);
            byte[] data = new byte[size];
            buffer.readBytes(data, 0, size);
            request.setData(data);
            return request;
          }
        } else if (opcode == 0x07) { // QUIT
          channel.disconnect();
        }
      } else {
        buffer.resetReaderIndex(); // reset to get to the first byte
        // need to read a header
        boolean done = false;
        StringBuffer sb = this.sb;
        int readableBytes = buffer.readableBytes();
        for (int i = 0; i < readableBytes; i++) {
          byte next = buffer.readByte();
          if (next == CR) {
            next = buffer.readByte();
            if (next == LF) {
              done = true;
              break;
            }
          } else if (next == LF) {
            done = true;
            break;
          } else {
            sb.append((char) next);
          }
        }
        if (!done) {
          buffer.resetReaderIndex();
          return null;
        }

        String[] args = lineSplit.split(sb);
        // we read the text, clear it
        sb.setLength(0);

        String cmd = args[0];
        String uri = args[1];
        if ("get".equals(cmd)) {
          request = new MemcachedRestRequest(RestRequest.Method.GET, uri, null, -1, false);
          if (args.length > 3) {
            request.setData(Unicode.fromStringAsBytes(args[2]));
          }
          return request;
        } else if ("delete".equals(cmd)) {
          request = new MemcachedRestRequest(RestRequest.Method.DELETE, uri, null, -1, false);
          //                if (args.length > 3) {
          //                    request.setData(Unicode.fromStringAsBytes(args[2]));
          //                }
          return request;
        } else if ("set".equals(cmd)) {
          this.request =
              new MemcachedRestRequest(
                  RestRequest.Method.POST, uri, null, Integer.parseInt(args[4]), false);
          buffer.markReaderIndex();
        } else if ("quit".equals(cmd)) {
          channel.disconnect();
        }
      }
    } else {
      if (buffer.readableBytes() < (request.getDataSize() + 2)) {
        return null;
      }
      byte[] data = new byte[request.getDataSize()];
      buffer.readBytes(data, 0, data.length);
      byte next = buffer.readByte();
      if (next == CR) {
        next = buffer.readByte();
        if (next == LF) {
          request.setData(data);
          // reset
          this.request = null;
          return request;
        } else {
          this.request = null;
          throw new StreamCorruptedException("Expecting \r\n after data block");
        }
      } else {
        this.request = null;
        throw new StreamCorruptedException("Expecting \r\n after data block");
      }
    }
    return null;
  }
  @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;
  }
Beispiel #13
0
  /*
   * Each ControlMessage is encoded as: code (<0) ... short(2) Each
   * TaskMessage is encoded as: task (>=0) ... short(2) len ... int(4) payload
   * ... byte[] *
   */
  protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf)
      throws Exception {
    // Make sure that we have received at least a short
    long available = buf.readableBytes();
    // Length of control message is 10.
    // Minimum length of a task message is 6(short taskId, int length).
    if (available < 10) {
      // need more data
      return null;
    }

    Long startTime = null;
    if (isServer) {
      startTime = System.nanoTime();
    }
    try {
      // Mark the current buffer position before reading task/len field
      // because the whole frame might not be in the buffer yet.
      // We will reset the buffer position to the marked position if
      // there's not enough bytes in the buffer.
      buf.markReaderIndex();

      // read the short field
      short code = buf.readShort();
      available -= 2;

      // case 1: Control message
      ControlMessage ctrl_msg = ControlMessage.mkMessage(code);
      if (ctrl_msg != null) {
        if (available < 12) {
          // The time stamp bytes were not received yet - return null.
          buf.resetReaderIndex();
          return null;
        }
        long timeStamp = buf.readLong();
        int clientPort = buf.readInt();
        available -= 12;
        if (ctrl_msg == ControlMessage.EOB_MESSAGE) {

          long interval = System.currentTimeMillis() - timeStamp;
          if (interval > 0) {

            Histogram netTransTime = getTransmitHistogram(channel, clientPort);
            if (netTransTime != null) {
              netTransTime.update(interval);
            }
          }

          recvSpeed.update(Double.valueOf(ControlMessage.encodeLength()));
        }

        return ctrl_msg;
      }

      // case 2: task Message
      short task = code;

      // Make sure that we have received at least an integer (length)
      if (available < 8) {
        // need more data
        buf.resetReaderIndex();

        return null;
      }

      // Read the length field.
      int length = buf.readInt();
      if (length <= 0) {
        LOG.info("Receive one message whose TaskMessage's message length is {}", length);
        return new TaskMessage(task, null);
      }
      int headerLength = buf.readInt();
      if (headerLength <= 0) {
        LOG.info("Receive one message whose TaskMessage's message header length is {}", length);
      }
      // Make sure if there's enough bytes in the buffer.
      available -= 8;
      if (available < length + headerLength) {
        // The whole bytes were not received yet - return null.
        buf.resetReaderIndex();

        return null;
      }

      String component = null;
      String stream = null;
      if (headerLength > 0) {
        ChannelBuffer header = buf.readBytes(headerLength);
        String headerValue = new String(header.array());
        String splits[] = headerValue.split(" ");
        stream = splits[0];
        component = splits[1];
      }

      // There's enough bytes in the buffer. Read it.
      ChannelBuffer payload = buf.readBytes(length);

      // Successfully decoded a frame.
      // Return a TaskMessage object

      byte[] rawBytes = payload.array();
      // @@@ TESTING CODE
      // LOG.info("Receive task:{}, length: {}, data:{}",
      // task, length, JStormUtils.toPrintableString(rawBytes));

      TaskMessage ret = new TaskMessage(task, rawBytes, component, stream);
      recvSpeed.update(Double.valueOf(rawBytes.length + 6));
      return ret;
    } finally {
      if (isServer) {
        Long endTime = System.nanoTime();
        timer.update((endTime - startTime) / 1000000.0d);
      }
    }
  }
  @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
  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
    Object m = e.getMessage();
    if (!(m instanceof ChannelBuffer)) {
      ctx.sendUpstream(e);
      return;
    }
    ChannelBuffer buffer = (ChannelBuffer) m;
    int size = buffer.getInt(buffer.readerIndex() - 4);
    transportServiceAdapter.received(size + 6);

    // we have additional bytes to read, outside of the header
    boolean hasMessageBytesToRead = (size - (NettyHeader.HEADER_SIZE - 6)) != 0;

    int markedReaderIndex = buffer.readerIndex();
    int expectedIndexReader = markedReaderIndex + size;

    // netty always copies a buffer, either in NioWorker in its read handler, where it copies to a
    // fresh
    // buffer, or in the cumlation buffer, which is cleaned each time
    StreamInput streamIn = ChannelBufferStreamInputFactory.create(buffer, size);

    long requestId = buffer.readLong();
    byte status = buffer.readByte();
    Version version = Version.fromId(buffer.readInt());

    StreamInput wrappedStream;
    if (TransportStatus.isCompress(status) && hasMessageBytesToRead && buffer.readable()) {
      Compressor compressor = CompressorFactory.compressor(buffer);
      if (compressor == null) {
        int maxToRead = Math.min(buffer.readableBytes(), 10);
        int offset = buffer.readerIndex();
        StringBuilder sb =
            new StringBuilder("stream marked as compressed, but no compressor found, first [")
                .append(maxToRead)
                .append("] content bytes out of [")
                .append(buffer.readableBytes())
                .append("] readable bytes with message size [")
                .append(size)
                .append("] ")
                .append("] are [");
        for (int i = 0; i < maxToRead; i++) {
          sb.append(buffer.getByte(offset + i)).append(",");
        }
        sb.append("]");
        throw new ElasticsearchIllegalStateException(sb.toString());
      }
      wrappedStream = CachedStreamInput.cachedHandlesCompressed(compressor, streamIn);
    } else {
      wrappedStream = CachedStreamInput.cachedHandles(streamIn);
    }
    wrappedStream.setVersion(version);

    if (TransportStatus.isRequest(status)) {
      String action = handleRequest(ctx.getChannel(), wrappedStream, requestId, version);
      if (buffer.readerIndex() != expectedIndexReader) {
        if (buffer.readerIndex() < expectedIndexReader) {
          logger.warn(
              "Message not fully read (request) for [{}] and action [{}], resetting",
              requestId,
              action);
        } else {
          logger.warn(
              "Message read past expected size (request) for [{}] and action [{}], resetting",
              requestId,
              action);
        }
        buffer.readerIndex(expectedIndexReader);
      }
    } else {
      TransportResponseHandler handler = transportServiceAdapter.remove(requestId);
      // ignore if its null, the adapter logs it
      if (handler != null) {
        if (TransportStatus.isError(status)) {
          handlerResponseError(wrappedStream, handler);
        } else {
          handleResponse(ctx.getChannel(), wrappedStream, handler);
        }
      } else {
        // if its null, skip those bytes
        buffer.readerIndex(markedReaderIndex + size);
      }
      if (buffer.readerIndex() != expectedIndexReader) {
        if (buffer.readerIndex() < expectedIndexReader) {
          logger.warn(
              "Message not fully read (response) for [{}] handler {}, error [{}], resetting",
              requestId,
              handler,
              TransportStatus.isError(status));
        } else {
          logger.warn(
              "Message read past expected size (response) for [{}] handler {}, error [{}], resetting",
              requestId,
              handler,
              TransportStatus.isError(status));
        }
        buffer.readerIndex(expectedIndexReader);
      }
    }
    wrappedStream.close();
  }
Beispiel #16
0
 /**
  * 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
 public void readObject(ChannelBuffer aInputStream) throws IOException {
   startTimestamp = aInputStream.readLong();
 }