Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #2 from horacex/master

Added MosquittoMessage Class
  • Loading branch information...
commit a075f9c81b1fee270a2c7d9f4ee651d482a6e1da 2 parents 04425ce + b7bcbb9
@njh authored
Showing with 2,367 additions and 2,129 deletions.
  1. +1 −1  Classes/MarquetteViewController.h
  2. +11 −10 Classes/MarquetteViewController.m
  3. +10 −8 Classes/MosquittoClient.h
  4. +40 −19 Classes/MosquittoClient.m
  5. +31 −0 Classes/MosquittoMessage.h
  6. +26 −0 Classes/MosquittoMessage.m
  7. BIN  Default-568h@2x.png
  8. +10 −0 Marquette.xcodeproj/project.pbxproj
  9. +2 −2 libmosquitto/dummypthread.h
  10. +34 −34 libmosquitto/logging_mosq.c
  11. +27 −27 libmosquitto/logging_mosq.h
  12. +35 −35 libmosquitto/memory_mosq.c
  13. +27 −27 libmosquitto/memory_mosq.h
  14. +47 −43 libmosquitto/messages_mosq.c
  15. +27 −27 libmosquitto/messages_mosq.h
  16. +233 −144 libmosquitto/mosquitto.c
  17. +1,137 −1,104 libmosquitto/mosquitto.h
  18. +42 −41 libmosquitto/mosquitto_internal.h
  19. +27 −27 libmosquitto/mqtt3_protocol.h
  20. +118 −102 libmosquitto/net_mosq.c
  21. +29 −29 libmosquitto/net_mosq.h
  22. +42 −42 libmosquitto/read_handle.c
  23. +29 −29 libmosquitto/read_handle.h
  24. +29 −29 libmosquitto/read_handle_client.c
  25. +49 −49 libmosquitto/read_handle_shared.c
  26. +50 −50 libmosquitto/send_client_mosq.c
  27. +45 −45 libmosquitto/send_mosq.c
  28. +27 −27 libmosquitto/send_mosq.h
  29. +32 −32 libmosquitto/thread_mosq.c
  30. +60 −56 libmosquitto/util_mosq.c
  31. +27 −27 libmosquitto/util_mosq.h
  32. +36 −36 libmosquitto/will_mosq.c
  33. +27 −27 libmosquitto/will_mosq.h
View
2  Classes/MarquetteViewController.h
@@ -9,7 +9,7 @@
#import <UIKit/UIKit.h>
#import "MosquittoClient.h"
-@interface MarquetteViewController : UIViewController <MosquittoClientDeligate> {
+@interface MarquetteViewController : UIViewController <MosquittoClientDelegate> {
UISwitch *redLedSwitch;
UISwitch *greenLedSwitch;
View
21 Classes/MarquetteViewController.m
@@ -69,11 +69,11 @@ - (IBAction) redLedSwitchAction:(id)sender {
MosquittoClient *mosq = [app mosquittoClient];
if ([sender isOn]) {
NSLog(@"Red LED On");
- [mosq publishString:@"1" toTopic:@"nanode/red_led" retain:YES];
+ [mosq publishString:@"1" toTopic:@"nanode/red_led" withQos:0 retain:YES];
}
else {
NSLog(@"Red LED Off");
- [mosq publishString:@"0" toTopic:@"nanode/red_led" retain:YES];
+ [mosq publishString:@"0" toTopic:@"nanode/red_led" withQos:0 retain:YES];
}
}
@@ -82,11 +82,11 @@ - (IBAction) greenLedSwitchAction:(id)sender {
MosquittoClient *mosq = [app mosquittoClient];
if ([sender isOn]) {
NSLog(@"Green LED On");
- [mosq publishString:@"1" toTopic:@"nanode/green_led" retain:YES];
+ [mosq publishString:@"1" toTopic:@"nanode/green_led" withQos:0 retain:YES];
}
else {
NSLog(@"Green LED Off");
- [mosq publishString:@"0" toTopic:@"nanode/green_led" retain:YES];
+ [mosq publishString:@"0" toTopic:@"nanode/green_led" withQos:0 retain:YES];
}
}
@@ -111,21 +111,22 @@ - (void) didDisconnect {
[[self connectButton] setTitle:@"Connect" forState:UIControlStateNormal];
}
-- (void) didReceiveMessage: (NSString*)message topic:(NSString*)topic {
- NSLog(@"%@ => %@", topic, message);
+- (void) didReceiveMessage:(MosquittoMessage*) mosq_msg {
+
+ NSLog(@"%@ => %@", mosq_msg.topic, mosq_msg.payload);
UISwitch *sw = nil;
- if ([topic isEqualToString:@"nanode/red_led"]) {
+ if ([mosq_msg.topic isEqualToString:@"nanode/red_led"]) {
sw = redLedSwitch;
- } else if ([topic isEqualToString:@"nanode/green_led"]) {
+ } else if ([mosq_msg.topic isEqualToString:@"nanode/green_led"]) {
sw = greenLedSwitch;
} else {
return;
}
- if ([message isEqualToString:@"1"]) {
+ if ([mosq_msg.payload isEqualToString:@"1"]) {
[sw setOn: YES];
- } else if ([message isEqualToString:@"0"]) {
+ } else if ([mosq_msg.payload isEqualToString:@"0"]) {
[sw setOn: NO];
}
}
View
18 Classes/MosquittoClient.h
@@ -5,15 +5,15 @@
//
#import <Foundation/Foundation.h>
+#import "MosquittoMessage.h"
-@protocol MosquittoClientDeligate
+@protocol MosquittoClientDelegate
- (void) didConnect: (NSUInteger)code;
- (void) didDisconnect;
- (void) didPublish: (NSUInteger)messageId;
-// FIXME: create MosquittoMessage class
-- (void) didReceiveMessage: (NSString*)message topic:(NSString*)topic;
+- (void) didReceiveMessage: (MosquittoMessage*)mosq_msg;
- (void) didSubscribe: (NSUInteger)messageId grantedQos:(NSArray*)qos;
- (void) didUnsubscribe: (NSUInteger)messageId;
@@ -28,8 +28,8 @@
NSString *password;
unsigned short keepAlive;
BOOL cleanSession;
-
- id<MosquittoClientDeligate> delegate;
+
+ id<MosquittoClientDelegate> delegate;
NSTimer *timer;
}
@@ -39,7 +39,7 @@
@property (readwrite,retain) NSString *password;
@property (readwrite,assign) unsigned short keepAlive;
@property (readwrite,assign) BOOL cleanSession;
-@property (readwrite,assign) id<MosquittoClientDeligate> delegate;
+@property (readwrite,assign) id<MosquittoClientDelegate> delegate;
+ (void) initialize;
+ (NSString*) version;
@@ -52,8 +52,10 @@
- (void) reconnect;
- (void) disconnect;
-- (void)publishString: (NSString *)payload toTopic:(NSString *)topic retain:(BOOL)retain;
-//- (void)publishMessage
+- (void)setWill: (NSString *)payload toTopic:(NSString *)willTopic withQos:(NSUInteger)willQos retain:(BOOL)retain;
+- (void)clearWill;
+
+- (void)publishString: (NSString *)payload toTopic:(NSString *)topic withQos:(NSUInteger)qos retain:(BOOL)retain;
- (void)subscribe: (NSString *)topic;
- (void)subscribe: (NSString *)topic withQos:(NSUInteger)qos;
View
59 Classes/MosquittoClient.m
@@ -38,14 +38,16 @@ static void on_publish(struct mosquitto *mosq, void *obj, int message_id)
static void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
+ MosquittoMessage *mosq_msg = [[MosquittoMessage alloc] init];
+ mosq_msg.topic = [NSString stringWithUTF8String: message->topic];
+ mosq_msg.payload = [[[NSString alloc] initWithBytes:message->payload
+ length:message->payloadlen
+ encoding:NSUTF8StringEncoding] autorelease];
MosquittoClient* client = (MosquittoClient*)obj;
- NSString *topic = [NSString stringWithUTF8String: message->topic];
- NSString *payload = [[[NSString alloc] initWithBytes:message->payload
- length:message->payloadlen
- encoding:NSUTF8StringEncoding] autorelease];
-
- // FIXME: create MosquittoMessage class instead
- [[client delegate] didReceiveMessage:payload topic:topic];
+
+ //[[client delegate] didReceiveMessage:payload topic:topic];
+ [[client delegate] didReceiveMessage:mosq_msg];
+ [mosq_msg release];
}
static void on_subscribe(struct mosquitto *mosq, void *obj, int message_id, int qos_count, const int *granted_qos)
@@ -79,8 +81,8 @@ - (MosquittoClient*) initWithClientId: (NSString*) clientId {
[self setHost: nil];
[self setPort: 1883];
[self setKeepAlive: 60];
- [self setCleanSession: YES];
-
+ [self setCleanSession: YES]; //NOTE: this isdisable clean to keep the broker remember this client
+
mosq = mosquitto_new(cstrClientId, cleanSession, self);
mosquitto_connect_callback_set(mosq, on_connect);
mosquitto_disconnect_callback_set(mosq, on_disconnect);
@@ -97,18 +99,18 @@ - (MosquittoClient*) initWithClientId: (NSString*) clientId {
- (void) connect {
const char *cstrHost = [host cStringUsingEncoding:NSASCIIStringEncoding];
const char *cstrUsername = NULL, *cstrPassword = NULL;
-
+
if (username)
cstrUsername = [username cStringUsingEncoding:NSUTF8StringEncoding];
-
+
if (password)
cstrPassword = [password cStringUsingEncoding:NSUTF8StringEncoding];
-
+
// FIXME: check for errors
mosquitto_username_pw_set(mosq, cstrUsername, cstrPassword);
-
+
mosquitto_connect(mosq, cstrHost, port, keepAlive);
-
+
// Setup timer to handle network events
// FIXME: better way to do this - hook into iOS Run Loop select() ?
// or run in seperate thread?
@@ -136,13 +138,32 @@ - (void) loop: (NSTimer *)timer {
mosquitto_loop(mosq, 1, 1);
}
-// FIXME: add QoS parameter?
-- (void)publishString: (NSString *)payload toTopic:(NSString *)topic retain:(BOOL)retain {
+
+- (void)setWill: (NSString *)payload toTopic:(NSString *)willTopic withQos:(NSUInteger)willQos retain:(BOOL)retain;
+{
+ const char* cstrTopic = [willTopic cStringUsingEncoding:NSUTF8StringEncoding];
+ const uint8_t* cstrPayload = (const uint8_t*)[payload cStringUsingEncoding:NSUTF8StringEncoding];
+ size_t cstrlen = [payload lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+ mosquitto_will_set(mosq, cstrTopic, cstrlen, cstrPayload, willQos, retain);
+}
+
+
+- (void)clearWill
+{
+ mosquitto_will_clear(mosq);
+}
+
+
+- (void)publishString: (NSString *)payload toTopic:(NSString *)topic withQos:(NSUInteger)qos retain:(BOOL)retain {
const char* cstrTopic = [topic cStringUsingEncoding:NSUTF8StringEncoding];
const uint8_t* cstrPayload = (const uint8_t*)[payload cStringUsingEncoding:NSUTF8StringEncoding];
- mosquitto_publish(mosq, NULL, cstrTopic, [payload length], cstrPayload, 0, retain);
+ size_t cstrlen = [payload lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+ mosquitto_publish(mosq, NULL, cstrTopic, cstrlen, cstrPayload, qos, retain);
+
}
+
+
- (void)subscribe: (NSString *)topic {
[self subscribe:topic withQos:0];
}
@@ -168,12 +189,12 @@ - (void) dealloc {
mosquitto_destroy(mosq);
mosq = NULL;
}
-
+
if (timer) {
[timer invalidate];
timer = nil;
}
-
+
[super dealloc];
}
View
31 Classes/MosquittoMessage.h
@@ -0,0 +1,31 @@
+//
+// MosquittoMessage.h
+// Marquette
+//
+// Created by horace on 11/10/12.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+@interface MosquittoMessage : NSObject
+{
+ unsigned short mid;
+ NSString *topic;
+ NSString *payload;
+ unsigned short payloadlen;
+ unsigned short qos;
+ BOOL retain;
+}
+
+
+@property (readwrite, assign) unsigned short mid;
+@property (readwrite, retain) NSString *topic;
+@property (readwrite, retain) NSString *payload;
+@property (readwrite, assign) unsigned short payloadlen;
+@property (readwrite, assign) unsigned short qos;
+@property (readwrite, assign) BOOL retain;
+
+-(id)init;
+
+@end
View
26 Classes/MosquittoMessage.m
@@ -0,0 +1,26 @@
+//
+// MosquittoMessage.m
+// Marquette
+//
+// Created by horace on 11/10/12.
+//
+//
+
+#import "MosquittoMessage.h"
+
+@implementation MosquittoMessage
+
+@synthesize mid, topic, payload, payloadlen, qos, retain;
+
+-(id)init
+{
+ self.mid = 0;
+ self.topic = nil;
+ self.payload = nil;
+ self.payloadlen = 0;
+ self.qos = 0;
+ self.retain = FALSE;
+ return self;
+}
+
+@end
View
BIN  Default-568h@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
10 Marquette.xcodeproj/project.pbxproj
@@ -16,6 +16,8 @@
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; };
28D7ACF80DDB3853001CB0EB /* MarquetteViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* MarquetteViewController.m */; };
62F7DB0714C4CCED000EC631 /* getMacAddress.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F7DB0614C4CCED000EC631 /* getMacAddress.m */; };
+ AA3B4C2B164E80760089BCC4 /* MosquittoMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = AA3B4C2A164E80760089BCC4 /* MosquittoMessage.m */; };
+ AA64278B16D8A13A005D7C5F /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AA64278A16D8A13A005D7C5F /* Default-568h@2x.png */; };
AA6B0B2A16481437007DC0D9 /* logging_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = AA6B0B1116481425007DC0D9 /* logging_mosq.c */; };
AA6B0B2B16481437007DC0D9 /* memory_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = AA6B0B1216481425007DC0D9 /* memory_mosq.c */; };
AA6B0B2C16481437007DC0D9 /* messages_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = AA6B0B1316481425007DC0D9 /* messages_mosq.c */; };
@@ -48,6 +50,9 @@
62F7DB0514C4CCED000EC631 /* getMacAddress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = getMacAddress.h; sourceTree = "<group>"; };
62F7DB0614C4CCED000EC631 /* getMacAddress.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = getMacAddress.m; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* Marquette-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Marquette-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
+ AA3B4C29164E80760089BCC4 /* MosquittoMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MosquittoMessage.h; sourceTree = "<group>"; };
+ AA3B4C2A164E80760089BCC4 /* MosquittoMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MosquittoMessage.m; sourceTree = "<group>"; };
+ AA64278A16D8A13A005D7C5F /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
AA6B0B1116481425007DC0D9 /* logging_mosq.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = logging_mosq.c; sourceTree = "<group>"; };
AA6B0B1216481425007DC0D9 /* memory_mosq.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memory_mosq.c; sourceTree = "<group>"; };
AA6B0B1316481425007DC0D9 /* messages_mosq.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = messages_mosq.c; sourceTree = "<group>"; };
@@ -101,6 +106,8 @@
28D7ACF70DDB3853001CB0EB /* MarquetteViewController.m */,
AA6B0B381648147E007DC0D9 /* MosquittoClient.h */,
AA6B0B391648147E007DC0D9 /* MosquittoClient.m */,
+ AA3B4C29164E80760089BCC4 /* MosquittoMessage.h */,
+ AA3B4C2A164E80760089BCC4 /* MosquittoMessage.m */,
);
path = Classes;
sourceTree = "<group>";
@@ -143,6 +150,7 @@
2899E5210DE3E06400AC0155 /* MarquetteViewController.xib */,
28AD733E0D9D9553002E5188 /* MainWindow.xib */,
8D1107310486CEB800E47090 /* Marquette-Info.plist */,
+ AA64278A16D8A13A005D7C5F /* Default-568h@2x.png */,
);
name = Resources;
sourceTree = "<group>";
@@ -244,6 +252,7 @@
files = (
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */,
2899E5220DE3E06400AC0155 /* MarquetteViewController.xib in Resources */,
+ AA64278B16D8A13A005D7C5F /* Default-568h@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -272,6 +281,7 @@
AA6B0B3516481437007DC0D9 /* util_mosq.c in Sources */,
AA6B0B3616481437007DC0D9 /* will_mosq.c in Sources */,
AA6B0B3A1648147E007DC0D9 /* MosquittoClient.m in Sources */,
+ AA3B4C2B164E80760089BCC4 /* MosquittoMessage.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
4 libmosquitto/dummypthread.h
@@ -7,7 +7,7 @@
#define pthread_mutex_init(A, B)
#define pthread_mutex_destroy(A)
-#define pthread_mutex_lock(A)
-#define pthread_mutex_unlock(A)
+#define pthread_mutex_lock(A)
+#define pthread_mutex_unlock(A)
#endif
View
68 libmosquitto/logging_mosq.c
@@ -1,31 +1,31 @@
/*
-Copyright (c) 2009,2010, Roger Light <roger@atchoo.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of mosquitto nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
+ Copyright (c) 2009,2010, Roger Light <roger@atchoo.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of mosquitto nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
@@ -40,10 +40,10 @@ int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt,
va_list va;
char *s;
int len;
-
+
assert(mosq);
assert(fmt);
-
+
pthread_mutex_lock(&mosq->log_callback_mutex);
if(mosq->on_log){
len = strlen(fmt) + 500;
@@ -52,18 +52,18 @@ int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt,
pthread_mutex_unlock(&mosq->log_callback_mutex);
return MOSQ_ERR_NOMEM;
}
-
+
va_start(va, fmt);
vsnprintf(s, len, fmt, va);
va_end(va);
s[len-1] = '\0'; /* Ensure string is null terminated. */
-
- mosq->on_log(mosq, mosq->obj, priority, s);
-
+
+ mosq->on_log(mosq, mosq->userdata, priority, s);
+
_mosquitto_free(s);
}
pthread_mutex_unlock(&mosq->log_callback_mutex);
-
+
return MOSQ_ERR_SUCCESS;
}
View
54 libmosquitto/logging_mosq.h
@@ -1,31 +1,31 @@
/*
-Copyright (c) 2009,2010, Roger Light <roger@atchoo.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of mosquitto nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
+ Copyright (c) 2009,2010, Roger Light <roger@atchoo.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of mosquitto nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
#ifndef _LOGGING_MOSQ_H_
#define _LOGGING_MOSQ_H_
View
70 libmosquitto/memory_mosq.c
@@ -1,31 +1,31 @@
/*
-Copyright (c) 2009,2010, Roger Light <roger@atchoo.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of mosquitto nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
+ Copyright (c) 2009,2010, Roger Light <roger@atchoo.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of mosquitto nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
#include <config.h>
@@ -54,14 +54,14 @@ static unsigned long max_memcount = 0;
void *_mosquitto_calloc(size_t nmemb, size_t size)
{
void *mem = calloc(nmemb, size);
-
+
#ifdef REAL_WITH_MEMORY_TRACKING
memcount += malloc_usable_size(mem);
if(memcount > max_memcount){
max_memcount = memcount;
}
#endif
-
+
return mem;
}
@@ -76,14 +76,14 @@ void _mosquitto_free(void *mem)
void *_mosquitto_malloc(size_t size)
{
void *mem = malloc(size);
-
+
#ifdef REAL_WITH_MEMORY_TRACKING
memcount += malloc_usable_size(mem);
if(memcount > max_memcount){
max_memcount = memcount;
}
#endif
-
+
return mem;
}
@@ -108,28 +108,28 @@ void *_mosquitto_realloc(void *ptr, size_t size)
}
#endif
mem = realloc(ptr, size);
-
+
#ifdef REAL_WITH_MEMORY_TRACKING
memcount += malloc_usable_size(mem);
if(memcount > max_memcount){
max_memcount = memcount;
}
#endif
-
+
return mem;
}
char *_mosquitto_strdup(const char *s)
{
char *str = strdup(s);
-
+
#ifdef REAL_WITH_MEMORY_TRACKING
memcount += malloc_usable_size(str);
if(memcount > max_memcount){
max_memcount = memcount;
}
#endif
-
+
return str;
}
View
54 libmosquitto/memory_mosq.h
@@ -1,31 +1,31 @@
/*
-Copyright (c) 2010, Roger Light <roger@atchoo.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of mosquitto nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
+ Copyright (c) 2010, Roger Light <roger@atchoo.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of mosquitto nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
#ifndef _MEMORY_MOSQ_H_
#define _MEMORY_MOSQ_H_
View
90 libmosquitto/messages_mosq.c
@@ -1,31 +1,31 @@
/*
-Copyright (c) 2010, Roger Light <roger@atchoo.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of mosquitto nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
+ Copyright (c) 2010, Roger Light <roger@atchoo.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of mosquitto nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
#include <assert.h>
#include <stdlib.h>
@@ -40,11 +40,11 @@ POSSIBILITY OF SUCH DAMAGE.
void _mosquitto_message_cleanup(struct mosquitto_message_all **message)
{
struct mosquitto_message_all *msg;
-
+
if(!message || !*message) return;
-
+
msg = *message;
-
+
if(msg->msg.topic) _mosquitto_free(msg->msg.topic);
if(msg->msg.payload) _mosquitto_free(msg->msg.payload);
_mosquitto_free(msg);
@@ -53,9 +53,9 @@ void _mosquitto_message_cleanup(struct mosquitto_message_all **message)
void _mosquitto_message_cleanup_all(struct mosquitto *mosq)
{
struct mosquitto_message_all *tmp;
-
+
assert(mosq);
-
+
while(mosq->messages){
tmp = mosq->messages->next;
_mosquitto_message_cleanup(&mosq->messages);
@@ -66,7 +66,7 @@ void _mosquitto_message_cleanup_all(struct mosquitto *mosq)
int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src)
{
if(!dst || !src) return MOSQ_ERR_INVAL;
-
+
dst->mid = src->mid;
dst->topic = _mosquitto_strdup(src->topic);
if(!dst->topic) return MOSQ_ERR_NOMEM;
@@ -92,7 +92,7 @@ int _mosquitto_message_delete(struct mosquitto *mosq, uint16_t mid, enum mosquit
struct mosquitto_message_all *message;
int rc;
assert(mosq);
-
+
rc = _mosquitto_message_remove(mosq, mid, dir, &message);
if(rc == MOSQ_ERR_SUCCESS){
_mosquitto_message_cleanup(&message);
@@ -103,11 +103,11 @@ int _mosquitto_message_delete(struct mosquitto *mosq, uint16_t mid, enum mosquit
void mosquitto_message_free(struct mosquitto_message **message)
{
struct mosquitto_message *msg;
-
+
if(!message || !*message) return;
-
+
msg = *message;
-
+
if(msg->topic) _mosquitto_free(msg->topic);
if(msg->payload) _mosquitto_free(msg->payload);
_mosquitto_free(msg);
@@ -116,10 +116,11 @@ void mosquitto_message_free(struct mosquitto_message **message)
void _mosquitto_message_queue(struct mosquitto *mosq, struct mosquitto_message_all *message)
{
struct mosquitto_message_all *tail;
-
+
assert(mosq);
assert(message);
-
+
+ mosq->queue_len++;
message->next = NULL;
if(mosq->messages){
tail = mosq->messages;
@@ -137,7 +138,8 @@ void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq)
struct mosquitto_message_all *message;
struct mosquitto_message_all *prev = NULL;
assert(mosq);
-
+
+ mosq->queue_len = 0;
message = mosq->messages;
while(message){
message->timestamp = 0;
@@ -147,6 +149,7 @@ void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq)
}else if(message->msg.qos == 2){
message->state = mosq_ms_wait_pubrec;
}
+ mosq->queue_len++;
}else{
if(prev){
prev->next = message->next;
@@ -168,7 +171,7 @@ int _mosquitto_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquit
struct mosquitto_message_all *cur, *prev = NULL;
assert(mosq);
assert(message);
-
+
cur = mosq->messages;
while(cur){
if(cur->msg.mid == mid && cur->direction == dir){
@@ -178,6 +181,7 @@ int _mosquitto_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquit
mosq->messages = cur->next;
}
*message = cur;
+ mosq->queue_len--;
return MOSQ_ERR_SUCCESS;
}
prev = cur;
@@ -191,7 +195,7 @@ void _mosquitto_message_retry_check(struct mosquitto *mosq)
struct mosquitto_message_all *message;
time_t now = time(NULL);
assert(mosq);
-
+
message = mosq->messages;
while(message){
if(message->timestamp + mosq->message_retry < now){
@@ -230,7 +234,7 @@ int _mosquitto_message_update(struct mosquitto *mosq, uint16_t mid, enum mosquit
{
struct mosquitto_message_all *message;
assert(mosq);
-
+
message = mosq->messages;
while(message){
if(message->msg.mid == mid && message->direction == dir){
View
54 libmosquitto/messages_mosq.h
@@ -1,31 +1,31 @@
/*
-Copyright (c) 2010, Roger Light <roger@atchoo.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of mosquitto nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
+ Copyright (c) 2010, Roger Light <roger@atchoo.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of mosquitto nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
#ifndef _MESSAGES_MOSQ_H_
#define _MESSAGES_MOSQ_H_
View
377 libmosquitto/mosquitto.c
@@ -1,34 +1,35 @@
/*
-Copyright (c) 2010-2012 Roger Light <roger@atchoo.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of mosquitto nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
+ Copyright (c) 2010-2012 Roger Light <roger@atchoo.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of mosquitto nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
#include <assert.h>
#include <errno.h>
+#include <signal.h>
#include <stdio.h>
#include <string.h>
#ifndef WIN32
@@ -73,40 +74,44 @@ int mosquitto_lib_init(void)
srand(GetTickCount());
#else
struct timeval tv;
-
+
gettimeofday(&tv, NULL);
srand(tv.tv_sec*1000 + tv.tv_usec/1000);
#endif
-
+
_mosquitto_net_init();
-
+
return MOSQ_ERR_SUCCESS;
}
int mosquitto_lib_cleanup(void)
{
_mosquitto_net_cleanup();
-
+
return MOSQ_ERR_SUCCESS;
}
-struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj)
+struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *userdata)
{
struct mosquitto *mosq = NULL;
int rc;
-
+
if(clean_session == false && id == NULL){
errno = EINVAL;
return NULL;
}
-
+
+#ifndef WIN32
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
mosq = (struct mosquitto *)_mosquitto_calloc(1, sizeof(struct mosquitto));
if(mosq){
mosq->sock = INVALID_SOCKET;
#ifdef WITH_THREADING
mosq->thread_id = pthread_self();
#endif
- rc = mosquitto_reinitialise(mosq, id, clean_session, obj);
+ rc = mosquitto_reinitialise(mosq, id, clean_session, userdata);
if(rc){
mosquitto_destroy(mosq);
if(rc == MOSQ_ERR_INVAL){
@@ -122,23 +127,23 @@ struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj)
return mosq;
}
-int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj)
+int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *userdata)
{
int i;
-
+
if(!mosq) return MOSQ_ERR_INVAL;
-
+
if(clean_session == false && id == NULL){
return MOSQ_ERR_INVAL;
}
-
+
_mosquitto_destroy(mosq);
memset(mosq, 0, sizeof(struct mosquitto));
-
- if(obj){
- mosq->obj = obj;
+
+ if(userdata){
+ mosq->userdata = userdata;
}else{
- mosq->obj = mosq;
+ mosq->userdata = mosq;
}
mosq->sock = INVALID_SOCKET;
mosq->keepalive = 60;
@@ -160,7 +165,7 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_se
mosq->id[2] = 's';
mosq->id[3] = 'q';
mosq->id[4] = '/';
-
+
for(i=5; i<23; i++){
mosq->id[i] = (rand()%73)+48;
}
@@ -184,8 +189,10 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_se
mosq->host = NULL;
mosq->port = 1883;
mosq->in_callback = false;
+ mosq->queue_len = 0;
#ifdef WITH_TLS
mosq->ssl = NULL;
+ mosq->tls_cert_reqs = SSL_VERIFY_PEER;
#endif
#ifdef WITH_THREADING
pthread_mutex_init(&mosq->callback_mutex, NULL);
@@ -196,7 +203,7 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_se
pthread_mutex_init(&mosq->msgtime_mutex, NULL);
mosq->thread_id = pthread_self();
#endif
-
+
return MOSQ_ERR_SUCCESS;
}
@@ -215,7 +222,7 @@ int mosquitto_will_clear(struct mosquitto *mosq)
int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password)
{
if(!mosq) return MOSQ_ERR_INVAL;
-
+
if(username){
mosq->username = _mosquitto_strdup(username);
if(!mosq->username) return MOSQ_ERR_NOMEM;
@@ -249,13 +256,13 @@ void _mosquitto_destroy(struct mosquitto *mosq)
{
struct _mosquitto_packet *packet;
if(!mosq) return;
-
+
#ifdef WITH_THREADING
if(!pthread_equal(mosq->thread_id, pthread_self())){
pthread_cancel(mosq->thread_id);
pthread_join(mosq->thread_id, NULL);
}
-
+
if(mosq->id){
/* If mosq->id is not NULL then the client has already been initialised
* and so the mutexes need destroying. If mosq->id is NULL, the mutexes
@@ -290,13 +297,13 @@ void _mosquitto_destroy(struct mosquitto *mosq)
if(mosq->tls_psk) _mosquitto_free(mosq->tls_psk);
if(mosq->tls_psk_identity) _mosquitto_free(mosq->tls_psk_identity);
#endif
-
+
if(mosq->address) _mosquitto_free(mosq->address);
if(mosq->id) _mosquitto_free(mosq->id);
if(mosq->username) _mosquitto_free(mosq->username);
if(mosq->password) _mosquitto_free(mosq->password);
if(mosq->host) _mosquitto_free(mosq->host);
-
+
/* Out packet cleanup */
if(mosq->out_packet && !mosq->current_out_packet){
mosq->current_out_packet = mosq->out_packet;
@@ -309,11 +316,11 @@ void _mosquitto_destroy(struct mosquitto *mosq)
if(mosq->out_packet){
mosq->out_packet = mosq->out_packet->next;
}
-
+
_mosquitto_packet_cleanup(packet);
_mosquitto_free(packet);
}
-
+
_mosquitto_packet_cleanup(&mosq->in_packet);
}
@@ -334,7 +341,7 @@ int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int ke
int rc;
rc = mosquitto_connect_async(mosq, host, port, keepalive);
if(rc) return rc;
-
+
return mosquitto_reconnect(mosq);
}
@@ -342,17 +349,17 @@ int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port,
{
if(!mosq) return MOSQ_ERR_INVAL;
if(!host || port <= 0) return MOSQ_ERR_INVAL;
-
+
if(mosq->host) _mosquitto_free(mosq->host);
mosq->host = _mosquitto_strdup(host);
if(!mosq->host) return MOSQ_ERR_NOMEM;
mosq->port = port;
-
+
mosq->keepalive = keepalive;
pthread_mutex_lock(&mosq->state_mutex);
mosq->state = mosq_cs_connect_async;
pthread_mutex_unlock(&mosq->state_mutex);
-
+
return MOSQ_ERR_SUCCESS;
}
@@ -362,28 +369,28 @@ int mosquitto_reconnect(struct mosquitto *mosq)
struct _mosquitto_packet *packet;
if(!mosq) return MOSQ_ERR_INVAL;
if(!mosq->host || mosq->port <= 0) return MOSQ_ERR_INVAL;
-
+
pthread_mutex_lock(&mosq->state_mutex);
mosq->state = mosq_cs_new;
pthread_mutex_unlock(&mosq->state_mutex);
-
+
pthread_mutex_lock(&mosq->msgtime_mutex);
mosq->last_msg_in = time(NULL);
mosq->last_msg_out = time(NULL);
pthread_mutex_unlock(&mosq->msgtime_mutex);
-
+
mosq->ping_t = 0;
-
+
_mosquitto_packet_cleanup(&mosq->in_packet);
-
+
pthread_mutex_lock(&mosq->current_out_packet_mutex);
pthread_mutex_lock(&mosq->out_packet_mutex);
-
+
if(mosq->out_packet && !mosq->current_out_packet){
mosq->current_out_packet = mosq->out_packet;
mosq->out_packet = mosq->out_packet->next;
}
-
+
while(mosq->current_out_packet){
packet = mosq->current_out_packet;
/* Free data and reset values */
@@ -391,20 +398,20 @@ int mosquitto_reconnect(struct mosquitto *mosq)
if(mosq->out_packet){
mosq->out_packet = mosq->out_packet->next;
}
-
+
_mosquitto_packet_cleanup(packet);
_mosquitto_free(packet);
}
pthread_mutex_unlock(&mosq->out_packet_mutex);
pthread_mutex_unlock(&mosq->current_out_packet_mutex);
-
+
_mosquitto_messages_reconnect_reset(mosq);
-
+
rc = _mosquitto_socket_connect(mosq, mosq->host, mosq->port);
if(rc){
return rc;
}
-
+
return _mosquitto_send_connect(mosq, mosq->keepalive, mosq->clean_session);
}
@@ -412,11 +419,11 @@ int mosquitto_disconnect(struct mosquitto *mosq)
{
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
-
+
pthread_mutex_lock(&mosq->state_mutex);
mosq->state = mosq_cs_disconnecting;
pthread_mutex_unlock(&mosq->state_mutex);
-
+
return _mosquitto_send_disconnect(mosq);
}
@@ -424,26 +431,26 @@ int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int p
{
struct mosquitto_message_all *message;
uint16_t local_mid;
-
+
if(!mosq || !topic || qos<0 || qos>2) return MOSQ_ERR_INVAL;
if(strlen(topic) == 0) return MOSQ_ERR_INVAL;
if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE;
-
+
if(_mosquitto_topic_wildcard_len_check(topic) != MOSQ_ERR_SUCCESS){
return MOSQ_ERR_INVAL;
}
-
+
local_mid = _mosquitto_mid_generate(mosq);
if(mid){
*mid = local_mid;
}
-
+
if(qos == 0){
return _mosquitto_send_publish(mosq, local_mid, topic, payloadlen, payload, qos, retain, false);
}else{
message = _mosquitto_calloc(1, sizeof(struct mosquitto_message_all));
if(!message) return MOSQ_ERR_NOMEM;
-
+
message->next = NULL;
message->timestamp = time(NULL);
message->direction = mosq_md_out;
@@ -473,7 +480,7 @@ int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int p
message->msg.qos = qos;
message->msg.retain = retain;
message->dup = false;
-
+
_mosquitto_message_queue(mosq, message);
return _mosquitto_send_publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup);
}
@@ -483,7 +490,7 @@ int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int q
{
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
-
+
return _mosquitto_send_subscribe(mosq, mid, false, sub, qos);
}
@@ -491,17 +498,26 @@ int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub)
{
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
-
+
return _mosquitto_send_unsubscribe(mosq, mid, false, sub);
}
int mosquitto_tls_set(struct mosquitto *mosq, const char *cafile, const char *capath, const char *certfile, const char *keyfile, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata))
{
#ifdef WITH_TLS
+ FILE *fptr;
+
if(!mosq || (!cafile && !capath) || (certfile && !keyfile) || (!certfile && keyfile)) return MOSQ_ERR_INVAL;
-
+
if(cafile){
+ fptr = fopen(cafile, "rt");
+ if(fptr){
+ fclose(fptr);
+ }else{
+ return MOSQ_ERR_INVAL;
+ }
mosq->tls_cafile = _mosquitto_strdup(cafile);
+
if(!mosq->tls_cafile){
return MOSQ_ERR_NOMEM;
}
@@ -509,7 +525,7 @@ int mosquitto_tls_set(struct mosquitto *mosq, const char *cafile, const char *ca
_mosquitto_free(mosq->tls_cafile);
mosq->tls_cafile = NULL;
}
-
+
if(capath){
mosq->tls_capath = _mosquitto_strdup(capath);
if(!mosq->tls_capath){
@@ -519,8 +535,22 @@ int mosquitto_tls_set(struct mosquitto *mosq, const char *cafile, const char *ca
_mosquitto_free(mosq->tls_capath);
mosq->tls_capath = NULL;
}
-
+
if(certfile){
+ fptr = fopen(certfile, "rt");
+ if(fptr){
+ fclose(fptr);
+ }else{
+ if(mosq->tls_cafile){
+ _mosquitto_free(mosq->tls_cafile);
+ mosq->tls_cafile = NULL;
+ }
+ if(mosq->tls_capath){
+ _mosquitto_free(mosq->tls_capath);
+ mosq->tls_capath = NULL;
+ }
+ return MOSQ_ERR_INVAL;
+ }
mosq->tls_certfile = _mosquitto_strdup(certfile);
if(!mosq->tls_certfile){
return MOSQ_ERR_NOMEM;
@@ -529,8 +559,26 @@ int mosquitto_tls_set(struct mosquitto *mosq, const char *cafile, const char *ca
if(mosq->tls_certfile) _mosquitto_free(mosq->tls_certfile);
mosq->tls_certfile = NULL;
}
-
+
if(keyfile){
+ fptr = fopen(keyfile, "rt");
+ if(fptr){
+ fclose(fptr);
+ }else{
+ if(mosq->tls_cafile){
+ _mosquitto_free(mosq->tls_cafile);
+ mosq->tls_cafile = NULL;
+ }
+ if(mosq->tls_capath){
+ _mosquitto_free(mosq->tls_capath);
+ mosq->tls_capath = NULL;
+ }
+ if(mosq->tls_certfile){
+ _mosquitto_free(mosq->tls_certfile);
+ mosq->tls_capath = NULL;
+ }
+ return MOSQ_ERR_INVAL;
+ }
mosq->tls_keyfile = _mosquitto_strdup(keyfile);
if(!mosq->tls_keyfile){
return MOSQ_ERR_NOMEM;
@@ -539,14 +587,14 @@ int mosquitto_tls_set(struct mosquitto *mosq, const char *cafile, const char *ca
if(mosq->tls_keyfile) _mosquitto_free(mosq->tls_keyfile);
mosq->tls_keyfile = NULL;
}
-
+
mosq->tls_pw_callback = pw_callback;
-
-
+
+
return MOSQ_ERR_SUCCESS;
#else
return MOSQ_ERR_NOT_SUPPORTED;
-
+
#endif
}
@@ -554,7 +602,7 @@ int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tl
{
#ifdef WITH_TLS
if(!mosq) return MOSQ_ERR_INVAL;
-
+
mosq->tls_cert_reqs = cert_reqs;
if(tls_version){
if(!strcasecmp(tls_version, "tlsv1")){
@@ -573,12 +621,12 @@ int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tl
}else{
mosq->tls_ciphers = NULL;
}
-
-
+
+
return MOSQ_ERR_SUCCESS;
#else
return MOSQ_ERR_NOT_SUPPORTED;
-
+
#endif
}
@@ -587,14 +635,14 @@ int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *i
{
#if defined(WITH_TLS) && defined(WITH_TLS_PSK)
if(!mosq || !psk || !identity) return MOSQ_ERR_INVAL;
-
+
/* Check for hex only digits */
if(strspn(psk, "0123456789abcdefABCDEF") < strlen(psk)){
return MOSQ_ERR_INVAL;
}
mosq->tls_psk = _mosquitto_strdup(psk);
if(!mosq->tls_psk) return MOSQ_ERR_NOMEM;
-
+
mosq->tls_psk_identity = _mosquitto_strdup(identity);
if(!mosq->tls_psk_identity){
_mosquitto_free(mosq->tls_psk);
@@ -606,7 +654,7 @@ int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *i
}else{
mosq->tls_ciphers = NULL;
}
-
+
return MOSQ_ERR_SUCCESS;
#else
return MOSQ_ERR_NOT_SUPPORTED;
@@ -624,10 +672,10 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
fd_set readfds, writefds;
int fdcount;
int rc;
-
+
if(!mosq || max_packets < 1) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
-
+
FD_ZERO(&readfds);
FD_SET(mosq->sock, &readfds);
FD_ZERO(&writefds);
@@ -655,7 +703,7 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
local_timeout.tv_usec = 0;
#endif
}
-
+
#ifdef HAVE_PSELECT
fdcount = pselect(mosq->sock+1, &readfds, &writefds, NULL, &local_timeout, NULL);
#else
@@ -665,43 +713,21 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
#ifdef WIN32
errno = WSAGetLastError();
#endif
- return MOSQ_ERR_ERRNO;
+ if(errno == EINTR){
+ return MOSQ_ERR_SUCCESS;
+ }else{
+ return MOSQ_ERR_ERRNO;
+ }
}else{
if(FD_ISSET(mosq->sock, &readfds)){
rc = mosquitto_loop_read(mosq, max_packets);
- if(rc){
- _mosquitto_socket_close(mosq);
- pthread_mutex_lock(&mosq->state_mutex);
- if(mosq->state == mosq_cs_disconnecting){
- rc = MOSQ_ERR_SUCCESS;
- }
- pthread_mutex_unlock(&mosq->state_mutex);
- pthread_mutex_lock(&mosq->callback_mutex);
- if(mosq->on_disconnect){
- mosq->in_callback = true;
- mosq->on_disconnect(mosq, mosq->obj, rc);
- mosq->in_callback = false;
- }
- pthread_mutex_unlock(&mosq->callback_mutex);
+ if(rc || mosq->sock == INVALID_SOCKET){
return rc;
}
}
if(FD_ISSET(mosq->sock, &writefds)){
rc = mosquitto_loop_write(mosq, max_packets);
- if(rc){
- _mosquitto_socket_close(mosq);
- pthread_mutex_lock(&mosq->state_mutex);
- if(mosq->state == mosq_cs_disconnecting){
- rc = MOSQ_ERR_SUCCESS;
- }
- pthread_mutex_unlock(&mosq->state_mutex);
- pthread_mutex_lock(&mosq->callback_mutex);
- if(mosq->on_disconnect){
- mosq->in_callback = true;
- mosq->on_disconnect(mosq, mosq->obj, rc);
- mosq->in_callback = false;
- }
- pthread_mutex_unlock(&mosq->callback_mutex);
+ if(rc || mosq->sock == INVALID_SOCKET){
return rc;
}
}
@@ -709,14 +735,46 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
return mosquitto_loop_misc(mosq);
}
+int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets)
+{
+ int run = 1;
+ int rc;
+
+ if(!mosq) return MOSQ_ERR_INVAL;
+
+ if(mosq->state == mosq_cs_connect_async){
+ mosquitto_reconnect(mosq);
+ }
+
+ while(run){
+ do{
+ rc = mosquitto_loop(mosq, timeout, max_packets);
+ }while(rc == MOSQ_ERR_SUCCESS);
+ if(errno == EPROTO){
+ return rc;
+ }
+ if(mosq->state == mosq_cs_disconnecting){
+ run = 0;
+ }else{
+#ifdef WIN32
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+ mosquitto_reconnect(mosq);
+ }
+ }
+ return rc;
+}
+
int mosquitto_loop_misc(struct mosquitto *mosq)
{
time_t now = time(NULL);
int rc;
-
+
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
-
+
_mosquitto_check_keepalive(mosq);
if(mosq->last_retry_check+1 < now){
_mosquitto_message_retry_check(mosq);
@@ -737,7 +795,7 @@ int mosquitto_loop_misc(struct mosquitto *mosq)
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_disconnect){
mosq->in_callback = true;
- mosq->on_disconnect(mosq, mosq->obj, rc);
+ mosq->on_disconnect(mosq, mosq->userdata, rc);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
@@ -746,16 +804,42 @@ int mosquitto_loop_misc(struct mosquitto *mosq)
return MOSQ_ERR_SUCCESS;
}
+static int _mosquitto_loop_rc_handle(struct mosquitto *mosq, int rc)
+{
+ if(rc){
+ _mosquitto_socket_close(mosq);
+ pthread_mutex_lock(&mosq->state_mutex);
+ if(mosq->state == mosq_cs_disconnecting){
+ rc = MOSQ_ERR_SUCCESS;
+ }
+ pthread_mutex_unlock(&mosq->state_mutex);
+ pthread_mutex_lock(&mosq->callback_mutex);
+ if(mosq->on_disconnect){
+ mosq->in_callback = true;
+ mosq->on_disconnect(mosq, mosq->userdata, rc);
+ mosq->in_callback = false;
+ }
+ pthread_mutex_unlock(&mosq->callback_mutex);
+ return rc;
+ }
+ return rc;
+}
+
int mosquitto_loop_read(struct mosquitto *mosq, int max_packets)
{
int rc;
int i;
if(max_packets < 1) return MOSQ_ERR_INVAL;
-
+
+ max_packets = mosq->queue_len;
+ if(max_packets < 1) max_packets = 1;
+ /* Queue len here tells us how many messages are awaiting processing and
+ * have QoS > 0. We should try to deal with that many in this loop in order
+ * to keep up. */
for(i=0; i<max_packets; i++){
rc = _mosquitto_packet_read(mosq);
if(rc || errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
- return rc;
+ return _mosquitto_loop_rc_handle(mosq, rc);
}
}
return rc;
@@ -766,11 +850,16 @@ int mosquitto_loop_write(struct mosquitto *mosq, int max_packets)
int rc;
int i;
if(max_packets < 1) return MOSQ_ERR_INVAL;
-
+
+ max_packets = mosq->queue_len;
+ if(max_packets < 1) max_packets = 1;
+ /* Queue len here tells us how many messages are awaiting processing and
+ * have QoS > 0. We should try to deal with that many in this loop in order
+ * to keep up. */
for(i=0; i<max_packets; i++){
rc = _mosquitto_packet_write(mosq);
if(rc || errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
- return rc;
+ return _mosquitto_loop_rc_handle(mosq, rc);
}
}
return rc;
@@ -834,10 +923,10 @@ void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mo
pthread_mutex_unlock(&mosq->log_callback_mutex);
}
-void mosquitto_user_data_set(struct mosquitto *mosq, void *obj)
+void mosquitto_user_data_set(struct mosquitto *mosq, void *userdata)
{
if(mosq){
- mosq->obj = obj;
+ mosq->userdata = userdata;
}
}
@@ -907,11 +996,11 @@ int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *coun
int hier;
int tlen;
int i, j;
-
+
if(!subtopic || !topics || !count) return MOSQ_ERR_INVAL;
-
+
len = strlen(subtopic);
-
+
for(i=0; i<len; i++){
if(subtopic[i] == '/'){
while(i<len && subtopic[i] == '/'){
@@ -925,14 +1014,14 @@ int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *coun
}
}
}
-
+
(*topics) = _mosquitto_calloc(hier_count, sizeof(char *));
if(!(*topics)) return MOSQ_ERR_NOMEM;
-
+
start = 0;
stop = 0;
hier = 0;
-
+
for(i=0; i<len+1; i++){
if(subtopic[i] == '/' || subtopic[i] == '\0'){
if(i>0 && subtopic[i] == '/' && subtopic[i-1] == '/'){
@@ -960,23 +1049,23 @@ int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *coun
hier++;
}
}
-
+
*count = hier_count;
-
+
return MOSQ_ERR_SUCCESS;
}
int mosquitto_sub_topic_tokens_free(char ***topics, int count)
{
int i;
-
+
if(!topics || !(*topics) || count<1) return MOSQ_ERR_INVAL;
-
+
for(i=0; i<count; i++){
if((*topics)[i]) _mosquitto_free((*topics)[i]);
}
_mosquitto_free(*topics);
-
+
return MOSQ_ERR_SUCCESS;
}
View
2,241 libmosquitto/mosquitto.h
@@ -1,31 +1,31 @@
/*
-Copyright (c) 2010-2012 Roger Light <roger@atchoo.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of mosquitto nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
+ Copyright (c) 2010-2012 Roger Light <roger@atchoo.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of mosquitto nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
#ifndef _MOSQUITTO_H_
#define _MOSQUITTO_H_
@@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
#ifdef __cplusplus
extern "C" {
#endif
-
+
#if defined(WIN32) && !defined(WITH_BROKER)
# ifdef libmosquitto_EXPORTS
# define libmosq_EXPORT __declspec(dllexport)
@@ -43,7 +43,7 @@ extern "C" {
#else
# define libmosq_EXPORT
#endif
-
+
#ifdef WIN32
# ifndef __cplusplus
# define bool char
@@ -55,13 +55,13 @@ extern "C" {
# include <stdbool.h>
# endif
#endif
-
+
#define LIBMOSQUITTO_MAJOR 1
-#define LIBMOSQUITTO_MINOR 0
-#define LIBMOSQUITTO_REVISION 5
+#define LIBMOSQUITTO_MINOR 1
+#define LIBMOSQUITTO_REVISION 3
#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION)
-
-/* Log types */
+
+ /* Log types */
#define MOSQ_LOG_NONE 0x00
#define MOSQ_LOG_INFO 0x01
#define MOSQ_LOG_NOTICE 0x02
@@ -69,1077 +69,1110 @@ extern "C" {
#define MOSQ_LOG_ERR 0x08
#define MOSQ_LOG_DEBUG 0x10
#define MOSQ_LOG_ALL 0xFF
-
-/* Error values */
-enum mosq_err_t {
- MOSQ_ERR_SUCCESS = 0,
- MOSQ_ERR_NOMEM = 1,
- MOSQ_ERR_PROTOCOL = 2,
- MOSQ_ERR_INVAL = 3,
- MOSQ_ERR_NO_CONN = 4,
- MOSQ_ERR_CONN_REFUSED = 5,
- MOSQ_ERR_NOT_FOUND = 6,
- MOSQ_ERR_CONN_LOST = 7,
- MOSQ_ERR_TLS = 8,
- MOSQ_ERR_PAYLOAD_SIZE = 9,
- MOSQ_ERR_NOT_SUPPORTED = 10,
- MOSQ_ERR_AUTH = 11,
- MOSQ_ERR_ACL_DENIED = 12,
- MOSQ_ERR_UNKNOWN = 13,
- MOSQ_ERR_ERRNO = 14
-};
-
-/* MQTT specification restricts client ids to a maximum of 23 characters */
+
+ /* Error values */
+ enum mosq_err_t {
+ MOSQ_ERR_SUCCESS = 0,
+ MOSQ_ERR_NOMEM = 1,
+ MOSQ_ERR_PROTOCOL = 2,
+ MOSQ_ERR_INVAL = 3,
+ MOSQ_ERR_NO_CONN = 4,
+ MOSQ_ERR_CONN_REFUSED = 5,
+ MOSQ_ERR_NOT_FOUND = 6,
+ MOSQ_ERR_CONN_LOST = 7,
+ MOSQ_ERR_TLS = 8,
+ MOSQ_ERR_PAYLOAD_SIZE = 9,
+ MOSQ_ERR_NOT_SUPPORTED = 10,
+ MOSQ_ERR_AUTH = 11,
+ MOSQ_ERR_ACL_DENIED = 12,
+ MOSQ_ERR_UNKNOWN = 13,
+ MOSQ_ERR_ERRNO = 14
+ };
+
+ /* MQTT specification restricts client ids to a maximum of 23 characters */
#define MOSQ_MQTT_ID_MAX_LENGTH 23
-
-struct mosquitto_message{
- int mid;
- char *topic;
- void *payload;
- int payloadlen;
- int qos;
- bool retain;
-};
-
-struct mosquitto;
-
-/*
- * Topic: Threads
- * libmosquitto provides thread safe operation.
- */
-/***************************************************
- * Important note
- *
- * The following functions that deal with network operations will return
- * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has
- * taken place. An attempt will be made to write the network data, but if the
- * socket is not available for writing at that time then the packet will not be
- * sent. To ensure the packet is sent, call mosquitto_loop() (which must also
- * be called to process incoming network data).
- * This is especially important when disconnecting a client that has a will. If
- * the broker does not receive the DISCONNECT command, it will assume that the
- * client has disconnected unexpectedly and send the will.
- *
- * mosquitto_connect()
- * mosquitto_disconnect()
- * mosquitto_subscribe()
- * mosquitto_unsubscribe()
- * mosquitto_publish()
- ***************************************************/
-
-/*
- * Function: mosquitto_lib_version
- *
- * Can be used to obtain version information for the mosquitto library.
- * This allows the application to compare the library version against the
- * version it was compiled against by using the LIBMOSQUITTO_MAJOR,
- * LIBMOSQUITTO_MINOR and LIBMOSQUITTO_REVISION defines.
- *
- * Parameters:
- * major - an integer pointer. If not NULL, the major version of the
- * library will be returned in this variable.
- * minor - an integer pointer. If not NULL, the minor version of the
- * library will be returned in this variable.
- * revision - an integer pointer. If not NULL, the revision of the library will
- * be returned in this variable.
- *
- * Returns:
- * LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major,
- * minor and revision values.
- * See Also:
- * <mosquitto_lib_cleanup>, <mosquitto_lib_init>
- */
-libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision);
-
-/*
- * Function: mosquitto_lib_init
- *
- * Must be called before any other mosquitto functions.
- *
- * Returns:
- * MOSQ_ERR_SUCCESS - always
- *
- * See Also:
- * <mosquitto_lib_cleanup>, <mosquitto_lib_version>
- */
-libmosq_EXPORT int mosquitto_lib_init(void);
-
-/*
- * Function: mosquitto_lib_cleanup
- *
- * Call to free resources associated with the library.
- *
- * Returns:
- * MOSQ_ERR_SUCCESS - always
- *
- * See Also:
- * <mosquitto_lib_init>, <mosquitto_lib_version>
- */
-libmosq_EXPORT int mosquitto_lib_cleanup(void);
-
-/*
- * Function: mosquitto_new
- *
- * Create a new mosquitto client instance.
- *
- * Parameters:
- * id - String to use as the client id. If NULL, a random client id
- * will be generated. If id is NULL, clean_session must be true.
- * clean_session - set to true to instruct the broker to clean all messages
- * and subscriptions on disconnect, false to instruct it to
- * keep them. See the man page mqtt(7) for more details.
- * Note that a client will never discard its own outgoing
- * messages on disconnect. Calling <mosquitto_connect> or
- * <mosquitto_reconnect> will cause the messages to be resent.
- * Use <mosquitto_reinitialise> to reset a client to its
- * original state.
- * Must be set to true if the id parameter is NULL.
- * obj - A user pointer that will be passed as an argument to any
- * callbacks that are specified.
- *
- * Returns:
- * Pointer to a struct mosquitto on success.
- * NULL on failure. Interrogate errno to determine the cause for the failure:
- * - ENOMEM on out of memory.
- * - EINVAL on invalid input parameters.
- *
- * See Also:
- * <mosquitto_reinitialise>, <mosquitto_destroy>, <mosquitto_user_data_set>
- */
-libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
-
-/*
- * Function: mosquitto_destroy
- *
- * Use to free memory associated with a mosquitto client instance.
- *
- * Parameters:
- * mosq - a struct mosquitto pointer to free.
- *
- * See Also:
- * <mosquitto_new>, <mosquitto_reinitialise>
- */
-libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq);
-
-/*
- * Function: mosquitto_reinitialise
- *
- * This function allows an existing mosquitto client to be reused. Call on a
- * mosquitto instance to close any open network connections, free memory
- * and reinitialise the client with the new parameters. The end result is the
- * same as the output of <mosquitto_new>.
- *
- * Parameters:
- * mosq - a valid mosquitto instance.
- * id - string to use as the client id. If NULL, a random client id
- * will be generated. If id is NULL, clean_session must be true.
- * clean_session - set to true to instruct the broker to clean all messages
- * and subscriptions on disconnect, false to instruct it to
- * keep them. See the man page mqtt(7) for more details.
- * Must be set to true if the id parameter is NULL.
- * obj - A user pointer that will be passed as an argument to any
- * callbacks that are specified.
- *
- * Returns:
- * MOSQ_ERR_SUCCESS - on success.
- * MOSQ_ERR_INVAL - if the input parameters were invalid.
- * MOSQ_ERR_NOMEM - if an out of memory condition occurred.
- *
- * See Also:
- * <mosquitto_new>, <mosquitto_destroy>
- */
-libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj);
-
-/*
- * Function: mosquitto_will_set
- *
- * Configure will information for a mosquitto instance. By default, clients do
- * not have a will. This must be called before calling <mosquitto_connect>.
- *
- * Parameters:
- * mosq - a valid mosquitto instance.
- * topic - the topic on which to publish the will.
- * payloadlen - the size of the payload (bytes). Valid values are between 0 and
- * 268,435,455.
- * payload - pointer to the data to send. If payloadlen > 0 this must be a
- * valid memory location.
- * qos - integer value 0, 1 or 2 indicating the Quality of Service to be
- * used for the will.
- * retain - set to true to make the will a retained message.
- *
- * Returns:
- * MOSQ_ERR_SUCCESS - on success.
- * MOSQ_ERR_INVAL - if the input parameters were invalid.
- * MOSQ_ERR_NOMEM - if an out of memory condition occurred.
- * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large.
- */
-libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain);
-
-/*
- * Function: mosquitto_will_clear
- *
- * Remove a previously configured will. This must be called before calling
- * <mosquitto_connect>.
- *
- * Parameters:
- * mosq - a valid mosquitto instance.
- *
- * Returns:
- * MOSQ_ERR_SUCCESS - on success.
- * MOSQ_ERR_INVAL - if the input parameters were invalid.
- */
-libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq);
-
-/*
- * Function: mosquitto_username_pw_set
- *
- * Configure username and password for a mosquitton instance. This is only
- * supported by brokers that implement the MQTT spec v3.1. By default, no
- * username or password will be sent.
- * If username is NULL, the password argument is ignored.
- * This must be called before calling mosquitto_connect().
- *
- * This is must be called before calling <mosquitto_connect>.
- *
- * Parameters:
- * mosq - a valid mosquitto instance.
- * username - the username to send as a string, or NULL to disable
- * authentication.
- * password - the password to send as a string. Set to NULL when username is
- * valid in order to send just a username.
- *
- * Returns:
- * MOSQ_ERR_SUCCESS - on success.
- * MOSQ_ERR_INVAL - if the input parameters were invalid.
- * MOSQ_ERR_NOMEM - if an out of memory condition occurred.
- */
-libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password);
-
-/*
- * Function: mosquitto_connect
- *
- * Connect to an MQTT broker.
- *
- * Parameters:
- * mosq - a valid mosquitto instance.
- * host - the hostname or ip address of the broker to connect to.
- * port - the network port to connect to. Usually 1883.
- * keepalive - the number of seconds after which the broker should send a PING
- * message to the client if no other messages have been exchanged
- * in that time.
- *
- * Returns:
- * MOSQ_ERR_SUCCESS - on success.
- * MOSQ_ERR_INVAL - if the input parameters were invalid.
- * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno
- * contains the error code, even on Windows.
- * Use strerror_r() where available or FormatMessage() on
- * Windows.
- *
- * See Also:
- * <mosquitto_connect_async>, <mosquitto_reconnect>, <mosquitto_disconnect>, <mosquitto_tls_set>
- */
-libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
-
-/*
- * Function: mosquitto_connect_async
- *
- * Connect to an MQTT broker. This is a non-blocking call. If you use
- * <mosquitto_connect_async> your client must use the threaded interface
- * <mosquitto_loop_start>. If you need to use <mosquitto_loop>, you must use
- * <mosquitto_connect> to connect the client.
- *
- * May be called before or after <mosquitto_loop_start>.
- *
- * Parameters:
- * mosq - a valid mosquitto instance.
- * host - the hostname or ip address of the broker to connect to.
- * port - the network port to connect to. Usually 1883.
- * keepalive - the number of seconds after which the broker should send a PING
- * message to the client if no other messages have been exchanged
- * in that time.
- *
- * Returns:
- * MOSQ_ERR_SUCCESS - on success.
- * MOSQ_ERR_INVAL - if the input parameters were invalid.
- * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno
- * contains the error code, even on Windows.
- * Use strerror_r() where available or FormatMessage() on
- * Windows.
- *
- * See Also:
- * <mosquitto_connect>, <mosquitto_reconnect>, <mosquitto_disconnect>, <mosquitto_tls_set>
- */
-libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive);
-