├── HomeWatch
├── en.lproj
│ └── InfoPlist.strings
├── Default.png
├── lite-off.png
├── lite-red.png
├── Default@2x.png
├── lite-green.png
├── lite-green@2x.png
├── lite-off@2x.png
├── lite-red@2x.png
├── Default-568h@2x.png
├── MosquittoMessage.m
├── HomeWatch-Prefix.pch
├── ViewController.h
├── main.m
├── AppDelegate.h
├── MosquittoMessage.h
├── Sensor.h
├── HomeWatch-Info.plist
├── AppDelegate.m
├── MosquittoClient.h
├── ViewController.m
├── Sensor.m
└── MosquittoClient.m
├── HomeWatch.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── libmosquitto
├── dummypthread.h
├── config.h
├── logging_mosq.h
├── will_mosq.h
├── util_mosq.h
├── memory_mosq.h
├── read_handle.h
├── messages_mosq.h
├── mqtt3_protocol.h
├── logging_mosq.c
├── read_handle_client.c
├── send_mosq.h
├── thread_mosq.c
├── memory_mosq.c
├── net_mosq.h
├── will_mosq.c
├── mosquitto_internal.h
├── read_handle.c
├── messages_mosq.c
├── send_client_mosq.c
├── read_handle_shared.c
├── util_mosq.c
├── send_mosq.c
├── net_mosq.c
└── mosquitto.c
├── README.md
└── monitor.py
/HomeWatch/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/HomeWatch/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basuke/homewatch/master/HomeWatch/Default.png
--------------------------------------------------------------------------------
/HomeWatch/lite-off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basuke/homewatch/master/HomeWatch/lite-off.png
--------------------------------------------------------------------------------
/HomeWatch/lite-red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basuke/homewatch/master/HomeWatch/lite-red.png
--------------------------------------------------------------------------------
/HomeWatch/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basuke/homewatch/master/HomeWatch/Default@2x.png
--------------------------------------------------------------------------------
/HomeWatch/lite-green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basuke/homewatch/master/HomeWatch/lite-green.png
--------------------------------------------------------------------------------
/HomeWatch/lite-green@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basuke/homewatch/master/HomeWatch/lite-green@2x.png
--------------------------------------------------------------------------------
/HomeWatch/lite-off@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basuke/homewatch/master/HomeWatch/lite-off@2x.png
--------------------------------------------------------------------------------
/HomeWatch/lite-red@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basuke/homewatch/master/HomeWatch/lite-red@2x.png
--------------------------------------------------------------------------------
/HomeWatch/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/basuke/homewatch/master/HomeWatch/Default-568h@2x.png
--------------------------------------------------------------------------------
/HomeWatch.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HomeWatch/MosquittoMessage.m:
--------------------------------------------------------------------------------
1 | //
2 | // MosquittoMessage.m
3 | // Marquette
4 | //
5 | // Created by horace on 11/10/12.
6 | // Modified by Basuke Suzuki 2013.
7 | //
8 | //
9 |
10 | #import "MosquittoMessage.h"
11 |
12 | @implementation MosquittoMessage
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/libmosquitto/dummypthread.h:
--------------------------------------------------------------------------------
1 | #ifndef _DUMMYPTHREAD_H_
2 | #define _DUMMYPTHREAD_H_
3 |
4 | #define pthread_create(A, B, C, D)
5 | #define pthread_join(A, B)
6 | #define pthread_cancel(A)
7 |
8 | #define pthread_mutex_init(A, B)
9 | #define pthread_mutex_destroy(A)
10 | #define pthread_mutex_lock(A)
11 | #define pthread_mutex_unlock(A)
12 |
13 | #endif
14 |
--------------------------------------------------------------------------------
/HomeWatch/HomeWatch-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'MonHome' target in the 'MonHome' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_4_0
8 | #warning "This project uses features only available in iOS SDK 4.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/HomeWatch/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // MonHome
4 | //
5 | // Created by Yosuke Suzuki on 2013/05/03.
6 | // Copyright (c) 2013年 Basuke. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Sensor.h"
11 |
12 | @class MosquittoMessage;
13 |
14 | @interface ViewController : UIViewController
15 |
16 | @property(nonatomic) Sensor *sensor;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/HomeWatch/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // MonHome
4 | //
5 | // Created by Yosuke Suzuki on 2013/05/03.
6 | // Copyright (c) 2013年 Basuke. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "AppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Home Watch
2 | ==========
3 |
4 | MQTT server script and iPhone Client application to monitor gas range status of my kitchen.
5 |
6 | Requirement
7 | -----------
8 | - mosquitto 1.1.3 - MQTT broker, C library and python module
9 | - Gas ranges with rotary knob.
10 | - Raspberry Pi or any server that can be placed at the kitchen.
11 | - A device with iOS 6.1.
12 |
13 | See also
14 | --------
15 | http://www.basuke.com/2013/04/27/gas-range-watcher-3/
16 |
--------------------------------------------------------------------------------
/HomeWatch/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // MonHome
4 | //
5 | // Created by Yosuke Suzuki on 2013/05/03.
6 | // Copyright (c) 2013年 Basuke. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class ViewController;
12 |
13 | @interface AppDelegate : UIResponder
14 |
15 | @property (strong, nonatomic) UIWindow *window;
16 |
17 | @property (strong, nonatomic) ViewController *viewController;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/HomeWatch/MosquittoMessage.h:
--------------------------------------------------------------------------------
1 | //
2 | // MosquittoMessage.h
3 | // Marquette
4 | //
5 | // Created by horace on 11/10/12.
6 | // Modified by Basuke Suzuki 2013.
7 | //
8 | //
9 |
10 | #import
11 |
12 | @interface MosquittoMessage : NSObject
13 |
14 | @property (readwrite) unsigned short mid;
15 | @property (readwrite) NSString *topic;
16 | @property (readwrite) NSString *payload;
17 | @property (readwrite) unsigned short qos;
18 | @property (readwrite) BOOL retained;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/libmosquitto/config.h:
--------------------------------------------------------------------------------
1 | /* ============================================================
2 | * Control compile time options.
3 | * ============================================================
4 | *
5 | * Compile time options have moved to config.mk.
6 | */
7 |
8 |
9 | #define WITH_THREADING 1
10 |
11 | /* ============================================================
12 | * Compatibility defines
13 | *
14 | * Generally for Windows native support.
15 | * ============================================================ */
16 | #ifdef WIN32
17 | #define snprintf sprintf_s
18 | #define strcasecmp strcmpi
19 | #define strtok_r strtok_s
20 | #define strerror_r(e, b, l) strerror_s(b, l, e)
21 | #endif
22 |
--------------------------------------------------------------------------------
/HomeWatch/Sensor.h:
--------------------------------------------------------------------------------
1 | //
2 | // Sensor.h
3 | // MonHome
4 | //
5 | // Created by Yosuke Suzuki on 2013/05/04.
6 | // Copyright (c) 2013年 Basuke. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, LogLevel) {
12 | LogNone = 0,
13 | LogMessage,
14 | LogWarning,
15 | LogError,
16 | };
17 |
18 | @class Sensor;
19 |
20 |
21 | @protocol SensorDelegate
22 |
23 | - (void)sensor:(Sensor *)sensor log:(NSString *)message level:(LogLevel)level timestamp:(NSDate *)timestamp;
24 | - (void)sensor:(Sensor *)sensor monitorDidChange:(BOOL)state timestamp:(NSDate *)timestamp;
25 | - (void)sensor:(Sensor *)sensor gasRange:(NSInteger)range didChange:(BOOL)state timestamp:(NSDate *)timestamp;
26 |
27 | @end
28 |
29 |
30 | @interface Sensor : NSObject
31 |
32 | - (id)initWithHost:(NSString *)host port:(NSInteger)port;
33 |
34 | @property(weak) id delegate;
35 |
36 | @property(readonly) NSString *clientId;
37 | @property(readonly) NSString *host;
38 | @property(readonly) NSInteger port;
39 |
40 | - (void)connect;
41 | - (void)disconnect;
42 |
43 | - (BOOL)isConnected;
44 |
45 | @property(readonly, assign) BOOL monitor;
46 |
47 | @property(readonly, assign) BOOL gas1;
48 | @property(readonly, assign) BOOL gas2;
49 | @property(readonly, assign) BOOL gas3;
50 | @property(readonly, assign) BOOL gas4;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/libmosquitto/logging_mosq.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009,2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 | #ifndef _LOGGING_MOSQ_H_
30 | #define _LOGGING_MOSQ_H_
31 |
32 | #include
33 |
34 | int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt, ...);
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/HomeWatch/HomeWatch-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIcons
12 |
13 | CFBundlePrimaryIcon
14 |
15 | CFBundleIconFiles
16 |
17 | Icon@2x.png
18 | Icon.png
19 |
20 | UIPrerenderedIcon
21 |
22 |
23 |
24 | CFBundleIdentifier
25 | com.basuke.iphoneapp.${PRODUCT_NAME:rfc1034identifier}
26 | CFBundleInfoDictionaryVersion
27 | 6.0
28 | CFBundleName
29 | ${PRODUCT_NAME}
30 | CFBundlePackageType
31 | APPL
32 | CFBundleShortVersionString
33 | 1.0
34 | CFBundleSignature
35 | ????
36 | CFBundleVersion
37 | 1.0
38 | LSRequiresIPhoneOS
39 |
40 | UIPrerenderedIcon
41 |
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 |
50 | UISupportedInterfaceOrientations~ipad
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationPortraitUpsideDown
54 | UIInterfaceOrientationLandscapeLeft
55 | UIInterfaceOrientationLandscapeRight
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/HomeWatch/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // MonHome
4 | //
5 | // Created by Yosuke Suzuki on 2013/05/03.
6 | // Copyright (c) 2013年 Basuke. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "ViewController.h"
11 | #import "Sensor.h"
12 |
13 | @implementation AppDelegate {
14 | Sensor *_sensor;
15 | UIBackgroundTaskIdentifier _disconnectTask;
16 | }
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
19 | {
20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
21 | self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
22 |
23 | _sensor = [[Sensor alloc] initWithHost:@"mqtt.example.com" port:1883];
24 | [_sensor connect];
25 |
26 | self.viewController.sensor = _sensor;
27 | _sensor.delegate = self.viewController;
28 |
29 | self.window.rootViewController = self.viewController;
30 | [self.window makeKeyAndVisible];
31 | return YES;
32 | }
33 |
34 | - (void)applicationDidEnterBackground:(UIApplication *)application
35 | {
36 | _disconnectTask = [application beginBackgroundTaskWithExpirationHandler:^{
37 | [application endBackgroundTask:_disconnectTask];
38 | _disconnectTask = UIBackgroundTaskInvalid;
39 | }];
40 |
41 | [_sensor disconnect];
42 | [self waitSensorDisconnected:application];
43 | }
44 |
45 | - (void)waitSensorDisconnected:(UIApplication *)application
46 | {
47 | if ([_sensor isConnected] == NO) {
48 | [application endBackgroundTask:_disconnectTask];
49 | _disconnectTask = UIBackgroundTaskInvalid;
50 | return;
51 | }
52 |
53 | NSLog(@"waiting disconnection");
54 | [self performSelector:@selector(waitSensorDisconnected:) withObject:application afterDelay:0.5];
55 | }
56 |
57 | - (void)applicationWillEnterForeground:(UIApplication *)application
58 | {
59 | [_sensor connect];
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/libmosquitto/will_mosq.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010,2011 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #ifndef _WILL_MOSQ_H_
31 | #define _WILL_MOSQ_H_
32 |
33 | #include
34 | #include
35 |
36 | int _mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain);
37 | int _mosquitto_will_clear(struct mosquitto *mosq);
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/HomeWatch/MosquittoClient.h:
--------------------------------------------------------------------------------
1 | //
2 | // MosquittoClient.h
3 | //
4 | // Copyright 2012 Nicholas Humfrey. All rights reserved.
5 | // Modified by Basuke Suzuki 2013.
6 | //
7 |
8 | #import
9 | #import "MosquittoMessage.h"
10 | #import "mosquitto.h"
11 |
12 | @class MosquittoClient;
13 |
14 | @protocol MosquittoClientDelegate
15 |
16 | - (void)mosquitto:(MosquittoClient *)client didConnect:(NSUInteger)code;
17 | - (void)mosquitto:(MosquittoClient *)client didFailToConnectWithError:(NSError *)error;
18 | - (void)mosquittoDidDisconnect:(MosquittoClient *)client;
19 | - (void)mosquitto:(MosquittoClient *)client didPublish:(NSUInteger)messageId;
20 |
21 | - (void)mosquitto:(MosquittoClient *)client didReceiveMessage:(MosquittoMessage*)message;
22 | - (void)mosquitto:(MosquittoClient *)client didSubscribe:(NSUInteger)messageId grantedQos:(NSArray*)qos;
23 | - (void)mosquitto:(MosquittoClient *)client didUnsubscribe:(NSUInteger)messageId;
24 |
25 | - (void)mosquitto:(MosquittoClient *)client log:(NSString *)message level:(NSInteger)level;
26 |
27 | @end
28 |
29 |
30 | @interface MosquittoClient : NSObject
31 |
32 | @property (readwrite,retain) NSString *host;
33 | @property (readwrite,assign) unsigned short port;
34 | @property (readwrite,retain) NSString *username;
35 | @property (readwrite,retain) NSString *password;
36 | @property (readwrite,assign) unsigned short keepAlive;
37 | @property (readwrite,assign) id delegate;
38 |
39 | + (void) initialize;
40 | + (NSString*) version;
41 |
42 | - (MosquittoClient*)initWithClientId:(NSString *)clientId cleanSession:(BOOL)isCleanSession;
43 | - (void)setMessageRetry:(NSUInteger)seconds;
44 | - (BOOL)connect;
45 | - (void)disconnect;
46 | - (BOOL)isConnected;
47 |
48 | - (void)setWill:(NSString *)payload toTopic:(NSString *)topic withQos:(NSUInteger)qos retained:(BOOL)retain;
49 | - (void)clearWill;
50 |
51 | - (void)publish:(NSString *)payload toTopic:(NSString *)topic withQos:(NSUInteger)qos retained:(BOOL)retain;
52 |
53 | - (void)subscribe:(NSString *)topic;
54 | - (void)subscribe:(NSString *)topic withQos:(NSUInteger)qos;
55 | - (void)unsubscribe:(NSString *)topic;
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/libmosquitto/util_mosq.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009-2012 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 | #ifndef _UTIL_MOSQ_H_
30 | #define _UTIL_MOSQ_H_
31 |
32 | #include
33 |
34 | int _mosquitto_packet_alloc(struct _mosquitto_packet *packet);
35 | void _mosquitto_check_keepalive(struct mosquitto *mosq);
36 | int _mosquitto_fix_sub_topic(char **subtopic);
37 | uint16_t _mosquitto_mid_generate(struct mosquitto *mosq);
38 | int _mosquitto_topic_wildcard_len_check(const char *str);
39 |
40 | #if defined(WITH_TLS) && defined(WITH_TLS_PSK)
41 | int _mosquitto_hex2bin(const char *hex, unsigned char *bin, int bin_max_len);
42 | #endif
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/libmosquitto/memory_mosq.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #ifndef _MEMORY_MOSQ_H_
31 | #define _MEMORY_MOSQ_H_
32 |
33 | #include
34 |
35 | #if defined(WITH_MEMORY_TRACKING) && defined(WITH_BROKER) && !defined(WIN32) && !defined(__SYMBIAN32__)
36 | #define REAL_WITH_MEMORY_TRACKING
37 | #endif
38 |
39 | void *_mosquitto_calloc(size_t nmemb, size_t size);
40 | void _mosquitto_free(void *mem);
41 | void *_mosquitto_malloc(size_t size);
42 | #ifdef REAL_WITH_MEMORY_TRACKING
43 | unsigned long _mosquitto_memory_used(void);
44 | unsigned long _mosquitto_max_memory_used(void);
45 | #endif
46 | void *_mosquitto_realloc(void *ptr, size_t size);
47 | char *_mosquitto_strdup(const char *s);
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/HomeWatch/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // MonHome
4 | //
5 | // Created by Yosuke Suzuki on 2013/05/03.
6 | // Copyright (c) 2013年 Basuke. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "MosquittoMessage.h"
11 |
12 | @interface ViewController ()
13 |
14 | @property (weak, nonatomic) IBOutlet UIImageView *status;
15 |
16 | @property (weak, nonatomic) IBOutlet UISwitch *gas1;
17 | @property (weak, nonatomic) IBOutlet UISwitch *gas2;
18 | @property (weak, nonatomic) IBOutlet UISwitch *gas3;
19 | @property (weak, nonatomic) IBOutlet UISwitch *gas4;
20 |
21 | @property (weak, nonatomic) IBOutlet UITextView *logView;
22 |
23 | @end
24 |
25 | @implementation ViewController {
26 | NSString *_log;
27 | }
28 |
29 | - (void)viewDidLoad
30 | {
31 | [super viewDidLoad];
32 |
33 | [self setStatusIcon:self.sensor.monitor];
34 |
35 | self.gas1.on = self.sensor.gas1;
36 | self.gas2.on = self.sensor.gas2;
37 | self.gas3.on = self.sensor.gas3;
38 | self.gas4.on = self.sensor.gas4;
39 |
40 | self.logView.text = _log;
41 | }
42 |
43 | - (void)setStatusIcon:(BOOL)status
44 | {
45 | self.status.image = [UIImage imageNamed:(status ? @"lite-green" : @"lite-red")];
46 | }
47 |
48 | - (void)sensor:(Sensor *)sensor monitorDidChange:(BOOL)state timestamp:(NSDate *)timestamp
49 | {
50 | [self setStatusIcon:state];
51 | }
52 |
53 | - (void)sensor:(Sensor *)sensor gasRange:(NSInteger)range didChange:(BOOL)state timestamp:(NSDate *)timestamp
54 | {
55 | switch (range) {
56 | case 1:
57 | self.gas1.on = state;
58 | break;
59 |
60 | case 2:
61 | self.gas2.on = state;
62 | break;
63 |
64 | case 3:
65 | self.gas3.on = state;
66 | break;
67 |
68 | case 4:
69 | self.gas4.on = state;
70 | break;
71 | }
72 | }
73 |
74 | - (void)sensor:(Sensor *)sensor log:(NSString *)message level:(LogLevel)level timestamp:(NSDate *)timestamp
75 | {
76 | NSRange selection;
77 |
78 | if (_log) {
79 | selection.location = [_log length] + 1;
80 | _log = [[_log stringByAppendingString:@"\n"] stringByAppendingString:message];
81 | } else {
82 | selection.location = 0;
83 | _log = message;
84 | }
85 | selection.length = [_log length] - selection.location;
86 |
87 | self.logView.text = _log;
88 | [self.logView scrollRangeToVisible:selection];
89 | }
90 |
91 | @end
92 |
--------------------------------------------------------------------------------
/libmosquitto/read_handle.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 | #ifndef _READ_HANDLE_H_
30 | #define _READ_HANDLE_H_
31 |
32 | #include
33 | struct mosquitto_db;
34 |
35 | int _mosquitto_packet_handle(struct mosquitto *mosq);
36 | int _mosquitto_handle_connack(struct mosquitto *mosq);
37 | int _mosquitto_handle_pingreq(struct mosquitto *mosq);
38 | int _mosquitto_handle_pingresp(struct mosquitto *mosq);
39 | int _mosquitto_handle_pubackcomp(struct mosquitto *mosq, const char *type);
40 | int _mosquitto_handle_publish(struct mosquitto *mosq);
41 | int _mosquitto_handle_pubrec(struct mosquitto *mosq);
42 | int _mosquitto_handle_pubrel(struct mosquitto_db *db, struct mosquitto *mosq);
43 | int _mosquitto_handle_suback(struct mosquitto *mosq);
44 | int _mosquitto_handle_unsuback(struct mosquitto *mosq);
45 |
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/libmosquitto/messages_mosq.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 | #ifndef _MESSAGES_MOSQ_H_
30 | #define _MESSAGES_MOSQ_H_
31 |
32 | #include
33 | #include
34 |
35 | void _mosquitto_message_cleanup_all(struct mosquitto *mosq);
36 | void _mosquitto_message_cleanup(struct mosquitto_message_all **message);
37 | int _mosquitto_message_delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir);
38 | void _mosquitto_message_queue(struct mosquitto *mosq, struct mosquitto_message_all *message);
39 | void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq);
40 | int _mosquitto_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message);
41 | void _mosquitto_message_retry_check(struct mosquitto *mosq);
42 | int _mosquitto_message_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, enum mosquitto_msg_state state);
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/libmosquitto/mqtt3_protocol.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009,2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #ifndef _MQTT3_PROTOCOL_H_
31 | #define _MQTT3_PROTOCOL_H_
32 |
33 | /* For version 3 of the MQTT protocol */
34 |
35 | #define PROTOCOL_NAME "MQIsdp"
36 | #define PROTOCOL_VERSION 3
37 |
38 | /* Message types */
39 | #define CONNECT 0x10
40 | #define CONNACK 0x20
41 | #define PUBLISH 0x30
42 | #define PUBACK 0x40
43 | #define PUBREC 0x50
44 | #define PUBREL 0x60
45 | #define PUBCOMP 0x70
46 | #define SUBSCRIBE 0x80
47 | #define SUBACK 0x90
48 | #define UNSUBSCRIBE 0xA0
49 | #define UNSUBACK 0xB0
50 | #define PINGREQ 0xC0
51 | #define PINGRESP 0xD0
52 | #define DISCONNECT 0xE0
53 |
54 | #define CONNACK_ACCEPTED 0
55 | #define CONNACK_REFUSED_PROTOCOL_VERSION 1
56 | #define CONNACK_REFUSED_IDENTIFIER_REJECTED 2
57 | #define CONNACK_REFUSED_SERVER_UNAVAILABLE 3
58 | #define CONNACK_REFUSED_BAD_USERNAME_PASSWORD 4
59 | #define CONNACK_REFUSED_NOT_AUTHORIZED 5
60 |
61 | #define MQTT_MAX_PAYLOAD 268435455
62 |
63 | #endif
64 |
--------------------------------------------------------------------------------
/libmosquitto/logging_mosq.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009,2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | #include
35 | #include
36 | #include
37 |
38 | int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt, ...)
39 | {
40 | va_list va;
41 | char *s;
42 | int len;
43 |
44 | assert(mosq);
45 | assert(fmt);
46 |
47 | pthread_mutex_lock(&mosq->log_callback_mutex);
48 | if(mosq->on_log){
49 | len = strlen(fmt) + 500;
50 | s = _mosquitto_malloc(len*sizeof(char));
51 | if(!s){
52 | pthread_mutex_unlock(&mosq->log_callback_mutex);
53 | return MOSQ_ERR_NOMEM;
54 | }
55 |
56 | va_start(va, fmt);
57 | vsnprintf(s, len, fmt, va);
58 | va_end(va);
59 | s[len-1] = '\0'; /* Ensure string is null terminated. */
60 |
61 | mosq->on_log(mosq, mosq->userdata, priority, s);
62 |
63 | _mosquitto_free(s);
64 | }
65 | pthread_mutex_unlock(&mosq->log_callback_mutex);
66 |
67 | return MOSQ_ERR_SUCCESS;
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/libmosquitto/read_handle_client.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009,2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 |
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 |
38 | int _mosquitto_handle_connack(struct mosquitto *mosq)
39 | {
40 | uint8_t byte;
41 | uint8_t result;
42 | int rc;
43 |
44 | assert(mosq);
45 | #ifdef WITH_STRICT_PROTOCOL
46 | if(mosq->in_packet.remaining_length != 2){
47 | return MOSQ_ERR_PROTOCOL;
48 | }
49 | #endif
50 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received CONNACK", mosq->id);
51 | rc = _mosquitto_read_byte(&mosq->in_packet, &byte); // Reserved byte, not used
52 | if(rc) return rc;
53 | rc = _mosquitto_read_byte(&mosq->in_packet, &result);
54 | if(rc) return rc;
55 | pthread_mutex_lock(&mosq->callback_mutex);
56 | if(mosq->on_connect){
57 | mosq->in_callback = true;
58 | mosq->on_connect(mosq, mosq->userdata, result);
59 | mosq->in_callback = false;
60 | }
61 | pthread_mutex_unlock(&mosq->callback_mutex);
62 | switch(result){
63 | case 0:
64 | mosq->state = mosq_cs_connected;
65 | return MOSQ_ERR_SUCCESS;
66 | case 1:
67 | case 2:
68 | case 3:
69 | case 4:
70 | case 5:
71 | return MOSQ_ERR_CONN_REFUSED;
72 | default:
73 | return MOSQ_ERR_PROTOCOL;
74 | }
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/libmosquitto/send_mosq.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 | #ifndef _SEND_MOSQ_H_
30 | #define _SEND_MOSQ_H_
31 |
32 | #include
33 |
34 | int _mosquitto_send_simple_command(struct mosquitto *mosq, uint8_t command);
35 | int _mosquitto_send_command_with_mid(struct mosquitto *mosq, uint8_t command, uint16_t mid, bool dup);
36 | int _mosquitto_send_real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup);
37 |
38 | int _mosquitto_send_connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session);
39 | int _mosquitto_send_disconnect(struct mosquitto *mosq);
40 | int _mosquitto_send_pingreq(struct mosquitto *mosq);
41 | int _mosquitto_send_pingresp(struct mosquitto *mosq);
42 | int _mosquitto_send_puback(struct mosquitto *mosq, uint16_t mid);
43 | int _mosquitto_send_pubcomp(struct mosquitto *mosq, uint16_t mid);
44 | int _mosquitto_send_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup);
45 | int _mosquitto_send_pubrec(struct mosquitto *mosq, uint16_t mid);
46 | int _mosquitto_send_pubrel(struct mosquitto *mosq, uint16_t mid, bool dup);
47 | int _mosquitto_send_subscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic, uint8_t topic_qos);
48 | int _mosquitto_send_unsubscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic);
49 |
50 | #endif
51 |
--------------------------------------------------------------------------------
/libmosquitto/thread_mosq.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 |
32 | #ifndef WIN32
33 | #include
34 | #endif
35 |
36 | #include
37 |
38 | void *_mosquitto_thread_main(void *obj);
39 |
40 | int mosquitto_loop_start(struct mosquitto *mosq)
41 | {
42 | #ifdef WITH_THREADING
43 | if(!mosq) return MOSQ_ERR_INVAL;
44 |
45 | pthread_create(&mosq->thread_id, NULL, _mosquitto_thread_main, mosq);
46 | return MOSQ_ERR_SUCCESS;
47 | #else
48 | return MOSQ_ERR_NOT_SUPPORTED;
49 | #endif
50 | }
51 |
52 | int mosquitto_loop_stop(struct mosquitto *mosq, bool force)
53 | {
54 | #ifdef WITH_THREADING
55 | if(!mosq) return MOSQ_ERR_INVAL;
56 |
57 | if(force){
58 | pthread_cancel(mosq->thread_id);
59 | }
60 | pthread_join(mosq->thread_id, NULL);
61 | mosq->thread_id = pthread_self();
62 |
63 | return MOSQ_ERR_SUCCESS;
64 | #else
65 | return MOSQ_ERR_NOT_SUPPORTED;
66 | #endif
67 | }
68 |
69 | #ifdef WITH_THREADING
70 | void *_mosquitto_thread_main(void *obj)
71 | {
72 | struct mosquitto *mosq = obj;
73 | int run = 1;
74 | int rc;
75 |
76 | if(!mosq) return NULL;
77 |
78 | pthread_mutex_lock(&mosq->state_mutex);
79 | if(mosq->state == mosq_cs_connect_async){
80 | pthread_mutex_unlock(&mosq->state_mutex);
81 | mosquitto_reconnect(mosq);
82 | }else{
83 | pthread_mutex_unlock(&mosq->state_mutex);
84 | }
85 |
86 | while(run){
87 | do{
88 | rc = mosquitto_loop(mosq, -1, 1);
89 | }while(rc == MOSQ_ERR_SUCCESS);
90 | pthread_mutex_lock(&mosq->state_mutex);
91 | if(mosq->state == mosq_cs_disconnecting){
92 | run = 0;
93 | pthread_mutex_unlock(&mosq->state_mutex);
94 | }else{
95 | pthread_mutex_unlock(&mosq->state_mutex);
96 | #ifdef WIN32
97 | Sleep(1000);
98 | #else
99 | sleep(1);
100 | #endif
101 | mosquitto_reconnect(mosq);
102 | }
103 | }
104 | return obj;
105 | }
106 | #endif
107 |
108 |
--------------------------------------------------------------------------------
/monitor.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8
2 |
3 | import RPi.GPIO as GPIO
4 | import mosquitto
5 | import sys
6 | from datetime import datetime
7 |
8 |
9 | PINS = (18, 23, 24, 25) # GPIO ports
10 | SERVER = "mqtt.example.com" # MQTT Server
11 |
12 |
13 | def main():
14 | # setup MQTT
15 | conn = MQTTServer(SERVER)
16 |
17 | # setup GPIO
18 | GPIO.setmode(GPIO.BCM)
19 | [GPIO.setup(pin, GPIO.IN) for pin in PINS]
20 |
21 | labels = range(1, len(PINS) + 1)
22 | sensors = [Sensor(label, pin) for label, pin in zip(labels, PINS)]
23 |
24 | def on_connect():
25 | # send initial state
26 | for sensor in sensors:
27 | conn.publish(*sensor.event())
28 |
29 | conn.publish("home/kitchen/monitor", "ON")
30 |
31 | conn.set_will("home/kitchen/monitor", "OFF")
32 | conn.connect(on_connect)
33 |
34 | while True:
35 | conn.loop()
36 |
37 | for sensor in sensors:
38 | if sensor.check():
39 | conn.publish(*sensor.event())
40 |
41 |
42 | class Sensor(object):
43 | def __init__(self, label, pin):
44 | self.pin = pin
45 | self.state = GPIO.input(self.pin)
46 | self.topic = "home/kitchen/gas/%s" % label
47 |
48 | def check(self):
49 | state = self.state
50 | self.state = GPIO.input(self.pin)
51 | return (state != self.state)
52 |
53 | def event(self):
54 | state = "ON" if self.state else "OFF"
55 | msg = ' '.join([state, utctimestamp()])
56 |
57 | return (self.topic, msg)
58 |
59 |
60 | class MQTTServer(object):
61 | def __init__(self, server):
62 | self.server = server
63 | self.client = mosquitto.Mosquitto("Daidokoro-monitor", userdata=self)
64 | self.connected = False
65 | self.on_connect = None
66 |
67 | def on_connect(mosq, self, rc):
68 | if rc != 0:
69 | log("Cannot connect to server. Exit.")
70 | sys.exit(255)
71 |
72 | log("Connected successfully.")
73 | self.connected = True
74 |
75 | if self.on_connect:
76 | self.on_connect()
77 |
78 | def on_disconnect(mosq, self, rc):
79 | log("Disconnected. Try to connect again.")
80 | self.connected = False
81 |
82 | self.reconnect()
83 |
84 | self.client.on_connect = on_connect
85 | self.client.on_disconnect = on_disconnect
86 |
87 | def connect(self, on_connect):
88 | log("Connecting to MQTT server.")
89 | self.on_connect = on_connect
90 |
91 | self.client.connect(self.server, keepalive=10)
92 | self.wait_connection()
93 |
94 | def reconnect(self):
95 | log("Reconnecting to MQTT server.")
96 | self.client.reconnect()
97 | self.wait_connection()
98 |
99 | def publish(self, topic, payload):
100 | log("Publish %s => %s" % (topic, payload))
101 | self.client.publish(topic, payload, retain=True)
102 |
103 | def set_will(self, topic, payload):
104 | log("Set Will %s => %s" % (topic, payload))
105 | self.client.will_set(topic, payload, retain=True)
106 |
107 | def loop(self, timeout=0.1):
108 | self.client.loop(timeout=timeout)
109 |
110 | def wait_connection(self):
111 | while not self.connected:
112 | self.loop()
113 |
114 |
115 | def utctimestamp():
116 | now = datetime.utcnow().replace(microsecond = 0)
117 | return now.isoformat() + 'Z'
118 |
119 | def log(msg):
120 | print msg
121 |
122 |
123 | if __name__ == '__main__':
124 | main()
125 |
--------------------------------------------------------------------------------
/libmosquitto/memory_mosq.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009,2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 |
32 | #include
33 | #include
34 |
35 | #include
36 |
37 | #ifdef REAL_WITH_MEMORY_TRACKING
38 | # if defined(__APPLE__)
39 | # define malloc_usable_size malloc_good_size
40 | # elif defined(__FreeBSD__)
41 | # include
42 | # else
43 | # include
44 | # endif
45 | #endif
46 |
47 | #include
48 |
49 | #ifdef REAL_WITH_MEMORY_TRACKING
50 | static unsigned long memcount = 0;
51 | static unsigned long max_memcount = 0;
52 | #endif
53 |
54 | void *_mosquitto_calloc(size_t nmemb, size_t size)
55 | {
56 | void *mem = calloc(nmemb, size);
57 |
58 | #ifdef REAL_WITH_MEMORY_TRACKING
59 | memcount += malloc_usable_size(mem);
60 | if(memcount > max_memcount){
61 | max_memcount = memcount;
62 | }
63 | #endif
64 |
65 | return mem;
66 | }
67 |
68 | void _mosquitto_free(void *mem)
69 | {
70 | #ifdef REAL_WITH_MEMORY_TRACKING
71 | memcount -= malloc_usable_size(mem);
72 | #endif
73 | free(mem);
74 | }
75 |
76 | void *_mosquitto_malloc(size_t size)
77 | {
78 | void *mem = malloc(size);
79 |
80 | #ifdef REAL_WITH_MEMORY_TRACKING
81 | memcount += malloc_usable_size(mem);
82 | if(memcount > max_memcount){
83 | max_memcount = memcount;
84 | }
85 | #endif
86 |
87 | return mem;
88 | }
89 |
90 | #ifdef REAL_WITH_MEMORY_TRACKING
91 | unsigned long _mosquitto_memory_used(void)
92 | {
93 | return memcount;
94 | }
95 |
96 | unsigned long _mosquitto_max_memory_used(void)
97 | {
98 | return max_memcount;
99 | }
100 | #endif
101 |
102 | void *_mosquitto_realloc(void *ptr, size_t size)
103 | {
104 | void *mem;
105 | #ifdef REAL_WITH_MEMORY_TRACKING
106 | if(ptr){
107 | memcount -= malloc_usable_size(ptr);
108 | }
109 | #endif
110 | mem = realloc(ptr, size);
111 |
112 | #ifdef REAL_WITH_MEMORY_TRACKING
113 | memcount += malloc_usable_size(mem);
114 | if(memcount > max_memcount){
115 | max_memcount = memcount;
116 | }
117 | #endif
118 |
119 | return mem;
120 | }
121 |
122 | char *_mosquitto_strdup(const char *s)
123 | {
124 | char *str = strdup(s);
125 |
126 | #ifdef REAL_WITH_MEMORY_TRACKING
127 | memcount += malloc_usable_size(str);
128 | if(memcount > max_memcount){
129 | max_memcount = memcount;
130 | }
131 | #endif
132 |
133 | return str;
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/libmosquitto/net_mosq.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010,2011 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 | #ifndef _NET_MOSQ_H_
30 | #define _NET_MOSQ_H_
31 |
32 | #ifndef WIN32
33 | #include
34 | #else
35 | #include
36 | typedef int ssize_t;
37 | #endif
38 |
39 | #include
40 | #include
41 |
42 | #ifdef WITH_BROKER
43 | struct mosquitto_db;
44 | #endif
45 |
46 | #ifdef WIN32
47 | # define COMPAT_CLOSE(a) closesocket(a)
48 | # define COMPAT_ECONNRESET WSAECONNRESET
49 | # define COMPAT_EWOULDBLOCK WSAEWOULDBLOCK
50 | #else
51 | # define COMPAT_CLOSE(a) close(a)
52 | # define COMPAT_ECONNRESET ECONNRESET
53 | # define COMPAT_EWOULDBLOCK EWOULDBLOCK
54 | #endif
55 |
56 | #ifndef WIN32
57 | #else
58 | #endif
59 |
60 | /* For when not using winsock libraries. */
61 | #ifndef INVALID_SOCKET
62 | #define INVALID_SOCKET -1
63 | #endif
64 |
65 | /* Macros for accessing the MSB and LSB of a uint16_t */
66 | #define MOSQ_MSB(A) (uint8_t)((A & 0xFF00) >> 8)
67 | #define MOSQ_LSB(A) (uint8_t)(A & 0x00FF)
68 |
69 | void _mosquitto_net_init(void);
70 | void _mosquitto_net_cleanup(void);
71 |
72 | void _mosquitto_packet_cleanup(struct _mosquitto_packet *packet);
73 | int _mosquitto_packet_queue(struct mosquitto *mosq, struct _mosquitto_packet *packet);
74 | int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port);
75 | int _mosquitto_socket_close(struct mosquitto *mosq);
76 |
77 | int _mosquitto_read_byte(struct _mosquitto_packet *packet, uint8_t *byte);
78 | int _mosquitto_read_bytes(struct _mosquitto_packet *packet, void *bytes, uint32_t count);
79 | int _mosquitto_read_string(struct _mosquitto_packet *packet, char **str);
80 | int _mosquitto_read_uint16(struct _mosquitto_packet *packet, uint16_t *word);
81 |
82 | void _mosquitto_write_byte(struct _mosquitto_packet *packet, uint8_t byte);
83 | void _mosquitto_write_bytes(struct _mosquitto_packet *packet, const void *bytes, uint32_t count);
84 | void _mosquitto_write_string(struct _mosquitto_packet *packet, const char *str, uint16_t length);
85 | void _mosquitto_write_uint16(struct _mosquitto_packet *packet, uint16_t word);
86 |
87 | ssize_t _mosquitto_net_read(struct mosquitto *mosq, void *buf, size_t count);
88 | ssize_t _mosquitto_net_write(struct mosquitto *mosq, void *buf, size_t count);
89 |
90 | int _mosquitto_packet_write(struct mosquitto *mosq);
91 | #ifdef WITH_BROKER
92 | int _mosquitto_packet_read(struct mosquitto_db *db, struct mosquitto *mosq);
93 | #else
94 | int _mosquitto_packet_read(struct mosquitto *mosq);
95 | #endif
96 |
97 | #endif
98 |
--------------------------------------------------------------------------------
/libmosquitto/will_mosq.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010,2011 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 | #ifndef WIN32
35 | #include
36 | #include
37 | #else
38 | #include
39 | typedef int ssize_t;
40 | #endif
41 |
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 | #include
52 |
53 | int _mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain)
54 | {
55 | int rc = MOSQ_ERR_SUCCESS;
56 |
57 | if(!mosq || !topic) return MOSQ_ERR_INVAL;
58 | if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE;
59 | if(payloadlen > 0 && !payload) return MOSQ_ERR_INVAL;
60 |
61 | if(mosq->will){
62 | if(mosq->will->topic){
63 | _mosquitto_free(mosq->will->topic);
64 | mosq->will->topic = NULL;
65 | }
66 | if(mosq->will->payload){
67 | _mosquitto_free(mosq->will->payload);
68 | mosq->will->payload = NULL;
69 | }
70 | _mosquitto_free(mosq->will);
71 | mosq->will = NULL;
72 | }
73 |
74 | mosq->will = _mosquitto_calloc(1, sizeof(struct mosquitto_message));
75 | if(!mosq->will) return MOSQ_ERR_NOMEM;
76 | mosq->will->topic = _mosquitto_strdup(topic);
77 | if(!mosq->will->topic){
78 | rc = MOSQ_ERR_NOMEM;
79 | goto cleanup;
80 | }
81 | mosq->will->payloadlen = payloadlen;
82 | if(mosq->will->payloadlen > 0){
83 | if(!payload){
84 | rc = MOSQ_ERR_INVAL;
85 | goto cleanup;
86 | }
87 | mosq->will->payload = _mosquitto_malloc(sizeof(char)*mosq->will->payloadlen);
88 | if(!mosq->will->payload){
89 | rc = MOSQ_ERR_NOMEM;
90 | goto cleanup;
91 | }
92 |
93 | memcpy(mosq->will->payload, payload, payloadlen);
94 | }
95 | mosq->will->qos = qos;
96 | mosq->will->retain = retain;
97 |
98 | return MOSQ_ERR_SUCCESS;
99 |
100 | cleanup:
101 | if(mosq->will){
102 | if(mosq->will->topic) _mosquitto_free(mosq->will->topic);
103 | if(mosq->will->payload) _mosquitto_free(mosq->will->payload);
104 | }
105 | _mosquitto_free(mosq->will);
106 | mosq->will = NULL;
107 |
108 | return rc;
109 | }
110 |
111 | int _mosquitto_will_clear(struct mosquitto *mosq)
112 | {
113 | if(!mosq->will) return MOSQ_ERR_SUCCESS;
114 |
115 | if(mosq->will->topic){
116 | _mosquitto_free(mosq->will->topic);
117 | mosq->will->topic = NULL;
118 | }
119 | if(mosq->will->payload){
120 | _mosquitto_free(mosq->will->payload);
121 | mosq->will->payload = NULL;
122 | }
123 | _mosquitto_free(mosq->will);
124 | mosq->will = NULL;
125 |
126 | return MOSQ_ERR_SUCCESS;
127 | }
128 |
129 |
--------------------------------------------------------------------------------
/HomeWatch/Sensor.m:
--------------------------------------------------------------------------------
1 | //
2 | // Sensor.m
3 | // MonHome
4 | //
5 | // Created by Yosuke Suzuki on 2013/05/04.
6 | // Copyright (c) 2013年 Basuke. All rights reserved.
7 | //
8 |
9 | #import "Sensor.h"
10 | #import "MosquittoClient.h"
11 |
12 | @interface Sensor()
13 |
14 | @property(readwrite, assign) BOOL monitor;
15 |
16 | @property(readwrite, assign) BOOL gas1;
17 | @property(readwrite, assign) BOOL gas2;
18 | @property(readwrite, assign) BOOL gas3;
19 | @property(readwrite, assign) BOOL gas4;
20 |
21 | @end
22 |
23 | @implementation Sensor {
24 | MosquittoClient *_mosquitto;
25 | NSInteger _logLevel;
26 | NSDateFormatter *_timestampFormatter;
27 | NSRegularExpression *_gasRangeTopicRE;
28 | }
29 |
30 | @synthesize host=_host, port=_port, clientId=_clientId;
31 |
32 | - (id)initWithHost:(NSString *)host port:(NSInteger)port
33 | {
34 | self = [super init];
35 | if (self) {
36 | _host = host;
37 | _port = port;
38 |
39 | // Create unique serial
40 | NSString *uuid = [[[NSUUID UUID] UUIDString] substringToIndex:16];
41 | _clientId = [NSString stringWithFormat:@"HomeWatch-%@", uuid];
42 |
43 | // Create Mosquitto instance
44 | _mosquitto = [[MosquittoClient alloc] initWithClientId:_clientId cleanSession:YES];
45 | _mosquitto.delegate = self;
46 |
47 | // Date Formatter for parsing timestamp
48 | NSDateFormatter *f = [[NSDateFormatter alloc] init];
49 | f.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'";
50 | f.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
51 | f.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
52 | f.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
53 |
54 | _timestampFormatter = f;
55 |
56 | // Regular Expression for Topic parsing
57 | NSError *error;
58 | _gasRangeTopicRE = [NSRegularExpression regularExpressionWithPattern:@"^home/kitchen/(gas/(\\d+)|monitor)$" options:0 error:&error];
59 | }
60 | return self;
61 | }
62 |
63 | - (void)connect
64 | {
65 | _mosquitto.host = _host;
66 | if (_port) _mosquitto.port = _port;
67 |
68 | [_mosquitto connect];
69 | }
70 |
71 | - (void)disconnect
72 | {
73 | [_mosquitto disconnect];
74 | }
75 |
76 | - (BOOL)isConnected
77 | {
78 | return [_mosquitto isConnected];
79 | }
80 |
81 | - (void)log:(NSString *)message level:(LogLevel)level
82 | {
83 | [self.delegate sensor:self log:message level:level timestamp:[NSDate date]];
84 | }
85 |
86 | - (void)log:(NSString *)message
87 | {
88 | [self log:message level:LogMessage];
89 |
90 | #if DEBUG
91 | NSLog(@"%@", message);
92 | #endif
93 | }
94 |
95 | #pragma mark - Mosquitto Delegate
96 |
97 | - (void)mosquitto:(MosquittoClient *)client didConnect:(NSUInteger)code
98 | {
99 | [self log:[NSString stringWithFormat:@"connected to %@ port %d", _host, _port]];
100 |
101 | [client subscribe:@"home/kitchen/gas/+"];
102 | [client subscribe:@"home/kitchen/monitor"];
103 | }
104 |
105 | - (void)mosquitto:(MosquittoClient *)client didFailToConnectWithError:(NSError *)error
106 | {
107 |
108 | }
109 |
110 | - (void)mosquittoDidDisconnect:(MosquittoClient *)client
111 | {
112 | [self log:@"disconnected"];
113 | }
114 |
115 | - (void)mosquitto:(MosquittoClient *)client didReceiveMessage:(MosquittoMessage*)message
116 | {
117 | #if DEBUG
118 | [self log:[NSString stringWithFormat:@"%@ : %@ qos:%d%@", message.topic, message.payload, message.qos, (message.retained ? @" RETAIN" : @"")]];
119 | #endif
120 |
121 | BOOL on;
122 | NSDate *timestamp;
123 |
124 | NSArray *values = [message.payload componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
125 |
126 | if ([values count] >= 1) {
127 | on = [values[0] isEqualToString:@"ON"];
128 | }
129 |
130 | if ([values count] >= 2) {
131 | timestamp = [_timestampFormatter dateFromString:values[1]];
132 | }
133 |
134 | NSTextCheckingResult *match = [_gasRangeTopicRE firstMatchInString:message.topic options:0 range:NSMakeRange(0, message.topic.length)];
135 | if (match) {
136 | NSString *what = [message.topic substringWithRange:[match rangeAtIndex:1]];
137 |
138 | if ([what isEqualToString:@"monitor"]) {
139 | [self.delegate sensor:self monitorDidChange:on timestamp:timestamp];
140 | } else {
141 | NSInteger range = [[message.topic substringWithRange:[match rangeAtIndex:2]] integerValue];
142 |
143 | [self.delegate sensor:self gasRange:range didChange:on timestamp:timestamp];
144 | }
145 | }
146 | }
147 |
148 | - (void)mosquitto:(MosquittoClient *)client didPublish:(NSUInteger)messageId
149 | {
150 | }
151 |
152 | - (void)mosquitto:(MosquittoClient *)client didSubscribe:(NSUInteger)messageId grantedQos:(NSArray*)qos
153 | {
154 | [self log:[NSString stringWithFormat:@"subscribed (mid=%d)", messageId]];
155 | }
156 |
157 | - (void)mosquitto:(MosquittoClient *)client didUnsubscribe:(NSUInteger)messageId
158 | {
159 | [self log:[NSString stringWithFormat:@"unsubscribed (mid=%d)", messageId]];
160 | }
161 |
162 | - (void)mosquitto:(MosquittoClient *)client log:(NSString *)message level:(NSInteger)level
163 | {
164 | LogLevel logLevel = LogNone;
165 |
166 | switch (level) {
167 | case MOSQ_LOG_INFO:
168 | logLevel = LogMessage;
169 | break;
170 |
171 | case MOSQ_LOG_NOTICE:
172 | logLevel = LogMessage;
173 | break;
174 |
175 | case MOSQ_LOG_WARNING:
176 | logLevel = LogWarning;
177 | break;
178 |
179 | case MOSQ_LOG_ERR:
180 | logLevel = LogError;
181 | break;
182 |
183 | #if DEBUG
184 | case MOSQ_LOG_DEBUG:
185 | logLevel = LogMessage;
186 | break;
187 | #endif
188 | default:
189 | break;
190 | }
191 |
192 | if (logLevel != LogNone) {
193 | [self log:message level:logLevel];
194 | }
195 | }
196 |
197 | @end
198 |
--------------------------------------------------------------------------------
/libmosquitto/mosquitto_internal.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010,2011 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #ifndef _MOSQUITTO_INTERNAL_H_
31 | #define _MOSQUITTO_INTERNAL_H_
32 |
33 | #include
34 |
35 | #ifdef WIN32
36 | # include
37 | #endif
38 |
39 | #ifdef WITH_TLS
40 | #include
41 | #endif
42 | #include
43 | #include
44 |
45 | #if defined(WITH_THREADING) && !defined(WITH_BROKER)
46 | # include
47 | #else
48 | # include
49 | #endif
50 |
51 | #ifdef WIN32
52 | # if _MSC_VER < 1600
53 | typedef unsigned char uint8_t;
54 | typedef unsigned short uint16_t;
55 | typedef unsigned int uint32_t;
56 | typedef unsigned long long uint64_t;
57 | # else
58 | # include
59 | # endif
60 | #else
61 | # include
62 | #endif
63 |
64 | #include
65 | #ifdef WITH_BROKER
66 | struct mosquitto_client_msg;
67 | #endif
68 |
69 | enum mosquitto_msg_direction {
70 | mosq_md_in = 0,
71 | mosq_md_out = 1
72 | };
73 |
74 | enum mosquitto_msg_state {
75 | mosq_ms_invalid = 0,
76 | mosq_ms_wait_puback = 1,
77 | mosq_ms_wait_pubrec = 2,
78 | mosq_ms_wait_pubrel = 3,
79 | mosq_ms_wait_pubcomp = 4
80 | };
81 |
82 | enum mosquitto_client_state {
83 | mosq_cs_new = 0,
84 | mosq_cs_connected = 1,
85 | mosq_cs_disconnecting = 2,
86 | mosq_cs_connect_async = 3
87 | };
88 |
89 | struct _mosquitto_packet{
90 | uint8_t command;
91 | uint8_t have_remaining;
92 | uint8_t remaining_count;
93 | uint16_t mid;
94 | uint32_t remaining_mult;
95 | uint32_t remaining_length;
96 | uint32_t packet_length;
97 | uint32_t to_process;
98 | uint32_t pos;
99 | uint8_t *payload;
100 | struct _mosquitto_packet *next;
101 | };
102 |
103 | struct mosquitto_message_all{
104 | struct mosquitto_message_all *next;
105 | time_t timestamp;
106 | enum mosquitto_msg_direction direction;
107 | enum mosquitto_msg_state state;
108 | bool dup;
109 | struct mosquitto_message msg;
110 | };
111 |
112 | struct mosquitto {
113 | #ifndef WIN32
114 | int sock;
115 | #else
116 | SOCKET sock;
117 | #endif
118 | char *address;
119 | char *id;
120 | char *username;
121 | char *password;
122 | uint16_t keepalive;
123 | bool clean_session;
124 | enum mosquitto_client_state state;
125 | time_t last_msg_in;
126 | time_t last_msg_out;
127 | time_t ping_t;
128 | uint16_t last_mid;
129 | struct _mosquitto_packet in_packet;
130 | struct _mosquitto_packet *current_out_packet;
131 | struct _mosquitto_packet *out_packet;
132 | struct mosquitto_message *will;
133 | #ifdef WITH_TLS
134 | SSL *ssl;
135 | SSL_CTX *ssl_ctx;
136 | char *tls_cafile;
137 | char *tls_capath;
138 | char *tls_certfile;
139 | char *tls_keyfile;
140 | int (*tls_pw_callback)(char *buf, int size, int rwflag, void *userdata);
141 | int tls_cert_reqs;
142 | char *tls_version;
143 | char *tls_ciphers;
144 | char *tls_psk;
145 | char *tls_psk_identity;
146 | #endif
147 | bool want_read;
148 | bool want_write;
149 | #if defined(WITH_THREADING) && !defined(WITH_BROKER)
150 | pthread_mutex_t callback_mutex;
151 | pthread_mutex_t log_callback_mutex;
152 | pthread_mutex_t msgtime_mutex;
153 | pthread_mutex_t out_packet_mutex;
154 | pthread_mutex_t current_out_packet_mutex;
155 | pthread_mutex_t state_mutex;
156 | pthread_t thread_id;
157 | #endif
158 | #ifdef WITH_BROKER
159 | bool is_bridge;
160 | struct _mqtt3_bridge *bridge;
161 | struct mosquitto_client_msg *msgs;
162 | struct _mosquitto_acl_user *acl_list;
163 | struct _mqtt3_listener *listener;
164 | time_t disconnect_t;
165 | int pollfd_index;
166 | #else
167 | void *userdata;
168 | bool in_callback;
169 | unsigned int message_retry;
170 | time_t last_retry_check;
171 | struct mosquitto_message_all *messages;
172 | void (*on_connect)(struct mosquitto *, void *userdata, int rc);
173 | void (*on_disconnect)(struct mosquitto *, void *userdata, int rc);
174 | void (*on_publish)(struct mosquitto *, void *userdata, int mid);
175 | void (*on_message)(struct mosquitto *, void *userdata, const struct mosquitto_message *message);
176 | void (*on_subscribe)(struct mosquitto *, void *userdata, int mid, int qos_count, const int *granted_qos);
177 | void (*on_unsubscribe)(struct mosquitto *, void *userdata, int mid);
178 | void (*on_log)(struct mosquitto *, void *userdata, int level, const char *str);
179 | //void (*on_error)();
180 | char *host;
181 | int port;
182 | int queue_len;
183 | #endif
184 | };
185 |
186 | #endif
187 |
--------------------------------------------------------------------------------
/libmosquitto/read_handle.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009,2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 |
44 | int _mosquitto_packet_handle(struct mosquitto *mosq)
45 | {
46 | assert(mosq);
47 |
48 | switch((mosq->in_packet.command)&0xF0){
49 | case PINGREQ:
50 | return _mosquitto_handle_pingreq(mosq);
51 | case PINGRESP:
52 | return _mosquitto_handle_pingresp(mosq);
53 | case PUBACK:
54 | return _mosquitto_handle_pubackcomp(mosq, "PUBACK");
55 | case PUBCOMP:
56 | return _mosquitto_handle_pubackcomp(mosq, "PUBCOMP");
57 | case PUBLISH:
58 | return _mosquitto_handle_publish(mosq);
59 | case PUBREC:
60 | return _mosquitto_handle_pubrec(mosq);
61 | case PUBREL:
62 | return _mosquitto_handle_pubrel(NULL, mosq);
63 | case CONNACK:
64 | return _mosquitto_handle_connack(mosq);
65 | case SUBACK:
66 | return _mosquitto_handle_suback(mosq);
67 | case UNSUBACK:
68 | return _mosquitto_handle_unsuback(mosq);
69 | default:
70 | /* If we don't recognise the command, return an error straight away. */
71 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unrecognised command %d\n", (mosq->in_packet.command)&0xF0);
72 | return MOSQ_ERR_PROTOCOL;
73 | }
74 | }
75 |
76 | int _mosquitto_handle_publish(struct mosquitto *mosq)
77 | {
78 | uint8_t header;
79 | struct mosquitto_message_all *message;
80 | int rc = 0;
81 | uint16_t mid;
82 |
83 | assert(mosq);
84 |
85 | message = _mosquitto_calloc(1, sizeof(struct mosquitto_message_all));
86 | if(!message) return MOSQ_ERR_NOMEM;
87 |
88 | header = mosq->in_packet.command;
89 |
90 | message->direction = mosq_md_in;
91 | message->dup = (header & 0x08)>>3;
92 | message->msg.qos = (header & 0x06)>>1;
93 | message->msg.retain = (header & 0x01);
94 |
95 | rc = _mosquitto_read_string(&mosq->in_packet, &message->msg.topic);
96 | if(rc){
97 | _mosquitto_message_cleanup(&message);
98 | return rc;
99 | }
100 | rc = _mosquitto_fix_sub_topic(&message->msg.topic);
101 | if(rc){
102 | _mosquitto_message_cleanup(&message);
103 | return rc;
104 | }
105 | if(!strlen(message->msg.topic)){
106 | _mosquitto_message_cleanup(&message);
107 | return MOSQ_ERR_PROTOCOL;
108 | }
109 |
110 | if(message->msg.qos > 0){
111 | rc = _mosquitto_read_uint16(&mosq->in_packet, &mid);
112 | if(rc){
113 | _mosquitto_message_cleanup(&message);
114 | return rc;
115 | }
116 | message->msg.mid = (int)mid;
117 | }
118 |
119 | message->msg.payloadlen = mosq->in_packet.remaining_length - mosq->in_packet.pos;
120 | if(message->msg.payloadlen){
121 | message->msg.payload = _mosquitto_calloc(message->msg.payloadlen+1, sizeof(uint8_t));
122 | rc = _mosquitto_read_bytes(&mosq->in_packet, message->msg.payload, message->msg.payloadlen);
123 | if(rc){
124 | _mosquitto_message_cleanup(&message);
125 | return rc;
126 | }
127 | }
128 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG,
129 | "Client %s received PUBLISH (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))",
130 | mosq->id, message->dup, message->msg.qos, message->msg.retain,
131 | message->msg.mid, message->msg.topic,
132 | (long)message->msg.payloadlen);
133 |
134 | message->timestamp = time(NULL);
135 | switch(message->msg.qos){
136 | case 0:
137 | pthread_mutex_lock(&mosq->callback_mutex);
138 | if(mosq->on_message){
139 | mosq->in_callback = true;
140 | mosq->on_message(mosq, mosq->userdata, &message->msg);
141 | mosq->in_callback = false;
142 | }
143 | pthread_mutex_unlock(&mosq->callback_mutex);
144 | _mosquitto_message_cleanup(&message);
145 | return MOSQ_ERR_SUCCESS;
146 | case 1:
147 | rc = _mosquitto_send_puback(mosq, message->msg.mid);
148 | pthread_mutex_lock(&mosq->callback_mutex);
149 | if(mosq->on_message){
150 | mosq->in_callback = true;
151 | mosq->on_message(mosq, mosq->userdata, &message->msg);
152 | mosq->in_callback = false;
153 | }
154 | pthread_mutex_unlock(&mosq->callback_mutex);
155 | _mosquitto_message_cleanup(&message);
156 | return rc;
157 | case 2:
158 | rc = _mosquitto_send_pubrec(mosq, message->msg.mid);
159 | message->state = mosq_ms_wait_pubrel;
160 | _mosquitto_message_queue(mosq, message);
161 | return rc;
162 | default:
163 | return MOSQ_ERR_PROTOCOL;
164 | }
165 | }
166 |
167 |
--------------------------------------------------------------------------------
/HomeWatch/MosquittoClient.m:
--------------------------------------------------------------------------------
1 | //
2 | // MosquittoClient.m
3 | //
4 | // Copyright 2012 Nicholas Humfrey. All rights reserved.
5 | // Modified by Basuke Suzuki 2013.
6 | //
7 |
8 | #import "MosquittoClient.h"
9 |
10 | // C Callbacks
11 | static void on_connect(struct mosquitto *mosq, void *obj, int rc);
12 | static void on_disconnect(struct mosquitto *mosq, void *obj, int rc);
13 | static void on_publish(struct mosquitto *mosq, void *obj, int message_id);
14 | static void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message);
15 | static void on_subscribe(struct mosquitto *mosq, void *obj, int message_id, int qos_count, const int *granted_qos);
16 | static void on_unsubscribe(struct mosquitto *mosq, void *obj, int message_id);
17 | static void on_log(struct mosquitto *mosq, void *obj, int level, const char *str);
18 |
19 |
20 | @implementation MosquittoClient {
21 | struct mosquitto *_mosq;
22 | BOOL _connected;
23 | NSTimer *_idleTimer;
24 | }
25 |
26 | // Initialize is called just before the first object is allocated
27 | + (void)initialize {
28 | mosquitto_lib_init();
29 | }
30 |
31 | + (NSString*)version {
32 | int major, minor, revision;
33 | mosquitto_lib_version(&major, &minor, &revision);
34 | return [NSString stringWithFormat:@"%d.%d.%d", major, minor, revision];
35 | }
36 |
37 | - (MosquittoClient*)initWithClientId:(NSString*)clientId cleanSession:(BOOL)isCleanSession {
38 | if ((self = [super init])) {
39 | const char* cstrClientId = [clientId UTF8String];
40 | [self setHost: @"localhost"];
41 | [self setPort: 1883];
42 | [self setKeepAlive: 60];
43 |
44 | _mosq = mosquitto_new(cstrClientId, isCleanSession, (__bridge void *)(self));
45 | mosquitto_connect_callback_set(_mosq, on_connect);
46 | mosquitto_disconnect_callback_set(_mosq, on_disconnect);
47 | mosquitto_publish_callback_set(_mosq, on_publish);
48 | mosquitto_message_callback_set(_mosq, on_message);
49 | mosquitto_subscribe_callback_set(_mosq, on_subscribe);
50 | mosquitto_unsubscribe_callback_set(_mosq, on_unsubscribe);
51 | }
52 | return self;
53 | }
54 |
55 | - (void)dealloc {
56 | if (_mosq) {
57 | [self disconnect];
58 |
59 | mosquitto_destroy(_mosq);
60 | _mosq = NULL;
61 | }
62 | }
63 |
64 | - (BOOL)connect {
65 | if (_connected) return YES;
66 |
67 | const char *cstrHost = [_host cStringUsingEncoding:NSASCIIStringEncoding];
68 | const char *cstrUsername = NULL, *cstrPassword = NULL;
69 |
70 | if (_username)
71 | cstrUsername = [_username UTF8String];
72 |
73 | if (_password)
74 | cstrPassword = [_password UTF8String];
75 |
76 | mosquitto_username_pw_set(_mosq, cstrUsername, cstrPassword);
77 |
78 | int rc = mosquitto_connect(_mosq, cstrHost, _port, _keepAlive);
79 | if (rc == MOSQ_ERR_ERRNO) {
80 | NSError *err = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:@{NSLocalizedDescriptionKey:[NSString stringWithUTF8String:strerror(errno)]}];
81 | [self.delegate mosquitto:self didFailToConnectWithError:err];
82 | return NO;
83 | }
84 |
85 | _connected = YES;
86 | _idleTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(onIdle:) userInfo:nil repeats:YES];
87 |
88 | return YES;
89 | }
90 |
91 | - (void)disconnect {
92 | if (_connected) {
93 | mosquitto_disconnect(_mosq);
94 | }
95 | }
96 |
97 | - (BOOL)isConnected
98 | {
99 | return _connected;
100 | }
101 |
102 | - (void)setWill:(NSString *)payload toTopic:(NSString *)topic withQos:(NSUInteger)qos retained:(BOOL)retained;
103 | {
104 | const char* cstrTopic = [topic UTF8String];
105 | const uint8_t* cstrPayload = (const uint8_t*)[payload UTF8String];
106 | size_t cstrlen = [payload lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
107 | mosquitto_will_set(_mosq, cstrTopic, cstrlen, cstrPayload, qos, retained);
108 | }
109 |
110 |
111 | - (void)clearWill
112 | {
113 | mosquitto_will_clear(_mosq);
114 | }
115 |
116 | - (void)publish:(NSString *)payload toTopic:(NSString *)topic withQos:(NSUInteger)qos retained:(BOOL)retained {
117 | const char* cstrTopic = [topic UTF8String];
118 | const uint8_t* cstrPayload = (const uint8_t*)[payload UTF8String];
119 | size_t cstrlen = [payload lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
120 | mosquitto_publish(_mosq, NULL, cstrTopic, cstrlen, cstrPayload, qos, retained);
121 |
122 | }
123 |
124 | - (void)subscribe: (NSString *)topic {
125 | [self subscribe:topic withQos:0];
126 | }
127 |
128 | - (void)subscribe: (NSString *)topic withQos:(NSUInteger)qos {
129 | const char* cstrTopic = [topic UTF8String];
130 | mosquitto_subscribe(_mosq, NULL, cstrTopic, qos);
131 | }
132 |
133 | - (void)unsubscribe: (NSString *)topic {
134 | const char* cstrTopic = [topic UTF8String];
135 | mosquitto_unsubscribe(_mosq, NULL, cstrTopic);
136 | }
137 |
138 | - (void)setMessageRetry: (NSUInteger)seconds
139 | {
140 | mosquitto_message_retry_set(_mosq, (unsigned int)seconds);
141 | }
142 |
143 | - (void)onMessage:(const struct mosquitto_message *)message
144 | {
145 | MosquittoMessage *mosq_msg = [[MosquittoMessage alloc] init];
146 |
147 | mosq_msg.mid = message->mid;
148 | mosq_msg.qos = message->qos;
149 | mosq_msg.retained = message->retain;
150 |
151 | mosq_msg.topic = [NSString stringWithUTF8String: message->topic];
152 | mosq_msg.payload = [[NSString alloc] initWithBytes:message->payload
153 | length:message->payloadlen
154 | encoding:NSUTF8StringEncoding];
155 |
156 | [self.delegate mosquitto:self didReceiveMessage:mosq_msg];
157 | }
158 |
159 | - (void)onDisconnected
160 | {
161 | [_idleTimer invalidate];
162 | _idleTimer = nil;
163 | _connected = NO;
164 |
165 | [self.delegate mosquittoDidDisconnect:self];
166 | }
167 |
168 | - (void)onIdle:(NSTimer *)timer
169 | {
170 | mosquitto_loop(_mosq, 1, 1);
171 | }
172 |
173 | @end
174 |
175 | static void on_connect(struct mosquitto *mosq, void *obj, int rc)
176 | {
177 | MosquittoClient* client = (__bridge MosquittoClient*)obj;
178 | [[client delegate] mosquitto:client didConnect:(NSUInteger)rc];
179 | }
180 |
181 | static void on_disconnect(struct mosquitto *mosq, void *obj, int rc)
182 | {
183 | MosquittoClient* client = (__bridge MosquittoClient*)obj;
184 | [client onDisconnected];
185 | }
186 |
187 | static void on_publish(struct mosquitto *mosq, void *obj, int message_id)
188 | {
189 | MosquittoClient* client = (__bridge MosquittoClient*)obj;
190 | [[client delegate] mosquitto:client didPublish:(NSUInteger)message_id];
191 | }
192 |
193 | static void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
194 | {
195 | MosquittoClient* client = (__bridge MosquittoClient*)obj;
196 | [client onMessage:message];
197 | }
198 |
199 | static void on_subscribe(struct mosquitto *mosq, void *obj, int message_id, int qos_count, const int *granted_qos)
200 | {
201 | MosquittoClient* client = (__bridge MosquittoClient*)obj;
202 | // FIXME: implement this
203 | [[client delegate] mosquitto:client didSubscribe:message_id grantedQos:nil];
204 | }
205 |
206 | static void on_unsubscribe(struct mosquitto *mosq, void *obj, int message_id)
207 | {
208 | MosquittoClient* client = (__bridge MosquittoClient*)obj;
209 | [[client delegate] mosquitto:client didUnsubscribe:message_id];
210 | }
211 |
212 | static void on_log(struct mosquitto *mosq, void *obj, int level, const char *str)
213 | {
214 | MosquittoClient* client = (__bridge MosquittoClient*)obj;
215 | NSString *message = [NSString stringWithUTF8String:str];
216 | [[client delegate] mosquitto:client log:message level:level];
217 | }
218 |
219 |
--------------------------------------------------------------------------------
/libmosquitto/messages_mosq.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 | void _mosquitto_message_cleanup(struct mosquitto_message_all **message)
41 | {
42 | struct mosquitto_message_all *msg;
43 |
44 | if(!message || !*message) return;
45 |
46 | msg = *message;
47 |
48 | if(msg->msg.topic) _mosquitto_free(msg->msg.topic);
49 | if(msg->msg.payload) _mosquitto_free(msg->msg.payload);
50 | _mosquitto_free(msg);
51 | }
52 |
53 | void _mosquitto_message_cleanup_all(struct mosquitto *mosq)
54 | {
55 | struct mosquitto_message_all *tmp;
56 |
57 | assert(mosq);
58 |
59 | while(mosq->messages){
60 | tmp = mosq->messages->next;
61 | _mosquitto_message_cleanup(&mosq->messages);
62 | mosq->messages = tmp;
63 | }
64 | }
65 |
66 | int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src)
67 | {
68 | if(!dst || !src) return MOSQ_ERR_INVAL;
69 |
70 | dst->mid = src->mid;
71 | dst->topic = _mosquitto_strdup(src->topic);
72 | if(!dst->topic) return MOSQ_ERR_NOMEM;
73 | dst->qos = src->qos;
74 | dst->retain = src->retain;
75 | if(src->payloadlen){
76 | dst->payload = _mosquitto_malloc(src->payloadlen);
77 | if(!dst->payload){
78 | _mosquitto_free(dst->topic);
79 | return MOSQ_ERR_NOMEM;
80 | }
81 | memcpy(dst->payload, src->payload, src->payloadlen);
82 | dst->payloadlen = src->payloadlen;
83 | }else{
84 | dst->payloadlen = 0;
85 | dst->payload = NULL;
86 | }
87 | return MOSQ_ERR_SUCCESS;
88 | }
89 |
90 | int _mosquitto_message_delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir)
91 | {
92 | struct mosquitto_message_all *message;
93 | int rc;
94 | assert(mosq);
95 |
96 | rc = _mosquitto_message_remove(mosq, mid, dir, &message);
97 | if(rc == MOSQ_ERR_SUCCESS){
98 | _mosquitto_message_cleanup(&message);
99 | }
100 | return rc;
101 | }
102 |
103 | void mosquitto_message_free(struct mosquitto_message **message)
104 | {
105 | struct mosquitto_message *msg;
106 |
107 | if(!message || !*message) return;
108 |
109 | msg = *message;
110 |
111 | if(msg->topic) _mosquitto_free(msg->topic);
112 | if(msg->payload) _mosquitto_free(msg->payload);
113 | _mosquitto_free(msg);
114 | }
115 |
116 | void _mosquitto_message_queue(struct mosquitto *mosq, struct mosquitto_message_all *message)
117 | {
118 | struct mosquitto_message_all *tail;
119 |
120 | assert(mosq);
121 | assert(message);
122 |
123 | mosq->queue_len++;
124 | message->next = NULL;
125 | if(mosq->messages){
126 | tail = mosq->messages;
127 | while(tail->next){
128 | tail = tail->next;
129 | }
130 | tail->next = message;
131 | }else{
132 | mosq->messages = message;
133 | }
134 | }
135 |
136 | void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq)
137 | {
138 | struct mosquitto_message_all *message;
139 | struct mosquitto_message_all *prev = NULL;
140 | assert(mosq);
141 |
142 | mosq->queue_len = 0;
143 | message = mosq->messages;
144 | while(message){
145 | message->timestamp = 0;
146 | if(message->direction == mosq_md_out){
147 | if(message->msg.qos == 1){
148 | message->state = mosq_ms_wait_puback;
149 | }else if(message->msg.qos == 2){
150 | message->state = mosq_ms_wait_pubrec;
151 | }
152 | mosq->queue_len++;
153 | }else{
154 | if(prev){
155 | prev->next = message->next;
156 | _mosquitto_message_cleanup(&message);
157 | message = prev;
158 | }else{
159 | mosq->messages = message->next;
160 | _mosquitto_message_cleanup(&message);
161 | message = mosq->messages;
162 | }
163 | }
164 | prev = message;
165 | message = message->next;
166 | }
167 | }
168 |
169 | int _mosquitto_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message)
170 | {
171 | struct mosquitto_message_all *cur, *prev = NULL;
172 | assert(mosq);
173 | assert(message);
174 |
175 | cur = mosq->messages;
176 | while(cur){
177 | if(cur->msg.mid == mid && cur->direction == dir){
178 | if(prev){
179 | prev->next = cur->next;
180 | }else{
181 | mosq->messages = cur->next;
182 | }
183 | *message = cur;
184 | mosq->queue_len--;
185 | return MOSQ_ERR_SUCCESS;
186 | }
187 | prev = cur;
188 | cur = cur->next;
189 | }
190 | return MOSQ_ERR_NOT_FOUND;
191 | }
192 |
193 | void _mosquitto_message_retry_check(struct mosquitto *mosq)
194 | {
195 | struct mosquitto_message_all *message;
196 | time_t now = time(NULL);
197 | assert(mosq);
198 |
199 | message = mosq->messages;
200 | while(message){
201 | if(message->timestamp + mosq->message_retry < now){
202 | switch(message->state){
203 | case mosq_ms_wait_puback:
204 | case mosq_ms_wait_pubrec:
205 | message->timestamp = now;
206 | message->dup = true;
207 | _mosquitto_send_publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup);
208 | break;
209 | case mosq_ms_wait_pubrel:
210 | message->timestamp = now;
211 | message->dup = true;
212 | _mosquitto_send_pubrec(mosq, message->msg.mid);
213 | break;
214 | case mosq_ms_wait_pubcomp:
215 | message->timestamp = now;
216 | message->dup = true;
217 | _mosquitto_send_pubrel(mosq, message->msg.mid, true);
218 | break;
219 | default:
220 | break;
221 | }
222 | }
223 | message = message->next;
224 | }
225 | }
226 |
227 | void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry)
228 | {
229 | assert(mosq);
230 | if(mosq) mosq->message_retry = message_retry;
231 | }
232 |
233 | int _mosquitto_message_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, enum mosquitto_msg_state state)
234 | {
235 | struct mosquitto_message_all *message;
236 | assert(mosq);
237 |
238 | message = mosq->messages;
239 | while(message){
240 | if(message->msg.mid == mid && message->direction == dir){
241 | message->state = state;
242 | message->timestamp = time(NULL);
243 | return MOSQ_ERR_SUCCESS;
244 | }
245 | message = message->next;
246 | }
247 | return MOSQ_ERR_NOT_FOUND;
248 | }
249 |
250 |
--------------------------------------------------------------------------------
/libmosquitto/send_client_mosq.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009-2011 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 | #include
32 |
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 |
41 | #ifdef WITH_BROKER
42 | #include
43 | #endif
44 |
45 | int _mosquitto_send_connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session)
46 | {
47 | struct _mosquitto_packet *packet = NULL;
48 | int payloadlen;
49 | uint8_t will = 0;
50 | uint8_t byte;
51 | int rc;
52 | uint8_t version = PROTOCOL_VERSION;
53 |
54 | assert(mosq);
55 | assert(mosq->id);
56 |
57 | packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
58 | if(!packet) return MOSQ_ERR_NOMEM;
59 |
60 | payloadlen = 2+strlen(mosq->id);
61 | if(mosq->will){
62 | will = 1;
63 | assert(mosq->will->topic);
64 |
65 | payloadlen += 2+strlen(mosq->will->topic) + 2+mosq->will->payloadlen;
66 | }
67 | if(mosq->username){
68 | payloadlen += 2+strlen(mosq->username);
69 | if(mosq->password){
70 | payloadlen += 2+strlen(mosq->password);
71 | }
72 | }
73 |
74 | packet->command = CONNECT;
75 | packet->remaining_length = 12+payloadlen;
76 | rc = _mosquitto_packet_alloc(packet);
77 | if(rc){
78 | _mosquitto_free(packet);
79 | return rc;
80 | }
81 |
82 | /* Variable header */
83 | _mosquitto_write_string(packet, PROTOCOL_NAME, strlen(PROTOCOL_NAME));
84 | #if defined(WITH_BROKER) && defined(WITH_BRIDGE)
85 | if(mosq->bridge && mosq->bridge->try_private && mosq->bridge->try_private_accepted){
86 | version |= 0x80;
87 | }else{
88 | }
89 | #endif
90 | _mosquitto_write_byte(packet, version);
91 | byte = (clean_session&0x1)<<1;
92 | if(will){
93 | byte = byte | ((mosq->will->retain&0x1)<<5) | ((mosq->will->qos&0x3)<<3) | ((will&0x1)<<2);
94 | }
95 | if(mosq->username){
96 | byte = byte | 0x1<<7;
97 | if(mosq->password){
98 | byte = byte | 0x1<<6;
99 | }
100 | }
101 | _mosquitto_write_byte(packet, byte);
102 | _mosquitto_write_uint16(packet, keepalive);
103 |
104 | /* Payload */
105 | _mosquitto_write_string(packet, mosq->id, strlen(mosq->id));
106 | if(will){
107 | _mosquitto_write_string(packet, mosq->will->topic, strlen(mosq->will->topic));
108 | _mosquitto_write_string(packet, (const char *)mosq->will->payload, mosq->will->payloadlen);
109 | }
110 | if(mosq->username){
111 | _mosquitto_write_string(packet, mosq->username, strlen(mosq->username));
112 | if(mosq->password){
113 | _mosquitto_write_string(packet, mosq->password, strlen(mosq->password));
114 | }
115 | }
116 |
117 | mosq->keepalive = keepalive;
118 | #ifdef WITH_BROKER
119 | # ifdef WITH_BRIDGE
120 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending CONNECT", mosq->id);
121 | # endif
122 | #else
123 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending CONNECT", mosq->id);
124 | #endif
125 | return _mosquitto_packet_queue(mosq, packet);
126 | }
127 |
128 | int _mosquitto_send_disconnect(struct mosquitto *mosq)
129 | {
130 | assert(mosq);
131 | #ifdef WITH_BROKER
132 | # ifdef WITH_BRIDGE
133 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending DISCONNECT", mosq->id);
134 | # endif
135 | #else
136 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending DISCONNECT", mosq->id);
137 | #endif
138 | return _mosquitto_send_simple_command(mosq, DISCONNECT);
139 | }
140 |
141 | int _mosquitto_send_subscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic, uint8_t topic_qos)
142 | {
143 | /* FIXME - only deals with a single topic */
144 | struct _mosquitto_packet *packet = NULL;
145 | uint32_t packetlen;
146 | uint16_t local_mid;
147 | int rc;
148 |
149 | assert(mosq);
150 | assert(topic);
151 |
152 | packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
153 | if(!packet) return MOSQ_ERR_NOMEM;
154 |
155 | packetlen = 2 + 2+strlen(topic) + 1;
156 |
157 | packet->command = SUBSCRIBE | (dup<<3) | (1<<1);
158 | packet->remaining_length = packetlen;
159 | rc = _mosquitto_packet_alloc(packet);
160 | if(rc){
161 | _mosquitto_free(packet);
162 | return rc;
163 | }
164 |
165 | /* Variable header */
166 | local_mid = _mosquitto_mid_generate(mosq);
167 | if(mid) *mid = (int)local_mid;
168 | _mosquitto_write_uint16(packet, local_mid);
169 |
170 | /* Payload */
171 | _mosquitto_write_string(packet, topic, strlen(topic));
172 | _mosquitto_write_byte(packet, topic_qos);
173 |
174 | #ifdef WITH_BROKER
175 | # ifdef WITH_BRIDGE
176 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending SUBSCRIBE (Mid: %d, Topic: %s, QoS: %d)", mosq->id, local_mid, topic, topic_qos);
177 | # endif
178 | #else
179 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending SUBSCRIBE (Mid: %d, Topic: %s, QoS: %d)", mosq->id, local_mid, topic, topic_qos);
180 | #endif
181 |
182 | return _mosquitto_packet_queue(mosq, packet);
183 | }
184 |
185 |
186 | int _mosquitto_send_unsubscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic)
187 | {
188 | /* FIXME - only deals with a single topic */
189 | struct _mosquitto_packet *packet = NULL;
190 | uint32_t packetlen;
191 | uint16_t local_mid;
192 | int rc;
193 |
194 | assert(mosq);
195 | assert(topic);
196 |
197 | packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
198 | if(!packet) return MOSQ_ERR_NOMEM;
199 |
200 | packetlen = 2 + 2+strlen(topic);
201 |
202 | packet->command = UNSUBSCRIBE | (dup<<3) | (1<<1);
203 | packet->remaining_length = packetlen;
204 | rc = _mosquitto_packet_alloc(packet);
205 | if(rc){
206 | _mosquitto_free(packet);
207 | return rc;
208 | }
209 |
210 | /* Variable header */
211 | local_mid = _mosquitto_mid_generate(mosq);
212 | if(mid) *mid = (int)local_mid;
213 | _mosquitto_write_uint16(packet, local_mid);
214 |
215 | /* Payload */
216 | _mosquitto_write_string(packet, topic, strlen(topic));
217 |
218 | #ifdef WITH_BROKER
219 | # ifdef WITH_BRIDGE
220 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic);
221 | # endif
222 | #else
223 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic);
224 | #endif
225 | return _mosquitto_packet_queue(mosq, packet);
226 | }
227 |
228 |
--------------------------------------------------------------------------------
/libmosquitto/read_handle_shared.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009-2012 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #ifdef WITH_BROKER
44 | #include
45 | #endif
46 |
47 | int _mosquitto_handle_pingreq(struct mosquitto *mosq)
48 | {
49 | assert(mosq);
50 | #ifdef WITH_STRICT_PROTOCOL
51 | if(mosq->in_packet.remaining_length != 0){
52 | return MOSQ_ERR_PROTOCOL;
53 | }
54 | #endif
55 | #ifdef WITH_BROKER
56 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PINGREQ from %s", mosq->id);
57 | #else
58 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGREQ", mosq->id);
59 | #endif
60 | return _mosquitto_send_pingresp(mosq);
61 | }
62 |
63 | int _mosquitto_handle_pingresp(struct mosquitto *mosq)
64 | {
65 | assert(mosq);
66 | #ifdef WITH_STRICT_PROTOCOL
67 | if(mosq->in_packet.remaining_length != 0){
68 | return MOSQ_ERR_PROTOCOL;
69 | }
70 | #endif
71 | mosq->ping_t = 0; /* No longer waiting for a PINGRESP. */
72 | #ifdef WITH_BROKER
73 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PINGRESP from %s", mosq->id);
74 | #else
75 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGRESP", mosq->id);
76 | #endif
77 | return MOSQ_ERR_SUCCESS;
78 | }
79 |
80 | int _mosquitto_handle_pubackcomp(struct mosquitto *mosq, const char *type)
81 | {
82 | uint16_t mid;
83 | int rc;
84 |
85 | assert(mosq);
86 | #ifdef WITH_STRICT_PROTOCOL
87 | if(mosq->in_packet.remaining_length != 2){
88 | return MOSQ_ERR_PROTOCOL;
89 | }
90 | #endif
91 | rc = _mosquitto_read_uint16(&mosq->in_packet, &mid);
92 | if(rc) return rc;
93 | #ifdef WITH_BROKER
94 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received %s from %s (Mid: %d)", type, mosq->id, mid);
95 |
96 | if(mid){
97 | rc = mqtt3_db_message_delete(mosq, mid, mosq_md_out);
98 | if(rc) return rc;
99 | }
100 | #else
101 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received %s (Mid: %d)", mosq->id, type, mid);
102 |
103 | if(!_mosquitto_message_delete(mosq, mid, mosq_md_out)){
104 | /* Only inform the client the message has been sent once. */
105 | pthread_mutex_lock(&mosq->callback_mutex);
106 | if(mosq->on_publish){
107 | mosq->in_callback = true;
108 | mosq->on_publish(mosq, mosq->userdata, mid);
109 | mosq->in_callback = false;
110 | }
111 | pthread_mutex_unlock(&mosq->callback_mutex);
112 | }
113 | #endif
114 |
115 | return MOSQ_ERR_SUCCESS;
116 | }
117 |
118 | int _mosquitto_handle_pubrec(struct mosquitto *mosq)
119 | {
120 | uint16_t mid;
121 | int rc;
122 |
123 | assert(mosq);
124 | #ifdef WITH_STRICT_PROTOCOL
125 | if(mosq->in_packet.remaining_length != 2){
126 | return MOSQ_ERR_PROTOCOL;
127 | }
128 | #endif
129 | rc = _mosquitto_read_uint16(&mosq->in_packet, &mid);
130 | if(rc) return rc;
131 | #ifdef WITH_BROKER
132 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREC from %s (Mid: %d)", mosq->id, mid);
133 |
134 | rc = mqtt3_db_message_update(mosq, mid, mosq_md_out, ms_wait_for_pubcomp);
135 | #else
136 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREC (Mid: %d)", mosq->id, mid);
137 |
138 | rc = _mosquitto_message_update(mosq, mid, mosq_md_out, mosq_ms_wait_pubcomp);
139 | #endif
140 | if(rc) return rc;
141 | rc = _mosquitto_send_pubrel(mosq, mid, false);
142 | if(rc) return rc;
143 |
144 | return MOSQ_ERR_SUCCESS;
145 | }
146 |
147 | int _mosquitto_handle_pubrel(struct mosquitto_db *db, struct mosquitto *mosq)
148 | {
149 | uint16_t mid;
150 | #ifndef WITH_BROKER
151 | struct mosquitto_message_all *message = NULL;
152 | #endif
153 | int rc;
154 |
155 | assert(mosq);
156 | #ifdef WITH_STRICT_PROTOCOL
157 | if(mosq->in_packet.remaining_length != 2){
158 | return MOSQ_ERR_PROTOCOL;
159 | }
160 | #endif
161 | rc = _mosquitto_read_uint16(&mosq->in_packet, &mid);
162 | if(rc) return rc;
163 | #ifdef WITH_BROKER
164 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREL from %s (Mid: %d)", mosq->id, mid);
165 |
166 | if(mqtt3_db_message_release(db, mosq, mid, mosq_md_in)){
167 | /* Message not found. */
168 | return MOSQ_ERR_SUCCESS;
169 | }
170 | #else
171 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREL (Mid: %d)", mosq->id, mid);
172 |
173 | if(!_mosquitto_message_remove(mosq, mid, mosq_md_in, &message)){
174 | /* Only pass the message on if we have removed it from the queue - this
175 | * prevents multiple callbacks for the same message. */
176 | pthread_mutex_lock(&mosq->callback_mutex);
177 | if(mosq->on_message){
178 | mosq->in_callback = true;
179 | mosq->on_message(mosq, mosq->userdata, &message->msg);
180 | mosq->in_callback = false;
181 | }
182 | pthread_mutex_unlock(&mosq->callback_mutex);
183 | _mosquitto_message_cleanup(&message);
184 | }
185 | #endif
186 | rc = _mosquitto_send_pubcomp(mosq, mid);
187 | if(rc) return rc;
188 |
189 | return MOSQ_ERR_SUCCESS;
190 | }
191 |
192 | int _mosquitto_handle_suback(struct mosquitto *mosq)
193 | {
194 | uint16_t mid;
195 | uint8_t qos;
196 | int *granted_qos;
197 | int qos_count;
198 | int i = 0;
199 | int rc;
200 |
201 | assert(mosq);
202 | #ifdef WITH_BROKER
203 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received SUBACK from %s", mosq->id);
204 | #else
205 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received SUBACK", mosq->id);
206 | #endif
207 | rc = _mosquitto_read_uint16(&mosq->in_packet, &mid);
208 | if(rc) return rc;
209 |
210 | qos_count = mosq->in_packet.remaining_length - mosq->in_packet.pos;
211 | granted_qos = _mosquitto_malloc(qos_count*sizeof(int));
212 | if(!granted_qos) return MOSQ_ERR_NOMEM;
213 | while(mosq->in_packet.pos < mosq->in_packet.remaining_length){
214 | rc = _mosquitto_read_byte(&mosq->in_packet, &qos);
215 | if(rc){
216 | _mosquitto_free(granted_qos);
217 | return rc;
218 | }
219 | granted_qos[i] = (int)qos;
220 | i++;
221 | }
222 | #ifndef WITH_BROKER
223 | pthread_mutex_lock(&mosq->callback_mutex);
224 | if(mosq->on_subscribe){
225 | mosq->in_callback = true;
226 | mosq->on_subscribe(mosq, mosq->userdata, mid, qos_count, granted_qos);
227 | mosq->in_callback = false;
228 | }
229 | pthread_mutex_unlock(&mosq->callback_mutex);
230 | #endif
231 | _mosquitto_free(granted_qos);
232 |
233 | return MOSQ_ERR_SUCCESS;
234 | }
235 |
236 | int _mosquitto_handle_unsuback(struct mosquitto *mosq)
237 | {
238 | uint16_t mid;
239 | int rc;
240 |
241 | assert(mosq);
242 | #ifdef WITH_STRICT_PROTOCOL
243 | if(mosq->in_packet.remaining_length != 2){
244 | return MOSQ_ERR_PROTOCOL;
245 | }
246 | #endif
247 | #ifdef WITH_BROKER
248 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBACK from %s", mosq->id);
249 | #else
250 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received UNSUBACK", mosq->id);
251 | #endif
252 | rc = _mosquitto_read_uint16(&mosq->in_packet, &mid);
253 | if(rc) return rc;
254 | #ifndef WITH_BROKER
255 | pthread_mutex_lock(&mosq->callback_mutex);
256 | if(mosq->on_unsubscribe){
257 | mosq->in_callback = true;
258 | mosq->on_unsubscribe(mosq, mosq->userdata, mid);
259 | mosq->in_callback = false;
260 | }
261 | pthread_mutex_unlock(&mosq->callback_mutex);
262 | #endif
263 |
264 | return MOSQ_ERR_SUCCESS;
265 | }
266 |
267 |
--------------------------------------------------------------------------------
/libmosquitto/util_mosq.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009-2012 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | #ifdef WIN32
35 | #include
36 | #endif
37 |
38 | #if defined(WITH_TLS) && defined(WITH_TLS_PSK)
39 | #include
40 | #endif
41 |
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 | #ifdef WITH_BROKER
49 | #include
50 | #endif
51 |
52 | int _mosquitto_packet_alloc(struct _mosquitto_packet *packet)
53 | {
54 | uint8_t remaining_bytes[5], byte;
55 | uint32_t remaining_length;
56 | int i;
57 |
58 | assert(packet);
59 |
60 | remaining_length = packet->remaining_length;
61 | packet->payload = NULL;
62 | packet->remaining_count = 0;
63 | do{
64 | byte = remaining_length % 128;
65 | remaining_length = remaining_length / 128;
66 | /* If there are more digits to encode, set the top bit of this digit */
67 | if(remaining_length > 0){
68 | byte = byte | 0x80;
69 | }
70 | remaining_bytes[packet->remaining_count] = byte;
71 | packet->remaining_count++;
72 | }while(remaining_length > 0 && packet->remaining_count < 5);
73 | if(packet->remaining_count == 5) return MOSQ_ERR_PAYLOAD_SIZE;
74 | packet->packet_length = packet->remaining_length + 1 + packet->remaining_count;
75 | packet->payload = _mosquitto_malloc(sizeof(uint8_t)*packet->packet_length);
76 | if(!packet->payload) return MOSQ_ERR_NOMEM;
77 |
78 | packet->payload[0] = packet->command;
79 | for(i=0; iremaining_count; i++){
80 | packet->payload[i+1] = remaining_bytes[i];
81 | }
82 | packet->pos = 1 + packet->remaining_count;
83 |
84 | return MOSQ_ERR_SUCCESS;
85 | }
86 |
87 | void _mosquitto_check_keepalive(struct mosquitto *mosq)
88 | {
89 | time_t last_msg_out;
90 | time_t last_msg_in;
91 | time_t now = time(NULL);
92 | #ifndef WITH_BROKER
93 | int rc;
94 | #endif
95 |
96 | assert(mosq);
97 | #if defined(WITH_BROKER) && defined(WITH_BRIDGE)
98 | /* Check if a lazy bridge should be timed out due to idle. */
99 | if(mosq->bridge && mosq->bridge->start_type == bst_lazy
100 | && mosq->sock != INVALID_SOCKET
101 | && now - mosq->last_msg_out >= mosq->bridge->idle_timeout){
102 |
103 | _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Bridge connection %s has exceeded idle timeout, disconnecting.", mosq->id);
104 | _mosquitto_socket_close(mosq);
105 | return;
106 | }
107 | #endif
108 | pthread_mutex_lock(&mosq->msgtime_mutex);
109 | last_msg_out = mosq->last_msg_out;
110 | last_msg_in = mosq->last_msg_in;
111 | pthread_mutex_unlock(&mosq->msgtime_mutex);
112 | if(mosq->sock != INVALID_SOCKET &&
113 | (now - last_msg_out >= mosq->keepalive || now - last_msg_in >= mosq->keepalive)){
114 |
115 | if(mosq->state == mosq_cs_connected && mosq->ping_t == 0){
116 | _mosquitto_send_pingreq(mosq);
117 | /* Reset last msg times to give the server time to send a pingresp */
118 | pthread_mutex_lock(&mosq->msgtime_mutex);
119 | mosq->last_msg_in = now;
120 | mosq->last_msg_out = now;
121 | pthread_mutex_unlock(&mosq->msgtime_mutex);
122 | }else{
123 | #ifdef WITH_BROKER
124 | if(mosq->listener){
125 | mosq->listener->client_count--;
126 | assert(mosq->listener->client_count >= 0);
127 | }
128 | mosq->listener = NULL;
129 | #endif
130 | _mosquitto_socket_close(mosq);
131 | #ifndef WITH_BROKER
132 | pthread_mutex_lock(&mosq->state_mutex);
133 | if(mosq->state == mosq_cs_disconnecting){
134 | rc = MOSQ_ERR_SUCCESS;
135 | }else{
136 | rc = 1;
137 | }
138 | pthread_mutex_unlock(&mosq->state_mutex);
139 | pthread_mutex_lock(&mosq->callback_mutex);
140 | if(mosq->on_disconnect){
141 | mosq->in_callback = true;
142 | mosq->on_disconnect(mosq, mosq->userdata, rc);
143 | mosq->in_callback = false;
144 | }
145 | pthread_mutex_unlock(&mosq->callback_mutex);
146 | #endif
147 | }
148 | }
149 | }
150 |
151 | /* Convert ////some////over/slashed///topic/etc/etc//
152 | * into some/over/slashed/topic/etc/etc
153 | */
154 | int _mosquitto_fix_sub_topic(char **subtopic)
155 | {
156 | char *fixed = NULL;
157 | char *token;
158 | char *saveptr = NULL;
159 |
160 | assert(subtopic);
161 | assert(*subtopic);
162 |
163 | if(strlen(*subtopic) == 0) return MOSQ_ERR_SUCCESS;
164 | /* size of fixed here is +1 for the terminating 0 and +1 for the spurious /
165 | * that gets appended. */
166 | fixed = _mosquitto_calloc(strlen(*subtopic)+2, 1);
167 | if(!fixed) return MOSQ_ERR_NOMEM;
168 |
169 | if((*subtopic)[0] == '/'){
170 | fixed[0] = '/';
171 | }
172 | token = strtok_r(*subtopic, "/", &saveptr);
173 | while(token){
174 | strcat(fixed, token);
175 | strcat(fixed, "/");
176 | token = strtok_r(NULL, "/", &saveptr);
177 | }
178 |
179 | fixed[strlen(fixed)-1] = '\0';
180 | _mosquitto_free(*subtopic);
181 | *subtopic = fixed;
182 | return MOSQ_ERR_SUCCESS;
183 | }
184 |
185 | uint16_t _mosquitto_mid_generate(struct mosquitto *mosq)
186 | {
187 | assert(mosq);
188 |
189 | mosq->last_mid++;
190 | if(mosq->last_mid == 0) mosq->last_mid++;
191 |
192 | return mosq->last_mid;
193 | }
194 |
195 | /* Search for + or # in a topic. Return MOSQ_ERR_INVAL if found.
196 | * Also returns MOSQ_ERR_INVAL if the topic string is too long.
197 | * Returns MOSQ_ERR_SUCCESS if everything is fine.
198 | */
199 | int _mosquitto_topic_wildcard_len_check(const char *str)
200 | {
201 | int len = 0;
202 | while(str && str[0]){
203 | if(str[0] == '+' || str[0] == '#'){
204 | return MOSQ_ERR_INVAL;
205 | }
206 | len++;
207 | str = &str[1];
208 | }
209 | if(len > 65535) return MOSQ_ERR_INVAL;
210 |
211 | return MOSQ_ERR_SUCCESS;
212 | }
213 |
214 | /* Does a topic match a subscription? */
215 | int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result)
216 | {
217 | char *local_sub, *local_topic;
218 | int slen, tlen;
219 | int spos, tpos;
220 | int rc;
221 | bool multilevel_wildcard = false;
222 |
223 | if(!sub || !topic || !result) return MOSQ_ERR_INVAL;
224 |
225 | local_sub = _mosquitto_strdup(sub);
226 | if(!local_sub) return MOSQ_ERR_NOMEM;
227 | rc = _mosquitto_fix_sub_topic(&local_sub);
228 | if(rc){
229 | _mosquitto_free(local_sub);
230 | return rc;
231 | }
232 |
233 | local_topic = _mosquitto_strdup(topic);
234 | if(!local_topic){
235 | _mosquitto_free(local_sub);
236 | return MOSQ_ERR_NOMEM;
237 | }
238 | rc = _mosquitto_fix_sub_topic(&local_topic);
239 | if(rc){
240 | _mosquitto_free(local_sub);
241 | _mosquitto_free(local_topic);
242 | return rc;
243 | }
244 |
245 | slen = strlen(local_sub);
246 | tlen = strlen(local_topic);
247 |
248 | spos = 0;
249 | tpos = 0;
250 |
251 | while(spos < slen && tpos < tlen){
252 | if(local_sub[spos] == local_topic[tpos]){
253 | spos++;
254 | tpos++;
255 | if(spos == slen && tpos == tlen){
256 | *result = true;
257 | break;
258 | }
259 | }else{
260 | if(local_sub[spos] == '+'){
261 | spos++;
262 | while(tpos < tlen && local_topic[tpos] != '/'){
263 | tpos++;
264 | }
265 | if(tpos == tlen && spos == slen){
266 | *result = true;
267 | break;
268 | }
269 | }else if(local_sub[spos] == '#'){
270 | multilevel_wildcard = true;
271 | if(spos+1 != slen){
272 | *result = false;
273 | break;
274 | }else{
275 | *result = true;
276 | break;
277 | }
278 | }else{
279 | *result = false;
280 | break;
281 | }
282 | }
283 | if(tpos == tlen-1){
284 | /* Check for e.g. foo matching foo/# */
285 | if(spos == slen-3
286 | && local_sub[spos+1] == '/'
287 | && local_sub[spos+2] == '#'){
288 | *result = true;
289 | multilevel_wildcard = true;
290 | break;
291 | }
292 | }
293 | }
294 | if(multilevel_wildcard == false && (tpos < tlen || spos < slen)){
295 | *result = false;
296 | }
297 |
298 | _mosquitto_free(local_sub);
299 | _mosquitto_free(local_topic);
300 | return MOSQ_ERR_SUCCESS;
301 | }
302 |
303 | #if defined(WITH_TLS) && defined(WITH_TLS_PSK)
304 | int _mosquitto_hex2bin(const char *hex, unsigned char *bin, int bin_max_len)
305 | {
306 | BIGNUM *bn = NULL;
307 | int len;
308 |
309 | if(BN_hex2bn(&bn, hex) == 0){
310 | if(bn) BN_free(bn);
311 | return 0;
312 | }
313 | if(BN_num_bytes(bn) > bin_max_len){
314 | BN_free(bn);
315 | return 0;
316 | }
317 |
318 | len = BN_bn2bin(bn, bin);
319 | BN_free(bn);
320 | return len;
321 | }
322 | #endif
323 |
--------------------------------------------------------------------------------
/libmosquitto/send_mosq.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009-2011 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 |
43 | #ifdef WITH_BROKER
44 | #include
45 | extern uint64_t g_pub_bytes_sent;
46 | #endif
47 |
48 | int _mosquitto_send_pingreq(struct mosquitto *mosq)
49 | {
50 | int rc;
51 | assert(mosq);
52 | #ifdef WITH_BROKER
53 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PINGREQ to %s", mosq->id);
54 | #else
55 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PINGREQ", mosq->id);
56 | #endif
57 | rc = _mosquitto_send_simple_command(mosq, PINGREQ);
58 | if(rc == MOSQ_ERR_SUCCESS){
59 | mosq->ping_t = time(NULL);
60 | }
61 | return rc;
62 | }
63 |
64 | int _mosquitto_send_pingresp(struct mosquitto *mosq)
65 | {
66 | #ifdef WITH_BROKER
67 | if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PINGRESP to %s", mosq->id);
68 | #else
69 | if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PINGRESP", mosq->id);
70 | #endif
71 | return _mosquitto_send_simple_command(mosq, PINGRESP);
72 | }
73 |
74 | int _mosquitto_send_puback(struct mosquitto *mosq, uint16_t mid)
75 | {
76 | #ifdef WITH_BROKER
77 | if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBACK to %s (Mid: %d)", mosq->id, mid);
78 | #else
79 | if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBACK (Mid: %d)", mosq->id, mid);
80 | #endif
81 | return _mosquitto_send_command_with_mid(mosq, PUBACK, mid, false);
82 | }
83 |
84 | int _mosquitto_send_pubcomp(struct mosquitto *mosq, uint16_t mid)
85 | {
86 | #ifdef WITH_BROKER
87 | if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBCOMP to %s (Mid: %d)", mosq->id, mid);
88 | #else
89 | if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBCOMP (Mid: %d)", mosq->id, mid);
90 | #endif
91 | return _mosquitto_send_command_with_mid(mosq, PUBCOMP, mid, false);
92 | }
93 |
94 | int _mosquitto_send_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup)
95 | {
96 | #ifdef WITH_BROKER
97 | size_t len;
98 | #ifdef WITH_BRIDGE
99 | int i;
100 | struct _mqtt3_bridge_topic *cur_topic;
101 | bool match;
102 | int rc;
103 | char *mapped_topic = NULL;
104 | char *topic_temp = NULL;
105 | #endif
106 | #endif
107 | assert(mosq);
108 | assert(topic);
109 |
110 | if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
111 | #ifdef WITH_BROKER
112 | if(mosq->listener && mosq->listener->mount_point){
113 | len = strlen(mosq->listener->mount_point);
114 | if(len > strlen(topic)){
115 | topic += strlen(mosq->listener->mount_point);
116 | }else{
117 | /* Invalid topic string. Should never happen, but silently swallow the message anyway. */
118 | return MOSQ_ERR_SUCCESS;
119 | }
120 | }
121 | #ifdef WITH_BRIDGE
122 | if(mosq->bridge && mosq->bridge->topics && mosq->bridge->topic_remapping){
123 | for(i=0; ibridge->topic_count; i++){
124 | cur_topic = &mosq->bridge->topics[i];
125 | if(cur_topic->remote_prefix || cur_topic->local_prefix){
126 | /* Topic mapping required on this topic if the message matches */
127 |
128 | rc = mosquitto_topic_matches_sub(cur_topic->local_topic, topic, &match);
129 | if(rc){
130 | return rc;
131 | }
132 | if(match){
133 | mapped_topic = _mosquitto_strdup(topic);
134 | if(!mapped_topic) return MOSQ_ERR_NOMEM;
135 | if(cur_topic->local_prefix){
136 | /* This prefix needs removing. */
137 | if(!strncmp(cur_topic->local_prefix, mapped_topic, strlen(cur_topic->local_prefix))){
138 | topic_temp = _mosquitto_strdup(mapped_topic+strlen(cur_topic->local_prefix));
139 | _mosquitto_free(mapped_topic);
140 | if(!topic_temp){
141 | return MOSQ_ERR_NOMEM;
142 | }
143 | mapped_topic = topic_temp;
144 | }
145 | }
146 |
147 | if(cur_topic->remote_prefix){
148 | /* This prefix needs adding. */
149 | len = strlen(mapped_topic) + strlen(cur_topic->remote_prefix)+1;
150 | topic_temp = _mosquitto_calloc(len+1, sizeof(char));
151 | if(!topic_temp){
152 | _mosquitto_free(mapped_topic);
153 | return MOSQ_ERR_NOMEM;
154 | }
155 | snprintf(topic_temp, len, "%s%s", cur_topic->remote_prefix, mapped_topic);
156 | _mosquitto_free(mapped_topic);
157 | mapped_topic = topic_temp;
158 | }
159 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBLISH to %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", mosq->id, dup, qos, retain, mid, mapped_topic, (long)payloadlen);
160 | g_pub_bytes_sent += payloadlen;
161 | rc = _mosquitto_send_real_publish(mosq, mid, mapped_topic, payloadlen, payload, qos, retain, dup);
162 | _mosquitto_free(mapped_topic);
163 | return rc;
164 | }
165 | }
166 | }
167 | }
168 | #endif
169 | _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBLISH to %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", mosq->id, dup, qos, retain, mid, topic, (long)payloadlen);
170 | g_pub_bytes_sent += payloadlen;
171 | #else
172 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBLISH (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", mosq->id, dup, qos, retain, mid, topic, (long)payloadlen);
173 | #endif
174 |
175 | return _mosquitto_send_real_publish(mosq, mid, topic, payloadlen, payload, qos, retain, dup);
176 | }
177 |
178 | int _mosquitto_send_pubrec(struct mosquitto *mosq, uint16_t mid)
179 | {
180 | #ifdef WITH_BROKER
181 | if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBREC to %s (Mid: %d)", mosq->id, mid);
182 | #else
183 | if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBREC (Mid: %d)", mosq->id, mid);
184 | #endif
185 | return _mosquitto_send_command_with_mid(mosq, PUBREC, mid, false);
186 | }
187 |
188 | int _mosquitto_send_pubrel(struct mosquitto *mosq, uint16_t mid, bool dup)
189 | {
190 | #ifdef WITH_BROKER
191 | if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBREL to %s (Mid: %d)", mosq->id, mid);
192 | #else
193 | if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBREL (Mid: %d)", mosq->id, mid);
194 | #endif
195 | return _mosquitto_send_command_with_mid(mosq, PUBREL|2, mid, dup);
196 | }
197 |
198 | /* For PUBACK, PUBCOMP, PUBREC, and PUBREL */
199 | int _mosquitto_send_command_with_mid(struct mosquitto *mosq, uint8_t command, uint16_t mid, bool dup)
200 | {
201 | struct _mosquitto_packet *packet = NULL;
202 | int rc;
203 |
204 | assert(mosq);
205 | packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
206 | if(!packet) return MOSQ_ERR_NOMEM;
207 |
208 | packet->command = command;
209 | if(dup){
210 | packet->command |= 8;
211 | }
212 | packet->remaining_length = 2;
213 | rc = _mosquitto_packet_alloc(packet);
214 | if(rc){
215 | _mosquitto_free(packet);
216 | return rc;
217 | }
218 |
219 | packet->payload[packet->pos+0] = MOSQ_MSB(mid);
220 | packet->payload[packet->pos+1] = MOSQ_LSB(mid);
221 |
222 | return _mosquitto_packet_queue(mosq, packet);
223 | }
224 |
225 | /* For DISCONNECT, PINGREQ and PINGRESP */
226 | int _mosquitto_send_simple_command(struct mosquitto *mosq, uint8_t command)
227 | {
228 | struct _mosquitto_packet *packet = NULL;
229 | int rc;
230 |
231 | assert(mosq);
232 | packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
233 | if(!packet) return MOSQ_ERR_NOMEM;
234 |
235 | packet->command = command;
236 | packet->remaining_length = 0;
237 |
238 | rc = _mosquitto_packet_alloc(packet);
239 | if(rc){
240 | _mosquitto_free(packet);
241 | return rc;
242 | }
243 |
244 | return _mosquitto_packet_queue(mosq, packet);
245 | }
246 |
247 | int _mosquitto_send_real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup)
248 | {
249 | struct _mosquitto_packet *packet = NULL;
250 | int packetlen;
251 | int rc;
252 |
253 | assert(mosq);
254 | assert(topic);
255 |
256 | packetlen = 2+strlen(topic) + payloadlen;
257 | if(qos > 0) packetlen += 2; /* For message id */
258 | packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
259 | if(!packet) return MOSQ_ERR_NOMEM;
260 |
261 | packet->mid = mid;
262 | packet->command = PUBLISH | ((dup&0x1)<<3) | (qos<<1) | retain;
263 | packet->remaining_length = packetlen;
264 | rc = _mosquitto_packet_alloc(packet);
265 | if(rc){
266 | _mosquitto_free(packet);
267 | return rc;
268 | }
269 | /* Variable header (topic string) */
270 | _mosquitto_write_string(packet, topic, strlen(topic));
271 | if(qos > 0){
272 | _mosquitto_write_uint16(packet, mid);
273 | }
274 |
275 | /* Payload */
276 | if(payloadlen){
277 | _mosquitto_write_bytes(packet, payload, payloadlen);
278 | }
279 |
280 | return _mosquitto_packet_queue(mosq, packet);
281 | }
282 |
--------------------------------------------------------------------------------
/libmosquitto/net_mosq.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2009-2012 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #ifndef WIN32
36 | #include
37 | #include
38 | #include
39 | #else
40 | #include
41 | #include
42 | #endif
43 |
44 | #ifdef __FreeBSD__
45 | # include
46 | #endif
47 |
48 | #ifdef __SYMBIAN32__
49 | #include
50 | #endif
51 |
52 | #ifdef __QNX__
53 | #ifndef AI_ADDRCONFIG
54 | #define AI_ADDRCONFIG 0
55 | #endif
56 | #include
57 | #include
58 | #endif
59 |
60 | #ifdef WITH_TLS
61 | #include
62 | #endif
63 |
64 | #ifdef WITH_BROKER
65 | # include
66 | extern uint64_t g_bytes_received;
67 | extern uint64_t g_bytes_sent;
68 | extern unsigned long g_msgs_received;
69 | extern unsigned long g_msgs_sent;
70 | extern unsigned long g_pub_msgs_received;
71 | extern unsigned long g_pub_msgs_sent;
72 | #else
73 | # include
74 | #endif
75 |
76 | #include "logging_mosq.h"
77 | #include
78 | #include
79 | #include
80 | #include
81 |
82 | #ifdef WITH_TLS
83 | static int tls_ex_index_mosq = -1;
84 | #endif
85 |
86 | void _mosquitto_net_init(void)
87 | {
88 | #ifdef WIN32
89 | WSADATA wsaData;
90 | WSAStartup(MAKEWORD(2,2), &wsaData);
91 | #endif
92 |
93 | #ifdef WITH_TLS
94 | SSL_load_error_strings();
95 | SSL_library_init();
96 | OpenSSL_add_all_algorithms();
97 | if(tls_ex_index_mosq == -1){
98 | tls_ex_index_mosq = SSL_get_ex_new_index(0, "client context", NULL, NULL, NULL);
99 | }
100 | #endif
101 | }
102 |
103 | void _mosquitto_net_cleanup(void)
104 | {
105 | #ifdef WITH_TLS
106 | ERR_free_strings();
107 | EVP_cleanup();
108 | #endif
109 |
110 | #ifdef WIN32
111 | WSACleanup();
112 | #endif
113 | }
114 |
115 | void _mosquitto_packet_cleanup(struct _mosquitto_packet *packet)
116 | {
117 | if(!packet) return;
118 |
119 | /* Free data and reset values */
120 | packet->command = 0;
121 | packet->have_remaining = 0;
122 | packet->remaining_count = 0;
123 | packet->remaining_mult = 1;
124 | packet->remaining_length = 0;
125 | if(packet->payload) _mosquitto_free(packet->payload);
126 | packet->payload = NULL;
127 | packet->to_process = 0;
128 | packet->pos = 0;
129 | }
130 |
131 | int _mosquitto_packet_queue(struct mosquitto *mosq, struct _mosquitto_packet *packet)
132 | {
133 | struct _mosquitto_packet *tail;
134 |
135 | assert(mosq);
136 | assert(packet);
137 |
138 | packet->pos = 0;
139 | packet->to_process = packet->packet_length;
140 |
141 | packet->next = NULL;
142 | pthread_mutex_lock(&mosq->out_packet_mutex);
143 | if(mosq->out_packet){
144 | tail = mosq->out_packet;
145 | while(tail->next){
146 | tail = tail->next;
147 | }
148 | tail->next = packet;
149 | }else{
150 | mosq->out_packet = packet;
151 | }
152 | pthread_mutex_unlock(&mosq->out_packet_mutex);
153 | #ifdef WITH_BROKER
154 | return _mosquitto_packet_write(mosq);
155 | #else
156 | if(mosq->in_callback == false){
157 | return _mosquitto_packet_write(mosq);
158 | }else{
159 | return MOSQ_ERR_SUCCESS;
160 | }
161 | #endif
162 | }
163 |
164 | /* Close a socket associated with a context and set it to -1.
165 | * Returns 1 on failure (context is NULL)
166 | * Returns 0 on success.
167 | */
168 | int _mosquitto_socket_close(struct mosquitto *mosq)
169 | {
170 | int rc = 0;
171 |
172 | assert(mosq);
173 | #ifdef WITH_TLS
174 | if(mosq->ssl){
175 | SSL_shutdown(mosq->ssl);
176 | SSL_free(mosq->ssl);
177 | mosq->ssl = NULL;
178 | }
179 | if(mosq->ssl_ctx){
180 | SSL_CTX_free(mosq->ssl_ctx);
181 | mosq->ssl_ctx = NULL;
182 | }
183 | #endif
184 |
185 | if(mosq->sock != INVALID_SOCKET){
186 | rc = COMPAT_CLOSE(mosq->sock);
187 | mosq->sock = INVALID_SOCKET;
188 | }
189 |
190 | return rc;
191 | }
192 |
193 | #ifdef WITH_TLS_PSK
194 | static unsigned int psk_client_callback(SSL *ssl, const char *hint,
195 | char *identity, unsigned int max_identity_len,
196 | unsigned char *psk, unsigned int max_psk_len)
197 | {
198 | struct mosquitto *mosq;
199 | int len;
200 |
201 | mosq = SSL_get_ex_data(ssl, tls_ex_index_mosq);
202 | if(!mosq) return 0;
203 |
204 | snprintf(identity, max_identity_len, "%s", mosq->tls_psk_identity);
205 |
206 | len = _mosquitto_hex2bin(mosq->tls_psk, psk, max_psk_len);
207 | if (len < 0) return 0;
208 | return len;
209 | }
210 | #endif
211 |
212 | /* Create a socket and connect it to 'ip' on port 'port'.
213 | * Returns -1 on failure (ip is NULL, socket creation/connection error)
214 | * Returns sock number on success.
215 | */
216 | int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port)
217 | {
218 | int sock = INVALID_SOCKET;
219 | #ifndef WIN32
220 | int opt;
221 | #endif
222 | struct addrinfo hints;
223 | struct addrinfo *ainfo, *rp;
224 | int s;
225 | #ifdef WIN32
226 | uint32_t val = 1;
227 | #endif
228 | #ifdef WITH_TLS
229 | int ret;
230 | BIO *bio;
231 | #endif
232 |
233 | if(!mosq || !host || !port) return MOSQ_ERR_INVAL;
234 |
235 | memset(&hints, 0, sizeof(struct addrinfo));
236 | hints.ai_family = PF_UNSPEC;
237 | hints.ai_flags = AI_ADDRCONFIG;
238 | hints.ai_socktype = SOCK_STREAM;
239 |
240 | s = getaddrinfo(host, NULL, &hints, &ainfo);
241 | if(s) return MOSQ_ERR_UNKNOWN;
242 |
243 | for(rp = ainfo; rp != NULL; rp = rp->ai_next){
244 | sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
245 | if(sock == INVALID_SOCKET) continue;
246 |
247 | if(rp->ai_family == PF_INET){
248 | ((struct sockaddr_in *)rp->ai_addr)->sin_port = htons(port);
249 | }else if(rp->ai_family == PF_INET6){
250 | ((struct sockaddr_in6 *)rp->ai_addr)->sin6_port = htons(port);
251 | }else{
252 | continue;
253 | }
254 | if(connect(sock, rp->ai_addr, rp->ai_addrlen) != -1){
255 | break;
256 | }
257 |
258 | #ifdef WIN32
259 | errno = WSAGetLastError();
260 | #endif
261 | COMPAT_CLOSE(sock);
262 | }
263 | freeaddrinfo(ainfo);
264 | if(!rp){
265 | return MOSQ_ERR_ERRNO;
266 | }
267 |
268 | /* Set non-blocking */
269 | #ifndef WIN32
270 | opt = fcntl(sock, F_GETFL, 0);
271 | if(opt == -1 || fcntl(sock, F_SETFL, opt | O_NONBLOCK) == -1){
272 | #ifdef WITH_TLS
273 | if(mosq->ssl){
274 | SSL_shutdown(mosq->ssl);
275 | SSL_free(mosq->ssl);
276 | mosq->ssl = NULL;
277 | }
278 | if(mosq->ssl_ctx){
279 | SSL_CTX_free(mosq->ssl_ctx);
280 | mosq->ssl_ctx = NULL;
281 | }
282 | #endif
283 | COMPAT_CLOSE(sock);
284 | return MOSQ_ERR_ERRNO;
285 | }
286 | #else
287 | if(ioctlsocket(sock, FIONBIO, &val)){
288 | errno = WSAGetLastError();
289 | #ifdef WITH_TLS
290 | if(mosq->ssl){
291 | SSL_shutdown(mosq->ssl);
292 | SSL_free(mosq->ssl);
293 | mosq->ssl = NULL;
294 | }
295 | if(mosq->ssl_ctx){
296 | SSL_CTX_free(mosq->ssl_ctx);
297 | mosq->ssl_ctx = NULL;
298 | }
299 | #endif
300 | COMPAT_CLOSE(sock);
301 | return MOSQ_ERR_ERRNO;
302 | }
303 | #endif
304 |
305 | #ifdef WITH_TLS
306 | if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){
307 | if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1")){
308 | mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
309 | if(!mosq->ssl_ctx){
310 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context.");
311 | COMPAT_CLOSE(sock);
312 | return MOSQ_ERR_TLS;
313 | }
314 | }else{
315 | COMPAT_CLOSE(sock);
316 | return MOSQ_ERR_INVAL;
317 | }
318 |
319 | #if OPENSSL_VERSION_NUMBER >= 0x10000000
320 | /* Disable compression */
321 | SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_COMPRESSION);
322 | #endif
323 | #ifdef SSL_MODE_RELEASE_BUFFERS
324 | /* Use even less memory per SSL connection. */
325 | SSL_CTX_set_mode(mosq->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
326 | #endif
327 |
328 | if(mosq->tls_ciphers){
329 | ret = SSL_CTX_set_cipher_list(mosq->ssl_ctx, mosq->tls_ciphers);
330 | if(ret == 0){
331 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", mosq->tls_ciphers);
332 | COMPAT_CLOSE(sock);
333 | return MOSQ_ERR_TLS;
334 | }
335 | }
336 | if(mosq->tls_cafile || mosq->tls_capath){
337 | ret = SSL_CTX_load_verify_locations(mosq->ssl_ctx, mosq->tls_cafile, mosq->tls_capath);
338 | if(ret == 0){
339 | #ifdef WITH_BROKER
340 | if(mosq->tls_cafile && mosq->tls_capath){
341 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\" and bridge_capath \"%s\".", mosq->tls_cafile, mosq->tls_capath);
342 | }else if(mosq->tls_cafile){
343 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile);
344 | }else{
345 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath);
346 | }
347 | #else
348 | if(mosq->tls_cafile && mosq->tls_capath){
349 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\" and capath \"%s\".", mosq->tls_cafile, mosq->tls_capath);
350 | }else if(mosq->tls_cafile){
351 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile);
352 | }else{
353 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath);
354 | }
355 | #endif
356 | COMPAT_CLOSE(sock);
357 | return MOSQ_ERR_TLS;
358 | }
359 | if(mosq->tls_cert_reqs == 0){
360 | SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_NONE, NULL);
361 | }else{
362 | SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_PEER, NULL);
363 | }
364 |
365 | if(mosq->tls_pw_callback){
366 | SSL_CTX_set_default_passwd_cb(mosq->ssl_ctx, mosq->tls_pw_callback);
367 | SSL_CTX_set_default_passwd_cb_userdata(mosq->ssl_ctx, mosq);
368 | }
369 |
370 | if(mosq->tls_certfile){
371 | ret = SSL_CTX_use_certificate_file(mosq->ssl_ctx, mosq->tls_certfile, SSL_FILETYPE_PEM);
372 | if(ret != 1){
373 | #ifdef WITH_BROKER
374 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate, check bridge_certfile \"%s\".", mosq->tls_certfile);
375 | #else
376 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile);
377 | #endif
378 | COMPAT_CLOSE(sock);
379 | return MOSQ_ERR_TLS;
380 | }
381 | }
382 | if(mosq->tls_keyfile){
383 | ret = SSL_CTX_use_PrivateKey_file(mosq->ssl_ctx, mosq->tls_keyfile, SSL_FILETYPE_PEM);
384 | if(ret != 1){
385 | #ifdef WITH_BROKER
386 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file, check bridge_keyfile \"%s\".", mosq->tls_keyfile);
387 | #else
388 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile);
389 | #endif
390 | COMPAT_CLOSE(sock);
391 | return MOSQ_ERR_TLS;
392 | }
393 | ret = SSL_CTX_check_private_key(mosq->ssl_ctx);
394 | if(ret != 1){
395 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent.");
396 | COMPAT_CLOSE(sock);
397 | return MOSQ_ERR_TLS;
398 | }
399 | }
400 | #ifdef WITH_TLS_PSK
401 | }else if(mosq->tls_psk){
402 | SSL_CTX_set_psk_client_callback(mosq->ssl_ctx, psk_client_callback);
403 | #endif
404 | }
405 |
406 | mosq->ssl = SSL_new(mosq->ssl_ctx);
407 | if(!mosq->ssl){
408 | COMPAT_CLOSE(sock);
409 | return MOSQ_ERR_TLS;
410 | }
411 | SSL_set_ex_data(mosq->ssl, tls_ex_index_mosq, mosq);
412 | bio = BIO_new_socket(sock, BIO_NOCLOSE);
413 | if(!bio){
414 | COMPAT_CLOSE(sock);
415 | return MOSQ_ERR_TLS;
416 | }
417 | SSL_set_bio(mosq->ssl, bio, bio);
418 |
419 | ret = SSL_connect(mosq->ssl);
420 | if(ret != 1){
421 | ret = SSL_get_error(mosq->ssl, ret);
422 | if(ret == SSL_ERROR_WANT_READ){
423 | mosq->want_read = true;
424 | }else if(ret == SSL_ERROR_WANT_WRITE){
425 | mosq->want_write = true;
426 | }else{
427 | COMPAT_CLOSE(sock);
428 | return MOSQ_ERR_TLS;
429 | }
430 | }
431 | }
432 | #endif
433 |
434 | mosq->sock = sock;
435 |
436 | return MOSQ_ERR_SUCCESS;
437 | }
438 |
439 | int _mosquitto_read_byte(struct _mosquitto_packet *packet, uint8_t *byte)
440 | {
441 | assert(packet);
442 | if(packet->pos+1 > packet->remaining_length) return MOSQ_ERR_PROTOCOL;
443 |
444 | *byte = packet->payload[packet->pos];
445 | packet->pos++;
446 |
447 | return MOSQ_ERR_SUCCESS;
448 | }
449 |
450 | void _mosquitto_write_byte(struct _mosquitto_packet *packet, uint8_t byte)
451 | {
452 | assert(packet);
453 | assert(packet->pos+1 <= packet->packet_length);
454 |
455 | packet->payload[packet->pos] = byte;
456 | packet->pos++;
457 | }
458 |
459 | int _mosquitto_read_bytes(struct _mosquitto_packet *packet, void *bytes, uint32_t count)
460 | {
461 | assert(packet);
462 | if(packet->pos+count > packet->remaining_length) return MOSQ_ERR_PROTOCOL;
463 |
464 | memcpy(bytes, &(packet->payload[packet->pos]), count);
465 | packet->pos += count;
466 |
467 | return MOSQ_ERR_SUCCESS;
468 | }
469 |
470 | void _mosquitto_write_bytes(struct _mosquitto_packet *packet, const void *bytes, uint32_t count)
471 | {
472 | assert(packet);
473 | assert(packet->pos+count <= packet->packet_length);
474 |
475 | memcpy(&(packet->payload[packet->pos]), bytes, count);
476 | packet->pos += count;
477 | }
478 |
479 | int _mosquitto_read_string(struct _mosquitto_packet *packet, char **str)
480 | {
481 | uint16_t len;
482 | int rc;
483 |
484 | assert(packet);
485 | rc = _mosquitto_read_uint16(packet, &len);
486 | if(rc) return rc;
487 |
488 | if(packet->pos+len > packet->remaining_length) return MOSQ_ERR_PROTOCOL;
489 |
490 | *str = _mosquitto_calloc(len+1, sizeof(char));
491 | if(*str){
492 | memcpy(*str, &(packet->payload[packet->pos]), len);
493 | packet->pos += len;
494 | }else{
495 | return MOSQ_ERR_NOMEM;
496 | }
497 |
498 | return MOSQ_ERR_SUCCESS;
499 | }
500 |
501 | void _mosquitto_write_string(struct _mosquitto_packet *packet, const char *str, uint16_t length)
502 | {
503 | assert(packet);
504 | _mosquitto_write_uint16(packet, length);
505 | _mosquitto_write_bytes(packet, str, length);
506 | }
507 |
508 | int _mosquitto_read_uint16(struct _mosquitto_packet *packet, uint16_t *word)
509 | {
510 | uint8_t msb, lsb;
511 |
512 | assert(packet);
513 | if(packet->pos+2 > packet->remaining_length) return MOSQ_ERR_PROTOCOL;
514 |
515 | msb = packet->payload[packet->pos];
516 | packet->pos++;
517 | lsb = packet->payload[packet->pos];
518 | packet->pos++;
519 |
520 | *word = (msb<<8) + lsb;
521 |
522 | return MOSQ_ERR_SUCCESS;
523 | }
524 |
525 | void _mosquitto_write_uint16(struct _mosquitto_packet *packet, uint16_t word)
526 | {
527 | _mosquitto_write_byte(packet, MOSQ_MSB(word));
528 | _mosquitto_write_byte(packet, MOSQ_LSB(word));
529 | }
530 |
531 | ssize_t _mosquitto_net_read(struct mosquitto *mosq, void *buf, size_t count)
532 | {
533 | #ifdef WITH_TLS
534 | int ret;
535 | int err;
536 | char ebuf[256];
537 | unsigned long e;
538 | #endif
539 | assert(mosq);
540 | errno = 0;
541 | #ifdef WITH_TLS
542 | if(mosq->ssl){
543 | ret = SSL_read(mosq->ssl, buf, count);
544 | if(ret <= 0){
545 | err = SSL_get_error(mosq->ssl, ret);
546 | if(err == SSL_ERROR_WANT_READ){
547 | ret = -1;
548 | mosq->want_read = true;
549 | errno = EAGAIN;
550 | }else if(err == SSL_ERROR_WANT_WRITE){
551 | ret = -1;
552 | mosq->want_write = true;
553 | errno = EAGAIN;
554 | }else{
555 | e = ERR_get_error();
556 | while(e){
557 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "OpenSSL Error: %s", ERR_error_string(e, ebuf));
558 | e = ERR_get_error();
559 | }
560 | errno = EPROTO;
561 | }
562 | }
563 | return (ssize_t )ret;
564 | }else{
565 | /* Call normal read/recv */
566 |
567 | #endif
568 |
569 | #ifndef WIN32
570 | return read(mosq->sock, buf, count);
571 | #else
572 | return recv(mosq->sock, buf, count, 0);
573 | #endif
574 |
575 | #ifdef WITH_TLS
576 | }
577 | #endif
578 | }
579 |
580 | ssize_t _mosquitto_net_write(struct mosquitto *mosq, void *buf, size_t count)
581 | {
582 | #ifdef WITH_TLS
583 | int ret;
584 | int err;
585 | char ebuf[256];
586 | unsigned long e;
587 | #endif
588 | assert(mosq);
589 |
590 | errno = 0;
591 | #ifdef WITH_TLS
592 | if(mosq->ssl){
593 | ret = SSL_write(mosq->ssl, buf, count);
594 | if(ret < 0){
595 | err = SSL_get_error(mosq->ssl, ret);
596 | if(err == SSL_ERROR_WANT_READ){
597 | ret = -1;
598 | mosq->want_read = true;
599 | errno = EAGAIN;
600 | }else if(err == SSL_ERROR_WANT_WRITE){
601 | ret = -1;
602 | mosq->want_write = true;
603 | errno = EAGAIN;
604 | }else{
605 | e = ERR_get_error();
606 | while(e){
607 | _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "OpenSSL Error: %s", ERR_error_string(e, ebuf));
608 | e = ERR_get_error();
609 | }
610 | errno = EPROTO;
611 | }
612 | }
613 | return (ssize_t )ret;
614 | }else{
615 | /* Call normal write/send */
616 | #endif
617 |
618 | #ifndef WIN32
619 | return write(mosq->sock, buf, count);
620 | #else
621 | return send(mosq->sock, buf, count, 0);
622 | #endif
623 |
624 | #ifdef WITH_TLS
625 | }
626 | #endif
627 | }
628 |
629 | int _mosquitto_packet_write(struct mosquitto *mosq)
630 | {
631 | ssize_t write_length;
632 | struct _mosquitto_packet *packet;
633 |
634 | if(!mosq) return MOSQ_ERR_INVAL;
635 | if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
636 |
637 | pthread_mutex_lock(&mosq->current_out_packet_mutex);
638 | pthread_mutex_lock(&mosq->out_packet_mutex);
639 | if(mosq->out_packet && !mosq->current_out_packet){
640 | mosq->current_out_packet = mosq->out_packet;
641 | mosq->out_packet = mosq->out_packet->next;
642 | }
643 | pthread_mutex_unlock(&mosq->out_packet_mutex);
644 |
645 | while(mosq->current_out_packet){
646 | packet = mosq->current_out_packet;
647 |
648 | while(packet->to_process > 0){
649 | write_length = _mosquitto_net_write(mosq, &(packet->payload[packet->pos]), packet->to_process);
650 | if(write_length > 0){
651 | #ifdef WITH_BROKER
652 | g_bytes_sent += write_length;
653 | #endif
654 | packet->to_process -= write_length;
655 | packet->pos += write_length;
656 | }else{
657 | #ifdef WIN32
658 | errno = WSAGetLastError();
659 | #endif
660 | if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
661 | pthread_mutex_unlock(&mosq->current_out_packet_mutex);
662 | return MOSQ_ERR_SUCCESS;
663 | }else{
664 | pthread_mutex_unlock(&mosq->current_out_packet_mutex);
665 | switch(errno){
666 | case COMPAT_ECONNRESET:
667 | return MOSQ_ERR_CONN_LOST;
668 | default:
669 | return MOSQ_ERR_ERRNO;
670 | }
671 | }
672 | }
673 | }
674 |
675 | #ifdef WITH_BROKER
676 | g_msgs_sent++;
677 | if(((packet->command)&0xF6) == PUBLISH){
678 | g_pub_msgs_sent++;
679 | }
680 | #else
681 | if(((packet->command)&0xF6) == PUBLISH){
682 | pthread_mutex_lock(&mosq->callback_mutex);
683 | if(mosq->on_publish){
684 | /* This is a QoS=0 message */
685 | mosq->in_callback = true;
686 | mosq->on_publish(mosq, mosq->userdata, packet->mid);
687 | mosq->in_callback = false;
688 | }
689 | pthread_mutex_unlock(&mosq->callback_mutex);
690 | }
691 | #endif
692 |
693 | /* Free data and reset values */
694 | pthread_mutex_lock(&mosq->out_packet_mutex);
695 | mosq->current_out_packet = mosq->out_packet;
696 | if(mosq->out_packet){
697 | mosq->out_packet = mosq->out_packet->next;
698 | }
699 | pthread_mutex_unlock(&mosq->out_packet_mutex);
700 |
701 | _mosquitto_packet_cleanup(packet);
702 | _mosquitto_free(packet);
703 |
704 | pthread_mutex_lock(&mosq->msgtime_mutex);
705 | mosq->last_msg_out = time(NULL);
706 | pthread_mutex_unlock(&mosq->msgtime_mutex);
707 | }
708 | pthread_mutex_unlock(&mosq->current_out_packet_mutex);
709 | return MOSQ_ERR_SUCCESS;
710 | }
711 |
712 | #ifdef WITH_BROKER
713 | int _mosquitto_packet_read(struct mosquitto_db *db, struct mosquitto *mosq)
714 | #else
715 | int _mosquitto_packet_read(struct mosquitto *mosq)
716 | #endif
717 | {
718 | uint8_t byte;
719 | ssize_t read_length;
720 | int rc = 0;
721 |
722 | if(!mosq) return MOSQ_ERR_INVAL;
723 | if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
724 | /* This gets called if pselect() indicates that there is network data
725 | * available - ie. at least one byte. What we do depends on what data we
726 | * already have.
727 | * If we've not got a command, attempt to read one and save it. This should
728 | * always work because it's only a single byte.
729 | * Then try to read the remaining length. This may fail because it is may
730 | * be more than one byte - will need to save data pending next read if it
731 | * does fail.
732 | * Then try to read the remaining payload, where 'payload' here means the
733 | * combined variable header and actual payload. This is the most likely to
734 | * fail due to longer length, so save current data and current position.
735 | * After all data is read, send to _mosquitto_handle_packet() to deal with.
736 | * Finally, free the memory and reset everything to starting conditions.
737 | */
738 | if(!mosq->in_packet.command){
739 | read_length = _mosquitto_net_read(mosq, &byte, 1);
740 | if(read_length == 1){
741 | mosq->in_packet.command = byte;
742 | #ifdef WITH_BROKER
743 | g_bytes_received++;
744 | /* Clients must send CONNECT as their first command. */
745 | if(!(mosq->bridge) && mosq->state == mosq_cs_new && (byte&0xF0) != CONNECT) return MOSQ_ERR_PROTOCOL;
746 | #endif
747 | }else{
748 | if(read_length == 0) return MOSQ_ERR_CONN_LOST; /* EOF */
749 | #ifdef WIN32
750 | errno = WSAGetLastError();
751 | #endif
752 | if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
753 | return MOSQ_ERR_SUCCESS;
754 | }else{
755 | switch(errno){
756 | case COMPAT_ECONNRESET:
757 | return MOSQ_ERR_CONN_LOST;
758 | default:
759 | return MOSQ_ERR_ERRNO;
760 | }
761 | }
762 | }
763 | }
764 | if(!mosq->in_packet.have_remaining){
765 | /* Read remaining
766 | * Algorithm for decoding taken from pseudo code at
767 | * http://publib.boulder.ibm.com/infocenter/wmbhelp/v6r0m0/topic/com.ibm.etools.mft.doc/ac10870_.htm
768 | */
769 | do{
770 | read_length = _mosquitto_net_read(mosq, &byte, 1);
771 | if(read_length == 1){
772 | mosq->in_packet.remaining_count++;
773 | /* Max 4 bytes length for remaining length as defined by protocol.
774 | * Anything more likely means a broken/malicious client.
775 | */
776 | if(mosq->in_packet.remaining_count > 4) return MOSQ_ERR_PROTOCOL;
777 |
778 | #ifdef WITH_BROKER
779 | g_bytes_received++;
780 | #endif
781 | mosq->in_packet.remaining_length += (byte & 127) * mosq->in_packet.remaining_mult;
782 | mosq->in_packet.remaining_mult *= 128;
783 | }else{
784 | if(read_length == 0) return MOSQ_ERR_CONN_LOST; /* EOF */
785 | #ifdef WIN32
786 | errno = WSAGetLastError();
787 | #endif
788 | if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
789 | return MOSQ_ERR_SUCCESS;
790 | }else{
791 | switch(errno){
792 | case COMPAT_ECONNRESET:
793 | return MOSQ_ERR_CONN_LOST;
794 | default:
795 | return MOSQ_ERR_ERRNO;
796 | }
797 | }
798 | }
799 | }while((byte & 128) != 0);
800 |
801 | if(mosq->in_packet.remaining_length > 0){
802 | mosq->in_packet.payload = _mosquitto_malloc(mosq->in_packet.remaining_length*sizeof(uint8_t));
803 | if(!mosq->in_packet.payload) return MOSQ_ERR_NOMEM;
804 | mosq->in_packet.to_process = mosq->in_packet.remaining_length;
805 | }
806 | mosq->in_packet.have_remaining = 1;
807 | }
808 | while(mosq->in_packet.to_process>0){
809 | read_length = _mosquitto_net_read(mosq, &(mosq->in_packet.payload[mosq->in_packet.pos]), mosq->in_packet.to_process);
810 | if(read_length > 0){
811 | #ifdef WITH_BROKER
812 | g_bytes_received += read_length;
813 | #endif
814 | mosq->in_packet.to_process -= read_length;
815 | mosq->in_packet.pos += read_length;
816 | }else{
817 | #ifdef WIN32
818 | errno = WSAGetLastError();
819 | #endif
820 | if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
821 | return MOSQ_ERR_SUCCESS;
822 | }else{
823 | switch(errno){
824 | case COMPAT_ECONNRESET:
825 | return MOSQ_ERR_CONN_LOST;
826 | default:
827 | return MOSQ_ERR_ERRNO;
828 | }
829 | }
830 | }
831 | }
832 |
833 | /* All data for this packet is read. */
834 | mosq->in_packet.pos = 0;
835 | #ifdef WITH_BROKER
836 | g_msgs_received++;
837 | if(((mosq->in_packet.command)&0xF5) == PUBLISH){
838 | g_pub_msgs_received++;
839 | }
840 | rc = mqtt3_packet_handle(db, mosq);
841 | #else
842 | rc = _mosquitto_packet_handle(mosq);
843 | #endif
844 |
845 | /* Free data and reset values */
846 | _mosquitto_packet_cleanup(&mosq->in_packet);
847 |
848 | pthread_mutex_lock(&mosq->msgtime_mutex);
849 | mosq->last_msg_in = time(NULL);
850 | pthread_mutex_unlock(&mosq->msgtime_mutex);
851 | return rc;
852 | }
853 |
854 |
--------------------------------------------------------------------------------
/HomeWatch.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | EB030DC61734DE4E00EDFADA /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB030DC51734DE4E00EDFADA /* UIKit.framework */; };
11 | EB030DC81734DE4E00EDFADA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB030DC71734DE4E00EDFADA /* Foundation.framework */; };
12 | EB030DCA1734DE4E00EDFADA /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB030DC91734DE4E00EDFADA /* CoreGraphics.framework */; };
13 | EB030DD01734DE4E00EDFADA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = EB030DCE1734DE4E00EDFADA /* InfoPlist.strings */; };
14 | EB030DD21734DE4E00EDFADA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EB030DD11734DE4E00EDFADA /* main.m */; };
15 | EB030DD61734DE4E00EDFADA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EB030DD51734DE4E00EDFADA /* AppDelegate.m */; };
16 | EB030DD81734DE4E00EDFADA /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = EB030DD71734DE4E00EDFADA /* Default.png */; };
17 | EB030DDA1734DE4E00EDFADA /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EB030DD91734DE4E00EDFADA /* Default@2x.png */; };
18 | EB030DDC1734DE4E00EDFADA /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EB030DDB1734DE4E00EDFADA /* Default-568h@2x.png */; };
19 | EB030DDF1734DE4E00EDFADA /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EB030DDE1734DE4E00EDFADA /* ViewController.m */; };
20 | EB030DE21734DE4E00EDFADA /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EB030DE01734DE4E00EDFADA /* ViewController.xib */; };
21 | EB030E2E1734DFC800EDFADA /* logging_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E161734DFC800EDFADA /* logging_mosq.c */; };
22 | EB030E2F1734DFC800EDFADA /* memory_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E181734DFC800EDFADA /* memory_mosq.c */; };
23 | EB030E301734DFC800EDFADA /* messages_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E1A1734DFC800EDFADA /* messages_mosq.c */; };
24 | EB030E311734DFC800EDFADA /* mosquitto.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E1C1734DFC800EDFADA /* mosquitto.c */; };
25 | EB030E321734DFC800EDFADA /* net_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E201734DFC800EDFADA /* net_mosq.c */; };
26 | EB030E331734DFC800EDFADA /* read_handle.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E221734DFC800EDFADA /* read_handle.c */; };
27 | EB030E341734DFC800EDFADA /* read_handle_client.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E241734DFC800EDFADA /* read_handle_client.c */; };
28 | EB030E351734DFC800EDFADA /* read_handle_shared.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E251734DFC800EDFADA /* read_handle_shared.c */; };
29 | EB030E361734DFC800EDFADA /* send_client_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E261734DFC800EDFADA /* send_client_mosq.c */; };
30 | EB030E371734DFC800EDFADA /* send_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E271734DFC800EDFADA /* send_mosq.c */; };
31 | EB030E381734DFC800EDFADA /* thread_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E291734DFC800EDFADA /* thread_mosq.c */; };
32 | EB030E391734DFC800EDFADA /* util_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E2A1734DFC800EDFADA /* util_mosq.c */; };
33 | EB030E3A1734DFC800EDFADA /* will_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = EB030E2C1734DFC800EDFADA /* will_mosq.c */; };
34 | EB030E401734E04D00EDFADA /* MosquittoClient.m in Sources */ = {isa = PBXBuildFile; fileRef = EB030E3D1734E04D00EDFADA /* MosquittoClient.m */; };
35 | EB030E411734E04D00EDFADA /* MosquittoMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = EB030E3F1734E04D00EDFADA /* MosquittoMessage.m */; };
36 | EB030E441735F5BE00EDFADA /* Sensor.m in Sources */ = {isa = PBXBuildFile; fileRef = EB030E431735F5BE00EDFADA /* Sensor.m */; };
37 | EBAC0E33175095F300A0B864 /* lite-green.png in Resources */ = {isa = PBXBuildFile; fileRef = EBAC0E2D175095F300A0B864 /* lite-green.png */; };
38 | EBAC0E34175095F300A0B864 /* lite-green@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EBAC0E2E175095F300A0B864 /* lite-green@2x.png */; };
39 | EBAC0E35175095F300A0B864 /* lite-off.png in Resources */ = {isa = PBXBuildFile; fileRef = EBAC0E2F175095F300A0B864 /* lite-off.png */; };
40 | EBAC0E36175095F300A0B864 /* lite-off@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EBAC0E30175095F300A0B864 /* lite-off@2x.png */; };
41 | EBAC0E37175095F300A0B864 /* lite-red.png in Resources */ = {isa = PBXBuildFile; fileRef = EBAC0E31175095F300A0B864 /* lite-red.png */; };
42 | EBAC0E38175095F300A0B864 /* lite-red@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EBAC0E32175095F300A0B864 /* lite-red@2x.png */; };
43 | EBE0003C173C0C82004BE1AF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBE0003B173C0C82004BE1AF /* AudioToolbox.framework */; };
44 | EBE0003E173C0C8B004BE1AF /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBE0003D173C0C8B004BE1AF /* CFNetwork.framework */; };
45 | EBE00040173C0C98004BE1AF /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBE0003F173C0C98004BE1AF /* CoreLocation.framework */; };
46 | EBE00042173C0CA4004BE1AF /* libz.1.1.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = EBE00041173C0CA4004BE1AF /* libz.1.1.3.dylib */; };
47 | EBE00044173C0CAB004BE1AF /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBE00043173C0CAB004BE1AF /* MobileCoreServices.framework */; };
48 | EBE00046173C0CB6004BE1AF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBE00045173C0CB6004BE1AF /* QuartzCore.framework */; };
49 | EBE00048173C0CBC004BE1AF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBE00047173C0CBC004BE1AF /* Security.framework */; };
50 | EBE0004C173C0CC9004BE1AF /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBE0004B173C0CC9004BE1AF /* SystemConfiguration.framework */; };
51 | /* End PBXBuildFile section */
52 |
53 | /* Begin PBXFileReference section */
54 | EB030DC21734DE4E00EDFADA /* HomeWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HomeWatch.app; sourceTree = BUILT_PRODUCTS_DIR; };
55 | EB030DC51734DE4E00EDFADA /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
56 | EB030DC71734DE4E00EDFADA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
57 | EB030DC91734DE4E00EDFADA /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
58 | EB030DCD1734DE4E00EDFADA /* HomeWatch-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HomeWatch-Info.plist"; sourceTree = ""; };
59 | EB030DCF1734DE4E00EDFADA /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
60 | EB030DD11734DE4E00EDFADA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
61 | EB030DD31734DE4E00EDFADA /* HomeWatch-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "HomeWatch-Prefix.pch"; sourceTree = ""; };
62 | EB030DD41734DE4E00EDFADA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
63 | EB030DD51734DE4E00EDFADA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
64 | EB030DD71734DE4E00EDFADA /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; };
65 | EB030DD91734DE4E00EDFADA /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; };
66 | EB030DDB1734DE4E00EDFADA /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
67 | EB030DDD1734DE4E00EDFADA /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
68 | EB030DDE1734DE4E00EDFADA /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
69 | EB030DE11734DE4E00EDFADA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = ""; };
70 | EB030E141734DFC800EDFADA /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; };
71 | EB030E151734DFC800EDFADA /* dummypthread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dummypthread.h; sourceTree = ""; };
72 | EB030E161734DFC800EDFADA /* logging_mosq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = logging_mosq.c; sourceTree = ""; };
73 | EB030E171734DFC800EDFADA /* logging_mosq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logging_mosq.h; sourceTree = ""; };
74 | EB030E181734DFC800EDFADA /* memory_mosq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memory_mosq.c; sourceTree = ""; };
75 | EB030E191734DFC800EDFADA /* memory_mosq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory_mosq.h; sourceTree = ""; };
76 | EB030E1A1734DFC800EDFADA /* messages_mosq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = messages_mosq.c; sourceTree = ""; };
77 | EB030E1B1734DFC800EDFADA /* messages_mosq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = messages_mosq.h; sourceTree = ""; };
78 | EB030E1C1734DFC800EDFADA /* mosquitto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mosquitto.c; sourceTree = ""; };
79 | EB030E1D1734DFC800EDFADA /* mosquitto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mosquitto.h; sourceTree = ""; };
80 | EB030E1E1734DFC800EDFADA /* mosquitto_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mosquitto_internal.h; sourceTree = ""; };
81 | EB030E1F1734DFC800EDFADA /* mqtt3_protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mqtt3_protocol.h; sourceTree = ""; };
82 | EB030E201734DFC800EDFADA /* net_mosq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = net_mosq.c; sourceTree = ""; };
83 | EB030E211734DFC800EDFADA /* net_mosq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = net_mosq.h; sourceTree = ""; };
84 | EB030E221734DFC800EDFADA /* read_handle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = read_handle.c; sourceTree = ""; };
85 | EB030E231734DFC800EDFADA /* read_handle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = read_handle.h; sourceTree = ""; };
86 | EB030E241734DFC800EDFADA /* read_handle_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = read_handle_client.c; sourceTree = ""; };
87 | EB030E251734DFC800EDFADA /* read_handle_shared.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = read_handle_shared.c; sourceTree = ""; };
88 | EB030E261734DFC800EDFADA /* send_client_mosq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = send_client_mosq.c; sourceTree = ""; };
89 | EB030E271734DFC800EDFADA /* send_mosq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = send_mosq.c; sourceTree = ""; };
90 | EB030E281734DFC800EDFADA /* send_mosq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = send_mosq.h; sourceTree = ""; };
91 | EB030E291734DFC800EDFADA /* thread_mosq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = thread_mosq.c; sourceTree = ""; };
92 | EB030E2A1734DFC800EDFADA /* util_mosq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = util_mosq.c; sourceTree = ""; };
93 | EB030E2B1734DFC800EDFADA /* util_mosq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util_mosq.h; sourceTree = ""; };
94 | EB030E2C1734DFC800EDFADA /* will_mosq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = will_mosq.c; sourceTree = ""; };
95 | EB030E2D1734DFC800EDFADA /* will_mosq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = will_mosq.h; sourceTree = ""; };
96 | EB030E3C1734E04D00EDFADA /* MosquittoClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MosquittoClient.h; sourceTree = ""; };
97 | EB030E3D1734E04D00EDFADA /* MosquittoClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MosquittoClient.m; sourceTree = ""; };
98 | EB030E3E1734E04D00EDFADA /* MosquittoMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MosquittoMessage.h; sourceTree = ""; };
99 | EB030E3F1734E04D00EDFADA /* MosquittoMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MosquittoMessage.m; sourceTree = ""; };
100 | EB030E421735F5BE00EDFADA /* Sensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sensor.h; sourceTree = ""; };
101 | EB030E431735F5BE00EDFADA /* Sensor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Sensor.m; sourceTree = ""; };
102 | EB5645261751549C004445F7 /* monitor.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = monitor.py; sourceTree = ""; };
103 | EBAC0E2D175095F300A0B864 /* lite-green.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lite-green.png"; sourceTree = ""; };
104 | EBAC0E2E175095F300A0B864 /* lite-green@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lite-green@2x.png"; sourceTree = ""; };
105 | EBAC0E2F175095F300A0B864 /* lite-off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lite-off.png"; sourceTree = ""; };
106 | EBAC0E30175095F300A0B864 /* lite-off@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lite-off@2x.png"; sourceTree = ""; };
107 | EBAC0E31175095F300A0B864 /* lite-red.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lite-red.png"; sourceTree = ""; };
108 | EBAC0E32175095F300A0B864 /* lite-red@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lite-red@2x.png"; sourceTree = ""; };
109 | EBE0003B173C0C82004BE1AF /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
110 | EBE0003D173C0C8B004BE1AF /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
111 | EBE0003F173C0C98004BE1AF /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
112 | EBE00041173C0CA4004BE1AF /* libz.1.1.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.1.3.dylib; path = usr/lib/libz.1.1.3.dylib; sourceTree = SDKROOT; };
113 | EBE00043173C0CAB004BE1AF /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
114 | EBE00045173C0CB6004BE1AF /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
115 | EBE00047173C0CBC004BE1AF /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
116 | EBE0004B173C0CC9004BE1AF /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
117 | /* End PBXFileReference section */
118 |
119 | /* Begin PBXFrameworksBuildPhase section */
120 | EB030DBF1734DE4E00EDFADA /* Frameworks */ = {
121 | isa = PBXFrameworksBuildPhase;
122 | buildActionMask = 2147483647;
123 | files = (
124 | EBE0004C173C0CC9004BE1AF /* SystemConfiguration.framework in Frameworks */,
125 | EBE00048173C0CBC004BE1AF /* Security.framework in Frameworks */,
126 | EBE00046173C0CB6004BE1AF /* QuartzCore.framework in Frameworks */,
127 | EBE00044173C0CAB004BE1AF /* MobileCoreServices.framework in Frameworks */,
128 | EBE00042173C0CA4004BE1AF /* libz.1.1.3.dylib in Frameworks */,
129 | EBE00040173C0C98004BE1AF /* CoreLocation.framework in Frameworks */,
130 | EBE0003E173C0C8B004BE1AF /* CFNetwork.framework in Frameworks */,
131 | EBE0003C173C0C82004BE1AF /* AudioToolbox.framework in Frameworks */,
132 | EB030DC61734DE4E00EDFADA /* UIKit.framework in Frameworks */,
133 | EB030DC81734DE4E00EDFADA /* Foundation.framework in Frameworks */,
134 | EB030DCA1734DE4E00EDFADA /* CoreGraphics.framework in Frameworks */,
135 | );
136 | runOnlyForDeploymentPostprocessing = 0;
137 | };
138 | /* End PBXFrameworksBuildPhase section */
139 |
140 | /* Begin PBXGroup section */
141 | EB030DB91734DE4E00EDFADA = {
142 | isa = PBXGroup;
143 | children = (
144 | EB5645261751549C004445F7 /* monitor.py */,
145 | EB030DCB1734DE4E00EDFADA /* HomeWatch */,
146 | EB030DC41734DE4E00EDFADA /* Frameworks */,
147 | EB030DC31734DE4E00EDFADA /* Products */,
148 | );
149 | sourceTree = "";
150 | };
151 | EB030DC31734DE4E00EDFADA /* Products */ = {
152 | isa = PBXGroup;
153 | children = (
154 | EB030DC21734DE4E00EDFADA /* HomeWatch.app */,
155 | );
156 | name = Products;
157 | sourceTree = "";
158 | };
159 | EB030DC41734DE4E00EDFADA /* Frameworks */ = {
160 | isa = PBXGroup;
161 | children = (
162 | EB030DC51734DE4E00EDFADA /* UIKit.framework */,
163 | EB030DC71734DE4E00EDFADA /* Foundation.framework */,
164 | EB030DC91734DE4E00EDFADA /* CoreGraphics.framework */,
165 | EBE0004B173C0CC9004BE1AF /* SystemConfiguration.framework */,
166 | EBE00047173C0CBC004BE1AF /* Security.framework */,
167 | EBE00045173C0CB6004BE1AF /* QuartzCore.framework */,
168 | EBE00043173C0CAB004BE1AF /* MobileCoreServices.framework */,
169 | EBE00041173C0CA4004BE1AF /* libz.1.1.3.dylib */,
170 | EBE0003F173C0C98004BE1AF /* CoreLocation.framework */,
171 | EBE0003D173C0C8B004BE1AF /* CFNetwork.framework */,
172 | EBE0003B173C0C82004BE1AF /* AudioToolbox.framework */,
173 | );
174 | name = Frameworks;
175 | sourceTree = "";
176 | };
177 | EB030DCB1734DE4E00EDFADA /* HomeWatch */ = {
178 | isa = PBXGroup;
179 | children = (
180 | EB030DD41734DE4E00EDFADA /* AppDelegate.h */,
181 | EB030DD51734DE4E00EDFADA /* AppDelegate.m */,
182 | EB030E421735F5BE00EDFADA /* Sensor.h */,
183 | EB030E431735F5BE00EDFADA /* Sensor.m */,
184 | EB030DDD1734DE4E00EDFADA /* ViewController.h */,
185 | EB030DDE1734DE4E00EDFADA /* ViewController.m */,
186 | EB030DE01734DE4E00EDFADA /* ViewController.xib */,
187 | EB030E3B1734E02C00EDFADA /* Marquette */,
188 | EB030E131734DFC800EDFADA /* libmosquitto */,
189 | EB030DCC1734DE4E00EDFADA /* Supporting Files */,
190 | );
191 | path = HomeWatch;
192 | sourceTree = "";
193 | };
194 | EB030DCC1734DE4E00EDFADA /* Supporting Files */ = {
195 | isa = PBXGroup;
196 | children = (
197 | EB030DCD1734DE4E00EDFADA /* HomeWatch-Info.plist */,
198 | EB030DCE1734DE4E00EDFADA /* InfoPlist.strings */,
199 | EB030DD11734DE4E00EDFADA /* main.m */,
200 | EB030DD31734DE4E00EDFADA /* HomeWatch-Prefix.pch */,
201 | EB030DD71734DE4E00EDFADA /* Default.png */,
202 | EB030DD91734DE4E00EDFADA /* Default@2x.png */,
203 | EB030DDB1734DE4E00EDFADA /* Default-568h@2x.png */,
204 | EBAC0E2D175095F300A0B864 /* lite-green.png */,
205 | EBAC0E2E175095F300A0B864 /* lite-green@2x.png */,
206 | EBAC0E2F175095F300A0B864 /* lite-off.png */,
207 | EBAC0E30175095F300A0B864 /* lite-off@2x.png */,
208 | EBAC0E31175095F300A0B864 /* lite-red.png */,
209 | EBAC0E32175095F300A0B864 /* lite-red@2x.png */,
210 | );
211 | name = "Supporting Files";
212 | sourceTree = "";
213 | };
214 | EB030E131734DFC800EDFADA /* libmosquitto */ = {
215 | isa = PBXGroup;
216 | children = (
217 | EB030E141734DFC800EDFADA /* config.h */,
218 | EB030E151734DFC800EDFADA /* dummypthread.h */,
219 | EB030E161734DFC800EDFADA /* logging_mosq.c */,
220 | EB030E171734DFC800EDFADA /* logging_mosq.h */,
221 | EB030E181734DFC800EDFADA /* memory_mosq.c */,
222 | EB030E191734DFC800EDFADA /* memory_mosq.h */,
223 | EB030E1A1734DFC800EDFADA /* messages_mosq.c */,
224 | EB030E1B1734DFC800EDFADA /* messages_mosq.h */,
225 | EB030E1C1734DFC800EDFADA /* mosquitto.c */,
226 | EB030E1D1734DFC800EDFADA /* mosquitto.h */,
227 | EB030E1E1734DFC800EDFADA /* mosquitto_internal.h */,
228 | EB030E1F1734DFC800EDFADA /* mqtt3_protocol.h */,
229 | EB030E201734DFC800EDFADA /* net_mosq.c */,
230 | EB030E211734DFC800EDFADA /* net_mosq.h */,
231 | EB030E221734DFC800EDFADA /* read_handle.c */,
232 | EB030E231734DFC800EDFADA /* read_handle.h */,
233 | EB030E241734DFC800EDFADA /* read_handle_client.c */,
234 | EB030E251734DFC800EDFADA /* read_handle_shared.c */,
235 | EB030E261734DFC800EDFADA /* send_client_mosq.c */,
236 | EB030E271734DFC800EDFADA /* send_mosq.c */,
237 | EB030E281734DFC800EDFADA /* send_mosq.h */,
238 | EB030E291734DFC800EDFADA /* thread_mosq.c */,
239 | EB030E2A1734DFC800EDFADA /* util_mosq.c */,
240 | EB030E2B1734DFC800EDFADA /* util_mosq.h */,
241 | EB030E2C1734DFC800EDFADA /* will_mosq.c */,
242 | EB030E2D1734DFC800EDFADA /* will_mosq.h */,
243 | );
244 | path = libmosquitto;
245 | sourceTree = SOURCE_ROOT;
246 | };
247 | EB030E3B1734E02C00EDFADA /* Marquette */ = {
248 | isa = PBXGroup;
249 | children = (
250 | EB030E3C1734E04D00EDFADA /* MosquittoClient.h */,
251 | EB030E3D1734E04D00EDFADA /* MosquittoClient.m */,
252 | EB030E3E1734E04D00EDFADA /* MosquittoMessage.h */,
253 | EB030E3F1734E04D00EDFADA /* MosquittoMessage.m */,
254 | );
255 | name = Marquette;
256 | sourceTree = "";
257 | };
258 | /* End PBXGroup section */
259 |
260 | /* Begin PBXNativeTarget section */
261 | EB030DC11734DE4E00EDFADA /* HomeWatch */ = {
262 | isa = PBXNativeTarget;
263 | buildConfigurationList = EB030DE81734DE4E00EDFADA /* Build configuration list for PBXNativeTarget "HomeWatch" */;
264 | buildPhases = (
265 | EB030DBE1734DE4E00EDFADA /* Sources */,
266 | EB030DBF1734DE4E00EDFADA /* Frameworks */,
267 | EB030DC01734DE4E00EDFADA /* Resources */,
268 | );
269 | buildRules = (
270 | );
271 | dependencies = (
272 | );
273 | name = HomeWatch;
274 | productName = MonHome;
275 | productReference = EB030DC21734DE4E00EDFADA /* HomeWatch.app */;
276 | productType = "com.apple.product-type.application";
277 | };
278 | /* End PBXNativeTarget section */
279 |
280 | /* Begin PBXProject section */
281 | EB030DBA1734DE4E00EDFADA /* Project object */ = {
282 | isa = PBXProject;
283 | attributes = {
284 | LastUpgradeCheck = 0460;
285 | ORGANIZATIONNAME = Basuke;
286 | };
287 | buildConfigurationList = EB030DBD1734DE4E00EDFADA /* Build configuration list for PBXProject "HomeWatch" */;
288 | compatibilityVersion = "Xcode 3.2";
289 | developmentRegion = English;
290 | hasScannedForEncodings = 0;
291 | knownRegions = (
292 | en,
293 | );
294 | mainGroup = EB030DB91734DE4E00EDFADA;
295 | productRefGroup = EB030DC31734DE4E00EDFADA /* Products */;
296 | projectDirPath = "";
297 | projectRoot = "";
298 | targets = (
299 | EB030DC11734DE4E00EDFADA /* HomeWatch */,
300 | );
301 | };
302 | /* End PBXProject section */
303 |
304 | /* Begin PBXResourcesBuildPhase section */
305 | EB030DC01734DE4E00EDFADA /* Resources */ = {
306 | isa = PBXResourcesBuildPhase;
307 | buildActionMask = 2147483647;
308 | files = (
309 | EB030DD01734DE4E00EDFADA /* InfoPlist.strings in Resources */,
310 | EB030DD81734DE4E00EDFADA /* Default.png in Resources */,
311 | EB030DDA1734DE4E00EDFADA /* Default@2x.png in Resources */,
312 | EB030DDC1734DE4E00EDFADA /* Default-568h@2x.png in Resources */,
313 | EB030DE21734DE4E00EDFADA /* ViewController.xib in Resources */,
314 | EBAC0E33175095F300A0B864 /* lite-green.png in Resources */,
315 | EBAC0E34175095F300A0B864 /* lite-green@2x.png in Resources */,
316 | EBAC0E35175095F300A0B864 /* lite-off.png in Resources */,
317 | EBAC0E36175095F300A0B864 /* lite-off@2x.png in Resources */,
318 | EBAC0E37175095F300A0B864 /* lite-red.png in Resources */,
319 | EBAC0E38175095F300A0B864 /* lite-red@2x.png in Resources */,
320 | );
321 | runOnlyForDeploymentPostprocessing = 0;
322 | };
323 | /* End PBXResourcesBuildPhase section */
324 |
325 | /* Begin PBXSourcesBuildPhase section */
326 | EB030DBE1734DE4E00EDFADA /* Sources */ = {
327 | isa = PBXSourcesBuildPhase;
328 | buildActionMask = 2147483647;
329 | files = (
330 | EB030DD21734DE4E00EDFADA /* main.m in Sources */,
331 | EB030DD61734DE4E00EDFADA /* AppDelegate.m in Sources */,
332 | EB030DDF1734DE4E00EDFADA /* ViewController.m in Sources */,
333 | EB030E2E1734DFC800EDFADA /* logging_mosq.c in Sources */,
334 | EB030E2F1734DFC800EDFADA /* memory_mosq.c in Sources */,
335 | EB030E301734DFC800EDFADA /* messages_mosq.c in Sources */,
336 | EB030E311734DFC800EDFADA /* mosquitto.c in Sources */,
337 | EB030E321734DFC800EDFADA /* net_mosq.c in Sources */,
338 | EB030E331734DFC800EDFADA /* read_handle.c in Sources */,
339 | EB030E341734DFC800EDFADA /* read_handle_client.c in Sources */,
340 | EB030E351734DFC800EDFADA /* read_handle_shared.c in Sources */,
341 | EB030E361734DFC800EDFADA /* send_client_mosq.c in Sources */,
342 | EB030E371734DFC800EDFADA /* send_mosq.c in Sources */,
343 | EB030E381734DFC800EDFADA /* thread_mosq.c in Sources */,
344 | EB030E391734DFC800EDFADA /* util_mosq.c in Sources */,
345 | EB030E3A1734DFC800EDFADA /* will_mosq.c in Sources */,
346 | EB030E401734E04D00EDFADA /* MosquittoClient.m in Sources */,
347 | EB030E411734E04D00EDFADA /* MosquittoMessage.m in Sources */,
348 | EB030E441735F5BE00EDFADA /* Sensor.m in Sources */,
349 | );
350 | runOnlyForDeploymentPostprocessing = 0;
351 | };
352 | /* End PBXSourcesBuildPhase section */
353 |
354 | /* Begin PBXVariantGroup section */
355 | EB030DCE1734DE4E00EDFADA /* InfoPlist.strings */ = {
356 | isa = PBXVariantGroup;
357 | children = (
358 | EB030DCF1734DE4E00EDFADA /* en */,
359 | );
360 | name = InfoPlist.strings;
361 | sourceTree = "";
362 | };
363 | EB030DE01734DE4E00EDFADA /* ViewController.xib */ = {
364 | isa = PBXVariantGroup;
365 | children = (
366 | EB030DE11734DE4E00EDFADA /* en */,
367 | );
368 | name = ViewController.xib;
369 | sourceTree = "";
370 | };
371 | /* End PBXVariantGroup section */
372 |
373 | /* Begin XCBuildConfiguration section */
374 | EB030DE61734DE4E00EDFADA /* Debug */ = {
375 | isa = XCBuildConfiguration;
376 | buildSettings = {
377 | ALWAYS_SEARCH_USER_PATHS = NO;
378 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
379 | CLANG_CXX_LIBRARY = "libc++";
380 | CLANG_ENABLE_OBJC_ARC = YES;
381 | CLANG_WARN_CONSTANT_CONVERSION = YES;
382 | CLANG_WARN_EMPTY_BODY = YES;
383 | CLANG_WARN_ENUM_CONVERSION = YES;
384 | CLANG_WARN_INT_CONVERSION = YES;
385 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
386 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
387 | COPY_PHASE_STRIP = NO;
388 | GCC_C_LANGUAGE_STANDARD = gnu99;
389 | GCC_DYNAMIC_NO_PIC = NO;
390 | GCC_OPTIMIZATION_LEVEL = 0;
391 | GCC_PREPROCESSOR_DEFINITIONS = (
392 | "DEBUG=1",
393 | "$(inherited)",
394 | );
395 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
396 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
397 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
398 | GCC_WARN_UNUSED_VARIABLE = YES;
399 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
400 | ONLY_ACTIVE_ARCH = YES;
401 | SDKROOT = iphoneos;
402 | TARGETED_DEVICE_FAMILY = "1,2";
403 | };
404 | name = Debug;
405 | };
406 | EB030DE71734DE4E00EDFADA /* Release */ = {
407 | isa = XCBuildConfiguration;
408 | buildSettings = {
409 | ALWAYS_SEARCH_USER_PATHS = NO;
410 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
411 | CLANG_CXX_LIBRARY = "libc++";
412 | CLANG_ENABLE_OBJC_ARC = YES;
413 | CLANG_WARN_CONSTANT_CONVERSION = YES;
414 | CLANG_WARN_EMPTY_BODY = YES;
415 | CLANG_WARN_ENUM_CONVERSION = YES;
416 | CLANG_WARN_INT_CONVERSION = YES;
417 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
418 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
419 | COPY_PHASE_STRIP = YES;
420 | GCC_C_LANGUAGE_STANDARD = gnu99;
421 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
422 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
423 | GCC_WARN_UNUSED_VARIABLE = YES;
424 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
425 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
426 | SDKROOT = iphoneos;
427 | TARGETED_DEVICE_FAMILY = "1,2";
428 | VALIDATE_PRODUCT = YES;
429 | };
430 | name = Release;
431 | };
432 | EB030DE91734DE4E00EDFADA /* Debug */ = {
433 | isa = XCBuildConfiguration;
434 | buildSettings = {
435 | CODE_SIGN_ENTITLEMENTS = "";
436 | CODE_SIGN_IDENTITY = "iPhone Developer";
437 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
438 | FRAMEWORK_SEARCH_PATHS = (
439 | "$(inherited)",
440 | "\"$(SRCROOT)\"",
441 | );
442 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
443 | GCC_PREFIX_HEADER = "HomeWatch/HomeWatch-Prefix.pch";
444 | HEADER_SEARCH_PATHS = libmosquitto;
445 | INFOPLIST_FILE = "HomeWatch/HomeWatch-Info.plist";
446 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
447 | PRODUCT_NAME = "$(TARGET_NAME)";
448 | PROVISIONING_PROFILE = "";
449 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
450 | TARGETED_DEVICE_FAMILY = 1;
451 | WRAPPER_EXTENSION = app;
452 | };
453 | name = Debug;
454 | };
455 | EB030DEA1734DE4E00EDFADA /* Release */ = {
456 | isa = XCBuildConfiguration;
457 | buildSettings = {
458 | CODE_SIGN_ENTITLEMENTS = "";
459 | CODE_SIGN_IDENTITY = "iPhone Distribution";
460 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
461 | FRAMEWORK_SEARCH_PATHS = (
462 | "$(inherited)",
463 | "\"$(SRCROOT)\"",
464 | );
465 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
466 | GCC_PREFIX_HEADER = "HomeWatch/HomeWatch-Prefix.pch";
467 | HEADER_SEARCH_PATHS = libmosquitto;
468 | INFOPLIST_FILE = "HomeWatch/HomeWatch-Info.plist";
469 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
470 | PRODUCT_NAME = "$(TARGET_NAME)";
471 | PROVISIONING_PROFILE = "";
472 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
473 | TARGETED_DEVICE_FAMILY = 1;
474 | WRAPPER_EXTENSION = app;
475 | };
476 | name = Release;
477 | };
478 | /* End XCBuildConfiguration section */
479 |
480 | /* Begin XCConfigurationList section */
481 | EB030DBD1734DE4E00EDFADA /* Build configuration list for PBXProject "HomeWatch" */ = {
482 | isa = XCConfigurationList;
483 | buildConfigurations = (
484 | EB030DE61734DE4E00EDFADA /* Debug */,
485 | EB030DE71734DE4E00EDFADA /* Release */,
486 | );
487 | defaultConfigurationIsVisible = 0;
488 | defaultConfigurationName = Release;
489 | };
490 | EB030DE81734DE4E00EDFADA /* Build configuration list for PBXNativeTarget "HomeWatch" */ = {
491 | isa = XCConfigurationList;
492 | buildConfigurations = (
493 | EB030DE91734DE4E00EDFADA /* Debug */,
494 | EB030DEA1734DE4E00EDFADA /* Release */,
495 | );
496 | defaultConfigurationIsVisible = 0;
497 | defaultConfigurationName = Release;
498 | };
499 | /* End XCConfigurationList section */
500 | };
501 | rootObject = EB030DBA1734DE4E00EDFADA /* Project object */;
502 | }
503 |
--------------------------------------------------------------------------------
/libmosquitto/mosquitto.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010-2012 Roger Light
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | 3. Neither the name of mosquitto nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #ifndef WIN32
36 | #include