The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
13 | indicated below, the Content is provided to you under the terms and conditions of the
14 | Eclipse Public License Version 1.0 ("EPL") and Eclipse Distribution License Version 1.0 ("EDL").
15 | A copy of the EPL is available at
16 | http://www.eclipse.org/legal/epl-v10.html
17 | and a copy of the EDL is available at
18 | http://www.eclipse.org/org/documents/edl-v10.php.
19 | For purposes of the EPL, "Program" will mean the Content.
20 |
21 |
If you did not receive this Content directly from the Eclipse Foundation, the Content is
22 | being redistributed by another party ("Redistributor") and different terms and conditions may
23 | apply to your use of any object code in the Content. Check the Redistributor's license that was
24 | provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
25 | indicated below, the terms and conditions of the EPL still apply to any source code in the Content
26 | and such source code may be obtained at http://www.eclipse.org.
27 |
28 |
29 |
--------------------------------------------------------------------------------
/build/run_test2am:
--------------------------------------------------------------------------------
1 | LD_LIBRARY_PATH=. ./test3 --test_no 3 --hostname localhost --server_key /home/icraggs/nobackup/mosquitto-1.2/pkeys/test-root-ca.crt --client_key /home/icraggs/nobackup/mosquitto-1.2/pkeys/client.pem
2 |
--------------------------------------------------------------------------------
/build/run_test2as:
--------------------------------------------------------------------------------
1 | LD_LIBRARY_PATH=. ./test3 --test_no 2 --connection ssl://localhost:8883 --server_key /home/icraggs/nobackup/mosquitto-1.2/pkeys/server.pem --client_key /home/icraggs/nobackup/mosquitto-1.2/pkeys/client.pem
2 |
--------------------------------------------------------------------------------
/build/run_test3s:
--------------------------------------------------------------------------------
1 | LD_LIBRARY_PATH=. ./test3 --test_no 7 --connection ssl://localhost:8885 --server_key /home/icraggs/nobackup/mosquitto-1.2/pkeys/server.pem
2 |
--------------------------------------------------------------------------------
/doc/pahologo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yunba/yunba-c-sdk/84679219d8eeda39e439711d4cb2b68970fa4f2f/doc/pahologo.png
--------------------------------------------------------------------------------
/edl-v10:
--------------------------------------------------------------------------------
1 |
2 | Eclipse Distribution License - v 1.0
3 |
4 | Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
5 |
6 | All rights reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
9 |
10 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
11 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
12 | Neither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 |
16 |
--------------------------------------------------------------------------------
/src/Clients.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs - add SSL support
16 | *******************************************************************************/
17 |
18 | /**
19 | * @file
20 | * \brief functions which apply to client structures
21 | * */
22 |
23 |
24 | #include "Clients.h"
25 |
26 | #include
27 | #include
28 |
29 | #include "Log.h"
30 |
31 | extern ClientStates* bstate;
32 | /**
33 | * List callback function for comparing clients by clientid
34 | * @param a first integer value
35 | * @param b second integer value
36 | * @return boolean indicating whether a and b are equal
37 | */
38 | int clientIDCompare(void* a, void* b)
39 | {
40 | Clients* client = (Clients*)a;
41 | /*printf("comparing clientdIDs %s with %s\n", client->clientID, (char*)b);*/
42 | return strcmp(client->clientID, (char*)b) == 0;
43 | }
44 |
45 |
46 | /**
47 | * List callback function for comparing clients by socket
48 | * @param a first integer value
49 | * @param b second integer value
50 | * @return boolean indicating whether a and b are equal
51 | */
52 | int clientSocketCompare(void* a, void* b)
53 | {
54 | Clients* client = (Clients*)a;
55 | /*printf("comparing %d with %d\n", (char*)a, (char*)b); */
56 | return client->net.socket == *(int*)b;
57 | }
58 |
59 | int get_client_mqtt_version_from_network_handler(networkHandles* handler)
60 | {
61 | if(NULL == handler || NULL == bstate )
62 | {
63 | return MQTTVERSION_YUNBA_3_1;
64 | }
65 | int sockId = handler->socket;
66 | Clients* client = (Clients*)(ListFindItem(bstate->clients, &sockId, clientSocketCompare)->content);
67 | if(NULL == client)
68 | {
69 | //use yunba mqtt by default
70 | return MQTTVERSION_YUNBA_3_1;
71 | }else{
72 |
73 | Log(TRACE_MINIMUM, -1, "mqttversion is :%d", client->MQTTVersion);
74 | if(client->MQTTVersion == 0)
75 | {
76 | return MQTTVERSION_YUNBA_3_1;
77 | }else{
78 | return client->MQTTVersion;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/Clients.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs - add SSL support
16 | * Ian Craggs - fix for bug 413429 - connectionLost not called
17 | *******************************************************************************/
18 |
19 | #if !defined(CLIENTS_H)
20 | #define CLIENTS_H
21 |
22 | #include
23 | #include
24 | #if defined(OPENSSL)
25 | #if defined(WIN32) || defined(WIN64)
26 | #include "winsock2.h"
27 | #endif
28 | #include
29 | #endif
30 | #include "MQTTClient.h"
31 | #include "LinkedList.h"
32 | #include "MQTTClientPersistence.h"
33 | /*BE
34 | include "LinkedList"
35 | BE*/
36 |
37 | /*BE
38 | def PUBLICATIONS
39 | {
40 | n32 ptr STRING open "topic"
41 | n32 ptr DATA "payload"
42 | n32 dec "payloadlen"
43 | n32 dec "refcount"
44 | }
45 | BE*/
46 | /**
47 | * Stored publication data to minimize copying
48 | */
49 | typedef struct
50 | {
51 | char *topic;
52 | int topiclen;
53 | char* payload;
54 | int payloadlen;
55 | int refcount;
56 | } Publications;
57 |
58 | /*BE
59 | // This should get moved to MQTTProtocol, but the includes don't quite work yet
60 | map MESSAGE_TYPES
61 | {
62 | "PUBREC" 5
63 | "PUBREL" .
64 | "PUBCOMP" .
65 | }
66 |
67 |
68 | def MESSAGES
69 | {
70 | n32 dec "qos"
71 | n32 map bool "retain"
72 | n32 dec "msgid"
73 | n32 ptr PUBLICATIONS "publish"
74 | n32 time "lastTouch"
75 | n8 map MESSAGE_TYPES "nextMessageType"
76 | n32 dec "len"
77 | }
78 | defList(MESSAGES)
79 | BE*/
80 | /**
81 | * Client publication message data
82 | */
83 | typedef struct
84 | {
85 | int qos;
86 | int retain;
87 | uint64_t msgid;
88 | Publications *publish;
89 | time_t lastTouch; /**> used for retry and expiry */
90 | char nextMessageType; /**> PUBREC, PUBREL, PUBCOMP */
91 | int len; /**> length of the whole structure+data */
92 | } Messages;
93 |
94 |
95 | /*BE
96 | def WILLMESSAGES
97 | {
98 | n32 ptr STRING open "topic"
99 | n32 ptr DATA open "msg"
100 | n32 dec "retained"
101 | n32 dec "qos"
102 | }
103 | BE*/
104 |
105 | /**
106 | * Client will message data
107 | */
108 | typedef struct
109 | {
110 | char *topic;
111 | char *msg;
112 | int retained;
113 | int qos;
114 | } willMessages;
115 |
116 | /*BE
117 | map CLIENT_BITS
118 | {
119 | "cleansession" 1 : .
120 | "connected" 2 : .
121 | "good" 4 : .
122 | "ping_outstanding" 8 : .
123 | }
124 | def CLIENTS
125 | {
126 | n32 ptr STRING open "clientID"
127 | n32 ptr STRING open "username"
128 | n32 ptr STRING open "password"
129 | n32 map CLIENT_BITS "bits"
130 | at 4 n8 bits 7:6 dec "connect_state"
131 | at 8
132 | n32 dec "socket"
133 | n32 ptr "SSL"
134 | n32 dec "msgID"
135 | n32 dec "keepAliveInterval"
136 | n32 dec "maxInflightMessages"
137 | n32 ptr BRIDGECONNECTIONS "bridge_context"
138 | n32 time "lastContact"
139 | n32 ptr WILLMESSAGES "will"
140 | n32 ptr MESSAGESList open "inboundMsgs"
141 | n32 ptr MESSAGESList open "outboundMsgs"
142 | n32 ptr MESSAGESList open "messageQueue"
143 | n32 dec "discardedMsgs"
144 | }
145 |
146 | defList(CLIENTS)
147 |
148 | BE*/
149 |
150 | typedef struct
151 | {
152 | int socket;
153 | time_t lastSent;
154 | time_t lastReceived;
155 | #if defined(OPENSSL)
156 | SSL* ssl;
157 | SSL_CTX* ctx;
158 | #endif
159 | } networkHandles;
160 |
161 | /**
162 | * Data related to one client
163 | */
164 | typedef struct
165 | {
166 | char* clientID; /**< the string id of the client */
167 | const char* username; /**< MQTT v3.1 user name */
168 | const char* password; /**< MQTT v3.1 password */
169 | unsigned int cleansession : 1; /**< MQTT clean session flag */
170 | unsigned int connected : 1; /**< whether it is currently connected */
171 | unsigned int good : 1; /**< if we have an error on the socket we turn this off */
172 | unsigned int ping_outstanding : 1;
173 | int connect_state : 4;
174 | networkHandles net;
175 | int msgID;
176 | int keepAliveInterval;
177 | int retryInterval;
178 | int maxInflightMessages;
179 | willMessages* will;
180 | List* inboundMsgs;
181 | List* outboundMsgs; /**< in flight */
182 | List* messageQueue;
183 | unsigned int qentry_seqno;
184 | void* phandle; /* the persistence handle */
185 | MQTTClient_persistence* persistence; /* a persistence implementation */
186 | void* context; /* calling context - used when calling disconnect_internal */
187 | int MQTTVersion;
188 | #if defined(OPENSSL)
189 | MQTTClient_SSLOptions *sslopts;
190 | SSL_SESSION* session; /***< SSL session pointer for fast handhake */
191 | #endif
192 | } Clients;
193 |
194 | int clientIDCompare(void* a, void* b);
195 | int clientSocketCompare(void* a, void* b);
196 |
197 | int get_client_mqtt_version_from_network_handler(networkHandles* handler);
198 | /**
199 | * Configuration data related to all clients
200 | */
201 | typedef struct
202 | {
203 | const char* version;
204 | List* clients;
205 | } ClientStates;
206 |
207 | #endif
208 |
--------------------------------------------------------------------------------
/src/Heap.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs - use tree data structure instead of list
16 | *******************************************************************************/
17 |
18 |
19 | #if !defined(HEAP_H)
20 | #define HEAP_H
21 |
22 | #if defined(HIGH_PERFORMANCE)
23 | #define NO_HEAP_TRACKING 1
24 | #endif
25 |
26 | #include
27 | #include
28 | #include
29 |
30 | #if !defined(NO_HEAP_TRACKING)
31 | /**
32 | * redefines malloc to use "mymalloc" so that heap allocation can be tracked
33 | * @param x the size of the item to be allocated
34 | * @return the pointer to the item allocated, or NULL
35 | */
36 | #define malloc(x) mymalloc(__FILE__, __LINE__, x)
37 |
38 | /**
39 | * redefines realloc to use "myrealloc" so that heap allocation can be tracked
40 | * @param a the heap item to be reallocated
41 | * @param b the new size of the item
42 | * @return the new pointer to the heap item
43 | */
44 | #define realloc(a, b) myrealloc(__FILE__, __LINE__, a, b)
45 |
46 | /**
47 | * redefines free to use "myfree" so that heap allocation can be tracked
48 | * @param x the size of the item to be freed
49 | */
50 | #define free(x) myfree(__FILE__, __LINE__, x)
51 |
52 | #endif
53 |
54 | /**
55 | * Information about the state of the heap.
56 | */
57 | typedef struct
58 | {
59 | int current_size; /**< current size of the heap in bytes */
60 | int max_size; /**< max size the heap has reached in bytes */
61 | } heap_info;
62 |
63 |
64 | void* mymalloc(char*, int, size_t size);
65 | void* myrealloc(char*, int, void* p, size_t size);
66 | void myfree(char*, int, void* p);
67 |
68 | void Heap_scan(FILE* file);
69 | int Heap_initialize(void);
70 | void Heap_terminate(void);
71 | heap_info* Heap_get_info(void);
72 | int HeapDump(FILE* file);
73 | int HeapDumpString(FILE* file, char* str);
74 | void* Heap_findItem(void* p);
75 | void Heap_unlink(char* file, int line, void* p);
76 |
77 | #endif
78 |
--------------------------------------------------------------------------------
/src/LinkedList.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs - updates for the async client
16 | *******************************************************************************/
17 |
18 | #if !defined(LINKEDLIST_H)
19 | #define LINKEDLIST_H
20 |
21 | /*BE
22 | defm defList(T)
23 |
24 | def T concat Item
25 | {
26 | at 4
27 | n32 ptr T concat Item suppress "next"
28 | at 0
29 | n32 ptr T concat Item suppress "prev"
30 | at 8
31 | n32 ptr T id2str(T)
32 | }
33 |
34 | def T concat List
35 | {
36 | n32 ptr T concat Item suppress "first"
37 | n32 ptr T concat Item suppress "last"
38 | n32 ptr T concat Item suppress "current"
39 | n32 dec "count"
40 | n32 suppress "size"
41 | }
42 | endm
43 |
44 | defList(INT)
45 | defList(STRING)
46 | defList(TMP)
47 |
48 | BE*/
49 |
50 | /**
51 | * Structure to hold all data for one list element
52 | */
53 | typedef struct ListElementStruct
54 | {
55 | struct ListElementStruct *prev, /**< pointer to previous list element */
56 | *next; /**< pointer to next list element */
57 | void* content; /**< pointer to element content */
58 | } ListElement;
59 |
60 |
61 | /**
62 | * Structure to hold all data for one list
63 | */
64 | typedef struct
65 | {
66 | ListElement *first, /**< first element in the list */
67 | *last, /**< last element in the list */
68 | *current; /**< current element in the list, for iteration */
69 | int count, /**< no of items */
70 | size; /**< heap storage used */
71 | } List;
72 |
73 | void ListZero(List*);
74 | List* ListInitialize(void);
75 |
76 | void ListAppend(List* aList, void* content, int size);
77 | void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, int size);
78 | void ListInsert(List* aList, void* content, int size, ListElement* index);
79 |
80 | int ListRemove(List* aList, void* content);
81 | int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*));
82 | void* ListDetachHead(List* aList);
83 | int ListRemoveHead(List* aList);
84 | void* ListPopTail(List* aList);
85 |
86 | int ListDetach(List* aList, void* content);
87 | int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*));
88 |
89 | void ListFree(List* aList);
90 | void ListEmpty(List* aList);
91 | void ListFreeNoContent(List* aList);
92 |
93 | ListElement* ListNextElement(List* aList, ListElement** pos);
94 | ListElement* ListPrevElement(List* aList, ListElement** pos);
95 |
96 | ListElement* ListFind(List* aList, void* content);
97 | ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*));
98 |
99 | int intcompare(void* a, void* b);
100 | int stringcompare(void* a, void* b);
101 |
102 | #endif
103 |
--------------------------------------------------------------------------------
/src/Log.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs - updates for the async client
16 | *******************************************************************************/
17 |
18 | #if !defined(LOG_H)
19 | #define LOG_H
20 | #include "yunba.h"
21 | /*BE
22 | map LOG_LEVELS
23 | {
24 | "TRACE_MAXIMUM" 1
25 | "TRACE_MEDIUM" 2
26 | "TRACE_MINIMUM" 3
27 | "TRACE_PROTOCOL" 4
28 |
29 | "ERROR" 5
30 | "SEVERE" 6
31 | "FATAL" 7
32 | }
33 | BE*/
34 |
35 | enum LOG_LEVELS {
36 | TRACE_MAXIMUM = 1,
37 | TRACE_MEDIUM,
38 | TRACE_MINIMUM,
39 | TRACE_PROTOCOL,
40 | LOG_ERROR,
41 | LOG_SEVERE,
42 | LOG_FATAL,
43 | } Log_levels;
44 |
45 |
46 | /*BE
47 | def trace_settings_type
48 | {
49 | n32 map LOG_LEVELS "trace_level"
50 | n32 dec "max_trace_entries"
51 | n32 dec "trace_output_level"
52 | }
53 | BE*/
54 | typedef struct
55 | {
56 | int trace_level; /**< trace level */
57 | int max_trace_entries; /**< max no of entries in the trace buffer */
58 | int trace_output_level; /**< trace level to output to destination */
59 | } trace_settings_type;
60 |
61 | extern trace_settings_type trace_settings;
62 |
63 | #define LOG_PROTOCOL TRACE_PROTOCOL
64 | #define TRACE_MAX TRACE_MAXIMUM
65 | #define TRACE_MIN TRACE_MINIMUM
66 | #define TRACE_MED TRACE_MEDIUM
67 |
68 | typedef struct
69 | {
70 | const char* name;
71 | const char* value;
72 | } Log_nameValue;
73 |
74 | int Log_initialize(Log_nameValue*);
75 | void Log_terminate();
76 |
77 | void Log(int, int, char *, ...);
78 | void Log_stackTrace(int, int, int, int, const char*, int, int*);
79 |
80 | typedef void Log_traceCallback(enum LOG_LEVELS level, char* message);
81 | void Log_setTraceCallback(Log_traceCallback* callback);
82 | DLLExport void Log_setTraceLevel(enum LOG_LEVELS level);
83 |
84 | #endif
85 |
--------------------------------------------------------------------------------
/src/MQTTPacketOut.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs, Allan Stockdill-Mander - SSL updates
16 | * Ian Craggs - MQTT 3.1.1 support
17 | *******************************************************************************/
18 |
19 | #if !defined(MQTTPACKETOUT_H)
20 | #define MQTTPACKETOUT_H
21 |
22 | #include "MQTTPacket.h"
23 |
24 | int MQTTPacket_send_connect(Clients* client, int MQTTVersion);
25 | void* MQTTPacket_connack(unsigned char aHeader, char* data, size_t datalen, networkHandles* handler);
26 |
27 | int MQTTPacket_send_pingreq(networkHandles* net, const char* clientID);
28 |
29 | int MQTTPacket_send_subscribe(List* topics, List* qoss, uint64_t msgid, int dup, networkHandles* net, const char* clientID);
30 | void* MQTTPacket_suback(unsigned char aHeader, char* data, size_t datalen, networkHandles* handler);
31 |
32 | int MQTTPacket_send_unsubscribe(List* topics, uint64_t msgid, int dup, networkHandles* net, const char* clientID);
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/src/MQTTPersistence.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs - async client updates
16 | * Ian Craggs - fix for bug 432903 - queue persistence
17 | *******************************************************************************/
18 |
19 | #if defined(__cplusplus)
20 | extern "C" {
21 | #endif
22 |
23 | #include "Clients.h"
24 |
25 | /** Stem of the key for a sent PUBLISH QoS1 or QoS2 */
26 | #define PERSISTENCE_PUBLISH_SENT "s-"
27 | /** Stem of the key for a sent PUBREL */
28 | #define PERSISTENCE_PUBREL "sc-"
29 | /** Stem of the key for a received PUBLISH QoS2 */
30 | #define PERSISTENCE_PUBLISH_RECEIVED "r-"
31 | /** Stem of the key for an async client command */
32 | #define PERSISTENCE_COMMAND_KEY "c-"
33 | /** Stem of the key for an async client message queue */
34 | #define PERSISTENCE_QUEUE_KEY "q-"
35 | #define PERSISTENCE_MAX_KEY_LENGTH 8
36 |
37 | int MQTTPersistence_create(MQTTClient_persistence** per, int type, void* pcontext);
38 | int MQTTPersistence_initialize(Clients* c, const char* serverURI);
39 | int MQTTPersistence_close(Clients* c);
40 | int MQTTPersistence_clear(Clients* c);
41 | int MQTTPersistence_restore(Clients* c);
42 | void* MQTTPersistence_restorePacket(char* buffer, size_t buflen, networkHandles* handler);
43 | void MQTTPersistence_insertInOrder(List* list, void* content, size_t size);
44 | int MQTTPersistence_put(int socket, char* buf0, size_t buf0len, int count,
45 | char** buffers, size_t* buflens, int htype, uint64_t msgId, int scr);
46 | int MQTTPersistence_remove(Clients* c, char* type, int qos, uint64_t msgId);
47 | void MQTTPersistence_wrapMsgID(Clients *c);
48 |
49 | typedef struct
50 | {
51 | char struct_id[4];
52 | int struct_version;
53 | int payloadlen;
54 | void* payload;
55 | int qos;
56 | int retained;
57 | int dup;
58 | uint64_t msgid;
59 | } MQTTPersistence_message;
60 |
61 | typedef struct
62 | {
63 | MQTTPersistence_message* msg;
64 | char* topicName;
65 | int topicLen;
66 | unsigned int seqno; /* only used on restore */
67 | } MQTTPersistence_qEntry;
68 |
69 | int MQTTPersistence_unpersistQueueEntry(Clients* client, MQTTPersistence_qEntry* qe);
70 | int MQTTPersistence_persistQueueEntry(Clients* aclient, MQTTPersistence_qEntry* qe);
71 | int MQTTPersistence_restoreMessageQueue(Clients* c);
72 | #ifdef __cplusplus
73 | }
74 | #endif
75 |
--------------------------------------------------------------------------------
/src/MQTTPersistenceDefault.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | *******************************************************************************/
16 |
17 | /** 8.3 filesystem */
18 | #define MESSAGE_FILENAME_LENGTH 30
19 | /** Extension of the filename */
20 | #define MESSAGE_FILENAME_EXTENSION ".msg"
21 |
22 | /* prototypes of the functions for the default file system persistence */
23 | int pstopen(void** handle, const char* clientID, const char* serverURI, void* context);
24 | int pstclose(void* handle);
25 | int pstput(void* handle, char* key, int bufcount, char* buffers[], int buflens[]);
26 | int pstget(void* handle, char* key, char** buffer, int* buflen);
27 | int pstremove(void* handle, char* key);
28 | int pstkeys(void* handle, char*** keys, int* nkeys);
29 | int pstclear(void* handle);
30 | int pstcontainskey(void* handle, char* key);
31 |
32 | int pstmkdir(char *pPathname);
33 |
34 |
--------------------------------------------------------------------------------
/src/MQTTProtocol.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs - MQTT 3.1.1 updates
16 | *******************************************************************************/
17 |
18 | #if !defined(MQTTPROTOCOL_H)
19 | #define MQTTPROTOCOL_H
20 |
21 | #include "LinkedList.h"
22 | #include "MQTTPacket.h"
23 | #include "Clients.h"
24 |
25 | #define MAX_MSG_ID 65535
26 | #define MAX_CLIENTID_LEN 65535
27 |
28 | typedef struct
29 | {
30 | int socket;
31 | Publications* p;
32 | } pending_write;
33 |
34 |
35 | typedef struct
36 | {
37 | List publications;
38 | unsigned int msgs_received;
39 | unsigned int msgs_sent;
40 | List pending_writes; /* for qos 0 writes not complete */
41 | } MQTTProtocol;
42 |
43 |
44 | #include "MQTTProtocolOut.h"
45 |
46 | #endif
47 |
--------------------------------------------------------------------------------
/src/MQTTProtocolClient.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs, Allan Stockdill-Mander - SSL updates
16 | * Ian Craggs - MQTT 3.1.1 updates
17 | * Rong Xiang, Ian Craggs - C++ compatibility
18 | *******************************************************************************/
19 |
20 | #if !defined(MQTTPROTOCOLCLIENT_H)
21 | #define MQTTPROTOCOLCLIENT_H
22 |
23 | #include "LinkedList.h"
24 | #include "MQTTPacket.h"
25 | #include "Log.h"
26 | #include "MQTTProtocol.h"
27 | #include "Messages.h"
28 |
29 | #define MAX_MSG_ID 65535
30 | #define MAX_CLIENTID_LEN 65535
31 |
32 | uint64_t MQTTProtocol_assignMsgId(Clients* client);
33 | int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int retained, Messages** m);
34 | int MQTTProtocol_startGet(Clients* getclient, Get* get, int qos, int retained, Messages** m);
35 | Messages* MQTTProtocol_createMessage(Publish* publish, Messages** mm, int qos, int retained);
36 | Publications* MQTTProtocol_storePublication(Publish* publish, int* len);
37 | Messages* MQTTProtocol_createGetMessage(Get* get, Messages** mm, int qos, int retained);
38 | Publications* MQTTProtocol_storeGet(Get* get, int* len);
39 |
40 | int messageIDCompare(void* a, void* b);
41 | uint64_t MQTTProtocol_assignMsgId(Clients* client);
42 | void MQTTProtocol_removePublication(Publications* p);
43 |
44 | int MQTTProtocol_handlePublishes(void* pack, int sock);
45 | int MQTTProtocol_handleGets(void* pack, int sock);
46 | int MQTTProtocol_handlePubacks(void* pack, int sock);
47 | int MQTTProtocol_handlePubrecs(void* pack, int sock);
48 | int MQTTProtocol_handlePubrels(void* pack, int sock);
49 | int MQTTProtocol_handlePubcomps(void* pack, int sock);
50 |
51 | void MQTTProtocol_keepalive(time_t);
52 | void MQTTProtocol_retry(time_t, int, int);
53 | void MQTTProtocol_freeClient(Clients* client);
54 | void MQTTProtocol_emptyMessageList(List* msgList);
55 | void MQTTProtocol_freeMessageList(List* msgList);
56 |
57 | char* MQTTStrncpy(char *dest, const char* src, size_t num);
58 | char* MQTTStrdup(const char* src);
59 | #endif
60 |
--------------------------------------------------------------------------------
/src/MQTTProtocolOut.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs, Allan Stockdill-Mander - SSL updates
16 | * Ian Craggs - fix for buffer overflow in addressPort bug #433290
17 | * Ian Craggs - MQTT 3.1.1 support
18 | * Rong Xiang, Ian Craggs - C++ compatibility
19 | *******************************************************************************/
20 |
21 | /**
22 | * @file
23 | * \brief Functions dealing with the MQTT protocol exchanges
24 | *
25 | * Some other related functions are in the MQTTProtocolClient module
26 | */
27 |
28 | #include
29 |
30 | #include "MQTTProtocolOut.h"
31 | #include "StackTrace.h"
32 | #include "Heap.h"
33 |
34 | extern MQTTProtocol state;
35 | extern ClientStates* bstate;
36 |
37 |
38 | /**
39 | * Separates an address:port into two separate values
40 | * @param uri the input string - hostname:port
41 | * @param port the returned port integer
42 | * @return the address string
43 | */
44 | char* MQTTProtocol_addressPort(const char* uri, int* port)
45 | {
46 | char* colon_pos = strrchr(uri, ':'); /* reverse find to allow for ':' in IPv6 addresses */
47 | char* buf = (char*)uri;
48 | int len;
49 |
50 | FUNC_ENTRY;
51 | if (uri[0] == '[')
52 | { /* ip v6 */
53 | if (colon_pos < strrchr(uri, ']'))
54 | colon_pos = NULL; /* means it was an IPv6 separator, not for host:port */
55 | }
56 |
57 | if (colon_pos)
58 | {
59 | int addr_len = colon_pos - uri;
60 | buf = malloc(addr_len + 1);
61 | *port = atoi(colon_pos + 1);
62 | MQTTStrncpy(buf, uri, addr_len+1);
63 | }
64 | else
65 | *port = DEFAULT_PORT;
66 |
67 | len = strlen(buf);
68 | if (buf[len - 1] == ']')
69 | buf[len - 1] = '\0';
70 |
71 | FUNC_EXIT;
72 | return buf;
73 | }
74 |
75 |
76 | /**
77 | * MQTT outgoing connect processing for a client
78 | * @param ip_address the TCP address:port to connect to
79 | * @param aClient a structure with all MQTT data needed
80 | * @param int ssl
81 | * @param int MQTTVersion the MQTT version to connect with (3 or 4)
82 | * @return return code
83 | */
84 | #if defined(OPENSSL)
85 | int MQTTProtocol_connect(const char* ip_address, Clients* aClient, int ssl, int MQTTVersion)
86 | #else
87 | int MQTTProtocol_connect(const char* ip_address, Clients* aClient, int MQTTVersion)
88 | #endif
89 | {
90 | int rc, port;
91 | char* addr;
92 |
93 | FUNC_ENTRY;
94 | aClient->good = 1;
95 |
96 | addr = MQTTProtocol_addressPort(ip_address, &port);
97 | rc = Socket_new(addr, port, &(aClient->net.socket));
98 | if (rc == EINPROGRESS || rc == EWOULDBLOCK)
99 | aClient->connect_state = 1; /* TCP connect called - wait for connect completion */
100 | else if (rc == 0)
101 | { /* TCP connect completed. If SSL, send SSL connect */
102 | #if defined(OPENSSL)
103 | if (ssl)
104 | {
105 | if (SSLSocket_setSocketForSSL(&aClient->net, aClient->sslopts) != 1)
106 | {
107 | rc = SSLSocket_connect(aClient->net.ssl, aClient->net.socket);
108 | if (rc == -1)
109 | aClient->connect_state = 2; /* SSL connect called - wait for completion */
110 | }
111 | else
112 | rc = SOCKET_ERROR;
113 | }
114 | #endif
115 |
116 | if (rc == 0)
117 | {
118 | /* Now send the MQTT connect packet */
119 | if ((rc = MQTTPacket_send_connect(aClient, MQTTVersion)) == 0)
120 | aClient->connect_state = 3; /* MQTT Connect sent - wait for CONNACK */
121 | else
122 | aClient->connect_state = 0;
123 | }
124 | }
125 | if (addr != ip_address)
126 | free(addr);
127 |
128 | FUNC_EXIT_RC(rc);
129 | return rc;
130 | }
131 |
132 |
133 | /**
134 | * Process an incoming pingresp packet for a socket
135 | * @param pack pointer to the publish packet
136 | * @param sock the socket on which the packet was received
137 | * @return completion code
138 | */
139 | int MQTTProtocol_handlePingresps(void* pack, int sock)
140 | {
141 | Clients* client = NULL;
142 | int rc = TCPSOCKET_COMPLETE;
143 |
144 | FUNC_ENTRY;
145 | client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content);
146 | Log(LOG_PROTOCOL, 21, NULL, sock, client->clientID);
147 | client->ping_outstanding = 0;
148 | FUNC_EXIT_RC(rc);
149 | return rc;
150 | }
151 |
152 |
153 | /**
154 | * MQTT outgoing subscribe processing for a client
155 | * @param client the client structure
156 | * @param topics list of topics
157 | * @param qoss corresponding list of QoSs
158 | * @return completion code
159 | */
160 | int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, uint64_t msgID)
161 | {
162 | int rc = 0;
163 |
164 | FUNC_ENTRY;
165 | /* we should stack this up for retry processing too */
166 | rc = MQTTPacket_send_subscribe(topics, qoss, msgID, 0, &client->net, client->clientID);
167 | FUNC_EXIT_RC(rc);
168 | return rc;
169 | }
170 |
171 |
172 | /**
173 | * Process an incoming suback packet for a socket
174 | * @param pack pointer to the publish packet
175 | * @param sock the socket on which the packet was received
176 | * @return completion code
177 | */
178 | int MQTTProtocol_handleSubacks(void* pack, int sock)
179 | {
180 | Suback* suback = (Suback*)pack;
181 | Clients* client = NULL;
182 | int rc = TCPSOCKET_COMPLETE;
183 |
184 | FUNC_ENTRY;
185 | client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content);
186 | Log(LOG_PROTOCOL, 23, NULL, sock, client->clientID, suback->msgId);
187 | MQTTPacket_freeSuback(suback);
188 | FUNC_EXIT_RC(rc);
189 | return rc;
190 | }
191 |
192 |
193 | /**
194 | * MQTT outgoing unsubscribe processing for a client
195 | * @param client the client structure
196 | * @param topics list of topics
197 | * @return completion code
198 | */
199 | int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID)
200 | {
201 | int rc = 0;
202 |
203 | FUNC_ENTRY;
204 | /* we should stack this up for retry processing too? */
205 | rc = MQTTPacket_send_unsubscribe(topics, msgID, 0, &client->net, client->clientID);
206 | FUNC_EXIT_RC(rc);
207 | return rc;
208 | }
209 |
210 |
211 | /**
212 | * Process an incoming unsuback packet for a socket
213 | * @param pack pointer to the publish packet
214 | * @param sock the socket on which the packet was received
215 | * @return completion code
216 | */
217 | int MQTTProtocol_handleUnsubacks(void* pack, int sock)
218 | {
219 | Unsuback* unsuback = (Unsuback*)pack;
220 | Clients* client = NULL;
221 | int rc = TCPSOCKET_COMPLETE;
222 |
223 | FUNC_ENTRY;
224 | client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content);
225 | Log(LOG_PROTOCOL, 24, NULL, sock, client->clientID, unsuback->msgId);
226 | free(unsuback);
227 | FUNC_EXIT_RC(rc);
228 | return rc;
229 | }
230 |
231 |
--------------------------------------------------------------------------------
/src/MQTTProtocolOut.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs, Allan Stockdill-Mander - SSL updates
16 | * Ian Craggs - MQTT 3.1.1 support
17 | *******************************************************************************/
18 |
19 | #if !defined(MQTTPROTOCOLOUT_H)
20 | #define MQTTPROTOCOLOUT_H
21 |
22 | #include "LinkedList.h"
23 | #include "MQTTPacket.h"
24 | #include "Clients.h"
25 | #include "Log.h"
26 | #include "Messages.h"
27 | #include "MQTTProtocol.h"
28 | #include "MQTTProtocolClient.h"
29 |
30 | #define DEFAULT_PORT 1883
31 |
32 | void MQTTProtocol_reconnect(const char* ip_address, Clients* client);
33 | #if defined(OPENSSL)
34 | int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int MQTTVersion);
35 | #else
36 | int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int MQTTVersion);
37 | #endif
38 | int MQTTProtocol_handlePingresps(void* pack, int sock);
39 | int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, uint64_t msgID);
40 | int MQTTProtocol_handleSubacks(void* pack, int sock);
41 | int MQTTProtocol_unsubscribe(Clients* client, List* topics, int msgID);
42 | int MQTTProtocol_handleUnsubacks(void* pack, int sock);
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/src/MQTTVersion.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2012, 2015 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | *******************************************************************************/
16 |
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include "MQTTAsync.h"
26 |
27 | #if defined(WIN32) || defined(WIN64)
28 | #include
29 | #include
30 | #include
31 | #include
32 | #else
33 | #include
34 | #include
35 | #include
36 | #endif
37 |
38 |
39 | /**
40 | *
41 | * @file
42 | * \brief MQTTVersion - display the version and build information strings for a library.
43 | *
44 | * With no arguments, we try to load and call the version string for the libraries we
45 | * know about: mqttv3c, mqttv3cs, mqttv3a, mqttv3as.
46 | * With an argument:
47 | * 1) we try to load the named library, call getVersionInfo and display those values.
48 | * 2) If that doesn't work, we look through the binary for eyecatchers, and display those.
49 | * This will work if the library is not executable in the current environment.
50 | *
51 | * */
52 |
53 |
54 | char* libraries[] = {"paho-mqtt3c", "paho-mqtt3cs", "paho-mqtt3a", "paho-mqtt3as"};
55 | char* eyecatchers[] = {"MQTTAsyncV3_Version", "MQTTAsyncV3_Timestamp",
56 | "MQTTClientV3_Version", "MQTTClientV3_Timestamp"};
57 |
58 |
59 | /**
60 | * Finds an eyecatcher in a binary file and returns the following value.
61 | * @param filename the name of the file
62 | * @param eyecatcher_input the eyecatcher string to look for
63 | * @return the value found - "" if not found
64 | */
65 | char* FindString(char* filename, char* eyecatcher_input)
66 | {
67 | FILE* infile = NULL;
68 | static char value[100];
69 | char* eyecatcher = eyecatcher_input;
70 |
71 | memset(value, 0, 100);
72 | if ((infile = fopen(filename, "rb")) != NULL)
73 | {
74 | int buflen = strlen(eyecatcher);
75 | char* buffer = (char*) malloc(buflen);
76 | int count = 0;
77 | int c = fgetc(infile);
78 |
79 | while (feof(infile) == 0)
80 | {
81 | buffer[count++] = c;
82 | if (memcmp(eyecatcher, buffer, buflen) == 0)
83 | {
84 | char* ptr = value;
85 | c = fgetc(infile); /* skip space */
86 | c = fgetc(infile);
87 | while (isprint(c))
88 | {
89 | *ptr++ = c;
90 | c = fgetc(infile);
91 | }
92 | break;
93 | }
94 | if (count == buflen)
95 | {
96 | memmove(buffer, &buffer[1], buflen - 1);
97 | count--;
98 | }
99 | c = fgetc(infile);
100 | }
101 | free(buffer);
102 | }
103 | return value;
104 | }
105 |
106 |
107 | int printVersionInfo(MQTTAsync_nameValue* info)
108 | {
109 | int rc = 0;
110 |
111 | while (info->name)
112 | {
113 | printf("%s: %s\n", info->name, info->value);
114 | info++;
115 | rc = 1; /* at least one value printed */
116 | }
117 | return rc;
118 | }
119 |
120 | typedef MQTTAsync_nameValue* (*func_type)(void);
121 |
122 | int loadandcall(char* libname)
123 | {
124 | int rc = 0;
125 | MQTTAsync_nameValue* (*func_address)(void) = NULL;
126 | #if defined(WIN32) || defined(WIN64)
127 | wchar_t wlibname[30];
128 | HMODULE APILibrary;
129 |
130 | mbstowcs(wlibname, libname, strlen(libname) + 1);
131 | if ((APILibrary = LoadLibrary(wlibname)) == NULL)
132 | printf("Error loading library %s, error code %d\n", libname, GetLastError());
133 | else
134 | {
135 | func_address = (func_type)GetProcAddress(APILibrary, "MQTTAsync_getVersionInfo");
136 | if (func_address == NULL)
137 | func_address = (func_type)GetProcAddress(APILibrary, "MQTTClient_getVersionInfo");
138 | if (func_address)
139 | rc = printVersionInfo((*func_address)());
140 | FreeLibrary(APILibrary);
141 | }
142 | #else
143 | void* APILibrary = dlopen(libname, RTLD_LAZY); /* Open the Library in question */
144 | char* ErrorOutput = dlerror(); /* Check it opened properly */
145 | if (ErrorOutput != NULL)
146 | printf("Error loading library %s, error %s\n", libname, ErrorOutput);
147 | else
148 | {
149 | *(void **) (&func_address) = dlsym(APILibrary, "MQTTAsync_getVersionInfo");
150 | if (func_address == NULL)
151 | func_address = dlsym(APILibrary, "MQTTClient_getVersionInfo");
152 | if (func_address)
153 | rc = printVersionInfo((*func_address)());
154 | dlclose(APILibrary);
155 | }
156 | #endif
157 | return rc;
158 | }
159 |
160 |
161 | #if !defined(ARRAY_SIZE)
162 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
163 | #endif
164 |
165 | void printEyecatchers(char* filename)
166 | {
167 | int i = 0;
168 |
169 | for (i = 0; i < ARRAY_SIZE(eyecatchers); ++i)
170 | {
171 | char* value = FindString(filename, eyecatchers[i]);
172 | if (value[0])
173 | printf("%s: %s\n", eyecatchers[i], value);
174 | }
175 | }
176 |
177 |
178 | int main(int argc, char** argv)
179 | {
180 | printf("MQTTVersion: print the version strings of an MQTT client library\n");
181 | printf("Copyright (c) 2012, 2015 IBM Corp.\n");
182 |
183 | if (argc == 1)
184 | {
185 | int i = 0;
186 | char namebuf[60];
187 |
188 | printf("Specify a particular library name if it is not in the current directory, or not executable on this platform\n");
189 |
190 | for (i = 0; i < ARRAY_SIZE(libraries); ++i)
191 | {
192 | #if defined(WIN32) || defined(WIN64)
193 | sprintf(namebuf, "%s.dll", libraries[i]);
194 | #else
195 | sprintf(namebuf, "lib%s.so.1", libraries[i]);
196 | #endif
197 | printf("--- Trying library %s ---\n", libraries[i]);
198 | if (!loadandcall(namebuf))
199 | printEyecatchers(namebuf);
200 | }
201 | }
202 | else
203 | {
204 | if (!loadandcall(argv[1]))
205 | printEyecatchers(argv[1]);
206 | }
207 |
208 | return 0;
209 | }
210 |
--------------------------------------------------------------------------------
/src/Messages.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | *******************************************************************************/
16 |
17 | /**
18 | * @file
19 | * \brief Trace messages
20 | *
21 | */
22 |
23 |
24 | #include "Messages.h"
25 | #include "Log.h"
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #include "Heap.h"
33 |
34 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
35 |
36 | #define max_msg_len 120
37 |
38 | static char* protocol_message_list[] =
39 | {
40 | "%d %s -> CONNECT cleansession: %d (%d)", /* 0, was 131, 68 and 69 */
41 | "%d %s <- CONNACK rc: %d", /* 1, was 132 */
42 | "%d %s -> CONNACK rc: %d (%d)", /* 2, was 138 */
43 | "%d %s <- PINGREQ", /* 3, was 35 */
44 | "%d %s -> PINGRESP (%d)", /* 4 */
45 | "%d %s <- DISCONNECT", /* 5 */
46 | "%d %s <- SUBSCRIBE msgid: %llu", /* 6, was 39 */
47 | "%d %s -> SUBACK msgid: %llu (%d)", /* 7, was 40 */
48 | "%d %s <- UNSUBSCRIBE msgid: %llu", /* 8, was 41 */
49 | "%d %s -> UNSUBACK msgid: %llu (%d)", /* 9 */
50 | "%d %s -> PUBLISH msgid: %llu qos: %d retained: %d (%d) payload: %.*s", /* 10, was 42 */
51 | "%d %s <- PUBLISH msgid: %llu qos: %d retained: %d payload: %.*s", /* 11, was 46 */
52 | "%d %s -> PUBACK msgid: %llu (%d)", /* 12, was 47 */
53 | "%d %s -> PUBREC msgid: %llu (%d)", /* 13, was 48 */
54 | "%d %s <- PUBACK msgid: %llu", /* 14, was 49 */
55 | "%d %s <- PUBREC msgid: %llu", /* 15, was 53 */
56 | "%d %s -> PUBREL msgid: %llu (%d)", /* 16, was 57 */
57 | "%d %s <- PUBREL msgid: %llu", /* 17, was 58 */
58 | "%d %s -> PUBCOMP msgid: %llu (%d)", /* 18, was 62 */
59 | "%d %s <- PUBCOMP msgid: %llu", /* 19, was 63 */
60 | "%d %s -> PINGREQ (%d)", /* 20, was 137 */
61 | "%d %s <- PINGRESP", /* 21, was 70 */
62 | "%d %s -> SUBSCRIBE msgid: %llu (%d)", /* 22, was 72 */
63 | "%d %s <- SUBACK msgid: %llu", /* 23, was 73 */
64 | "%d %s <- UNSUBACK msgid: %llu", /* 24, was 74 */
65 | "%d %s -> UNSUBSCRIBE msgid: %llu (%d)", /* 25, was 106 */
66 | "%d %s <- CONNECT", /* 26 */
67 | "%d %s -> PUBLISH qos: 0 retained: %d (%d)", /* 27 */
68 | "%d %s -> DISCONNECT (%d)", /* 28 */
69 | "Socket error for client identifier %s, socket %d, peer address %s; ending connection", /* 29 */
70 | };
71 |
72 | static char* trace_message_list[] =
73 | {
74 | "Failed to remove client from bstate->clients", /* 0 */
75 | "Removed client %s from bstate->clients, socket %d", /* 1 */
76 | "Packet_Factory: unhandled packet type %d", /* 2 */
77 | "Packet %s received from client %s for message identifier %d, but no record of that message identifier found", /* 3 */
78 | "Packet %s received from client %s for message identifier %d, but message is wrong QoS, %d", /* 4 */
79 | "Packet %s received from client %s for message identifier %d, but message is in wrong state", /* 5 */
80 | "%s received from client %s for message id %d - removing publication", /* 6 */
81 | "Trying %s again for client %s, socket %d, message identifier %d", /* 7 */
82 | "", /* 8 */
83 | "(%lu) %*s(%d)> %s:%d", /* 9 */
84 | "(%lu) %*s(%d)< %s:%d", /* 10 */
85 | "(%lu) %*s(%d)< %s:%d (%d)", /* 11 */
86 | "Storing unsent QoS 0 message", /* 12 */
87 | };
88 |
89 | /**
90 | * Get a log message by its index
91 | * @param index the integer index
92 | * @param log_level the log level, used to determine which message list to use
93 | * @return the message format string
94 | */
95 | char* Messages_get(int index, int log_level)
96 | {
97 | char* msg = NULL;
98 |
99 | if (log_level == TRACE_PROTOCOL)
100 | msg = (index >= 0 && index < ARRAY_SIZE(protocol_message_list)) ? protocol_message_list[index] : NULL;
101 | else
102 | msg = (index >= 0 && index < ARRAY_SIZE(trace_message_list)) ? trace_message_list[index] : NULL;
103 | return msg;
104 | }
105 |
106 |
--------------------------------------------------------------------------------
/src/Messages.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | *******************************************************************************/
16 |
17 | #if !defined(MESSAGES_H)
18 | #define MESSAGES_H
19 |
20 | char* Messages_get(int, int);
21 |
22 | #endif
23 |
--------------------------------------------------------------------------------
/src/SSLSocket.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs, Allan Stockdill-Mander - initial implementation
15 | *******************************************************************************/
16 | #if !defined(SSLSOCKET_H)
17 | #define SSLSOCKET_H
18 |
19 | #if defined(WIN32) || defined(WIN64)
20 | #define ssl_mutex_type HANDLE
21 | #else
22 | #include
23 | #include
24 | #define ssl_mutex_type pthread_mutex_t
25 | #endif
26 |
27 | #include
28 | #include "SocketBuffer.h"
29 | #include "Clients.h"
30 |
31 | #define URI_SSL "ssl://"
32 |
33 | int SSLSocket_initialize();
34 | void SSLSocket_terminate();
35 | int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts);
36 | int SSLSocket_getch(SSL* ssl, int socket, char* c);
37 | char *SSLSocket_getdata(SSL* ssl, int socket, int bytes, int* actual_len);
38 |
39 | int SSLSocket_close(networkHandles* net);
40 | int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, int count, char** buffers, size_t* buflens, int* frees);
41 | int SSLSocket_connect(SSL* ssl, int socket);
42 |
43 | int SSLSocket_getPendingRead();
44 | int SSLSocket_continueWrite(pending_writes* pw);
45 |
46 | #endif
47 |
--------------------------------------------------------------------------------
/src/Socket.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial implementation and documentation
15 | * Ian Craggs - async client updates
16 | *******************************************************************************/
17 |
18 | #if !defined(SOCKET_H)
19 | #define SOCKET_H
20 |
21 | #include
22 |
23 | #if defined(WIN32) || defined(WIN64)
24 | #include
25 | #include
26 | #define MAXHOSTNAMELEN 256
27 | #if !defined(SSLSOCKET_H)
28 | #define EAGAIN WSAEWOULDBLOCK
29 | #define EINTR WSAEINTR
30 | #define EINPROGRESS WSAEINPROGRESS
31 | #define EWOULDBLOCK WSAEWOULDBLOCK
32 | #define ENOTCONN WSAENOTCONN
33 | #define ECONNRESET WSAECONNRESET
34 | #define ETIMEDOUT WAIT_TIMEOUT
35 | #endif
36 | #define ioctl ioctlsocket
37 | #define socklen_t int
38 | #else
39 | #define INVALID_SOCKET SOCKET_ERROR
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 | #include
52 | #include
53 | #include
54 | #endif
55 |
56 | /** socket operation completed successfully */
57 | #define TCPSOCKET_COMPLETE 0
58 | #if !defined(SOCKET_ERROR)
59 | /** error in socket operation */
60 | #define SOCKET_ERROR -1
61 | #endif
62 | /** must be the same as SOCKETBUFFER_INTERRUPTED */
63 | #define TCPSOCKET_INTERRUPTED -22
64 | #define SSL_FATAL -3
65 |
66 | #if !defined(INET6_ADDRSTRLEN)
67 | #define INET6_ADDRSTRLEN 46 /** only needed for gcc/cygwin on windows */
68 | #endif
69 |
70 |
71 | #if !defined(max)
72 | #define max(A,B) ( (A) > (B) ? (A):(B))
73 | #endif
74 |
75 | #include "LinkedList.h"
76 |
77 | /*BE
78 | def FD_SET
79 | {
80 | 128 n8 "data"
81 | }
82 |
83 | def SOCKETS
84 | {
85 | FD_SET "rset"
86 | FD_SET "rset_saved"
87 | n32 dec "maxfdp1"
88 | n32 ptr INTList "clientsds"
89 | n32 ptr INTItem "cur_clientsds"
90 | n32 ptr INTList "connect_pending"
91 | n32 ptr INTList "write_pending"
92 | FD_SET "pending_wset"
93 | }
94 | BE*/
95 |
96 |
97 | /**
98 | * Structure to hold all socket data for the module
99 | */
100 | typedef struct
101 | {
102 | fd_set rset, /**< socket read set (see select doc) */
103 | rset_saved; /**< saved socket read set */
104 | int maxfdp1; /**< max descriptor used +1 (again see select doc) */
105 | List* clientsds; /**< list of client socket descriptors */
106 | ListElement* cur_clientsds; /**< current client socket descriptor (iterator) */
107 | List* connect_pending; /**< list of sockets for which a connect is pending */
108 | List* write_pending; /**< list of sockets for which a write is pending */
109 | fd_set pending_wset; /**< socket pending write set for select */
110 | } Sockets;
111 |
112 |
113 | void Socket_outInitialize(void);
114 | void Socket_outTerminate(void);
115 | int Socket_getReadySocket(int more_work, struct timeval *tp);
116 | int Socket_getch(int socket, char* c);
117 | char *Socket_getdata(int socket, int bytes, int* actual_len);
118 | int Socket_putdatas(int socket, char* buf0, size_t buf0len, int count, char** buffers, size_t* buflens, int* frees);
119 | void Socket_close(int socket);
120 | int Socket_new(char* addr, int port, int* socket);
121 |
122 | int Socket_noPendingWrites(int socket);
123 | char* Socket_getpeer(int sock);
124 |
125 | void Socket_addPendingWrite(int socket);
126 | void Socket_clearPendingWrite(int socket);
127 |
128 | typedef void Socket_writeComplete(int socket);
129 | void Socket_setWriteCompleteCallback(Socket_writeComplete*);
130 |
131 | #endif /* SOCKET_H */
132 |
--------------------------------------------------------------------------------
/src/SocketBuffer.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | * Ian Craggs, Allan Stockdill-Mander - SSL updates
16 | *******************************************************************************/
17 |
18 | #if !defined(SOCKETBUFFER_H)
19 | #define SOCKETBUFFER_H
20 |
21 | #if defined(WIN32) || defined(WIN64)
22 | #include
23 | #else
24 | #include
25 | #endif
26 |
27 | #if defined(OPENSSL)
28 | #include
29 | #endif
30 |
31 | #if defined(WIN32) || defined(WIN64)
32 | typedef WSABUF iobuf;
33 | #else
34 | typedef struct iovec iobuf;
35 | #endif
36 |
37 | typedef struct
38 | {
39 | int socket;
40 | int index, headerlen;
41 | char fixed_header[5]; /**< header plus up to 4 length bytes */
42 | int buflen, /**< total length of the buffer */
43 | datalen; /**< current length of data in buf */
44 | char* buf;
45 | } socket_queue;
46 |
47 | typedef struct
48 | {
49 | int socket, total, count;
50 | #if defined(OPENSSL)
51 | SSL* ssl;
52 | #endif
53 | unsigned long bytes;
54 | iobuf iovecs[5];
55 | int frees[5];
56 | } pending_writes;
57 |
58 | #define SOCKETBUFFER_COMPLETE 0
59 | #if !defined(SOCKET_ERROR)
60 | #define SOCKET_ERROR -1
61 | #endif
62 | #define SOCKETBUFFER_INTERRUPTED -22 /* must be the same value as TCPSOCKET_INTERRUPTED */
63 |
64 | void SocketBuffer_initialize(void);
65 | void SocketBuffer_terminate(void);
66 | void SocketBuffer_cleanup(int socket);
67 | char* SocketBuffer_getQueuedData(int socket, int bytes, int* actual_len);
68 | int SocketBuffer_getQueuedChar(int socket, char* c);
69 | void SocketBuffer_interrupted(int socket, int actual_len);
70 | char* SocketBuffer_complete(int socket);
71 | void SocketBuffer_queueChar(int socket, char c);
72 |
73 | #if defined(OPENSSL)
74 | void SocketBuffer_pendingWrite(int socket, SSL* ssl, int count, iobuf* iovecs, int* frees, int total, int bytes);
75 | #else
76 | void SocketBuffer_pendingWrite(int socket, int count, iobuf* iovecs, int* frees, int total, int bytes);
77 | #endif
78 | pending_writes* SocketBuffer_getWrite(int socket);
79 | int SocketBuffer_writeComplete(int socket);
80 | pending_writes* SocketBuffer_updateWrite(int socket, char* topic, char* payload);
81 |
82 | #endif
83 |
--------------------------------------------------------------------------------
/src/StackTrace.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | *******************************************************************************/
16 |
17 | #include "StackTrace.h"
18 | #include "Log.h"
19 | #include "LinkedList.h"
20 |
21 | #include "Clients.h"
22 | #include "Thread.h"
23 |
24 | #include
25 | #include
26 | #include
27 |
28 | #if defined(WIN32) || defined(WIN64)
29 | #define snprintf _snprintf
30 | #endif
31 |
32 | /*BE
33 | def STACKENTRY
34 | {
35 | n32 ptr STRING open "name"
36 | n32 dec "line"
37 | }
38 |
39 | defList(STACKENTRY)
40 | BE*/
41 |
42 | #define MAX_STACK_DEPTH 50
43 | #define MAX_FUNCTION_NAME_LENGTH 30
44 | #define MAX_THREADS 255
45 |
46 | typedef struct
47 | {
48 | thread_id_type threadid;
49 | char name[MAX_FUNCTION_NAME_LENGTH];
50 | int line;
51 | } stackEntry;
52 |
53 | typedef struct
54 | {
55 | thread_id_type id;
56 | int maxdepth;
57 | int current_depth;
58 | stackEntry callstack[MAX_STACK_DEPTH];
59 | } threadEntry;
60 |
61 | #include "StackTrace.h"
62 |
63 | static int thread_count = 0;
64 | static threadEntry threads[MAX_THREADS];
65 | static threadEntry *cur_thread = NULL;
66 |
67 | #if defined(WIN32) || defined(WIN64)
68 | mutex_type stack_mutex;
69 | #else
70 | static pthread_mutex_t stack_mutex_store = PTHREAD_MUTEX_INITIALIZER;
71 | static mutex_type stack_mutex = &stack_mutex_store;
72 | #endif
73 |
74 |
75 | int setStack(int create)
76 | {
77 | int i = -1;
78 | thread_id_type curid = Thread_getid();
79 |
80 | cur_thread = NULL;
81 | for (i = 0; i < MAX_THREADS && i < thread_count; ++i)
82 | {
83 | if (threads[i].id == curid)
84 | {
85 | cur_thread = &threads[i];
86 | break;
87 | }
88 | }
89 |
90 | if (cur_thread == NULL && create && thread_count < MAX_THREADS)
91 | {
92 | cur_thread = &threads[thread_count];
93 | cur_thread->id = curid;
94 | cur_thread->maxdepth = 0;
95 | cur_thread->current_depth = 0;
96 | ++thread_count;
97 | }
98 | return cur_thread != NULL; /* good == 1 */
99 | }
100 |
101 | void StackTrace_entry(const char* name, int line, int trace_level)
102 | {
103 | Thread_lock_mutex(stack_mutex);
104 | if (!setStack(1))
105 | goto exit;
106 | if (trace_level != -1)
107 | Log_stackTrace(trace_level, 9, (int)cur_thread->id, cur_thread->current_depth, name, line, NULL);
108 | strncpy(cur_thread->callstack[cur_thread->current_depth].name, name, sizeof(cur_thread->callstack[0].name)-1);
109 | cur_thread->callstack[(cur_thread->current_depth)++].line = line;
110 | if (cur_thread->current_depth > cur_thread->maxdepth)
111 | cur_thread->maxdepth = cur_thread->current_depth;
112 | if (cur_thread->current_depth >= MAX_STACK_DEPTH)
113 | Log(LOG_FATAL, -1, "Max stack depth exceeded");
114 | exit:
115 | Thread_unlock_mutex(stack_mutex);
116 | }
117 |
118 |
119 | void StackTrace_exit(const char* name, int line, void* rc, int trace_level)
120 | {
121 | Thread_lock_mutex(stack_mutex);
122 | if (!setStack(0))
123 | goto exit;
124 | if (--(cur_thread->current_depth) < 0)
125 | Log(LOG_FATAL, -1, "Minimum stack depth exceeded for thread %lu", cur_thread->id);
126 | if (strncmp(cur_thread->callstack[cur_thread->current_depth].name, name, sizeof(cur_thread->callstack[0].name)-1) != 0)
127 | Log(LOG_FATAL, -1, "Stack mismatch. Entry:%s Exit:%s\n", cur_thread->callstack[cur_thread->current_depth].name, name);
128 | if (trace_level != -1)
129 | {
130 | if (rc == NULL)
131 | Log_stackTrace(trace_level, 10, (int)cur_thread->id, cur_thread->current_depth, name, line, NULL);
132 | else
133 | Log_stackTrace(trace_level, 11, (int)cur_thread->id, cur_thread->current_depth, name, line, (int*)rc);
134 | }
135 | exit:
136 | Thread_unlock_mutex(stack_mutex);
137 | }
138 |
139 |
140 | void StackTrace_printStack(FILE* dest)
141 | {
142 | FILE* file = stdout;
143 | int t = 0;
144 |
145 | if (dest)
146 | file = dest;
147 | for (t = 0; t < thread_count; ++t)
148 | {
149 | threadEntry *cur_thread = &threads[t];
150 |
151 | if (cur_thread->id > 0)
152 | {
153 | int i = cur_thread->current_depth - 1;
154 |
155 | fprintf(file, "=========== Start of stack trace for thread %lu ==========\n", (unsigned long)cur_thread->id);
156 | if (i >= 0)
157 | {
158 | fprintf(file, "%s (%d)\n", cur_thread->callstack[i].name, cur_thread->callstack[i].line);
159 | while (--i >= 0)
160 | fprintf(file, " at %s (%d)\n", cur_thread->callstack[i].name, cur_thread->callstack[i].line);
161 | }
162 | fprintf(file, "=========== End of stack trace for thread %lu ==========\n\n", (unsigned long)cur_thread->id);
163 | }
164 | }
165 | if (file != stdout && file != stderr && file != NULL)
166 | fclose(file);
167 | }
168 |
169 |
170 | char* StackTrace_get(thread_id_type threadid)
171 | {
172 | int bufsize = 256;
173 | char* buf = NULL;
174 | int t = 0;
175 |
176 | if ((buf = malloc(bufsize)) == NULL)
177 | goto exit;
178 | buf[0] = '\0';
179 | for (t = 0; t < thread_count; ++t)
180 | {
181 | threadEntry *cur_thread = &threads[t];
182 |
183 | if (cur_thread->id == threadid)
184 | {
185 | int i = cur_thread->current_depth - 1;
186 | int curpos = 0;
187 |
188 | if (i >= 0)
189 | {
190 | curpos += snprintf(&buf[curpos], bufsize - curpos -1,
191 | "%s (%d)\n", cur_thread->callstack[i].name, cur_thread->callstack[i].line);
192 | while (--i >= 0)
193 | curpos += snprintf(&buf[curpos], bufsize - curpos -1,
194 | " at %s (%d)\n", cur_thread->callstack[i].name, cur_thread->callstack[i].line);
195 | if (buf[--curpos] == '\n')
196 | buf[curpos] = '\0';
197 | }
198 | break;
199 | }
200 | }
201 | exit:
202 | return buf;
203 | }
204 |
205 |
--------------------------------------------------------------------------------
/src/StackTrace.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | *******************************************************************************/
16 |
17 | #ifndef STACKTRACE_H_
18 | #define STACKTRACE_H_
19 |
20 | #include
21 | #include "Log.h"
22 | #include "Thread.h"
23 |
24 | #if defined(NOSTACKTRACE)
25 | #define FUNC_ENTRY
26 | #define FUNC_ENTRY_NOLOG
27 | #define FUNC_ENTRY_MED
28 | #define FUNC_ENTRY_MAX
29 | #define FUNC_EXIT
30 | #define FUNC_EXIT_NOLOG
31 | #define FUNC_EXIT_MED
32 | #define FUNC_EXIT_MAX
33 | #define FUNC_EXIT_RC(x)
34 | #define FUNC_EXIT_MED_RC(x)
35 | #define FUNC_EXIT_MAX_RC(x)
36 | #else
37 | #if defined(WIN32) || defined(WIN64)
38 | #define inline __inline
39 | #define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM)
40 | #define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1)
41 | #define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM)
42 | #define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM)
43 | #define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM)
44 | #define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1)
45 | #define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM)
46 | #define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM)
47 | #define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM)
48 | #define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM)
49 | #define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM)
50 | #else
51 | #define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM)
52 | #define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1)
53 | #define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM)
54 | #define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM)
55 | #define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM)
56 | #define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1)
57 | #define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM)
58 | #define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM)
59 | #define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM)
60 | #define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM)
61 | #define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM)
62 | #endif
63 | #endif
64 |
65 | void StackTrace_entry(const char* name, int line, int trace);
66 | void StackTrace_exit(const char* name, int line, void* return_value, int trace);
67 |
68 | void StackTrace_printStack(FILE* dest);
69 | char* StackTrace_get(thread_id_type);
70 |
71 | #endif /* STACKTRACE_H_ */
72 |
--------------------------------------------------------------------------------
/src/Thread.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2014 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial implementation
15 | * Ian Craggs, Allan Stockdill-Mander - async client updates
16 | * Ian Craggs - fix for bug #420851
17 | *******************************************************************************/
18 |
19 | #if !defined(THREAD_H)
20 | #define THREAD_H
21 |
22 | #if defined(WIN32) || defined(WIN64)
23 | #include
24 | #define thread_type HANDLE
25 | #define thread_id_type DWORD
26 | #define thread_return_type DWORD
27 | #define thread_fn LPTHREAD_START_ROUTINE
28 | #define mutex_type HANDLE
29 | #define cond_type HANDLE
30 | #define sem_type HANDLE
31 | #else
32 | #include
33 | #include
34 | #define thread_type pthread_t
35 | #define thread_id_type pthread_t
36 | #define thread_return_type void*
37 | typedef thread_return_type (*thread_fn)(void*);
38 | #define mutex_type pthread_mutex_t*
39 | typedef struct { pthread_cond_t cond; pthread_mutex_t mutex; } cond_type_struct;
40 | typedef cond_type_struct *cond_type;
41 | typedef sem_t *sem_type;
42 |
43 | cond_type Thread_create_cond();
44 | int Thread_signal_cond(cond_type);
45 | int Thread_wait_cond(cond_type condvar, int timeout);
46 | int Thread_destroy_cond(cond_type);
47 | #endif
48 |
49 | thread_type Thread_start(thread_fn, void*);
50 |
51 | mutex_type Thread_create_mutex();
52 | int Thread_lock_mutex(mutex_type);
53 | int Thread_unlock_mutex(mutex_type);
54 | void Thread_destroy_mutex(mutex_type);
55 |
56 | thread_id_type Thread_getid();
57 |
58 | sem_type Thread_create_sem();
59 | int Thread_wait_sem(sem_type sem, int timeout);
60 | int Thread_check_sem(sem_type sem);
61 | int Thread_post_sem(sem_type sem);
62 | int Thread_destroy_sem(sem_type sem);
63 |
64 |
65 | #endif
66 |
--------------------------------------------------------------------------------
/src/Tree.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial implementation and documentation
15 | *******************************************************************************/
16 |
17 |
18 | #if !defined(TREE_H)
19 | #define TREE_H
20 |
21 | /*BE
22 | defm defTree(T) // macro to define a tree
23 |
24 | def T concat Node
25 | {
26 | n32 ptr T concat Node "parent"
27 | n32 ptr T concat Node "left"
28 | n32 ptr T concat Node "right"
29 | n32 ptr T id2str(T)
30 | n32 suppress "size"
31 | }
32 |
33 |
34 | def T concat Tree
35 | {
36 | struct
37 | {
38 | n32 ptr T concat Node suppress "root"
39 | n32 ptr DATA suppress "compare"
40 | }
41 | struct
42 | {
43 | n32 ptr T concat Node suppress "root"
44 | n32 ptr DATA suppress "compare"
45 | }
46 | n32 dec "count"
47 | n32 dec suppress "size"
48 | }
49 |
50 | endm
51 |
52 | defTree(INT)
53 | defTree(STRING)
54 | defTree(TMP)
55 |
56 | BE*/
57 |
58 | /**
59 | * Structure to hold all data for one list element
60 | */
61 | typedef struct NodeStruct
62 | {
63 | struct NodeStruct *parent, /**< pointer to parent tree node, in case we need it */
64 | *child[2]; /**< pointers to child tree nodes 0 = left, 1 = right */
65 | void* content; /**< pointer to element content */
66 | int size; /**< size of content */
67 | unsigned int red : 1;
68 | } Node;
69 |
70 |
71 | /**
72 | * Structure to hold all data for one tree
73 | */
74 | typedef struct
75 | {
76 | struct
77 | {
78 | Node *root; /**< root node pointer */
79 | int (*compare)(void*, void*, int); /**< comparison function */
80 | } index[2];
81 | int indexes, /**< no of indexes into tree */
82 | count, /**< no of items */
83 | size; /**< heap storage used */
84 | unsigned int heap_tracking : 1; /**< switch on heap tracking for this tree? */
85 | unsigned int allow_duplicates : 1; /**< switch to allow duplicate entries */
86 | } Tree;
87 |
88 |
89 | Tree* TreeInitialize(int(*compare)(void*, void*, int));
90 | void TreeInitializeNoMalloc(Tree* aTree, int(*compare)(void*, void*, int));
91 | void TreeAddIndex(Tree* aTree, int(*compare)(void*, void*, int));
92 |
93 | void* TreeAdd(Tree* aTree, void* content, int size);
94 |
95 | void* TreeRemove(Tree* aTree, void* content);
96 |
97 | void* TreeRemoveKey(Tree* aTree, void* key);
98 | void* TreeRemoveKeyIndex(Tree* aTree, void* key, int index);
99 |
100 | void* TreeRemoveNodeIndex(Tree* aTree, Node* aNode, int index);
101 |
102 | void TreeFree(Tree* aTree);
103 |
104 | Node* TreeFind(Tree* aTree, void* key);
105 | Node* TreeFindIndex(Tree* aTree, void* key, int index);
106 |
107 | Node* TreeNextElement(Tree* aTree, Node* curnode);
108 |
109 | int TreeIntCompare(void* a, void* b, int);
110 | int TreePtrCompare(void* a, void* b, int);
111 | int TreeStringCompare(void* a, void* b, int);
112 |
113 | #endif
114 |
--------------------------------------------------------------------------------
/src/samples/pahopub.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2012, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial contribution
15 | *******************************************************************************/
16 |
17 | /*
18 | stdin publisher
19 |
20 | compulsory parameters:
21 |
22 | --topic topic to publish on
23 |
24 | defaulted parameters:
25 |
26 | --host localhost
27 | --port 1883
28 | --qos 0
29 | --delimiters \n
30 | --clientid stdin_publisher
31 | --maxdatalen 100
32 |
33 | --userid none
34 | --password none
35 |
36 | */
37 |
38 | #include "MQTTClient.h"
39 | #include "MQTTClientPersistence.h"
40 |
41 | #include
42 | #include
43 | #include
44 |
45 |
46 | #if defined(WIN32)
47 | #include
48 | #define sleep Sleep
49 | #else
50 | #include
51 | #include
52 | #endif
53 |
54 |
55 | volatile int toStop = 0;
56 |
57 |
58 | void usage()
59 | {
60 | printf("MQTT stdin publisher\n");
61 | printf("Usage: stdinpub topicname , where options are:\n");
62 | printf(" --host (default is localhost)\n");
63 | printf(" --port (default is 1883)\n");
64 | printf(" --qos (default is 0)\n");
65 | printf(" --retained (default is off)\n");
66 | printf(" --delimiter (default is \\n)");
67 | printf(" --clientid (default is hostname+timestamp)");
68 | printf(" --maxdatalen 100\n");
69 | printf(" --username none\n");
70 | printf(" --password none\n");
71 | exit(-1);
72 | }
73 |
74 |
75 | void myconnect(MQTTClient* client, MQTTClient_connectOptions* opts)
76 | {
77 | printf("Connecting\n");
78 | if (MQTTClient_connect(*client, opts) != 0)
79 | {
80 | printf("Failed to connect\n");
81 | exit(-1);
82 | }
83 | printf("Connected\n");
84 | }
85 |
86 |
87 | void cfinish(int sig)
88 | {
89 | signal(SIGINT, NULL);
90 | toStop = 1;
91 | }
92 |
93 |
94 | struct
95 | {
96 | char* clientid;
97 | char* delimiter;
98 | int maxdatalen;
99 | int qos;
100 | int retained;
101 | char* username;
102 | char* password;
103 | char* host;
104 | char* port;
105 | int verbose;
106 | } opts =
107 | {
108 | "publisher", "\n", 100, 0, 0, NULL, NULL, "localhost", "1883", 0
109 | };
110 |
111 | void getopts(int argc, char** argv);
112 |
113 | int messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* m)
114 | {
115 | /* not expecting any messages */
116 | return 1;
117 | }
118 |
119 | int main(int argc, char** argv)
120 | {
121 | MQTTClient client;
122 | MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
123 | MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
124 | char* topic = NULL;
125 | char* buffer = NULL;
126 | int rc = 0;
127 | char url[100];
128 |
129 | if (argc < 2)
130 | usage();
131 |
132 | getopts(argc, argv);
133 |
134 | sprintf(url, "%s:%s", opts.host, opts.port);
135 | if (opts.verbose)
136 | printf("URL is %s\n", url);
137 |
138 | topic = argv[1];
139 | printf("Using topic %s\n", topic);
140 |
141 | rc = MQTTClient_create(&client, url, opts.clientid, MQTTCLIENT_PERSISTENCE_NONE, NULL);
142 |
143 | signal(SIGINT, cfinish);
144 | signal(SIGTERM, cfinish);
145 |
146 | rc = MQTTClient_setCallbacks(client, NULL, NULL, messageArrived, NULL);
147 |
148 | conn_opts.keepAliveInterval = 10;
149 | conn_opts.reliable = 0;
150 | conn_opts.cleansession = 1;
151 | conn_opts.username = opts.username;
152 | conn_opts.password = opts.password;
153 | ssl_opts.enableServerCertAuth = 0;
154 | conn_opts.ssl = &ssl_opts;
155 |
156 | myconnect(&client, &conn_opts);
157 |
158 | buffer = malloc(opts.maxdatalen);
159 |
160 | while (!toStop)
161 | {
162 | int data_len = 0;
163 | int delim_len = 0;
164 |
165 | delim_len = strlen(opts.delimiter);
166 | do
167 | {
168 | buffer[data_len++] = getchar();
169 | if (data_len > delim_len)
170 | {
171 | //printf("comparing %s %s\n", opts.delimiter, &buffer[data_len - delim_len]);
172 | if (strncmp(opts.delimiter, &buffer[data_len - delim_len], delim_len) == 0)
173 | break;
174 | }
175 | } while (data_len < opts.maxdatalen);
176 |
177 | if (opts.verbose)
178 | printf("Publishing data of length %d\n", data_len);
179 | rc = MQTTClient_publish(client, topic, data_len, buffer, opts.qos, opts.retained, NULL);
180 | if (rc != 0)
181 | {
182 | myconnect(&client, &conn_opts);
183 | rc = MQTTClient_publish(client, topic, data_len, buffer, opts.qos, opts.retained, NULL);
184 | }
185 | if (opts.qos > 0)
186 | MQTTClient_yield();
187 | }
188 |
189 | printf("Stopping\n");
190 |
191 | free(buffer);
192 |
193 | MQTTClient_disconnect(client, 0);
194 |
195 | MQTTClient_destroy(&client);
196 |
197 | return 0;
198 | }
199 |
200 | void getopts(int argc, char** argv)
201 | {
202 | int count = 2;
203 |
204 | while (count < argc)
205 | {
206 | if (strcmp(argv[count], "--retained") == 0)
207 | opts.retained = 1;
208 | if (strcmp(argv[count], "--verbose") == 0)
209 | opts.verbose = 1;
210 | else if (strcmp(argv[count], "--qos") == 0)
211 | {
212 | if (++count < argc)
213 | {
214 | if (strcmp(argv[count], "0") == 0)
215 | opts.qos = 0;
216 | else if (strcmp(argv[count], "1") == 0)
217 | opts.qos = 1;
218 | else if (strcmp(argv[count], "2") == 0)
219 | opts.qos = 2;
220 | else
221 | usage();
222 | }
223 | else
224 | usage();
225 | }
226 | else if (strcmp(argv[count], "--host") == 0)
227 | {
228 | if (++count < argc)
229 | opts.host = argv[count];
230 | else
231 | usage();
232 | }
233 | else if (strcmp(argv[count], "--port") == 0)
234 | {
235 | if (++count < argc)
236 | opts.port = argv[count];
237 | else
238 | usage();
239 | }
240 | else if (strcmp(argv[count], "--clientid") == 0)
241 | {
242 | if (++count < argc)
243 | opts.clientid = argv[count];
244 | else
245 | usage();
246 | }
247 | else if (strcmp(argv[count], "--username") == 0)
248 | {
249 | if (++count < argc)
250 | opts.username = argv[count];
251 | else
252 | usage();
253 | }
254 | else if (strcmp(argv[count], "--password") == 0)
255 | {
256 | if (++count < argc)
257 | opts.password = argv[count];
258 | else
259 | usage();
260 | }
261 | else if (strcmp(argv[count], "--maxdatalen") == 0)
262 | {
263 | if (++count < argc)
264 | opts.maxdatalen = atoi(argv[count]);
265 | else
266 | usage();
267 | }
268 | else if (strcmp(argv[count], "--delimiter") == 0)
269 | {
270 | if (++count < argc)
271 | opts.delimiter = argv[count];
272 | else
273 | usage();
274 | }
275 | count++;
276 | }
277 |
278 | }
279 |
280 |
--------------------------------------------------------------------------------
/src/samples/pubasync.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2012, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial contribution
15 | *******************************************************************************/
16 |
17 | #include "stdio.h"
18 | #include "stdlib.h"
19 | #include "string.h"
20 | #include "MQTTClient.h"
21 |
22 | #define ADDRESS "tcp://localhost:1883"
23 | #define CLIENTID "ExampleClientPub"
24 | #define TOPIC "MQTT Examples"
25 | #define PAYLOAD "Hello World!"
26 | #define QOS 1
27 | #define TIMEOUT 10000L
28 |
29 | volatile MQTTClient_deliveryToken deliveredtoken;
30 |
31 | void delivered(void *context, MQTTClient_deliveryToken dt)
32 | {
33 | printf("Message with token value %"PRIu64" delivery confirmed\n", dt);
34 | deliveredtoken = dt;
35 | }
36 |
37 | int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
38 | {
39 | int i;
40 | char* payloadptr;
41 |
42 | printf("Message arrived\n");
43 | printf(" topic: %s\n", topicName);
44 | printf(" message: ");
45 |
46 | payloadptr = message->payload;
47 | for(i=0; ipayloadlen; i++)
48 | {
49 | putchar(*payloadptr++);
50 | }
51 | putchar('\n');
52 | MQTTClient_freeMessage(&message);
53 | MQTTClient_free(topicName);
54 | return 1;
55 | }
56 |
57 | void connlost(void *context, char *cause)
58 | {
59 | printf("\nConnection lost\n");
60 | printf(" cause: %s\n", cause);
61 | }
62 |
63 | int main(int argc, char* argv[])
64 | {
65 | MQTTClient client;
66 | MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
67 | MQTTClient_message pubmsg = MQTTClient_message_initializer;
68 | MQTTClient_deliveryToken token;
69 | int rc;
70 |
71 | MQTTClient_create(&client, ADDRESS, CLIENTID,
72 | MQTTCLIENT_PERSISTENCE_NONE, NULL);
73 | conn_opts.keepAliveInterval = 300;
74 | conn_opts.cleansession = 1;
75 |
76 | MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered, NULL);
77 |
78 | if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
79 | {
80 | printf("Failed to connect, return code %d\n", rc);
81 | exit(-1);
82 | }
83 | pubmsg.payload = PAYLOAD;
84 | pubmsg.payloadlen = strlen(PAYLOAD);
85 | pubmsg.qos = QOS;
86 | pubmsg.retained = 0;
87 | deliveredtoken = 0;
88 | MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
89 | printf("Waiting for publication of %s\n"
90 | "on topic %s for client with ClientID: %s\n",
91 | PAYLOAD, TOPIC, CLIENTID);
92 | while(deliveredtoken != token);
93 | MQTTClient_disconnect(client, 10000);
94 | MQTTClient_destroy(&client);
95 | return rc;
96 | }
97 |
98 |
--------------------------------------------------------------------------------
/src/samples/pubsync.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2012, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial contribution
15 | *******************************************************************************/
16 |
17 | #include "stdio.h"
18 | #include "stdlib.h"
19 | #include "string.h"
20 | #include "MQTTClient.h"
21 |
22 | #define ADDRESS "tcp://localhost:1883"
23 | #define CLIENTID "ExampleClientPub"
24 | #define TOPIC "MQTT Examples"
25 | #define PAYLOAD "Hello World!"
26 | #define QOS 1
27 | #define TIMEOUT 10000L
28 |
29 | int main(int argc, char* argv[])
30 | {
31 | MQTTClient client;
32 | MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
33 | MQTTClient_message pubmsg = MQTTClient_message_initializer;
34 | MQTTClient_deliveryToken token;
35 | int rc;
36 |
37 | MQTTClient_create(&client, ADDRESS, CLIENTID,
38 | MQTTCLIENT_PERSISTENCE_NONE, NULL);
39 | conn_opts.keepAliveInterval = 300;
40 | conn_opts.cleansession = 1;
41 |
42 | if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
43 | {
44 | printf("Failed to connect, return code %d\n", rc);
45 | exit(-1);
46 | }
47 | pubmsg.payload = PAYLOAD;
48 | pubmsg.payloadlen = strlen(PAYLOAD);
49 | pubmsg.qos = QOS;
50 | pubmsg.retained = 0;
51 | MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
52 | printf("Waiting for up to %d seconds for publication of %s\n"
53 | "on topic %s for client with ClientID: %s\n",
54 | (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID);
55 | rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
56 | printf("Message with delivery token %"PRIu64" delivered\n", token);
57 | MQTTClient_disconnect(client, 10000);
58 | MQTTClient_destroy(&client);
59 | return rc;
60 | }
61 |
--------------------------------------------------------------------------------
/src/samples/stdinpub.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2012, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial contribution
15 | *******************************************************************************/
16 |
17 | /*
18 | stdin publisher
19 |
20 | compulsory parameters:
21 |
22 | --topic topic to publish on
23 |
24 | defaulted parameters:
25 |
26 | --host localhost
27 | --port 1883
28 | --qos 0
29 | --delimiters \n
30 | --clientid stdin_publisher
31 | --maxdatalen 100
32 |
33 | --userid none
34 | --password none
35 |
36 | */
37 |
38 | #include "MQTTClient.h"
39 | #include "MQTTClientPersistence.h"
40 |
41 | #include
42 | #include
43 | #include
44 |
45 |
46 | #if defined(WIN32)
47 | #include
48 | #define sleep Sleep
49 | #else
50 | #include
51 | #include
52 | #endif
53 |
54 |
55 | volatile int toStop = 0;
56 |
57 |
58 | void usage()
59 | {
60 | printf("MQTT stdin publisher\n");
61 | printf("Usage: stdinpub topicname , where options are:\n");
62 | printf(" --host (default is localhost)\n");
63 | printf(" --port (default is 1883)\n");
64 | printf(" --qos (default is 0)\n");
65 | printf(" --retained (default is off)\n");
66 | printf(" --delimiter (default is \\n)");
67 | printf(" --clientid (default is hostname+timestamp)");
68 | printf(" --maxdatalen 100\n");
69 | printf(" --username none\n");
70 | printf(" --password none\n");
71 | exit(-1);
72 | }
73 |
74 |
75 | void myconnect(MQTTClient* client, MQTTClient_connectOptions* opts)
76 | {
77 | printf("Connecting\n");
78 | if (MQTTClient_connect(*client, opts) != 0)
79 | {
80 | printf("Failed to connect\n");
81 | exit(-1);
82 | }
83 | }
84 |
85 |
86 | void cfinish(int sig)
87 | {
88 | signal(SIGINT, NULL);
89 | toStop = 1;
90 | }
91 |
92 |
93 |
94 |
95 | struct
96 | {
97 | char* clientid;
98 | char* delimiter;
99 | int maxdatalen;
100 | int qos;
101 | int retained;
102 | char* username;
103 | char* password;
104 | char* host;
105 | char* port;
106 | int verbose;
107 | } opts =
108 | {
109 | "publisher", "\n", 100, 0, 0, NULL, NULL, "localhost", "1883", 0
110 | };
111 |
112 | void getopts(int argc, char** argv);
113 |
114 | int messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* m)
115 | {
116 | /* not expecting any messages */
117 | return 1;
118 | }
119 |
120 | int main(int argc, char** argv)
121 | {
122 | MQTTClient client;
123 | MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
124 | char* topic = NULL;
125 | char* buffer = NULL;
126 | int rc = 0;
127 | char url[100];
128 |
129 | if (argc < 2)
130 | usage();
131 |
132 | getopts(argc, argv);
133 |
134 | sprintf(url, "%s:%s", opts.host, opts.port);
135 | if (opts.verbose)
136 | printf("URL is %s\n", url);
137 |
138 | topic = argv[1];
139 | printf("Using topic %s\n", topic);
140 |
141 | rc = MQTTClient_create(&client, url, opts.clientid, MQTTCLIENT_PERSISTENCE_NONE, NULL);
142 |
143 | signal(SIGINT, cfinish);
144 | signal(SIGTERM, cfinish);
145 |
146 | rc = MQTTClient_setCallbacks(client, NULL, NULL, messageArrived, NULL, NULL);
147 |
148 | conn_opts.keepAliveInterval = 300;
149 | conn_opts.reliable = 0;
150 | conn_opts.cleansession = 1;
151 | conn_opts.username = opts.username;
152 | conn_opts.password = opts.password;
153 |
154 | myconnect(&client, &conn_opts);
155 |
156 | int ret;
157 | printf("send push-alias\n");
158 | ret = MQTTClient_publish_to_alias(client, "000000018302", strlen("a"), "a");
159 | ret = MQTTClient_publish_to_alias(client, "000000018302", strlen("helloKitty"), "helloKitty");
160 | ret = MQTTClient_publish_to_alias(client, "000000018302", strlen("helloKitty1"), "helloKitty1");
161 |
162 | buffer = malloc(opts.maxdatalen);
163 |
164 | while (!toStop)
165 | {
166 | int data_len = 0;
167 | int delim_len = 0;
168 |
169 | delim_len = strlen(opts.delimiter);
170 | do
171 | {
172 | buffer[data_len++] = getchar();
173 | if (data_len > delim_len)
174 | {
175 | //printf("comparing %s %s\n", opts.delimiter, &buffer[data_len - delim_len]);
176 | if (strncmp(opts.delimiter, &buffer[data_len - delim_len], delim_len) == 0)
177 | break;
178 | }
179 | } while (data_len < opts.maxdatalen);
180 |
181 | if (opts.verbose)
182 | printf("Publishing data of length %d\n", data_len);
183 | rc = MQTTClient_publish(client, topic, data_len, buffer);
184 | if (rc != 0)
185 | {
186 | myconnect(&client, &conn_opts);
187 | rc = MQTTClient_publish(client, topic, data_len, buffer);
188 | }
189 | if (opts.qos > 0)
190 | MQTTClient_yield();
191 | }
192 |
193 | printf("Stopping\n");
194 |
195 | free(buffer);
196 |
197 | MQTTClient_disconnect(client, 0);
198 |
199 | MQTTClient_destroy(&client);
200 |
201 | return 0;
202 | }
203 |
204 | void getopts(int argc, char** argv)
205 | {
206 | int count = 2;
207 |
208 | while (count < argc)
209 | {
210 | if (strcmp(argv[count], "--retained") == 0)
211 | opts.retained = 1;
212 | if (strcmp(argv[count], "--verbose") == 0)
213 | opts.verbose = 1;
214 | else if (strcmp(argv[count], "--qos") == 0)
215 | {
216 | if (++count < argc)
217 | {
218 | if (strcmp(argv[count], "0") == 0)
219 | opts.qos = 0;
220 | else if (strcmp(argv[count], "1") == 0)
221 | opts.qos = 1;
222 | else if (strcmp(argv[count], "2") == 0)
223 | opts.qos = 2;
224 | else
225 | usage();
226 | }
227 | else
228 | usage();
229 | }
230 | else if (strcmp(argv[count], "--host") == 0)
231 | {
232 | if (++count < argc)
233 | opts.host = argv[count];
234 | else
235 | usage();
236 | }
237 | else if (strcmp(argv[count], "--port") == 0)
238 | {
239 | if (++count < argc)
240 | opts.port = argv[count];
241 | else
242 | usage();
243 | }
244 | else if (strcmp(argv[count], "--clientid") == 0)
245 | {
246 | if (++count < argc)
247 | opts.clientid = argv[count];
248 | else
249 | usage();
250 | }
251 | else if (strcmp(argv[count], "--username") == 0)
252 | {
253 | if (++count < argc)
254 | opts.username = argv[count];
255 | else
256 | usage();
257 | }
258 | else if (strcmp(argv[count], "--password") == 0)
259 | {
260 | if (++count < argc)
261 | opts.password = argv[count];
262 | else
263 | usage();
264 | }
265 | else if (strcmp(argv[count], "--maxdatalen") == 0)
266 | {
267 | if (++count < argc)
268 | opts.maxdatalen = atoi(argv[count]);
269 | else
270 | usage();
271 | }
272 | else if (strcmp(argv[count], "--delimiter") == 0)
273 | {
274 | if (++count < argc)
275 | opts.delimiter = argv[count];
276 | else
277 | usage();
278 | }
279 | count++;
280 | }
281 |
282 | }
283 |
284 |
--------------------------------------------------------------------------------
/src/samples/stdoutsub_demo.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2012, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial contribution
15 | * Ian Craggs - change delimiter option from char to string
16 | *******************************************************************************/
17 |
18 | /*
19 |
20 | stdout subscriber
21 |
22 | compulsory parameters:
23 |
24 | --topic topic to subscribe to
25 |
26 | defaulted parameters:
27 |
28 | --host localhost
29 | --port 1883
30 | --qos 2
31 | --delimiter \n
32 | --clientid stdout_subscriber
33 |
34 | --userid none
35 | --password none
36 |
37 | */
38 | #include "MQTTClient.h"
39 | #include "MQTTClientPersistence.h"
40 |
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 |
49 | #if defined(WIN32)
50 | #include
51 | #define sleep Sleep
52 | #else
53 | #include
54 | #include
55 | #endif
56 |
57 |
58 | volatile int toStop = 0;
59 |
60 | void usage()
61 | {
62 | printf("MQTT stdout subscriber\n");
63 | printf("Usage: stdoutsub topicname , where options are:\n");
64 | printf(" --host (default is localhost)\n");
65 | printf(" --port (default is 1883)\n");
66 | printf(" --qos (default is 2)\n");
67 | printf(" --delimiter (default is \\n)\n");
68 | printf(" --clientid (default is hostname+timestamp)\n");
69 | printf(" --username none\n");
70 | printf(" --password none\n");
71 | printf(" --showtopics (default is on if the topic has a wildcard, else off)\n");
72 | exit(-1);
73 | }
74 |
75 |
76 | int myconnect(MQTTClient* client, MQTTClient_connectOptions* opts)
77 | {
78 | int rc = 0;
79 | if ((rc = MQTTClient_connect(*client, opts)) != 0)
80 | {
81 | printf("Failed to connect, return code %d\n", rc);
82 | // exit(-1);
83 | return -1;
84 | }
85 | return 0;
86 | }
87 |
88 |
89 | void cfinish(int sig)
90 | {
91 | signal(SIGINT, NULL);
92 | toStop = 1;
93 | printf("-----------\n");
94 | }
95 |
96 |
97 | struct opts_struct
98 | {
99 | char* clientid;
100 | int nodelimiter;
101 | char* delimiter;
102 | int qos;
103 | char* username;
104 | char* password;
105 | char* host;
106 | char* port;
107 | int showtopics;
108 | } opts =
109 | {
110 | "stdout-subscriber", 0, "\n", 2, NULL, NULL, "localhost", "1883", 0
111 | };
112 |
113 | void getopts(int argc, char** argv);
114 |
115 | int main(int argc, char** argv)
116 | {
117 | MQTTClient client;
118 | MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
119 | char* topic = NULL;
120 | int rc = 0;
121 | char url[100];
122 |
123 | int fd;
124 | int count = 0;
125 |
126 | if (argc < 2)
127 | usage();
128 |
129 | topic = argv[1];
130 |
131 | if (strchr(topic, '#') || strchr(topic, '+'))
132 | opts.showtopics = 1;
133 | if (opts.showtopics)
134 | printf("topic is %s\n", topic);
135 |
136 | getopts(argc, argv);
137 | sprintf(url, "%s:%s", opts.host, opts.port);
138 |
139 | rc = MQTTClient_create(&client, url, opts.clientid, MQTTCLIENT_PERSISTENCE_NONE, NULL);
140 |
141 | signal(SIGINT, cfinish);
142 | signal(SIGTERM, cfinish);
143 |
144 | conn_opts.keepAliveInterval = 10000;
145 | conn_opts.reliable = 0;
146 | conn_opts.cleansession = 1;
147 | conn_opts.username = opts.username;
148 | conn_opts.password = opts.password;
149 |
150 | myconnect(&client, &conn_opts);
151 |
152 | int ret = MQTTClient_set_alias(client, "000000018302");
153 | (ret == 0)? printf("set alias OK\n") : printf("set alias fail\n");
154 |
155 | rc = MQTTClient_subscribe(client, topic);
156 |
157 | while (!toStop)
158 | {
159 | char* topicName = NULL;
160 | int topicLen;
161 | MQTTClient_message* message = NULL;
162 |
163 | rc = MQTTClient_receive(client, &topicName, &topicLen, &message, 100);
164 | if (message)
165 | {
166 |
167 | if (opts.showtopics)
168 | printf("%s\t", topicName);
169 | if (opts.nodelimiter)
170 | printf("%.*s", message->payloadlen, (char*)message->payload);
171 | else
172 | printf("%.*s%s", message->payloadlen, (char*)message->payload, opts.delimiter);
173 |
174 | fflush(stdout);
175 |
176 | MQTTClient_freeMessage(&message);
177 | MQTTClient_free(topicName);
178 | usleep(90000);
179 | }
180 | if (rc != 0)
181 | myconnect(&client, &conn_opts);
182 | }
183 |
184 | printf("Stopping\n");
185 |
186 | ret = MQTTClient_disconnect(client, 0);
187 | printf("%i\n", ret);
188 |
189 | MQTTClient_destroy(&client);
190 |
191 | return 0;
192 | }
193 |
194 | void getopts(int argc, char** argv)
195 | {
196 | int count = 2;
197 |
198 | while (count < argc)
199 | {
200 | if (strcmp(argv[count], "--qos") == 0)
201 | {
202 | if (++count < argc)
203 | {
204 | if (strcmp(argv[count], "0") == 0)
205 | opts.qos = 0;
206 | else if (strcmp(argv[count], "1") == 0)
207 | opts.qos = 1;
208 | else if (strcmp(argv[count], "2") == 0)
209 | opts.qos = 2;
210 | else
211 | usage();
212 | }
213 | else
214 | usage();
215 | }
216 | else if (strcmp(argv[count], "--host") == 0)
217 | {
218 | if (++count < argc)
219 | opts.host = argv[count];
220 | else
221 | usage();
222 | }
223 | else if (strcmp(argv[count], "--port") == 0)
224 | {
225 | if (++count < argc)
226 | opts.port = argv[count];
227 | else
228 | usage();
229 | }
230 | else if (strcmp(argv[count], "--clientid") == 0)
231 | {
232 | if (++count < argc)
233 | opts.clientid = argv[count];
234 | else
235 | usage();
236 | }
237 | else if (strcmp(argv[count], "--username") == 0)
238 | {
239 | if (++count < argc)
240 | opts.username = argv[count];
241 | else
242 | usage();
243 | }
244 | else if (strcmp(argv[count], "--password") == 0)
245 | {
246 | if (++count < argc)
247 | opts.password = argv[count];
248 | else
249 | usage();
250 | }
251 | else if (strcmp(argv[count], "--delimiter") == 0)
252 | {
253 | if (++count < argc)
254 | opts.delimiter = argv[count];
255 | else
256 | opts.nodelimiter = 1;
257 | }
258 | else if (strcmp(argv[count], "--showtopics") == 0)
259 | {
260 | if (++count < argc)
261 | {
262 | if (strcmp(argv[count], "on") == 0)
263 | opts.showtopics = 1;
264 | else if (strcmp(argv[count], "off") == 0)
265 | opts.showtopics = 0;
266 | else
267 | usage();
268 | }
269 | else
270 | usage();
271 | }
272 | count++;
273 | }
274 |
275 | }
276 |
--------------------------------------------------------------------------------
/src/utf-8.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | *******************************************************************************/
16 |
17 |
18 | /**
19 | * @file
20 | * \brief Functions for checking that strings contain UTF-8 characters only
21 | *
22 | * See page 104 of the Unicode Standard 5.0 for the list of well formed
23 | * UTF-8 byte sequences.
24 | *
25 | */
26 |
27 | #include
28 | #include
29 |
30 | #include "StackTrace.h"
31 |
32 | /**
33 | * Macro to determine the number of elements in a single-dimension array
34 | */
35 | #if !defined(ARRAY_SIZE)
36 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
37 | #endif
38 |
39 |
40 | /**
41 | * Structure to hold the valid ranges of UTF-8 characters, for each byte up to 4
42 | */
43 | struct
44 | {
45 | int len; /**< number of elements in the following array (1 to 4) */
46 | struct
47 | {
48 | char lower; /**< lower limit of valid range */
49 | char upper; /**< upper limit of valid range */
50 | } bytes[4]; /**< up to 4 bytes can be used per character */
51 | }
52 | valid_ranges[] =
53 | {
54 | {1, { {00, 0x7F} } },
55 | {2, { {0xC2, 0xDF}, {0x80, 0xBF} } },
56 | {3, { {0xE0, 0xE0}, {0xA0, 0xBF}, {0x80, 0xBF} } },
57 | {3, { {0xE1, 0xEC}, {0x80, 0xBF}, {0x80, 0xBF} } },
58 | {3, { {0xED, 0xED}, {0x80, 0x9F}, {0x80, 0xBF} } },
59 | {3, { {0xEE, 0xEF}, {0x80, 0xBF}, {0x80, 0xBF} } },
60 | {4, { {0xF0, 0xF0}, {0x90, 0xBF}, {0x80, 0xBF}, {0x80, 0xBF} } },
61 | {4, { {0xF1, 0xF3}, {0x80, 0xBF}, {0x80, 0xBF}, {0x80, 0xBF} } },
62 | {4, { {0xF4, 0xF4}, {0x80, 0x8F}, {0x80, 0xBF}, {0x80, 0xBF} } },
63 | };
64 |
65 |
66 | /**
67 | * Validate a single UTF-8 character
68 | * @param len the length of the string in "data"
69 | * @param data the bytes to check for a valid UTF-8 char
70 | * @return pointer to the start of the next UTF-8 character in "data"
71 | */
72 | const char* UTF8_char_validate(int len, const char* data)
73 | {
74 | int good = 0;
75 | int charlen = 2;
76 | int i, j;
77 | const char *rc = NULL;
78 |
79 | FUNC_ENTRY;
80 | /* first work out how many bytes this char is encoded in */
81 | if ((data[0] & 128) == 0)
82 | charlen = 1;
83 | else if ((data[0] & 0xF0) == 0xF0)
84 | charlen = 4;
85 | else if ((data[0] & 0xE0) == 0xE0)
86 | charlen = 3;
87 |
88 | if (charlen > len)
89 | goto exit; /* not enough characters in the string we were given */
90 |
91 | for (i = 0; i < ARRAY_SIZE(valid_ranges); ++i)
92 | { /* just has to match one of these rows */
93 | if (valid_ranges[i].len == charlen)
94 | {
95 | good = 1;
96 | for (j = 0; j < charlen; ++j)
97 | {
98 | if (data[j] < valid_ranges[i].bytes[j].lower ||
99 | data[j] > valid_ranges[i].bytes[j].upper)
100 | {
101 | good = 0; /* failed the check */
102 | break;
103 | }
104 | }
105 | if (good)
106 | break;
107 | }
108 | }
109 |
110 | if (good)
111 | rc = data + charlen;
112 | exit:
113 | FUNC_EXIT;
114 | return rc;
115 | }
116 |
117 |
118 | /**
119 | * Validate a length-delimited string has only UTF-8 characters
120 | * @param len the length of the string in "data"
121 | * @param data the bytes to check for valid UTF-8 characters
122 | * @return 1 (true) if the string has only UTF-8 characters, 0 (false) otherwise
123 | */
124 | int UTF8_validate(int len, const char* data)
125 | {
126 | const char* curdata = NULL;
127 | int rc = 0;
128 |
129 | FUNC_ENTRY;
130 | if (len == 0)
131 | {
132 | rc = 1;
133 | goto exit;
134 | }
135 | curdata = UTF8_char_validate(len, data);
136 | while (curdata && (curdata < data + len))
137 | curdata = UTF8_char_validate(len, curdata);
138 |
139 | rc = curdata != NULL;
140 | exit:
141 | FUNC_EXIT_RC(rc);
142 | return rc;
143 | }
144 |
145 |
146 | /**
147 | * Validate a null-terminated string has only UTF-8 characters
148 | * @param string the string to check for valid UTF-8 characters
149 | * @return 1 (true) if the string has only UTF-8 characters, 0 (false) otherwise
150 | */
151 | int UTF8_validateString(const char* string)
152 | {
153 | int rc = 0;
154 |
155 | FUNC_ENTRY;
156 | rc = UTF8_validate(strlen(string), string);
157 | FUNC_EXIT_RC(rc);
158 | return rc;
159 | }
160 |
161 |
162 |
163 | #if defined(UNIT_TESTS)
164 | #include
165 |
166 | typedef struct
167 | {
168 | int len;
169 | char data[20];
170 | } tests;
171 |
172 | tests valid_strings[] =
173 | {
174 | {3, "hjk" },
175 | {7, {0x41, 0xE2, 0x89, 0xA2, 0xCE, 0x91, 0x2E} },
176 | {3, {'f', 0xC9, 0xB1 } },
177 | {9, {0xED, 0x95, 0x9C, 0xEA, 0xB5, 0xAD, 0xEC, 0x96, 0xB4} },
178 | {9, {0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E} },
179 | {4, {0x2F, 0x2E, 0x2E, 0x2F} },
180 | {7, {0xEF, 0xBB, 0xBF, 0xF0, 0xA3, 0x8E, 0xB4} },
181 | };
182 |
183 | tests invalid_strings[] =
184 | {
185 | {2, {0xC0, 0x80} },
186 | {5, {0x2F, 0xC0, 0xAE, 0x2E, 0x2F} },
187 | {6, {0xED, 0xA1, 0x8C, 0xED, 0xBE, 0xB4} },
188 | {1, {0xF4} },
189 | };
190 |
191 | int main (int argc, char *argv[])
192 | {
193 | int i, failed = 0;
194 |
195 | for (i = 0; i < ARRAY_SIZE(valid_strings); ++i)
196 | {
197 | if (!UTF8_validate(valid_strings[i].len, valid_strings[i].data))
198 | {
199 | printf("valid test %d failed\n", i);
200 | failed = 1;
201 | }
202 | else
203 | printf("valid test %d passed\n", i);
204 | }
205 |
206 | for (i = 0; i < ARRAY_SIZE(invalid_strings); ++i)
207 | {
208 | if (UTF8_validate(invalid_strings[i].len, invalid_strings[i].data))
209 | {
210 | printf("invalid test %d failed\n", i);
211 | failed = 1;
212 | }
213 | else
214 | printf("invalid test %d passed\n", i);
215 | }
216 |
217 | if (failed)
218 | printf("Failed\n");
219 | else
220 | printf("Passed\n");
221 |
222 | return 0;
223 | } /* End of main function*/
224 |
225 | #endif
226 |
227 |
--------------------------------------------------------------------------------
/src/utf-8.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2009, 2013 IBM Corp.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Eclipse Distribution License v1.0 which accompany this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | * and the Eclipse Distribution License is available at
11 | * http://www.eclipse.org/org/documents/edl-v10.php.
12 | *
13 | * Contributors:
14 | * Ian Craggs - initial API and implementation and/or initial documentation
15 | *******************************************************************************/
16 |
17 | #if !defined(UTF8_H)
18 | #define UTF8_H
19 |
20 | int UTF8_validate(int len, char* data);
21 | int UTF8_validateString(const char* string);
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/src/yunba_common.h:
--------------------------------------------------------------------------------
1 | /*
2 | * yunba_common.h
3 | *
4 | * Created on: Nov 16, 2015
5 | * Author: yunba
6 | */
7 |
8 | #ifndef YUNBA_COMMON_H_
9 | #define YUNBA_COMMON_H_
10 |
11 | #if defined(WIN32) || defined(WIN64)
12 | #define DLLImport __declspec(dllimport)
13 | #define DLLExport __declspec(dllexport)
14 | #define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
15 | #else
16 | #define DLLImport extern
17 | #define DLLExport __attribute__ ((visibility ("default")))
18 | #endif
19 |
20 | #if defined(WIN32) || defined(WIN64)
21 | typedef int ssize_t;
22 | #endif
23 |
24 |
25 | /**
26 | * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1
27 | */
28 | #define MQTTVERSION_DEFAULT 0
29 | /**
30 | * MQTT version to connect with: 3.1
31 | */
32 | #define MQTTVERSION_3_1 3
33 | /**
34 | * MQTT version to connect with: 3.1.1
35 | */
36 | #define MQTTVERSION_3_1_1 4
37 | /**
38 | * Yunba MQTT version to connect with: 3.1.0
39 | */
40 | #define MQTTVERSION_YUNBA_3_1 0x13
41 | typedef enum {
42 | GET_ALIAS =1,
43 | GET_ALIAS_ACK,
44 | GET_TOPIC,
45 | GET_TOPIC_ACK,
46 | GET_ALIAS_LIST,
47 | GET_ALIAS_LIST_ACK,
48 | PUBLISH2,
49 | PUBLISH2_ACK,
50 | GET_STATUS = 9,
51 | GET_STATUS_ACK,
52 | GET_TOPIC_LIST2 = 13,
53 | GET_TOPIC_LIST2_ACK,
54 | GET_ALIASLIST2,
55 | GET_ALIASLIST2_ACK,
56 | GET_STATUS2 = 19,
57 | GET_STATUS2_ACK = 20
58 | } EXTED_CMD;
59 |
60 | enum {
61 | PUBLISH2_TLV_TOPIC,
62 | PUBLISH2_TLV_PAYLOAD,
63 | PUBLISH2_TLV_PLAT,
64 | PUBLISH2_TLV_TTL,
65 | PUBLISH2_TLV_TIME_DELAY,
66 | PUBLISH2_TLV_LOCATION,
67 | PUBLISH2_TLV_QOS,
68 | PUBLISH2_TLV_APN_JSON,
69 | PUBLISH2_TLV_MAX_NUM
70 | };
71 |
72 | typedef int (*PCALLBACK)(char *p);
73 | int http_post_json(char *json_data, char *hostname, uint16_t port, char *path, PCALLBACK cb);
74 |
75 | DLLExport void set_reg_url(const char url[20], int port);
76 | DLLExport void set_reg_url_v2(const char url[20], int port);
77 |
78 | typedef struct {
79 | /* in MQTT v3.1,If the Client ID contains more than 23 characters, the server responds to
80 | * the CONNECT message with a CONNACK return code 2: Identifier Rejected.
81 | * */
82 | char client_id[200];
83 | /* in MQTT v3.1, it is recommended that passwords are kept to 12 characters or fewer, but
84 | * it is not required. */
85 | char username[200];
86 | /*in MQTT v3.1, It is recommended that passwords are kept to 12 characters or fewer, but
87 | * it is not required. */
88 | char password[200];
89 | /* user define it, and change size of device id. */
90 | char device_id[200];
91 | } REG_info;
92 |
93 | DLLExport int MQTTClient_setup_with_appkey(char* appkey, REG_info *info);
94 |
95 | DLLExport int MQTTClient_setup_with_appkey_v2(char* appkey, REG_info *info);
96 |
97 | DLLExport int MQTTClient_setup_with_appkey_and_deviceid(char* appkey, char *deviceid, REG_info *info);
98 |
99 | DLLExport int MQTTClient_setup_with_appkey_and_deviceid_v2(char* appkey, char *deviceid, REG_info *info);
100 |
101 | DLLExport int MQTTClient_get_host(char *appkey, char* url);
102 | DLLExport int MQTTClient_get_host_v2(char *appkey, char* url);
103 |
104 |
105 | #endif /* YUNBA_COMMON_H_ */
106 |
107 |
--------------------------------------------------------------------------------
/window10pro_building.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yunba/yunba-c-sdk/84679219d8eeda39e439711d4cb2b68970fa4f2f/window10pro_building.tar.gz
--------------------------------------------------------------------------------