blob: 5871bdb9fa95115622319b1ef1359be748dff38c [file] [log] [blame]
//
// MQTTMessage.m
// MQtt Client
//
// Copyright (c) 2011, 2013, 2lemetry LLC
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Eclipse Distribution License v. 1.0 which accompanies this distribution.
// The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
// and the Eclipse Distribution License is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// Contributors:
// Kyle Roche - initial API and implementation and/or initial documentation
//
#import "MQTTMessage.h"
@implementation MQTTMessage
+ (id)connectMessageWithClientId:(NSString*)clientId
userName:(NSString*)userName
password:(NSString*)password
keepAlive:(NSInteger)keepAlive
cleanSession:(BOOL)cleanSessionFlag {
MQTTMessage* msg;
UInt8 flags = 0x00;
if (cleanSessionFlag) {
flags |= 0x02;
}
if ([userName length] > 0) {
flags |= 0x80;
if ([password length] > 0) {
flags |= 0x40;
}
}
NSMutableData* data = [NSMutableData data];
[data appendMQTTString:@"MQIsdp"];
[data appendByte:3];
[data appendByte:flags];
[data appendUInt16BigEndian:keepAlive];
[data appendMQTTString:clientId];
if ([userName length] > 0) {
[data appendMQTTString:userName];
if ([password length] > 0) {
[data appendMQTTString:password];
}
}
msg = [[MQTTMessage alloc] initWithType:MQTTConnect data:data];
return msg;
}
+ (id)connectMessageWithClientId:(NSString*)clientId
userName:(NSString*)userName
password:(NSString*)password
keepAlive:(NSInteger)keepAlive
cleanSession:(BOOL)cleanSessionFlag
willTopic:(NSString*)willTopic
willMsg:(NSData*)willMsg
willQoS:(UInt8)willQoS
willRetain:(BOOL)willRetainFlag {
UInt8 flags = 0x04 | (willQoS << 4 & 0x18);
if (willRetainFlag) {
flags |= 0x20;
}
if (cleanSessionFlag) {
flags |= 0x02;
}
if ([userName length] > 0) {
flags |= 0x80;
if ([password length] > 0) {
flags |= 0x40;
}
}
NSMutableData* data = [NSMutableData data];
[data appendMQTTString:@"MQIsdp"];
[data appendByte:3];
[data appendByte:flags];
[data appendUInt16BigEndian:keepAlive];
[data appendMQTTString:clientId];
[data appendMQTTString:willTopic];
[data appendUInt16BigEndian:[willMsg length]];
[data appendData:willMsg];
if ([userName length] > 0) {
[data appendMQTTString:userName];
if ([password length] > 0) {
[data appendMQTTString:password];
}
}
MQTTMessage *msg = [[MQTTMessage alloc] initWithType:MQTTConnect
data:data];
return msg;
}
+ (id)pingreqMessage {
return [[MQTTMessage alloc] initWithType:MQTTPingreq];
}
+ (id)subscribeMessageWithMessageId:(UInt16)msgId
topic:(NSString*)topic
qos:(UInt8)qos {
NSMutableData* data = [NSMutableData data];
[data appendUInt16BigEndian:msgId];
[data appendMQTTString:topic];
[data appendByte:qos];
MQTTMessage* msg = [[MQTTMessage alloc] initWithType:MQTTSubscribe
qos:1
data:data];
return msg;
}
+ (id)unsubscribeMessageWithMessageId:(UInt16)msgId
topic:(NSString*)topic {
NSMutableData* data = [NSMutableData data];
[data appendUInt16BigEndian:msgId];
[data appendMQTTString:topic];
MQTTMessage* msg = [[MQTTMessage alloc] initWithType:MQTTUnsubscribe
qos:1
data:data];
return msg;
}
+ (id)publishMessageWithData:(NSData*)payload
onTopic:(NSString*)topic
retainFlag:(BOOL)retain {
NSMutableData* data = [NSMutableData data];
[data appendMQTTString:topic];
[data appendData:payload];
MQTTMessage *msg = [[MQTTMessage alloc] initWithType:MQTTPublish
qos:0
retainFlag:retain
dupFlag:false
data:data];
return msg;
}
+ (id)publishMessageWithData:(NSData*)payload
onTopic:(NSString*)topic
qos:(UInt8)qosLevel
msgId:(UInt16)msgId
retainFlag:(BOOL)retain
dupFlag:(BOOL)dup {
NSMutableData* data = [NSMutableData data];
[data appendMQTTString:topic];
[data appendUInt16BigEndian:msgId];
[data appendData:payload];
MQTTMessage *msg = [[MQTTMessage alloc] initWithType:MQTTPublish
qos:qosLevel
retainFlag:retain
dupFlag:dup
data:data];
return msg;
}
+ (id)pubackMessageWithMessageId:(UInt16)msgId {
NSMutableData* data = [NSMutableData data];
[data appendUInt16BigEndian:msgId];
return [[MQTTMessage alloc] initWithType:MQTTPuback
data:data];
}
+ (id)pubrecMessageWithMessageId:(UInt16)msgId {
NSMutableData* data = [NSMutableData data];
[data appendUInt16BigEndian:msgId];
return [[MQTTMessage alloc] initWithType:MQTTPubrec
data:data];
}
+ (id)pubrelMessageWithMessageId:(UInt16)msgId {
NSMutableData* data = [NSMutableData data];
[data appendUInt16BigEndian:msgId];
return [[MQTTMessage alloc] initWithType:MQTTPubrel
data:data];
}
+ (id)pubcompMessageWithMessageId:(UInt16)msgId {
NSMutableData* data = [NSMutableData data];
[data appendUInt16BigEndian:msgId];
return [[MQTTMessage alloc] initWithType:MQTTPubcomp
data:data];
}
- (id)initWithType:(UInt8)aType {
type = aType;
self.data = nil;
return self;
}
- (id)initWithType:(UInt8)aType data:(NSData*)aData {
type = aType;
self.data = aData;
return self;
}
- (id)initWithType:(UInt8)aType
qos:(UInt8)aQos
data:(NSData*)aData {
type = aType;
qos = aQos;
self.data = aData;
return self;
}
- (id)initWithType:(UInt8)aType
qos:(UInt8)aQos
retainFlag:(BOOL)aRetainFlag
dupFlag:(BOOL)aDupFlag
data:(NSData*)aData {
type = aType;
qos = aQos;
retainFlag = aRetainFlag;
dupFlag = aDupFlag;
self.data = aData;
return self;
}
- (void)setDupFlag {
dupFlag = true;
}
- (UInt8)type {
return type;
}
- (UInt8)qos {
return qos;
}
- (BOOL)retainFlag {
return retainFlag;
}
- (BOOL)isDuplicate {
return dupFlag;
}
@end
@implementation NSMutableData (MQTT)
- (void)appendByte:(UInt8)byte {
[self appendBytes:&byte length:1];
}
- (void)appendUInt16BigEndian:(UInt16)val {
[self appendByte:val / 256];
[self appendByte:val % 256];
}
- (void)appendMQTTString:(NSString*)string {
UInt8 buf[2];
const char* utf8String = [string UTF8String];
int strLen = strlen(utf8String);
buf[0] = strLen / 256;
buf[1] = strLen % 256;
[self appendBytes:buf length:2];
[self appendBytes:utf8String length:strLen];
}
@end