wildfire chat server source initial submit

This commit is contained in:
heavyrain2012
2019-03-16 17:04:23 +08:00
parent e59217bd10
commit cab3ca0916
1466 changed files with 528862 additions and 15919 deletions
+103
View File
@@ -0,0 +1,103 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import org.fusesource.hawtbuf.*;
import java.io.IOException;
import java.net.ProtocolException;
import static org.fusesource.mqtt.codec.MessageSupport.*;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class CONNACK implements Message {
public static final byte TYPE = 2;
public byte[] payload;
public static enum Code {
CONNECTION_ACCEPTED,
CONNECTION_REFUSED_UNACCEPTED_PROTOCOL_VERSION,
CONNECTION_REFUSED_IDENTIFIER_REJECTED,
CONNECTION_REFUSED_SERVER_UNAVAILABLE,
CONNECTION_REFUSED_BAD_USERNAME_OR_PASSWORD,
CONNECTION_REFUSED_NOT_AUTHORIZED;
}
private Code code = Code.CONNECTION_ACCEPTED;
public byte messageType() {
return TYPE;
}
public CONNACK decode(MQTTFrame frame) throws ProtocolException {
assert(frame.buffers.length == 1);
DataByteArrayInputStream is = new DataByteArrayInputStream(frame.buffers[0]);
is.skip(1);
byte c = is.readByte();
if( c >= Code.values().length ) {
throw new ProtocolException("Invalid CONNACK encoding");
}
code = Code.values()[c];
payload = new byte[is.available()];
try {
is.read(payload);
} catch (IOException e) {
e.printStackTrace();
}
return this;
}
public MQTTFrame encode() {
try {
DataByteArrayOutputStream os = new DataByteArrayOutputStream(2);
os.writeByte(0);
os.writeByte(code.ordinal());
MQTTFrame frame = new MQTTFrame();
frame.commandType(TYPE);
return frame.buffer(os.toBuffer());
} catch (IOException e) {
throw new RuntimeException("The impossible happened");
}
}
public Code code() {
return code;
}
public CONNACK code(Code code) {
this.code = code;
return this;
}
@Override
public String toString() {
return "CONNACK{" +
"code=" + code +
'}';
}
}
+284
View File
@@ -0,0 +1,284 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import java.io.IOException;
import java.net.ProtocolException;
import org.fusesource.mqtt.client.QoS;
import org.fusesource.hawtbuf.DataByteArrayInputStream;
import org.fusesource.hawtbuf.DataByteArrayOutputStream;
import org.fusesource.hawtbuf.UTF8Buffer;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class CONNECT implements MessageSupport.Message {
public static final byte TYPE = 1;
private static final UTF8Buffer V3_PROTOCOL_NAME = new UTF8Buffer("MQIsdp");
private static final UTF8Buffer V4_PROTOCOL_NAME = new UTF8Buffer("MQTT");
private short keepAlive = 30;
private UTF8Buffer clientId;
private UTF8Buffer willTopic;
private UTF8Buffer willMessage = new UTF8Buffer("");
private boolean willRetain;
private byte willQos;
private boolean cleanSession = true;
private UTF8Buffer userName;
private UTF8Buffer password;
private int version = 3;
public CONNECT(){
}
public CONNECT(CONNECT other) {
this.keepAlive = other.keepAlive;
this.clientId = other.clientId;
this.willTopic = other.willTopic;
this.willMessage = other.willMessage;
this.willRetain = other.willRetain;
this.willQos = other.willQos;
this.cleanSession = other.cleanSession;
this.userName = other.userName;
this.password = other.password;
this.version = other.version;
}
public byte messageType() {
return TYPE;
}
public CONNECT decode(MQTTFrame frame) throws ProtocolException {
assert(frame.buffers.length == 1);
DataByteArrayInputStream is = new DataByteArrayInputStream(frame.buffers[0]);
UTF8Buffer protocolName = MessageSupport.readUTF(is);
if (V4_PROTOCOL_NAME.equals(protocolName)) {
version = is.readByte() & 0xFF;
if( version < 4 ) {
throw new ProtocolException("Invalid CONNECT frame: protocol name/version mismatch");
}
} else if( V3_PROTOCOL_NAME.equals(protocolName) ) {
version = is.readByte() & 0xFF;
if( version != 3 ) {
throw new ProtocolException("Invalid CONNECT frame: protocol name/version mismatch");
}
} else {
throw new ProtocolException("Invalid CONNECT frame");
}
byte flags = is.readByte();
boolean username_flag = (flags & 0x80) > 0;
boolean password_flag = (flags & 0x40) > 0;
willRetain = (flags & 0x20) > 0;
willQos = (byte) ((flags & 0x18) >>> 3);
boolean will_flag = (flags & 0x04) > 0;
cleanSession = (flags & 0x02) > 0;
keepAlive = is.readShort();
clientId = MessageSupport.readUTF(is);
if( clientId.length == 0 ) {
clientId = null;
}
if(will_flag) {
willTopic = MessageSupport.readUTF(is);
willMessage = MessageSupport.readUTF(is);
}
if( username_flag ) {
userName = MessageSupport.readUTF(is);
}
if( password_flag ) {
password = MessageSupport.readUTF(is);
}
return this;
}
public MQTTFrame encode() {
try {
if( (clientId==null || clientId.length == 0) && !cleanSession ) {
throw new IllegalArgumentException("A clean session must be used when no clientId is specified");
}
DataByteArrayOutputStream os = new DataByteArrayOutputStream(500);
if(version==3) {
MessageSupport.writeUTF(os, V3_PROTOCOL_NAME);
os.writeByte(version);
} else if(version >= 4) {
MessageSupport.writeUTF(os, V4_PROTOCOL_NAME);
os.writeByte(version);
} else {
throw new IllegalArgumentException("Invalid version: "+version);
}
int flags = 0;
if(userName!=null) {
flags |= 0x80;
}
if(password!=null) {
flags |= 0x40;
}
if(willTopic!=null && willMessage!=null) {
flags |= 0x04;
if(willRetain) {
flags |= 0x20;
}
flags |= (willQos << 3) & 0x18;
}
if(cleanSession) {
flags |= 0x02;
}
os.writeByte(flags);
os.writeShort(keepAlive);
MessageSupport.writeUTF(os, clientId);
if(willTopic!=null && willMessage!=null) {
MessageSupport.writeUTF(os, willTopic);
MessageSupport.writeUTF(os, willMessage);
}
if(userName!=null) {
MessageSupport.writeUTF(os, userName);
}
if(password!=null) {
MessageSupport.writeUTF(os, password);
}
MQTTFrame frame = new MQTTFrame();
frame.commandType(TYPE);
return frame.buffer(os.toBuffer());
} catch (IOException e) {
throw new RuntimeException("The impossible happened");
}
}
public boolean cleanSession() {
return cleanSession;
}
public CONNECT cleanSession(boolean cleanSession) {
this.cleanSession = cleanSession;
return this;
}
public UTF8Buffer clientId() {
return clientId;
}
public CONNECT clientId(UTF8Buffer clientId) {
this.clientId = clientId;
return this;
}
public short keepAlive() {
return keepAlive;
}
public CONNECT keepAlive(short keepAlive) {
this.keepAlive = keepAlive;
return this;
}
public UTF8Buffer password() {
return password;
}
public CONNECT password(UTF8Buffer password) {
this.password = password;
return this;
}
public UTF8Buffer userName() {
return userName;
}
public CONNECT userName(UTF8Buffer userName) {
this.userName = userName;
return this;
}
public UTF8Buffer willMessage() {
return willMessage;
}
public CONNECT willMessage(UTF8Buffer willMessage) {
this.willMessage = willMessage;
return this;
}
public QoS willQos() {
return QoS.values()[willQos];
}
public CONNECT willQos(QoS willQos) {
this.willQos = (byte) willQos.ordinal();
return this;
}
public boolean willRetain() {
return willRetain;
}
public CONNECT willRetain(boolean willRetain) {
this.willRetain = willRetain;
return this;
}
public UTF8Buffer willTopic() {
return willTopic;
}
public CONNECT willTopic(UTF8Buffer willTopic) {
this.willTopic = willTopic;
return this;
}
public int version() {
return version;
}
public CONNECT version(int version) {
if(version==3) {
this.version = version;
} else if(version >= 4) {
this.version = version;
} else {
throw new IllegalArgumentException("Invalid version: "+version);
}
return this;
}
@Override
public String toString() {
return "CONNECT{" +
"cleanSession=" + cleanSession +
", keepAlive=" + keepAlive +
", clientId=" + clientId +
", willTopic=" + willTopic +
", willMessage=" + willMessage +
", willRetain=" + willRetain +
", willQos=" + willQos +
", userName=" + userName +
", password=" + password +
'}';
}
}
@@ -0,0 +1,47 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import java.net.ProtocolException;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class DISCONNECT extends MessageSupport.EmptyBase implements MessageSupport.Message {
public static final byte TYPE = 14;
public byte messageType() {
return TYPE;
}
@Override
public DISCONNECT decode(MQTTFrame frame) throws ProtocolException {
return (DISCONNECT) super.decode(frame);
}
@Override
public String toString() {
return "DISCONNECT";
}
}
@@ -0,0 +1,159 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import org.fusesource.mqtt.client.QoS;
import org.fusesource.hawtbuf.Buffer;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class MQTTFrame extends MessageSupport.HeaderBase {
private static final Buffer[] NO_BUFFERS = new Buffer[0];
public Buffer[] buffers = NO_BUFFERS;
public MQTTFrame() {
}
public MQTTFrame( Buffer buffer) {
this(new Buffer[]{buffer});
}
public MQTTFrame( Buffer[] buffers) {
this.buffers = buffers;
}
public Buffer[] buffers() {
return buffers;
}
public MQTTFrame buffers(Buffer...buffers) {
this.buffers = buffers;
return this;
}
public MQTTFrame buffer(Buffer buffer) {
this.buffers = new Buffer[]{buffer};
return this;
}
@Override
public byte header() {
return super.header();
}
@Override
public MQTTFrame header(byte header) {
return (MQTTFrame)super.header(header);
}
@Override
public byte messageType() {
return super.messageType();
}
@Override
public MQTTFrame commandType(int type) {
return (MQTTFrame)super.commandType(type);
}
@Override
public boolean dup() {
return super.dup();
}
@Override
public MQTTFrame dup(boolean dup) {
return (MQTTFrame) super.dup(dup);
}
@Override
public QoS qos() {
return super.qos();
}
@Override
public MQTTFrame qos(QoS qos) {
return (MQTTFrame) super.qos(qos);
}
@Override
public boolean retain() {
return super.retain();
}
@Override
public MQTTFrame retain(boolean retain) {
return (MQTTFrame) super.retain(retain);
}
@Override
public String toString() {
String type = "unknown";
switch(messageType()) {
case CONNECT.TYPE:
type = "CONNECT";
break;
case CONNACK.TYPE:
type = "CONNACK";
break;
case DISCONNECT.TYPE:
type = "DISCONNECT";
break;
case PINGREQ.TYPE:
type = "PINGREQ";
break;
case PINGRESP.TYPE:
type = "PINGRESP";
break;
case SUBSCRIBE.TYPE:
type = "SUBSCRIBE";
break;
case UNSUBSCRIBE.TYPE:
type = "UNSUBSCRIBE";
break;
case UNSUBACK.TYPE:
type = "UNSUBACK";
break;
case PUBLISH.TYPE:
type = "PUBLISH";
break;
case SUBACK.TYPE:
type = "SUBACK";
break;
case PUBACK.TYPE:
type = "PUBACK";
break;
case PUBREC.TYPE:
type = "PUBREC";
break;
case PUBREL.TYPE:
type = "PUBREL";
break;
case PUBCOMP.TYPE:
type = "PUBCOMP";
break;
default:
}
return "MQTTFrame { type: "+type+", qos: "+qos()+", dup:"+dup()+" }";
}
}
@@ -0,0 +1,135 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtdispatch.transport.AbstractProtocolCodec;
import org.fusesource.hawtdispatch.util.BufferPools;
import java.io.IOException;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class MQTTProtocolCodec extends AbstractProtocolCodec {
private static final BufferPools BUFFER_POOLS = new BufferPools();
private int maxMessageLength = 1024*1024*100;
public MQTTProtocolCodec() {
this.bufferPools = BUFFER_POOLS;
}
public int getMaxMessageLength() {
return maxMessageLength;
}
public void setMaxMessageLength(int maxMessageLength) {
this.maxMessageLength = maxMessageLength;
}
@Override
protected void encode(Object value) throws IOException {
MQTTFrame frame = (MQTTFrame) value;
nextWriteBuffer.write(frame.header());
int remaining = 0;
for(Buffer buffer : frame.buffers) {
remaining += buffer.length;
}
do {
byte digit = (byte) (remaining & 0x7F);
remaining >>>= 7;
if (remaining > 0) {
digit |= 0x80;
}
nextWriteBuffer.write(digit);
} while (remaining > 0);
for(Buffer buffer : frame.buffers) {
nextWriteBuffer.write(buffer.data, buffer.offset, buffer.length);
}
}
@Override
protected Action initialDecodeAction() {
return readHeader;
}
private final Action readHeader = new Action() {
public MQTTFrame apply() throws IOException {
int length = readLength();
if( length >= 0 ) {
if( length > maxMessageLength) {
throw new IOException("The maximum message length was exceeded");
}
byte header = readBuffer.get(readStart);
readStart = readEnd;
if( length > 0 ) {
nextDecodeAction = readBody(header, length);
} else {
return new MQTTFrame().header(header);
}
}
return null;
}
};
private int readLength() throws IOException {
readEnd = readStart+2; // Header is at least 2 bytes..
int limit = readBuffer.position();
int length = 0;
int multiplier = 1;
byte digit;
while (readEnd-1 < limit) {
// last byte is part of the encoded length..
digit = readBuffer.get(readEnd-1);
length += (digit & 0x7F) * multiplier;
if( (digit & 0x80) == 0 ) {
return length;
}
// length extends out one more byte..
multiplier <<= 7;
readEnd++;
}
return -1;
}
Action readBody(final byte header, final int length) {
return new Action() {
public MQTTFrame apply() throws IOException {
int limit = readBuffer.position();
if ((limit - readStart) < length) {
readEnd = limit;
return null;
} else {
Buffer body = new Buffer(readBuffer.array(), readStart, length);
readEnd = readStart = readStart + length;
nextDecodeAction = readHeader;
return new MQTTFrame(body).header(header);
}
}
};
}
}
@@ -0,0 +1,202 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import java.io.IOException;
import java.net.ProtocolException;
import org.fusesource.mqtt.client.QoS;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.DataByteArrayInputStream;
import org.fusesource.hawtbuf.DataByteArrayOutputStream;
import org.fusesource.hawtbuf.UTF8Buffer;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public final class MessageSupport {
private MessageSupport() throws InstantiationException {
throw new InstantiationException("This class is not for instantiation");
}
/**
* All command objects implement this interface.
*/
static public interface Message {
public byte messageType();
public Message decode(MQTTFrame frame) throws ProtocolException;
public MQTTFrame encode();
}
/**
* All command objects that can get acked implement this interface.
*/
static public interface Acked extends Message {
public boolean dup();
public Acked dup(boolean dup);
public QoS qos();
public short messageId();
public Acked messageId(short messageId);
}
static protected UTF8Buffer readUTF(DataByteArrayInputStream is) throws ProtocolException {
int size = is.readUnsignedShort();
Buffer buffer = is.readBuffer(size);
if (buffer == null || buffer.length != size) {
throw new ProtocolException("Invalid message encoding");
}
return buffer.utf8();
}
static protected void writeUTF(DataByteArrayOutputStream os, Buffer buffer) throws IOException {
os.writeShort(buffer.length);
os.write(buffer);
}
static abstract public class AckBase {
private short messageId;
public byte[] payload;
abstract byte messageType();
protected AckBase decode(MQTTFrame frame) throws ProtocolException {
assert(frame.buffers.length == 1);
DataByteArrayInputStream is = new DataByteArrayInputStream(frame.buffers[0]);
messageId = is.readShort();
payload = new byte[is.available()];
try {
is.read(payload);
} catch (IOException e) {
e.printStackTrace();
}
return this;
}
public MQTTFrame encode() {
try {
DataByteArrayOutputStream os = new DataByteArrayOutputStream(2);
os.writeShort(messageId);
MQTTFrame frame = new MQTTFrame();
frame.commandType(messageType());
return frame.buffer(os.toBuffer());
} catch (IOException e) {
throw new RuntimeException("The impossible happened");
}
}
public short messageId() {
return messageId;
}
protected AckBase messageId(short messageId) {
this.messageId = messageId;
return this;
}
@Override
public String toString() {
return getClass().getSimpleName()+"{" +
"messageId=" + messageId +
'}';
}
}
static abstract public class EmptyBase {
abstract byte messageType();
protected EmptyBase decode(MQTTFrame frame) throws ProtocolException {
return this;
}
public MQTTFrame encode() {
return new MQTTFrame().commandType(messageType());
}
}
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
static public class HeaderBase {
protected byte header;
protected byte header() {
return header;
}
protected HeaderBase header(byte header) {
this.header = header;
return this;
}
protected byte messageType() {
return (byte) ((header & 0xF0) >>> 4);
}
protected HeaderBase commandType(int type) {
this.header &= 0x0F;
this.header |= (type << 4) & 0xF0;
return this;
}
protected QoS qos() {
return QoS.values()[((header & 0x06) >>> 1)];
}
protected HeaderBase qos(QoS qos) {
this.header &= 0xF9;
this.header |= (qos.ordinal() << 1) & 0x06;
return this;
}
protected boolean dup() {
return (header & 0x08) > 0;
}
protected HeaderBase dup(boolean dup) {
if(dup) {
this.header |= 0x08;
} else {
this.header &= 0xF7;
}
return this;
}
protected boolean retain() {
return (header & 0x01) > 0;
}
protected HeaderBase retain(boolean retain) {
if(retain) {
this.header |= 0x01;
} else {
this.header &= 0xFE;
}
return this;
}
}
}
@@ -0,0 +1,48 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import java.net.ProtocolException;
import static org.fusesource.mqtt.codec.MessageSupport.*;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class PINGREQ extends MessageSupport.EmptyBase implements Message {
public static final byte TYPE = 12;
public byte messageType() {
return TYPE;
}
@Override
public PINGREQ decode(MQTTFrame frame) throws ProtocolException {
return (PINGREQ) super.decode(frame);
}
@Override
public String toString() {
return "PINGREQ";
}
}
@@ -0,0 +1,47 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import java.net.ProtocolException;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class PINGRESP extends MessageSupport.EmptyBase implements MessageSupport.Message {
public static final byte TYPE = 13;
public byte messageType() {
return TYPE;
}
@Override
public PINGRESP decode(MQTTFrame frame) throws ProtocolException {
return (PINGRESP) super.decode(frame);
}
@Override
public String toString() {
return "PINGRESP";
}
}
+46
View File
@@ -0,0 +1,46 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import java.net.ProtocolException;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class PUBACK extends MessageSupport.AckBase implements MessageSupport.Message {
public static final byte TYPE = 4;
public byte messageType() {
return TYPE;
}
@Override
public PUBACK decode(MQTTFrame frame) throws ProtocolException {
return (PUBACK) super.decode(frame);
}
@Override
public PUBACK messageId(short messageId) {
return (PUBACK) super.messageId(messageId);
}
}
@@ -0,0 +1,47 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import java.net.ProtocolException;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class PUBCOMP extends MessageSupport.AckBase implements MessageSupport.Message {
public static final byte TYPE = 7;
public byte messageType() {
return TYPE;
}
@Override
public PUBCOMP decode(MQTTFrame frame) throws ProtocolException {
return (PUBCOMP) super.decode(frame);
}
@Override
public PUBCOMP messageId(short messageId) {
return (PUBCOMP) super.messageId(messageId);
}
}
+159
View File
@@ -0,0 +1,159 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import org.fusesource.mqtt.client.QoS;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.DataByteArrayInputStream;
import org.fusesource.hawtbuf.DataByteArrayOutputStream;
import org.fusesource.hawtbuf.UTF8Buffer;
import java.io.IOException;
import java.net.ProtocolException;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class PUBLISH extends MessageSupport.HeaderBase implements MessageSupport.Message, MessageSupport.Acked {
public static final byte TYPE = 3;
private UTF8Buffer topicName;
private short messageId;
private Buffer payload;
public PUBLISH() {
qos(QoS.AT_LEAST_ONCE);
}
public byte messageType() {
return TYPE;
}
public PUBLISH decode(MQTTFrame frame) throws ProtocolException {
assert(frame.buffers.length == 1);
header(frame.header());
DataByteArrayInputStream is = new DataByteArrayInputStream(frame.buffers[0]);
topicName = MessageSupport.readUTF(is);
QoS qos = qos();
if(qos != QoS.AT_MOST_ONCE) {
messageId = is.readShort();
}
payload = is.readBuffer(is.available());
if( payload == null ) {
payload = new Buffer(0);
}
return this;
}
public MQTTFrame encode() {
try {
DataByteArrayOutputStream os = new DataByteArrayOutputStream();
MessageSupport.writeUTF(os, topicName);
QoS qos = qos();
if(qos != QoS.AT_MOST_ONCE) {
os.writeShort(messageId);
}
MQTTFrame frame = new MQTTFrame();
frame.header(header());
frame.commandType(TYPE);
if(payload!=null && payload.length!=0) {
os.write(payload);
}
frame.buffer(os.toBuffer());
return frame;
} catch (IOException e) {
throw new RuntimeException("The impossible happened");
}
}
@Override
public boolean dup() {
return super.dup();
}
@Override
public PUBLISH dup(boolean dup) {
return (PUBLISH) super.dup(dup);
}
@Override
public QoS qos() {
return super.qos();
}
@Override
public PUBLISH qos(QoS qos) {
return (PUBLISH) super.qos(qos);
}
@Override
public boolean retain() {
return super.retain();
}
@Override
public PUBLISH retain(boolean retain) {
return (PUBLISH) super.retain(retain);
}
public short messageId() {
return messageId;
}
public PUBLISH messageId(short messageId) {
this.messageId = messageId;
return this;
}
public Buffer payload() {
return payload;
}
public PUBLISH payload(Buffer payload) {
this.payload = payload;
return this;
}
public UTF8Buffer topicName() {
return topicName;
}
public PUBLISH topicName(UTF8Buffer topicName) {
this.topicName = topicName;
return this;
}
@Override
public String toString() {
return "PUBLISH{" +
"dup=" + dup() +
", qos=" + qos() +
", retain=" + retain() +
", messageId=" + messageId +
", topicName=" + topicName +
", payload=" + payload +
'}';
}
}
+47
View File
@@ -0,0 +1,47 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import java.net.ProtocolException;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class PUBREC extends MessageSupport.AckBase implements MessageSupport.Message {
public static final byte TYPE = 5;
public byte messageType() {
return TYPE;
}
@Override
public PUBREC decode(MQTTFrame frame) throws ProtocolException {
return (PUBREC) super.decode(frame);
}
@Override
public PUBREC messageId(short messageId) {
return (PUBREC) super.messageId(messageId);
}
}
+103
View File
@@ -0,0 +1,103 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import org.fusesource.mqtt.client.QoS;
import org.fusesource.hawtbuf.DataByteArrayInputStream;
import org.fusesource.hawtbuf.DataByteArrayOutputStream;
import java.io.IOException;
import java.net.ProtocolException;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class PUBREL extends MessageSupport.HeaderBase implements MessageSupport.Message, MessageSupport.Acked {
public static final byte TYPE = 6;
private short messageId;
public byte messageType() {
return TYPE;
}
public PUBREL() {
qos(QoS.AT_LEAST_ONCE);
}
public PUBREL decode(MQTTFrame frame) throws ProtocolException {
assert(frame.buffers.length == 1);
header(frame.header());
DataByteArrayInputStream is = new DataByteArrayInputStream(frame.buffers[0]);
messageId = is.readShort();
return this;
}
public MQTTFrame encode() {
try {
DataByteArrayOutputStream os = new DataByteArrayOutputStream(2);
os.writeShort(messageId);
MQTTFrame frame = new MQTTFrame();
frame.header(header());
frame.commandType(TYPE);
return frame.buffer(os.toBuffer());
} catch (IOException e) {
throw new RuntimeException("The impossible happened");
}
}
@Override
public boolean dup() {
return super.dup();
}
@Override
public PUBREL dup(boolean dup) {
return (PUBREL) super.dup(dup);
}
@Override
public QoS qos() {
return super.qos();
}
public short messageId() {
return messageId;
}
public PUBREL messageId(short messageId) {
this.messageId = messageId;
return this;
}
@Override
public String toString() {
return "PUBREL{" +
"dup=" + dup() +
", qos=" + qos() +
", messageId=" + messageId +
'}';
}
}
+94
View File
@@ -0,0 +1,94 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import org.fusesource.hawtbuf.DataByteArrayInputStream;
import org.fusesource.hawtbuf.DataByteArrayOutputStream;
import java.io.IOException;
import java.net.ProtocolException;
import java.util.Arrays;
import static org.fusesource.mqtt.codec.MessageSupport.*;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class SUBACK implements Message {
public static final byte[] NO_GRANTED_QOS = new byte[0];
public static final byte TYPE = 9;
private short messageId;
private byte[] grantedQos = NO_GRANTED_QOS;
public byte messageType() {
return TYPE;
}
public SUBACK decode(MQTTFrame frame) throws ProtocolException {
assert(frame.buffers.length == 1);
DataByteArrayInputStream is = new DataByteArrayInputStream(frame.buffers[0]);
messageId = is.readShort();
grantedQos = is.readBuffer(is.available()).toByteArray();
return this;
}
public MQTTFrame encode() {
try {
DataByteArrayOutputStream os = new DataByteArrayOutputStream(2+grantedQos.length);
os.writeShort(messageId);
os.write(grantedQos);
MQTTFrame frame = new MQTTFrame();
frame.commandType(TYPE);
return frame.buffer(os.toBuffer());
} catch (IOException e) {
throw new RuntimeException("The impossible happened");
}
}
public byte[] grantedQos() {
return grantedQos;
}
public SUBACK grantedQos(byte[] grantedQos) {
this.grantedQos = grantedQos;
return this;
}
public short messageId() {
return messageId;
}
public SUBACK messageId(short messageId) {
this.messageId = messageId;
return this;
}
@Override
public String toString() {
return "SUBACK{" +
"grantedQos=" + Arrays.toString(grantedQos) +
", messageId=" +messageId +
'}';
}
}
@@ -0,0 +1,134 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import org.fusesource.mqtt.client.QoS;
import org.fusesource.mqtt.client.Topic;
import org.fusesource.hawtbuf.DataByteArrayInputStream;
import org.fusesource.hawtbuf.DataByteArrayOutputStream;
import java.io.IOException;
import java.net.ProtocolException;
import java.util.ArrayList;
import java.util.Arrays;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class SUBSCRIBE extends MessageSupport.HeaderBase implements MessageSupport.Message, MessageSupport.Acked {
public static final byte TYPE = 8;
public static final Topic[] NO_TOPICS = new Topic[0];
private short messageId;
private Topic[] topics = NO_TOPICS;
public SUBSCRIBE() {
qos(QoS.AT_LEAST_ONCE);
}
public byte messageType() {
return TYPE;
}
public SUBSCRIBE decode(MQTTFrame frame) throws ProtocolException {
assert(frame.buffers.length == 1);
header(frame.header());
DataByteArrayInputStream is = new DataByteArrayInputStream(frame.buffers[0]);
QoS qos = qos();
if(qos != QoS.AT_MOST_ONCE) {
messageId = is.readShort();
}
ArrayList<Topic> list = new ArrayList<Topic>();
while(is.available() > 0) {
Topic topic = new Topic(MessageSupport.readUTF(is), QoS.values()[is.readByte()]);
list.add(topic);
}
topics = list.toArray(new Topic[list.size()]);
return this;
}
public MQTTFrame encode() {
try {
DataByteArrayOutputStream os = new DataByteArrayOutputStream();
QoS qos = qos();
if(qos != QoS.AT_MOST_ONCE) {
os.writeShort(messageId);
}
for(Topic topic: topics) {
MessageSupport.writeUTF(os, topic.name());
os.writeByte(topic.qos().ordinal());
}
MQTTFrame frame = new MQTTFrame();
frame.header(header());
frame.commandType(TYPE);
return frame.buffer(os.toBuffer());
} catch (IOException e) {
throw new RuntimeException("The impossible happened");
}
}
@Override
public boolean dup() {
return super.dup();
}
@Override
public SUBSCRIBE dup(boolean dup) {
return (SUBSCRIBE) super.dup(dup);
}
@Override
public QoS qos() {
return super.qos();
}
public short messageId() {
return messageId;
}
public SUBSCRIBE messageId(short messageId) {
this.messageId = messageId;
return this;
}
public Topic[] topics() {
return topics;
}
public SUBSCRIBE topics(Topic[] topics) {
this.topics = topics;
return this;
}
@Override
public String toString() {
return "SUBSCRIBE{" +
"dup=" + dup() +
", qos=" + qos() +
", messageId=" + messageId +
", topics=" + (topics == null ? null : Arrays.asList(topics)) +
'}';
}
}
@@ -0,0 +1,49 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import java.net.ProtocolException;
import static org.fusesource.mqtt.codec.MessageSupport.AckBase;
import static org.fusesource.mqtt.codec.MessageSupport.*;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class UNSUBACK extends AckBase implements Message {
public static final byte TYPE = 11;
public byte messageType() {
return TYPE;
}
@Override
public UNSUBACK decode(MQTTFrame frame) throws ProtocolException {
return (UNSUBACK) super.decode(frame);
}
@Override
public UNSUBACK messageId(short messageId) {
return (UNSUBACK) super.messageId(messageId);
}
}
@@ -0,0 +1,130 @@
/**
* Copyright (C) 2010-2012, FuseSource Corp. All rights reserved.
*
* http://fusesource.com
*
* Licensed 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 org.fusesource.mqtt.codec;
import org.fusesource.mqtt.client.QoS;
import org.fusesource.hawtbuf.DataByteArrayInputStream;
import org.fusesource.hawtbuf.DataByteArrayOutputStream;
import org.fusesource.hawtbuf.UTF8Buffer;
import java.io.IOException;
import java.net.ProtocolException;
import java.util.ArrayList;
import java.util.Arrays;
/**
* <p>
* </p>
*
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
*/
public class UNSUBSCRIBE extends MessageSupport.HeaderBase implements MessageSupport.Message, MessageSupport.Acked {
public static final byte TYPE = 10;
public static final UTF8Buffer[] NO_TOPICS = new UTF8Buffer[0];
private short messageId;
private UTF8Buffer[] topics = NO_TOPICS;
public UNSUBSCRIBE() {
qos(QoS.AT_LEAST_ONCE);
}
public byte messageType() {
return TYPE;
}
public UNSUBSCRIBE decode(MQTTFrame frame) throws ProtocolException {
assert(frame.buffers.length == 1);
header(frame.header());
DataByteArrayInputStream is = new DataByteArrayInputStream(frame.buffers[0]);
messageId = is.readShort();
ArrayList<UTF8Buffer> list = new ArrayList<UTF8Buffer>();
while(is.available() > 0) {
list.add(MessageSupport.readUTF(is));
}
topics = list.toArray(new UTF8Buffer[list.size()]);
return this;
}
public MQTTFrame encode() {
try {
DataByteArrayOutputStream os = new DataByteArrayOutputStream();
QoS qos = qos();
if(qos != QoS.AT_MOST_ONCE) {
os.writeShort(messageId);
}
for(UTF8Buffer topic: topics) {
MessageSupport.writeUTF(os, topic);
}
MQTTFrame frame = new MQTTFrame();
frame.header(header());
frame.commandType(TYPE);
return frame.buffer(os.toBuffer());
} catch (IOException e) {
throw new RuntimeException("The impossible happened");
}
}
@Override
public boolean dup() {
return super.dup();
}
@Override
public UNSUBSCRIBE dup(boolean dup) {
return (UNSUBSCRIBE) super.dup(dup);
}
@Override
public QoS qos() {
return super.qos();
}
public short messageId() {
return messageId;
}
public UNSUBSCRIBE messageId(short messageId) {
this.messageId = messageId;
return this;
}
public UTF8Buffer[] topics() {
return topics;
}
public UNSUBSCRIBE topics(UTF8Buffer[] topics) {
this.topics = topics;
return this;
}
@Override
public String toString() {
return "UNSUBSCRIBE{" +
"dup=" + dup() +
", qos=" + qos() +
", messageId=" + messageId +
", topics=" + (topics == null ? null : Arrays.asList(topics)) +
'}';
}
}