diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a1bf923..544438bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ MQTT-Client-Framework iOS Release Notes ======================================= +## MQTT-Client-Framework 0.3.6 +>Release date: 2015-11-06 + +[FIX] crashes when publishing from different threads closes #61 +[PROBABLE FIX] crashes when publishing from different threads #59 #56 #53 #45 + ## MQTT-Client-Framework 0.3.5 >Release date: 2015-11-04 diff --git a/MQTTClient.podspec b/MQTTClient.podspec index 23e5e6d9..ba3ad46d 100644 --- a/MQTTClient.podspec +++ b/MQTTClient.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = "MQTTClient" - s.version = "0.3.5" + s.version = "0.3.6" s.summary = "iOS, OSX and tvOS native ObjectiveC MQTT Framework" s.homepage = "https://github.com/ckrey/MQTT-Client-Framework" s.license = { :type => "MIT", :file => "LICENSE" } s.author = { "Christoph Krey" => "krey.christoph@gmail.com" } - s.source = { :git => "https://github.com/ckrey/MQTT-Client-Framework.git", :tag => "0.3.5" } + s.source = { :git => "https://github.com/ckrey/MQTT-Client-Framework.git", :tag => "0.3.6" } s.source_files = "MQTTClient/MQTTClient", "MQTTClient/MQTTClient/**/*.{h,m}" s.requires_arc = true diff --git a/MQTTClient/MQTTClient/MQTTEncoder.h b/MQTTClient/MQTTClient/MQTTEncoder.h index a8303ca9..1a88a05e 100644 --- a/MQTTClient/MQTTClient/MQTTEncoder.h +++ b/MQTTClient/MQTTClient/MQTTEncoder.h @@ -7,15 +7,15 @@ // based on // // 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 // which accompanies this distribution, and is available at // http://www.eclipse.org/legal/epl-v10.html -// +// // Contributors: // Kyle Roche - initial API and implementation and/or initial documentation -// +// #import #import "MQTTMessage.h" @@ -65,7 +65,7 @@ typedef enum { - (void)close; - (MQTTEncoderStatus)status; - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode; -- (void)encodeMessage:(MQTTMessage*)msg; +- (BOOL)encodeMessage:(MQTTMessage*)msg; @end diff --git a/MQTTClient/MQTTClient/MQTTEncoder.m b/MQTTClient/MQTTClient/MQTTEncoder.m index 0ce08421..80a4580e 100644 --- a/MQTTClient/MQTTClient/MQTTEncoder.m +++ b/MQTTClient/MQTTClient/MQTTEncoder.m @@ -7,15 +7,15 @@ // based on // // 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 // which accompanies this distribution, and is available at // http://www.eclipse.org/legal/epl-v10.html -// +// // Contributors: // Kyle Roche - initial API and implementation and/or initial documentation -// +// #import "MQTTEncoder.h" @@ -78,17 +78,17 @@ - (BOOL)applySSLSecurityPolicy:(NSStream *)writeStream withEvent:(NSStreamEvent) if(!self.securityPolicy){ return YES; } - + // apply the policy only once. if(self.securityPolicyAlreadyApplied){ - return YES; + return YES; } - + SecTrustRef serverTrust = (__bridge SecTrustRef) [writeStream propertyForKey: (__bridge NSString *)kCFStreamPropertySSLPeerTrust]; if(!serverTrust){ return NO; } - + BOOL isValid = [self.securityPolicy evaluateServerTrust:serverTrust forDomain:self.securityDomain]; self.securityPolicyAlreadyApplied = isValid; return isValid; @@ -110,10 +110,10 @@ - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode { self.status = MQTTEncoderStatusError; NSError * sslError = [NSError errorWithDomain:@"MQTT" code:errSSLXCertChainInvalid - userInfo:@{NSLocalizedDescriptionKey : @"Unable to apply security policy, the SSL connection is insecure!"}]; + userInfo:@{NSLocalizedDescriptionKey : @"Unable to apply security policy, the SSL connection is insecure!"}]; [self.delegate encoder:self handleEvent:MQTTEncoderEventErrorOccurred error:sslError]; } - + if (self.status == MQTTEncoderStatusInitializing) { self.status = MQTTEncoderStatusReady; [self.delegate encoder:self handleEvent:MQTTEncoderEventReady error:nil]; @@ -159,66 +159,69 @@ - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode { } } -- (void)encodeMessage:(MQTTMessage*)msg { - UInt8 header; - NSInteger n, length; - - if (self.status != MQTTEncoderStatusReady) { - if (DEBUGENC) NSLog(@"%@ not status ready %d", self, self.status); - return; - } - - assert (self.buffer == NULL); - assert (self.byteIndex == 0); - - self.buffer = [[NSMutableData alloc] init]; - - // encode fixed header - header = ([msg type] & 0x0f) << 4; - if (msg.dupFlag) { - header |= 0x08; - } - header |= ([msg qos] & 0x03) << 1; - if ([msg retainFlag]) { - header |= 0x01; - } - [self.buffer appendBytes:&header length:1]; - - // encode remaining length - length = [[msg data] length]; - do { - UInt8 digit = length % 128; - length /= 128; - if (length > 0) { - digit |= 0x80; +- (BOOL)encodeMessage:(MQTTMessage*)msg { + @synchronized(self) { + UInt8 header; + NSInteger n, length; + + if (self.status != MQTTEncoderStatusReady) { + if (DEBUGENC) NSLog(@"%@ not status ready %d", self, self.status); + return FALSE; } - [self.buffer appendBytes:&digit length:1]; - } - while (length > 0); - - - // encode message data - if ([msg data] != NULL) { - [self.buffer appendData:[msg data]]; - } - - if (DEBUGENC) NSLog(@"%@ buffer to write (%lu)=%@...", self, (unsigned long)self.buffer.length, - [self.buffer subdataWithRange:NSMakeRange(0, MIN(16, self.buffer.length))]); - - [self.delegate encoder:self sending:msg.type qos:msg.qos retained:msg.retainFlag duped:msg.dupFlag mid:msg.mid data:self.buffer]; - - n = [self.stream write:[self.buffer bytes] maxLength:[self.buffer length]]; - if (n == -1) { - self.status = MQTTEncoderStatusError; - [self.delegate encoder:self handleEvent:MQTTEncoderEventErrorOccurred error:self.stream.streamError]; - } - else if (n < [self.buffer length]) { - self.byteIndex += n; - self.status = MQTTEncoderStatusSending; - } - else { - self.buffer = NULL; - // XXX [delegate encoder:self handleEvent:MQTTEncoderEventReady]; + + assert (self.buffer == NULL); + assert (self.byteIndex == 0); + + self.buffer = [[NSMutableData alloc] init]; + + // encode fixed header + header = ([msg type] & 0x0f) << 4; + if (msg.dupFlag) { + header |= 0x08; + } + header |= ([msg qos] & 0x03) << 1; + if ([msg retainFlag]) { + header |= 0x01; + } + [self.buffer appendBytes:&header length:1]; + + // encode remaining length + length = [[msg data] length]; + do { + UInt8 digit = length % 128; + length /= 128; + if (length > 0) { + digit |= 0x80; + } + [self.buffer appendBytes:&digit length:1]; + } + while (length > 0); + + + // encode message data + if ([msg data] != NULL) { + [self.buffer appendData:[msg data]]; + } + + if (DEBUGENC) NSLog(@"%@ buffer to write (%lu)=%@...", self, (unsigned long)self.buffer.length, + [self.buffer subdataWithRange:NSMakeRange(0, MIN(16, self.buffer.length))]); + + [self.delegate encoder:self sending:msg.type qos:msg.qos retained:msg.retainFlag duped:msg.dupFlag mid:msg.mid data:self.buffer]; + + n = [self.stream write:[self.buffer bytes] maxLength:[self.buffer length]]; + if (n == -1) { + self.status = MQTTEncoderStatusError; + [self.delegate encoder:self handleEvent:MQTTEncoderEventErrorOccurred error:self.stream.streamError]; + } + else if (n < [self.buffer length]) { + self.byteIndex += n; + self.status = MQTTEncoderStatusSending; + } + else { + self.buffer = NULL; + // XXX [delegate encoder:self handleEvent:MQTTEncoderEventReady]; + } + return TRUE; } } diff --git a/MQTTClient/MQTTClient/MQTTSession.m b/MQTTClient/MQTTClient/MQTTSession.m index daa0b855..daa7d753 100644 --- a/MQTTClient/MQTTClient/MQTTSession.m +++ b/MQTTClient/MQTTClient/MQTTSession.m @@ -577,8 +577,8 @@ - (UInt16)subscribeToTopic:(NSString *)topic //NSAssert(qosLevel >= 0 && qosLevel <= 2, @"qosLevel must be 0, 1, or 2"); UInt16 mid = [self nextMsgId]; - [self send:[MQTTMessage subscribeMessageWithMessageId:mid - topics:topic ? @{topic: @(qosLevel)} : @{}]]; + (void)[self.encoder encodeMessage:[MQTTMessage subscribeMessageWithMessageId:mid + topics:topic ? @{topic: @(qosLevel)} : @{}]]; return mid; } @@ -615,8 +615,8 @@ - (UInt16)subscribeToTopics:(NSDictionary *)topics //} UInt16 mid = [self nextMsgId]; - [self send:[MQTTMessage subscribeMessageWithMessageId:mid - topics:topics]]; + (void)[self.encoder encodeMessage:[MQTTMessage subscribeMessageWithMessageId:mid + topics:topics]]; return mid; } @@ -644,8 +644,8 @@ - (UInt16)unsubscribeTopic:(NSString*)theTopic { if (DEBUGSESS) NSLog(@"%@ unsubscribeTopic:%@", self, theTopic); UInt16 mid = [self nextMsgId]; - [self send:[MQTTMessage unsubscribeMessageWithMessageId:mid - topics:theTopic ? @[theTopic] : @[]]]; + (void)[self.encoder encodeMessage:[MQTTMessage unsubscribeMessageWithMessageId:mid + topics:theTopic ? @[theTopic] : @[]]]; return mid; } @@ -673,8 +673,8 @@ - (UInt16)unsubscribeTopics:(NSArray *)theTopics { if (DEBUGSESS) NSLog(@"%@ unsubscribeTopics:%@", self, theTopics); UInt16 mid = [self nextMsgId]; - [self send:[MQTTMessage unsubscribeMessageWithMessageId:mid - topics:theTopics]]; + (void)[self.encoder encodeMessage:[MQTTMessage unsubscribeMessageWithMessageId:mid + topics:theTopics]]; return mid; } @@ -710,10 +710,6 @@ - (UInt16)publishData:(NSData*)data retainFlag, (long)qos); -// if (!data) { -// data = [[NSData alloc] init]; -// } - //NSAssert(qos >= 0 && qos <= 2, @"qos must be 0, 1, or 2"); UInt16 msgId = 0; @@ -741,13 +737,13 @@ - (UInt16)publishData:(NSData*)data } else { [self tell]; if ([self.persistence windowSize:self.clientId] <= self.persistence.maxWindowSize) { - if ([self send:msg]) { + if ([self.encoder encodeMessage:msg]) { flow.deadline = [NSDate dateWithTimeIntervalSinceNow:DUPTIMEOUT]; } } } } else { - [self send:msg]; + (void)[self.encoder encodeMessage:msg]; } return msgId; @@ -825,7 +821,7 @@ - (void)close if (self.status == MQTTSessionStatusConnected) { if (DEBUGSESS) NSLog(@"%@ disconnecting", self); self.status = MQTTSessionStatusDisconnecting; - [self send:[MQTTMessage disconnectMessage]]; + (void)[self.encoder encodeMessage:[MQTTMessage disconnectMessage]]; } else { [self closeInternal]; } @@ -891,7 +887,7 @@ - (void)keepAlive:(NSTimer *)timer if (DEBUGSESS) NSLog(@"%@ keepAlive %@ @%.0f", self, self.clientId, [[NSDate date] timeIntervalSince1970]); if ([self.encoder status] == MQTTEncoderStatusReady) { MQTTMessage *msg = [MQTTMessage pingreqMessage]; - [self.encoder encodeMessage:msg]; + (void)[self.encoder encodeMessage:msg]; } } @@ -926,7 +922,7 @@ - (void)checkTxFlows { msgId:[flow.messageId intValue] retainFlag:[flow.retainedFlag boolValue] dupFlag:NO]; - [self send:message]; + (void)[self.encoder encodeMessage:message]; flow.commandType = @(MQTTPublish); flow.deadline = [NSDate dateWithTimeIntervalSinceNow:DUPTIMEOUT]; windowSize++; @@ -939,12 +935,12 @@ - (void)checkTxFlows { msgId:[flow.messageId intValue] retainFlag:[flow.retainedFlag boolValue] dupFlag:YES]; - [self send:message]; + (void)[self.encoder encodeMessage:message]; flow.deadline = [NSDate dateWithTimeIntervalSinceNow:DUPTIMEOUT]; break; case MQTTPubrel: message = [MQTTMessage pubrelMessageWithMessageId:[flow.messageId intValue]]; - [self send:message]; + (void)[self.encoder encodeMessage:message]; flow.deadline = [NSDate dateWithTimeIntervalSinceNow:DUPTIMEOUT]; break; default: @@ -970,19 +966,19 @@ - (void)encoder:(MQTTEncoder*)sender handleEvent:(MQTTEncoderEvent)eventCode err switch (self.status) { case MQTTSessionStatusCreated: if (!self.connectMessage) { - [sender encodeMessage:[MQTTMessage connectMessageWithClientId:self.clientId - userName:self.userName - password:self.password - keepAlive:self.keepAliveInterval - cleanSession:self.cleanSessionFlag - will:self.willFlag - willTopic:self.willTopic - willMsg:self.willMsg - willQoS:self.willQoS - willRetain:self.willRetainFlag - protocolLevel:self.protocolLevel]]; + (void)[sender encodeMessage:[MQTTMessage connectMessageWithClientId:self.clientId + userName:self.userName + password:self.password + keepAlive:self.keepAliveInterval + cleanSession:self.cleanSessionFlag + will:self.willFlag + willTopic:self.willTopic + willMsg:self.willMsg + willQoS:self.willQoS + willRetain:self.willRetainFlag + protocolLevel:self.protocolLevel]]; } else { - [sender encodeMessage:self.connectMessage]; + (void)[sender encodeMessage:self.connectMessage]; } self.status = MQTTSessionStatusConnecting; break; @@ -1042,141 +1038,141 @@ - (void)decoder:(MQTTDecoder*)sender handleEvent:(MQTTDecoderEvent)eventCode err - (void)decoder:(MQTTDecoder*)sender newMessage:(MQTTMessage*)msg { @synchronized(sender) { - if ([self.delegate respondsToSelector:@selector(received:type:qos:retained:duped:mid:data:)]) { - [self.delegate received:self - type:msg.type - qos:msg.qos - retained:msg.retainFlag - duped:msg.dupFlag - mid:0 - data:msg.data]; - } - if ([self.delegate respondsToSelector:@selector(ignoreReceived:type:qos:retained:duped:mid:data:)]) { - if ([self.delegate ignoreReceived:self - type:msg.type - qos:msg.qos - retained:msg.retainFlag - duped:msg.dupFlag - mid:0 - data:msg.data]) { - return; + if ([self.delegate respondsToSelector:@selector(received:type:qos:retained:duped:mid:data:)]) { + [self.delegate received:self + type:msg.type + qos:msg.qos + retained:msg.retainFlag + duped:msg.dupFlag + mid:0 + data:msg.data]; } - } - switch (self.status) { - case MQTTSessionStatusConnecting: - switch ([msg type]) { - case MQTTConnack: - if ([[msg data] length] != 2) { - [self protocolError:[NSError errorWithDomain:@"MQTT" - code:-2 - userInfo:@{NSLocalizedDescriptionKey : @"MQTT protocol CONNACK expected"}]]; - } - else { - const UInt8 *bytes = [[msg data] bytes]; - if (bytes[1] == 0) { - self.status = MQTTSessionStatusConnected; - - self.checkDupTimer = [NSTimer timerWithTimeInterval:DUPLOOP - target:self - selector:@selector(checkDup:) - userInfo:nil - repeats:YES]; - [self.runLoop addTimer:self.checkDupTimer forMode:self.runLoopMode]; - [self checkDup:self.checkDupTimer]; - - self.keepAliveTimer = [NSTimer timerWithTimeInterval:self.keepAliveInterval - target:self - selector:@selector(keepAlive:) - userInfo:nil - repeats:YES]; - [self.runLoop addTimer:self.keepAliveTimer forMode:self.runLoopMode]; - - if ([self.delegate respondsToSelector:@selector(handleEvent:event:error:)]) { - [self.delegate handleEvent:self event:MQTTSessionEventConnected error:nil]; - } - if ([self.delegate respondsToSelector:@selector(connected:)]) { - [self.delegate connected:self]; - } - if ([self.delegate respondsToSelector:@selector(connected:sessionPresent:)]) { - [self.delegate connected:self sessionPresent:((bytes[0] & 0x01) == 0x01)]; - } - - if(self.connectionHandler){ - self.connectionHandler(MQTTSessionEventConnected); - } - - self.synchronConnect = FALSE; - } else { - NSString *errorDescription; - switch (bytes[1]) { - case 1: - errorDescription = @"MQTT CONNACK: unacceptable protocol version"; - break; - case 2: - errorDescription = @"MQTT CONNACK: identifier rejected"; - break; - case 3: - errorDescription = @"MQTT CONNACK: server unavailable"; - break; - case 4: - errorDescription = @"MQTT CONNACK: bad user name or password"; - break; - case 5: - errorDescription = @"MQTT CONNACK: not authorized"; - break; - default: - errorDescription = @"MQTT CONNACK: reserved for future use"; - break; - } - - NSError *error = [NSError errorWithDomain:@"MQTT" - code:bytes[1] - userInfo:@{NSLocalizedDescriptionKey : errorDescription}]; - [self error:MQTTSessionEventConnectionRefused error:error]; - if ([self.delegate respondsToSelector:@selector(connectionRefused:error:)]) { - [self.delegate connectionRefused:self error:error]; + if ([self.delegate respondsToSelector:@selector(ignoreReceived:type:qos:retained:duped:mid:data:)]) { + if ([self.delegate ignoreReceived:self + type:msg.type + qos:msg.qos + retained:msg.retainFlag + duped:msg.dupFlag + mid:0 + data:msg.data]) { + return; + } + } + switch (self.status) { + case MQTTSessionStatusConnecting: + switch ([msg type]) { + case MQTTConnack: + if ([[msg data] length] != 2) { + [self protocolError:[NSError errorWithDomain:@"MQTT" + code:-2 + userInfo:@{NSLocalizedDescriptionKey : @"MQTT protocol CONNACK expected"}]]; + } + else { + const UInt8 *bytes = [[msg data] bytes]; + if (bytes[1] == 0) { + self.status = MQTTSessionStatusConnected; + + self.checkDupTimer = [NSTimer timerWithTimeInterval:DUPLOOP + target:self + selector:@selector(checkDup:) + userInfo:nil + repeats:YES]; + [self.runLoop addTimer:self.checkDupTimer forMode:self.runLoopMode]; + [self checkDup:self.checkDupTimer]; + + self.keepAliveTimer = [NSTimer timerWithTimeInterval:self.keepAliveInterval + target:self + selector:@selector(keepAlive:) + userInfo:nil + repeats:YES]; + [self.runLoop addTimer:self.keepAliveTimer forMode:self.runLoopMode]; + + if ([self.delegate respondsToSelector:@selector(handleEvent:event:error:)]) { + [self.delegate handleEvent:self event:MQTTSessionEventConnected error:nil]; + } + if ([self.delegate respondsToSelector:@selector(connected:)]) { + [self.delegate connected:self]; + } + if ([self.delegate respondsToSelector:@selector(connected:sessionPresent:)]) { + [self.delegate connected:self sessionPresent:((bytes[0] & 0x01) == 0x01)]; + } + + if(self.connectionHandler){ + self.connectionHandler(MQTTSessionEventConnected); + } + + self.synchronConnect = FALSE; + } else { + NSString *errorDescription; + switch (bytes[1]) { + case 1: + errorDescription = @"MQTT CONNACK: unacceptable protocol version"; + break; + case 2: + errorDescription = @"MQTT CONNACK: identifier rejected"; + break; + case 3: + errorDescription = @"MQTT CONNACK: server unavailable"; + break; + case 4: + errorDescription = @"MQTT CONNACK: bad user name or password"; + break; + case 5: + errorDescription = @"MQTT CONNACK: not authorized"; + break; + default: + errorDescription = @"MQTT CONNACK: reserved for future use"; + break; + } + + NSError *error = [NSError errorWithDomain:@"MQTT" + code:bytes[1] + userInfo:@{NSLocalizedDescriptionKey : errorDescription}]; + [self error:MQTTSessionEventConnectionRefused error:error]; + if ([self.delegate respondsToSelector:@selector(connectionRefused:error:)]) { + [self.delegate connectionRefused:self error:error]; + } + } - } - } - break; - default: - [self protocolError:[NSError errorWithDomain:@"MQTT" - code:-1 - userInfo:@{NSLocalizedDescriptionKey : @"MQTT protocol no CONNACK"}]]; - break; - } - break; - case MQTTSessionStatusConnected: - switch ([msg type]) { - case MQTTPublish: - [self handlePublish:msg]; - break; - case MQTTPuback: - [self handlePuback:msg]; - break; - case MQTTPubrec: - [self handlePubrec:msg]; - break; - case MQTTPubrel: - [self handlePubrel:msg]; - break; - case MQTTPubcomp: - [self handlePubcomp:msg]; - break; - case MQTTSuback: - [self handleSuback:msg]; - break; - case MQTTUnsuback: - [self handleUnsuback:msg]; - break; - default: - break; - } - break; - default: - break; - } + break; + default: + [self protocolError:[NSError errorWithDomain:@"MQTT" + code:-1 + userInfo:@{NSLocalizedDescriptionKey : @"MQTT protocol no CONNACK"}]]; + break; + } + break; + case MQTTSessionStatusConnected: + switch ([msg type]) { + case MQTTPublish: + [self handlePublish:msg]; + break; + case MQTTPuback: + [self handlePuback:msg]; + break; + case MQTTPubrec: + [self handlePubrec:msg]; + break; + case MQTTPubrel: + [self handlePubrel:msg]; + break; + case MQTTPubcomp: + [self handlePubcomp:msg]; + break; + case MQTTSuback: + [self handleSuback:msg]; + break; + case MQTTUnsuback: + [self handleUnsuback:msg]; + break; + default: + break; + } + break; + default: + break; + } } } @@ -1245,7 +1241,7 @@ - (void)handlePublish:(MQTTMessage*)msg self.messageHandler(data, topic); } if (processed) { - [self send:[MQTTMessage pubackMessageWithMessageId:msgId]]; + (void)[self.encoder encodeMessage:[MQTTMessage pubackMessageWithMessageId:msgId]]; } return; } else { @@ -1259,7 +1255,7 @@ - (void)handlePublish:(MQTTMessage*)msg if (DEBUGSESS) NSLog(@"%@ dropping incoming messages", self); } else { [self tell]; - [self send:[MQTTMessage pubrecMessageWithMessageId:msgId]]; + (void)[self.encoder encodeMessage:[MQTTMessage pubrecMessageWithMessageId:msgId]]; } } } @@ -1344,7 +1340,7 @@ - (void)handlePubrec:(MQTTMessage*)msg [self.persistence sync]; } } - [self send:pubrelmsg]; + (void)[self.encoder encodeMessage:pubrelmsg]; } } @@ -1383,7 +1379,7 @@ - (void)handlePubrel:(MQTTMessage*)msg [self.persistence deleteFlow:flow]; [self.persistence sync]; [self tell]; - [self send:[MQTTMessage pubcompMessageWithMessageId:messageId]]; + (void)[self.encoder encodeMessage:[MQTTMessage pubcompMessageWithMessageId:messageId]]; } } } @@ -1443,22 +1439,16 @@ - (void)error:(MQTTSessionEvent)eventCode error:(NSError *)error { self.synchronDisconnect = FALSE; } -- (BOOL)send:(MQTTMessage*)msg { - if ([self.encoder status] == MQTTEncoderStatusReady) { - [self.encoder encodeMessage:msg]; - return TRUE; - } - return FALSE; -} - - (UInt16)nextMsgId { - self.txMsgId++; - while (self.txMsgId == 0 || [self.persistence flowforClientId:self.clientId - incomingFlag:NO - messageId:self.txMsgId] != nil) { + @synchronized(self) { self.txMsgId++; + while (self.txMsgId == 0 || [self.persistence flowforClientId:self.clientId + incomingFlag:NO + messageId:self.txMsgId] != nil) { + self.txMsgId++; + } + return self.txMsgId; } - return self.txMsgId; } - (void)tell { diff --git a/MQTTClient/dist/MQTTClient.framework/Versions/A/Headers/MQTTEncoder.h b/MQTTClient/dist/MQTTClient.framework/Versions/A/Headers/MQTTEncoder.h index a8303ca9..1a88a05e 100644 --- a/MQTTClient/dist/MQTTClient.framework/Versions/A/Headers/MQTTEncoder.h +++ b/MQTTClient/dist/MQTTClient.framework/Versions/A/Headers/MQTTEncoder.h @@ -7,15 +7,15 @@ // based on // // 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 // which accompanies this distribution, and is available at // http://www.eclipse.org/legal/epl-v10.html -// +// // Contributors: // Kyle Roche - initial API and implementation and/or initial documentation -// +// #import #import "MQTTMessage.h" @@ -65,7 +65,7 @@ typedef enum { - (void)close; - (MQTTEncoderStatus)status; - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode; -- (void)encodeMessage:(MQTTMessage*)msg; +- (BOOL)encodeMessage:(MQTTMessage*)msg; @end diff --git a/MQTTClient/dist/MQTTClient.framework/Versions/A/MQTTClient b/MQTTClient/dist/MQTTClient.framework/Versions/A/MQTTClient index 4c65faf8..2a3d1760 100644 Binary files a/MQTTClient/dist/MQTTClient.framework/Versions/A/MQTTClient and b/MQTTClient/dist/MQTTClient.framework/Versions/A/MQTTClient differ