2014-04-16 23:59:09 +02:00
|
|
|
|
/*
|
|
|
|
|
* Copyright 2014 The Netty Project
|
|
|
|
|
*
|
|
|
|
|
* The Netty Project licenses this file to you 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 io.netty.handler.codec.mqtt;
|
|
|
|
|
|
2014-06-21 09:46:09 +02:00
|
|
|
|
import io.netty.handler.codec.DecoderException;
|
2014-04-16 23:59:09 +02:00
|
|
|
|
|
2014-06-21 09:46:09 +02:00
|
|
|
|
final class MqttCodecUtil {
|
|
|
|
|
|
|
|
|
|
private static final char[] TOPIC_WILDCARDS = {'#', '+'};
|
2014-10-10 13:34:37 +02:00
|
|
|
|
private static final int MIN_CLIENT_ID_LENGTH = 1;
|
2014-06-21 09:46:09 +02:00
|
|
|
|
private static final int MAX_CLIENT_ID_LENGTH = 23;
|
|
|
|
|
|
|
|
|
|
static boolean isValidPublishTopicName(String topicName) {
|
|
|
|
|
// publish topic name must not contain any wildcard
|
|
|
|
|
for (char c : TOPIC_WILDCARDS) {
|
|
|
|
|
if (topicName.indexOf(c) >= 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static boolean isValidMessageId(int messageId) {
|
|
|
|
|
return messageId != 0;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-14 11:59:45 +01:00
|
|
|
|
static boolean isValidClientId(MqttVersion mqttVersion, String clientId) {
|
|
|
|
|
if (mqttVersion == MqttVersion.MQTT_3_1) {
|
|
|
|
|
return clientId != null && clientId.length() >= MIN_CLIENT_ID_LENGTH &&
|
|
|
|
|
clientId.length() <= MAX_CLIENT_ID_LENGTH;
|
2016-03-22 14:29:34 +01:00
|
|
|
|
}
|
|
|
|
|
if (mqttVersion == MqttVersion.MQTT_3_1_1) {
|
2014-11-14 11:59:45 +01:00
|
|
|
|
// In 3.1.3.1 Client Identifier of MQTT 3.1.1 specification, The Server MAY allow ClientId’s
|
|
|
|
|
// that contain more than 23 encoded bytes. And, The Server MAY allow zero-length ClientId.
|
|
|
|
|
return clientId != null;
|
|
|
|
|
}
|
|
|
|
|
throw new IllegalArgumentException(mqttVersion + " is unknown mqtt version");
|
2014-06-21 09:46:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static MqttFixedHeader validateFixedHeader(MqttFixedHeader mqttFixedHeader) {
|
|
|
|
|
switch (mqttFixedHeader.messageType()) {
|
|
|
|
|
case PUBREL:
|
|
|
|
|
case SUBSCRIBE:
|
|
|
|
|
case UNSUBSCRIBE:
|
|
|
|
|
if (mqttFixedHeader.qosLevel() != MqttQoS.AT_LEAST_ONCE) {
|
|
|
|
|
throw new DecoderException(mqttFixedHeader.messageType().name() + " message must have QoS 1");
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return mqttFixedHeader;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static MqttFixedHeader resetUnusedFields(MqttFixedHeader mqttFixedHeader) {
|
2014-04-16 23:59:09 +02:00
|
|
|
|
switch (mqttFixedHeader.messageType()) {
|
|
|
|
|
case CONNECT:
|
|
|
|
|
case CONNACK:
|
|
|
|
|
case PUBACK:
|
|
|
|
|
case PUBREC:
|
|
|
|
|
case PUBCOMP:
|
|
|
|
|
case SUBACK:
|
|
|
|
|
case UNSUBACK:
|
|
|
|
|
case PINGREQ:
|
|
|
|
|
case PINGRESP:
|
|
|
|
|
case DISCONNECT:
|
|
|
|
|
if (mqttFixedHeader.isDup() ||
|
2014-06-21 09:46:09 +02:00
|
|
|
|
mqttFixedHeader.qosLevel() != MqttQoS.AT_MOST_ONCE ||
|
|
|
|
|
mqttFixedHeader.isRetain()) {
|
2014-04-16 23:59:09 +02:00
|
|
|
|
return new MqttFixedHeader(
|
|
|
|
|
mqttFixedHeader.messageType(),
|
|
|
|
|
false,
|
2014-06-21 09:46:09 +02:00
|
|
|
|
MqttQoS.AT_MOST_ONCE,
|
2014-04-16 23:59:09 +02:00
|
|
|
|
false,
|
|
|
|
|
mqttFixedHeader.remainingLength());
|
|
|
|
|
}
|
|
|
|
|
return mqttFixedHeader;
|
|
|
|
|
case PUBREL:
|
|
|
|
|
case SUBSCRIBE:
|
|
|
|
|
case UNSUBSCRIBE:
|
|
|
|
|
if (mqttFixedHeader.isRetain()) {
|
|
|
|
|
return new MqttFixedHeader(
|
|
|
|
|
mqttFixedHeader.messageType(),
|
|
|
|
|
mqttFixedHeader.isDup(),
|
|
|
|
|
mqttFixedHeader.qosLevel(),
|
|
|
|
|
false,
|
|
|
|
|
mqttFixedHeader.remainingLength());
|
|
|
|
|
}
|
|
|
|
|
return mqttFixedHeader;
|
|
|
|
|
default:
|
|
|
|
|
return mqttFixedHeader;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-21 09:46:09 +02:00
|
|
|
|
private MqttCodecUtil() { }
|
2014-04-16 23:59:09 +02:00
|
|
|
|
}
|