Refine search
@Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("mqtt-decoder", new MqttDecoder()); pipeline.addLast("mqtt-encoder", MqttEncoder.INSTANCE); pipeline.addLast("channel-idle-handler", new MqttIdleHandler()); pipeline.addLast("message-dispatcher", messageDispatcher); pipeline.addLast("connection-manager", connectionHandler); } });
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception { switch (state()) { case READ_FIXED_HEADER: try { mqttFixedHeader = decodeFixedHeader(buffer); bytesRemainingInVariablePart = mqttFixedHeader.remainingLength(); checkpoint(DecoderState.READ_VARIABLE_HEADER); out.add(invalidMessage(cause)); return; final Result<?> decodedVariableHeader = decodeVariableHeader(buffer, mqttFixedHeader); variableHeader = decodedVariableHeader.value; bytesRemainingInVariablePart -= decodedVariableHeader.numberOfBytesConsumed; checkpoint(DecoderState.READ_PAYLOAD); out.add(invalidMessage(cause)); return; decodePayload( buffer, mqttFixedHeader.messageType(), bytesRemainingInVariablePart, variableHeader); bytesRemainingInVariablePart -= decodedPayload.numberOfBytesConsumed; if (bytesRemainingInVariablePart != 0) { throw new DecoderException( "non-zero remaining payload bytes: " + bytesRemainingInVariablePart + " (" + mqttFixedHeader.messageType() + ')');
switch (mqttFixedHeader.messageType()) { case CONNECT: return decodeConnectionVariableHeader(buffer); return decodeConnAckVariableHeader(buffer); case PUBCOMP: case PUBREL: return decodeMessageIdVariableHeader(buffer); return decodePublishVariableHeader(buffer, mqttFixedHeader);
/** * Decodes the payload. * * @param buffer the buffer to decode from * @param messageType type of the message being decoded * @param bytesRemainingInVariablePart bytes remaining * @param variableHeader variable header of the same message * @return the payload */ private static Result<?> decodePayload( ByteBuf buffer, MqttMessageType messageType, int bytesRemainingInVariablePart, Object variableHeader) { switch (messageType) { case CONNECT: return decodeConnectionPayload(buffer, (MqttConnectVariableHeader) variableHeader); case SUBSCRIBE: return decodeSubscribePayload(buffer, bytesRemainingInVariablePart); case SUBACK: return decodeSubackPayload(buffer, bytesRemainingInVariablePart); case UNSUBSCRIBE: return decodeUnsubscribePayload(buffer, bytesRemainingInVariablePart); case PUBLISH: return decodePublishPayload(buffer, bytesRemainingInVariablePart); default: // unknown payload , no byte consumed return new Result<Object>(null, 0); } }
private static Result<String> decodeString(ByteBuf buffer, int minBytes, int maxBytes) { final Result<Integer> decodedSize = decodeMsbLsb(buffer); int size = decodedSize.value; int numberOfBytesConsumed = decodedSize.numberOfBytesConsumed; if (size < minBytes || size > maxBytes) { buffer.skipBytes(size); numberOfBytesConsumed += size; return new Result<String>(null, numberOfBytesConsumed); } String s = buffer.toString(buffer.readerIndex(), size, CharsetUtil.UTF_8); buffer.skipBytes(size); numberOfBytesConsumed += size; return new Result<String>(s, numberOfBytesConsumed); }
private static Result<MqttConnectVariableHeader> decodeConnectionVariableHeader(ByteBuf buffer) { final Result<String> protoString = decodeString(buffer); int numberOfBytesConsumed = protoString.numberOfBytesConsumed; final byte protocolLevel = buffer.readByte(); numberOfBytesConsumed += 1; final int b1 = buffer.readUnsignedByte(); numberOfBytesConsumed += 1; final Result<Integer> keepAlive = decodeMsbLsb(buffer); numberOfBytesConsumed += keepAlive.numberOfBytesConsumed; throw new DecoderException("non-zero reserved flag");
private static Result<byte[]> decodeByteArray(ByteBuf buffer) { final Result<Integer> decodedSize = decodeMsbLsb(buffer); int size = decodedSize.value; byte[] bytes = new byte[size]; buffer.readBytes(bytes); return new Result<byte[]>(bytes, decodedSize.numberOfBytesConsumed + size); }
private static Result<Integer> decodeMessageId(ByteBuf buffer) { final Result<Integer> messageId = decodeMsbLsb(buffer); if (!isValidMessageId(messageId.value)) { throw new DecoderException("invalid messageId: " + messageId.value); } return messageId; }
/** * Decodes the variable header (if any) * * @param buffer the buffer to decode from * @param mqttFixedHeader MqttFixedHeader of the same message * @return the variable header */ private static Result<?> decodeVariableHeader(ByteBuf buffer, MqttFixedHeader mqttFixedHeader) { switch (mqttFixedHeader.messageType()) { case CONNECT: return decodeConnectionVariableHeader(buffer); case CONNACK: return decodeConnAckVariableHeader(buffer); case SUBSCRIBE: case UNSUBSCRIBE: case SUBACK: case UNSUBACK: case PUBACK: case PUBREC: case PUBCOMP: case PUBREL: return decodePacketIdVariableHeader(buffer); case PUBLISH: return decodePublishVariableHeader(buffer, mqttFixedHeader); default: // no variable header , no byte consumed return new Result<>(null, 0); } }
/** * Decodes the payload. * * @param buffer the buffer to decode from * @param messageType type of the message being decoded * @param bytesRemainingInVariablePart bytes remaining * @param variableHeader variable header of the same message * @return the payload */ private static Result<?> decodePayload( ByteBuf buffer, MqttMessageType messageType, int bytesRemainingInVariablePart, Object variableHeader) { switch (messageType) { case CONNECT: return decodeConnectionPayload(buffer, (MqttConnectVariableHeader) variableHeader); case SUBSCRIBE: return decodeSubscribePayload(buffer, bytesRemainingInVariablePart); case SUBACK: return decodeSubAckPayload(buffer, bytesRemainingInVariablePart); case UNSUBSCRIBE: return decodeUnsubscribePayload(buffer, bytesRemainingInVariablePart); case PUBLISH: return decodePublishPayload(buffer, bytesRemainingInVariablePart); default: // no payload , no byte consumed return new Result<>(null, 0); } }
private static Result<Integer> decodeMsbLsb(ByteBuf buffer) { return decodeMsbLsb(buffer, 0, 65535); }
private MqttMessage invalidMessage(Throwable cause) { checkpoint(DecoderState.BAD_MESSAGE); return MqttMessageFactory.newInvalidMessage(cause); }
private static Result<String> decodeString(ByteBuf buffer, int minBytes, int maxBytes) { final Result<Integer> decodedSize = decodeMsbLsb(buffer); int size = decodedSize.value; int numberOfBytesConsumed = decodedSize.numberOfBytesConsumed; if (size < minBytes || size > maxBytes) { buffer.skipBytes(size); numberOfBytesConsumed += size; return new Result<>(null, numberOfBytesConsumed); } String s = buffer.toString(buffer.readerIndex(), size, CharsetUtil.UTF_8); buffer.skipBytes(size); numberOfBytesConsumed += size; return new Result<>(s, numberOfBytesConsumed); }
private static Result<MqttConnectVariableHeader> decodeConnectionVariableHeader(ByteBuf buffer) { final Result<String> protoString = decodeString(buffer); int numberOfBytesConsumed = protoString.numberOfBytesConsumed; final byte protocolLevel = buffer.readByte(); numberOfBytesConsumed += 1; final int b1 = buffer.readUnsignedByte(); numberOfBytesConsumed += 1; final Result<Integer> keepAlive = decodeMsbLsb(buffer); numberOfBytesConsumed += keepAlive.numberOfBytesConsumed; throw new DecoderException("non-zero reserved flag");
private static Result<byte[]> decodeByteArray(ByteBuf buffer) { final Result<Integer> decodedSize = decodeMsbLsb(buffer); int size = decodedSize.value; byte[] bytes = new byte[size]; buffer.readBytes(bytes); return new Result<byte[]>(bytes, decodedSize.numberOfBytesConsumed + size); }
private static Result<Integer> decodeMessageId(ByteBuf buffer) { final Result<Integer> messageId = decodeMsbLsb(buffer); if (!isValidMessageId(messageId.value)) { throw new DecoderException("invalid messageId: " + messageId.value); } return messageId; }
/** * Decodes the payload. * * @param buffer the buffer to decode from * @param messageType type of the message being decoded * @param bytesRemainingInVariablePart bytes remaining * @param variableHeader variable header of the same message * @return the payload */ private static Result<?> decodePayload( ByteBuf buffer, MqttMessageType messageType, int bytesRemainingInVariablePart, Object variableHeader) { switch (messageType) { case CONNECT: return decodeConnectionPayload(buffer, (MqttConnectVariableHeader) variableHeader); case SUBSCRIBE: return decodeSubscribePayload(buffer, bytesRemainingInVariablePart); case SUBACK: return decodeSubackPayload(buffer, bytesRemainingInVariablePart); case UNSUBSCRIBE: return decodeUnsubscribePayload(buffer, bytesRemainingInVariablePart); case PUBLISH: return decodePublishPayload(buffer, bytesRemainingInVariablePart); default: // unknown payload , no byte consumed return new Result<Object>(null, 0); } }
private static Result<Integer> decodeMsbLsb(ByteBuf buffer) { return decodeMsbLsb(buffer, 0, 65535); }
private MqttMessage invalidMessage(Throwable cause) { checkpoint(DecoderState.BAD_MESSAGE); return MqttMessageFactory.newInvalidMessage(cause); }
private static Result<String> decodeString(ByteBuf buffer, int minBytes, int maxBytes) { final Result<Integer> decodedSize = decodeMsbLsb(buffer); int size = decodedSize.value; int numberOfBytesConsumed = decodedSize.numberOfBytesConsumed; if (size < minBytes || size > maxBytes) { buffer.skipBytes(size); numberOfBytesConsumed += size; return new Result<String>(null, numberOfBytesConsumed); } String s = buffer.toString(buffer.readerIndex(), size, CharsetUtil.UTF_8); buffer.skipBytes(size); numberOfBytesConsumed += size; return new Result<String>(s, numberOfBytesConsumed); }