Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
paho.mqtt.c
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
eclipse
paho.mqtt.c
Commits
7ea13339
Commit
7ea13339
authored
Jun 07, 2018
by
Ian Craggs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MQTTClient v5 specific tests. Receive disconnect #469. Client topic aliases #472
parent
fcef9b5d
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
967 additions
and
17 deletions
+967
-17
Makefile
Makefile
+1
-1
CMakeLists.txt
src/CMakeLists.txt
+1
-0
MQTTClient.c
src/MQTTClient.c
+132
-2
MQTTClient.h
src/MQTTClient.h
+63
-0
MQTTPacket.c
src/MQTTPacket.c
+7
-5
MQTTProperties.c
src/MQTTProperties.c
+1
-1
MQTTProtocolClient.c
src/MQTTProtocolClient.c
+1
-0
MQTTReasonCodes.c
src/MQTTReasonCodes.c
+100
-0
MQTTReasonCodes.h
src/MQTTReasonCodes.h
+12
-2
CMakeLists.txt
test/CMakeLists.txt
+20
-0
test10.c
test/test10.c
+611
-0
test15.c
test/test15.c
+18
-6
No files found.
Makefile
View file @
7ea13339
...
@@ -90,7 +90,7 @@ SYNC_SAMPLES = ${addprefix ${blddir}/samples/,${SAMPLE_FILES_C}}
...
@@ -90,7 +90,7 @@ SYNC_SAMPLES = ${addprefix ${blddir}/samples/,${SAMPLE_FILES_C}}
SAMPLE_FILES_A
=
paho_c_pub paho_c_sub MQTTAsync_subscribe MQTTAsync_publish
SAMPLE_FILES_A
=
paho_c_pub paho_c_sub MQTTAsync_subscribe MQTTAsync_publish
ASYNC_SAMPLES
=
${
addprefix
${
blddir
}
/samples/,
${
SAMPLE_FILES_A
}}
ASYNC_SAMPLES
=
${
addprefix
${
blddir
}
/samples/,
${
SAMPLE_FILES_A
}}
TEST_FILES_C
=
test1 test15 test2 sync_client_test test_mqtt4sync
TEST_FILES_C
=
test1 test15 test2 sync_client_test test_mqtt4sync
test10
SYNC_TESTS
=
${
addprefix
${
blddir
}
/test/,
${
TEST_FILES_C
}}
SYNC_TESTS
=
${
addprefix
${
blddir
}
/test/,
${
TEST_FILES_C
}}
TEST_FILES_CS
=
test3
TEST_FILES_CS
=
test3
...
...
src/CMakeLists.txt
View file @
7ea13339
...
@@ -48,6 +48,7 @@ SET(common_src
...
@@ -48,6 +48,7 @@ SET(common_src
Heap.c
Heap.c
LinkedList.c
LinkedList.c
MQTTProperties.c
MQTTProperties.c
MQTTReasonCodes.c
Base64.c
Base64.c
SHA1.c
SHA1.c
WebSocket.c
WebSocket.c
...
...
src/MQTTClient.c
View file @
7ea13339
...
@@ -205,6 +205,12 @@ typedef struct
...
@@ -205,6 +205,12 @@ typedef struct
MQTTClient_deliveryComplete
*
dc
;
MQTTClient_deliveryComplete
*
dc
;
void
*
context
;
void
*
context
;
MQTTClient_disconnected
*
disconnected
;
void
*
disconnected_context
;
/* the context to be associated with the disconnected callback*/
MQTTClient_authHandle
*
auth_handle
;
void
*
auth_handle_context
;
/* the context to be associated with the authHandle callback*/
sem_type
connect_sem
;
sem_type
connect_sem
;
int
rc
;
/* getsockopt return code in connect */
int
rc
;
/* getsockopt return code in connect */
sem_type
connack_sem
;
sem_type
connack_sem
;
...
@@ -214,6 +220,13 @@ typedef struct
...
@@ -214,6 +220,13 @@ typedef struct
}
MQTTClients
;
}
MQTTClients
;
struct
props_rc_parms
{
MQTTClients
*
m
;
MQTTProperties
*
properties
;
enum
MQTTReasonCodes
reasonCode
;
};
void
MQTTClient_sleep
(
long
milliseconds
)
void
MQTTClient_sleep
(
long
milliseconds
)
{
{
FUNC_ENTRY
;
FUNC_ENTRY
;
...
@@ -546,6 +559,18 @@ void MQTTClient_free(void* memory)
...
@@ -546,6 +559,18 @@ void MQTTClient_free(void* memory)
}
}
DLLExport
void
MQTTResponse_free
(
MQTTResponse
response
)
{
FUNC_ENTRY
;
if
(
response
.
properties
)
{
MQTTProperties_free
(
response
.
properties
);
free
(
response
.
properties
);
}
FUNC_EXIT
;
}
static
int
MQTTClient_deliverMessage
(
int
rc
,
MQTTClients
*
m
,
char
**
topicName
,
int
*
topicLen
,
MQTTClient_message
**
message
)
static
int
MQTTClient_deliverMessage
(
int
rc
,
MQTTClients
*
m
,
char
**
topicName
,
int
*
topicLen
,
MQTTClient_message
**
message
)
{
{
qEntry
*
qe
=
(
qEntry
*
)(
m
->
c
->
messageQueue
->
first
->
content
);
qEntry
*
qe
=
(
qEntry
*
)(
m
->
c
->
messageQueue
->
first
->
content
);
...
@@ -594,6 +619,81 @@ static thread_return_type WINAPI connectionLost_call(void* context)
...
@@ -594,6 +619,81 @@ static thread_return_type WINAPI connectionLost_call(void* context)
}
}
int
MQTTClient_setDisconnected
(
MQTTClient
handle
,
void
*
context
,
MQTTClient_disconnected
*
disconnected
)
{
int
rc
=
MQTTCLIENT_SUCCESS
;
MQTTClients
*
m
=
handle
;
FUNC_ENTRY
;
Thread_lock_mutex
(
mqttclient_mutex
);
if
(
m
==
NULL
||
m
->
c
->
connect_state
!=
NOT_IN_PROGRESS
)
rc
=
MQTTCLIENT_FAILURE
;
else
{
m
->
disconnected_context
=
context
;
m
->
disconnected
=
disconnected
;
}
Thread_unlock_mutex
(
mqttclient_mutex
);
FUNC_EXIT_RC
(
rc
);
return
rc
;
}
/**
* Wrapper function to call disconnected on a separate thread. A separate thread is needed to allow the
* disconnected function to make API calls (e.g. connect)
* @param context a pointer to the relevant client
* @return thread_return_type standard thread return value - not used here
*/
static
thread_return_type
WINAPI
call_disconnected
(
void
*
context
)
{
struct
props_rc_parms
*
pr
=
(
struct
props_rc_parms
*
)
context
;
(
*
(
pr
->
m
->
disconnected
))(
pr
->
m
->
disconnected_context
,
pr
->
properties
,
pr
->
reasonCode
);
MQTTProperties_free
(
pr
->
properties
);
return
0
;
}
int
MQTTClient_setAuthHandle
(
MQTTClient
handle
,
void
*
context
,
MQTTClient_authHandle
*
auth_handle
)
{
int
rc
=
MQTTCLIENT_SUCCESS
;
MQTTClients
*
m
=
handle
;
FUNC_ENTRY
;
Thread_lock_mutex
(
mqttclient_mutex
);
if
(
m
==
NULL
||
m
->
c
->
connect_state
!=
NOT_IN_PROGRESS
)
rc
=
MQTTCLIENT_FAILURE
;
else
{
m
->
auth_handle_context
=
context
;
m
->
auth_handle
=
auth_handle
;
}
Thread_unlock_mutex
(
mqttclient_mutex
);
FUNC_EXIT_RC
(
rc
);
return
rc
;
}
/**
* Wrapper function to call authHandle on a separate thread. A separate thread is needed to allow the
* disconnected function to make API calls (e.g. MQTTClient_auth)
* @param context a pointer to the relevant client
* @return thread_return_type standard thread return value - not used here
*/
static
thread_return_type
WINAPI
call_auth_handle
(
void
*
context
)
{
struct
props_rc_parms
*
pr
=
(
struct
props_rc_parms
*
)
context
;
(
*
(
pr
->
m
->
auth_handle
))(
pr
->
m
->
auth_handle_context
,
pr
->
properties
,
pr
->
reasonCode
);
return
0
;
}
/* This is the thread function that handles the calling of callback functions if set */
/* This is the thread function that handles the calling of callback functions if set */
static
thread_return_type
WINAPI
MQTTClient_run
(
void
*
n
)
static
thread_return_type
WINAPI
MQTTClient_run
(
void
*
n
)
{
{
...
@@ -699,6 +799,33 @@ static thread_return_type WINAPI MQTTClient_run(void* n)
...
@@ -699,6 +799,33 @@ static thread_return_type WINAPI MQTTClient_run(void* n)
m
->
pack
=
pack
;
m
->
pack
=
pack
;
Thread_post_sem
(
m
->
unsuback_sem
);
Thread_post_sem
(
m
->
unsuback_sem
);
}
}
else
if
(
m
->
c
->
MQTTVersion
>=
MQTTVERSION_5
)
{
if
(
pack
->
header
.
bits
.
type
==
DISCONNECT
&&
m
->
disconnected
)
{
struct
props_rc_parms
dp
;
Ack
*
disc
=
(
Ack
*
)
pack
;
dp
.
m
=
m
;
dp
.
properties
=
&
disc
->
properties
;
dp
.
reasonCode
=
disc
->
rc
;
free
(
pack
);
Log
(
TRACE_MIN
,
-
1
,
"Calling disconnected for client %s"
,
m
->
c
->
clientID
);
Thread_start
(
call_disconnected
,
&
dp
);
}
if
(
pack
->
header
.
bits
.
type
==
AUTH
&&
m
->
auth_handle
)
{
struct
props_rc_parms
dp
;
Ack
*
disc
=
(
Ack
*
)
pack
;
dp
.
m
=
m
;
dp
.
properties
=
&
disc
->
properties
;
dp
.
reasonCode
=
disc
->
rc
;
free
(
pack
);
Log
(
TRACE_MIN
,
-
1
,
"Calling auth_handle for client %s"
,
m
->
c
->
clientID
);
Thread_start
(
call_auth_handle
,
&
dp
);
}
}
}
}
else
if
(
m
->
c
->
connect_state
==
TCP_IN_PROGRESS
&&
!
Thread_check_sem
(
m
->
connect_sem
))
else
if
(
m
->
c
->
connect_state
==
TCP_IN_PROGRESS
&&
!
Thread_check_sem
(
m
->
connect_sem
))
{
{
...
@@ -1112,7 +1239,10 @@ static MQTTResponse MQTTClient_connectURIVersion(MQTTClient handle, MQTTClient_c
...
@@ -1112,7 +1239,10 @@ static MQTTResponse MQTTClient_connectURIVersion(MQTTClient handle, MQTTClient_c
rc
=
MQTTCLIENT_DISCONNECTED
;
rc
=
MQTTCLIENT_DISCONNECTED
;
}
}
if
(
m
->
c
->
MQTTVersion
==
MQTTVERSION_5
)
if
(
m
->
c
->
MQTTVersion
==
MQTTVERSION_5
)
resp
.
properties
=
&
connack
->
properties
;
{
resp
.
properties
=
malloc
(
sizeof
(
MQTTProperties
));
*
resp
.
properties
=
MQTTProperties_copy
(
&
connack
->
properties
);
}
}
}
MQTTPacket_freeConnack
(
connack
);
MQTTPacket_freeConnack
(
connack
);
m
->
pack
=
NULL
;
m
->
pack
=
NULL
;
...
@@ -1930,7 +2060,7 @@ MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName
...
@@ -1930,7 +2060,7 @@ MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName
goto
exit
;
goto
exit
;
}
}
if
(
message
->
struct_version
=
=
1
)
if
(
message
->
struct_version
>
=
1
)
props
=
&
message
->
properties
;
props
=
&
message
->
properties
;
rc
=
MQTTClient_publish5
(
handle
,
topicName
,
message
->
payloadlen
,
message
->
payload
,
rc
=
MQTTClient_publish5
(
handle
,
topicName
,
message
->
payloadlen
,
message
->
payload
,
...
...
src/MQTTClient.h
View file @
7ea13339
...
@@ -414,6 +414,67 @@ DLLExport int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClie
...
@@ -414,6 +414,67 @@ DLLExport int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClie
MQTTClient_messageArrived
*
ma
,
MQTTClient_deliveryComplete
*
dc
);
MQTTClient_messageArrived
*
ma
,
MQTTClient_deliveryComplete
*
dc
);
/**
* This is a callback function, which will be called when the client
* library successfully connects. This is superfluous when the connection
* is made in response to a MQTTAsync_connect call, because the onSuccess
* callback can be used. It is intended for use when automatic reconnect
* is enabled, so that when a reconnection attempt succeeds in the background,
* the application is notified and can take any required actions.
* @param context A pointer to the <i>context</i> value originally passed to
* MQTTAsync_setCallbacks(), which contains any application-specific context.
* @param cause The reason for the disconnection.
* Currently, <i>cause</i> is always set to NULL.
*/
typedef
void
MQTTClient_disconnected
(
void
*
context
,
MQTTProperties
*
properties
,
enum
MQTTReasonCodes
reasonCode
);
/**
* Sets the MQTTClient_disconnected() callback function for a client.
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param context A pointer to any application-specific context. The
* the <i>context</i> pointer is passed to each of the callback functions to
* provide access to the context information in the callback.
* @param co A pointer to an MQTTAsync_connected() callback
* function. NULL removes the callback setting.
* @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
* ::MQTTASYNC_FAILURE if an error occurred.
*/
DLLExport
int
MQTTClient_setDisconnected
(
MQTTClient
handle
,
void
*
context
,
MQTTClient_disconnected
*
co
);
/**
* This is a callback function, which will be called when the client
* library successfully connects. This is superfluous when the connection
* is made in response to a MQTTAsync_connect call, because the onSuccess
* callback can be used. It is intended for use when automatic reconnect
* is enabled, so that when a reconnection attempt succeeds in the background,
* the application is notified and can take any required actions.
* @param context A pointer to the <i>context</i> value originally passed to
* MQTTAsync_setCallbacks(), which contains any application-specific context.
* @param cause The reason for the disconnection.
* Currently, <i>cause</i> is always set to NULL.
*/
typedef
void
MQTTClient_authHandle
(
void
*
context
,
MQTTProperties
*
properties
,
enum
MQTTReasonCodes
reasonCode
);
/**
* Sets the MQTTClient_authHandle() callback function for a client.
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param context A pointer to any application-specific context. The
* the <i>context</i> pointer is passed to each of the callback functions to
* provide access to the context information in the callback.
* @param co A pointer to an MQTTAsync_connected() callback
* function. NULL removes the callback setting.
* @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
* ::MQTTASYNC_FAILURE if an error occurred.
*/
DLLExport
int
MQTTClient_setAuthHandle
(
MQTTClient
handle
,
void
*
context
,
MQTTClient_authHandle
*
ah
);
/**
/**
* This function creates an MQTT client ready for connection to the
* This function creates an MQTT client ready for connection to the
* specified server and using the specified persistent storage (see
* specified server and using the specified persistent storage (see
...
@@ -785,6 +846,8 @@ typedef struct MQTTResponse
...
@@ -785,6 +846,8 @@ typedef struct MQTTResponse
MQTTProperties
*
properties
;
/* optional */
MQTTProperties
*
properties
;
/* optional */
}
MQTTResponse
;
}
MQTTResponse
;
DLLExport
void
MQTTResponse_free
(
MQTTResponse
response
);
DLLExport
MQTTResponse
MQTTClient_connect5
(
MQTTClient
handle
,
MQTTClient_connectOptions
*
options
,
DLLExport
MQTTResponse
MQTTClient_connect5
(
MQTTClient
handle
,
MQTTClient_connectOptions
*
options
,
MQTTProperties
*
connectProperties
,
MQTTProperties
*
willProperties
);
MQTTProperties
*
connectProperties
,
MQTTProperties
*
willProperties
);
...
...
src/MQTTPacket.c
View file @
7ea13339
...
@@ -85,7 +85,8 @@ pf new_packets[] =
...
@@ -85,7 +85,8 @@ pf new_packets[] =
MQTTPacket_unsuback
,
/**< UNSUBACK */
MQTTPacket_unsuback
,
/**< UNSUBACK */
MQTTPacket_header_only
,
/**< PINGREQ */
MQTTPacket_header_only
,
/**< PINGREQ */
MQTTPacket_header_only
,
/**< PINGRESP */
MQTTPacket_header_only
,
/**< PINGRESP */
MQTTPacket_header_only
/**< DISCONNECT */
MQTTPacket_ack
,
/**< DISCONNECT */
MQTTPacket_ack
/**< AUTH */
};
};
...
@@ -132,7 +133,9 @@ void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error)
...
@@ -132,7 +133,9 @@ void* MQTTPacket_Factory(int MQTTVersion, networkHandles* net, int* error)
else
else
{
{
ptype
=
header
.
bits
.
type
;
ptype
=
header
.
bits
.
type
;
if
(
ptype
<
CONNECT
||
ptype
>
DISCONNECT
||
new_packets
[
ptype
]
==
NULL
)
if
(
ptype
<
CONNECT
||
(
MQTTVersion
<
MQTTVERSION_5
&&
ptype
>=
DISCONNECT
)
||
(
MQTTVersion
>=
MQTTVERSION_5
&&
ptype
>
AUTH
)
||
new_packets
[
ptype
]
==
NULL
)
Log
(
TRACE_MIN
,
2
,
NULL
,
ptype
);
Log
(
TRACE_MIN
,
2
,
NULL
,
ptype
);
else
else
{
{
...
@@ -723,7 +726,8 @@ void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t
...
@@ -723,7 +726,8 @@ void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t
FUNC_ENTRY
;
FUNC_ENTRY
;
pack
->
MQTTVersion
=
MQTTVersion
;
pack
->
MQTTVersion
=
MQTTVersion
;
pack
->
header
.
byte
=
aHeader
;
pack
->
header
.
byte
=
aHeader
;
pack
->
msgId
=
readInt
(
&
curdata
);
if
(
pack
->
header
.
bits
.
type
!=
DISCONNECT
)
pack
->
msgId
=
readInt
(
&
curdata
);
if
(
MQTTVersion
>=
MQTTVERSION_5
)
if
(
MQTTVersion
>=
MQTTVERSION_5
)
{
{
MQTTProperties
props
=
MQTTProperties_initializer
;
MQTTProperties
props
=
MQTTProperties_initializer
;
...
@@ -736,8 +740,6 @@ void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t
...
@@ -736,8 +740,6 @@ void* MQTTPacket_ack(int MQTTVersion, unsigned char aHeader, char* data, size_t
if
(
datalen
>
3
)
if
(
datalen
>
3
)
{
{
pack
->
properties
.
max_count
=
10
;
pack
->
properties
.
array
=
malloc
(
sizeof
(
MQTTProperty
)
*
pack
->
properties
.
max_count
);
if
(
MQTTProperties_read
(
&
pack
->
properties
,
&
curdata
,
enddata
)
!=
1
)
if
(
MQTTProperties_read
(
&
pack
->
properties
,
&
curdata
,
enddata
)
!=
1
)
{
{
free
(
pack
);
free
(
pack
);
...
...
src/MQTTProperties.c
View file @
7ea13339
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
struct
nameToType
st
atic
st
ruct
nameToType
{
{
enum
PropertyNames
name
;
enum
PropertyNames
name
;
enum
PropertyTypes
type
;
enum
PropertyTypes
type
;
...
...
src/MQTTProtocolClient.c
View file @
7ea13339
...
@@ -163,6 +163,7 @@ int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int
...
@@ -163,6 +163,7 @@ int MQTTProtocol_startPublish(Clients* pubclient, Publish* publish, int qos, int
p
.
payload
=
(
*
mm
)
->
publish
->
payload
;
p
.
payload
=
(
*
mm
)
->
publish
->
payload
;
p
.
topic
=
(
*
mm
)
->
publish
->
topic
;
p
.
topic
=
(
*
mm
)
->
publish
->
topic
;
p
.
properties
=
(
*
mm
)
->
properties
;
p
.
properties
=
(
*
mm
)
->
properties
;
p
.
MQTTVersion
=
(
*
mm
)
->
MQTTVersion
;
}
}
rc
=
MQTTProtocol_startPublishCommon
(
pubclient
,
&
p
,
qos
,
retained
);
rc
=
MQTTProtocol_startPublishCommon
(
pubclient
,
&
p
,
qos
,
retained
);
FUNC_EXIT_RC
(
rc
);
FUNC_EXIT_RC
(
rc
);
...
...
src/MQTTReasonCodes.c
0 → 100644
View file @
7ea13339
/*******************************************************************************
* Copyright (c) 2017, 2018 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTReasonCodes.h"
#include "Heap.h"
#include "StackTrace.h"
#include <memory.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
static
struct
{
enum
MQTTReasonCodes
value
;
const
char
*
name
;
}
nameToString
[]
=
{
{
SUCCESS
,
"SUCCESS"
},
{
NORMAL_DISCONNECTION
,
"Normal disconnection"
},
{
GRANTED_QOS_0
,
"Granted QoS 0"
},
{
GRANTED_QOS_1
,
"Granted QoS 1"
},
{
GRANTED_QOS_2
,
"Granted QoS 2"
},
{
DISCONNECT_WITH_WILL_MESSAGE
,
"Disconnect with Will Messge"
},
{
NO_MATCHING_SUBSCRIBERS
,
"No matching subscribers"
},
{
NO_SUBSCRIPTION_FOUND
,
"No subscription found"
},
{
CONTINUE_AUTHENTICATION
,
"Continue authentication"
},
{
RE_AUTHENTICATE
,
"Re-authenticate"
},
{
UNSPECIFIED_ERROR
,
"Unspecified error"
},
{
MALFORMED_PACKET
,
"Malformed Packet"
},
{
PROTOCOL_ERROR
,
"Protocol error"
},
{
IMPLEMENTATION_SPECIFIC_ERROR
,
"Implementation specific error"
},
{
UNSUPPORTED_PROTOCOL_VERSION
,
"Unsupported Protocol Version"
},
{
CLIENT_IDENTIFIER_NOT_VALID
,
"Client Identifier not valid"
},
{
BAD_USER_NAME_OR_PASSWORD
,
"Bad User Name or Password"
},
{
NOT_AUTHORIZED
,
"Not authorized"
},
{
SERVER_UNAVAILABLE
,
"Server unavailable"
},
{
SERVER_BUSY
,
"Server busy"
},
{
BANNED
,
"Banned"
},
{
SERVER_SHUTTING_DOWN
,
"Server shutting down"
},
{
BAD_AUTHENTICATION_METHOD
,
"Bad authentication method"
},
{
KEEP_ALIVE_TIMEOUT
,
"Keep Alive timeout"
},
{
SESSION_TAKEN_OVER
,
"Session taken over"
},
{
TOPIC_FILTER_INVALID
,
"Topic filter invalid"
},
{
TOPIC_NAME_INVALID
,
"Topic name invalid"
},
{
PACKET_IDENTIFIER_IN_USE
,
"Packet Identifier in use"
},
{
PACKET_IDENTIFIER_NOT_FOUND
,
"Packet Identifier not found"
},
{
RECEIVE_MAXIMUM_EXCEEDED
,
"Receive Maximum exceeded"
},
{
TOPIC_ALIAS_INVALID
,
"Topic Alias invalid"
},
{
PACKET_TOO_LARGE
,
"Packet too large"
},
{
MESSAGE_RATE_TOO_HIGH
,
"Message rate too high"
},
{
QUOTA_EXCEEDED
,
"Quota exceeded"
},
{
ADMINISTRATIVE_ACTION
,
"Administrative action"
},
{
PAYLOAD_FORMAT_INVALID
,
"Payload format invalid"
},
{
RETAIN_NOT_SUPPORTED
,
"Retain not supported"
},
{
QOS_NOT_SUPPORTED
,
"QoS not supported"
},
{
USE_ANOTHER_SERVER
,
"Use another server"
},
{
SERVER_MOVED
,
"Server moved"
},
{
SHARED_SUBSCRIPTIONS_NOT_SUPPORTED
,
"Shared subscriptions not supported"
},
{
CONNECTION_RATE_EXCEEDED
,
"Connection rate exceeded"
},
{
MAXIMUM_CONNECT_TIME
,
"Maximum connect time"
},
{
SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED
,
"Subscription Identifiers not supported"
},
{
WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED
,
"Wildcard Subscriptions not supported"
}
};
const
char
*
MQTTReasonCodeString
(
enum
MQTTReasonCodes
value
)
{
int
i
=
0
;
const
char
*
result
=
NULL
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
nameToString
);
++
i
)
{
if
(
nameToString
[
i
].
value
==
value
)
{
result
=
nameToString
[
i
].
name
;
break
;
}
}
return
result
;
}
src/MQTTReasonCodes.h
View file @
7ea13339
...
@@ -58,11 +58,21 @@ enum MQTTReasonCodes {
...
@@ -58,11 +58,21 @@ enum MQTTReasonCodes {
QOS_NOT_SUPPORTED
=
155
,
QOS_NOT_SUPPORTED
=
155
,
USE_ANOTHER_SERVER
=
156
,
USE_ANOTHER_SERVER
=
156
,
SERVER_MOVED
=
157
,
SERVER_MOVED
=
157
,
SHARED_SUBSCRIPTION_NOT_SUPPORTED
=
158
,
SHARED_SUBSCRIPTION
S
_NOT_SUPPORTED
=
158
,
CONNECTION_RATE_EXCEEDED
=
159
,
CONNECTION_RATE_EXCEEDED
=
159
,
MAXIMUM_CONNECT_TIME
=
160
,
MAXIMUM_CONNECT_TIME
=
160
,
SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED
=
161
,
SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED
=
161
,
WILDCARD_SUBSCRIPTION_NOT_SUPPORTED
=
162
WILDCARD_SUBSCRIPTION
S
_NOT_SUPPORTED
=
162
};
};
#if defined(WIN32) || defined(WIN64)
#define DLLImport __declspec(dllimport)
#define DLLExport __declspec(dllexport)
#else
#define DLLImport extern
#define DLLExport __attribute__ ((visibility ("default")))
#endif
DLLExport
const
char
*
MQTTReasonCodeString
(
enum
MQTTReasonCodes
);
#endif
#endif
test/CMakeLists.txt
View file @
7ea13339
...
@@ -564,6 +564,26 @@ SET_TESTS_PROPERTIES(
...
@@ -564,6 +564,26 @@ SET_TESTS_PROPERTIES(
PROPERTIES TIMEOUT 540
PROPERTIES TIMEOUT 540
)
)
ADD_EXECUTABLE
(
test10
test10.c
)
TARGET_LINK_LIBRARIES
(
test10
paho-mqtt3c
)
ADD_TEST
(
NAME test10-1-client_topic_aliases
COMMAND
"test10"
"--test_no"
"1"
"--connection"
${
MQTT_TEST_BROKER
}
"--proxy_connection"
${
MQTT_TEST_PROXY
}
)
SET_TESTS_PROPERTIES
(
test10-1-client_topic_aliases
PROPERTIES TIMEOUT 540
)
ADD_EXECUTABLE
(
ADD_EXECUTABLE
(
test_issue373
test_issue373
test_issue373.c
test_issue373.c
...
...
test/test10.c
0 → 100644
View file @
7ea13339
/*******************************************************************************
* Copyright (c) 2009, 2018 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - MQTT 5.0 support
*******************************************************************************/
/**
* @file
* MQTT V5 specific tests for the MQTT C client
*
* - topic aliases
* - subscription ids
* - session expiry
* - payload format
* - flow control
* - QoS 2 exchange termination
* - request/response
* - shared subscriptions
* - server initiated disconnect
* - auth packets
* - server assigned clientid returned in a property
* - server defined keepalive
* - subscribe failure
*/
#include "MQTTClient.h"
#include <string.h>
#include <stdlib.h>
#if !defined(_WINDOWS)
#include <sys/time.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#else
#include <windows.h>
#define setenv(a, b, c) _putenv_s(a, b)
#endif
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
void
usage
(
void
)
{
printf
(
"help!!
\n
"
);
exit
(
EXIT_FAILURE
);
}
struct
Options
{
char
*
connection
;
/**< connection to system under test. */
char
**
haconnections
;
char
*
proxy_connection
;
int
hacount
;
int
verbose
;
int
test_no
;
int
MQTTVersion
;
int
iterations
;
}
options
=
{
"tcp://localhost:1883"
,
NULL
,
"tcp://localhost:1884"
,
0
,
0
,
0
,
MQTTVERSION_5
,
1
,
};
void
getopts
(
int
argc
,
char
**
argv
)
{
int
count
=
1
;
while
(
count
<
argc
)
{
if
(
strcmp
(
argv
[
count
],
"--test_no"
)
==
0
)
{
if
(
++
count
<
argc
)
options
.
test_no
=
atoi
(
argv
[
count
]);
else
usage
();
}
else
if
(
strcmp
(
argv
[
count
],
"--connection"
)
==
0
)
{
if
(
++
count
<
argc
)
{
options
.
connection
=
argv
[
count
];
printf
(
"
\n
Setting connection to %s
\n
"
,
options
.
connection
);
}
else
usage
();
}
else
if
(
strcmp
(
argv
[
count
],
"--haconnections"
)
==
0
)
{
if
(
++
count
<
argc
)
{
char
*
tok
=
strtok
(
argv
[
count
],
" "
);
options
.
hacount
=
0
;
options
.
haconnections
=
malloc
(
sizeof
(
char
*
)
*
5
);
while
(
tok
)
{
options
.
haconnections
[
options
.
hacount
]
=
malloc
(
strlen
(
tok
)
+
1
);
strcpy
(
options
.
haconnections
[
options
.
hacount
],
tok
);
options
.
hacount
++
;
tok
=
strtok
(
NULL
,
" "
);
}
}
else
usage
();
}
else
if
(
strcmp
(
argv
[
count
],
"--proxy_connection"
)
==
0
)
{
if
(
++
count
<
argc
)
options
.
proxy_connection
=
argv
[
count
];
else
usage
();
}
else
if
(
strcmp
(
argv
[
count
],
"--MQTTversion"
)
==
0
)
{
if
(
++
count
<
argc
)
{
options
.
MQTTVersion
=
atoi
(
argv
[
count
]);
printf
(
"setting MQTT version to %d
\n
"
,
options
.
MQTTVersion
);
}
else
usage
();
}
else
if
(
strcmp
(
argv
[
count
],
"--iterations"
)
==
0
)
{
if
(
++
count
<
argc
)
options
.
iterations
=
atoi
(
argv
[
count
]);
else
usage
();
}
else
if
(
strcmp
(
argv
[
count
],
"--verbose"
)
==
0
)
{
options
.
verbose
=
1
;
printf
(
"
\n
Setting verbose on
\n
"
);
}
count
++
;
}
}
#define LOGA_DEBUG 0
#define LOGA_INFO 1
#include <stdarg.h>
#include <time.h>
#include <sys/timeb.h>
void
MyLog
(
int
LOGA_level
,
char
*
format
,
...)
{
static
char
msg_buf
[
256
];
va_list
args
;
struct
timeb
ts
;
struct
tm
timeinfo
;
if
(
LOGA_level
==
LOGA_DEBUG
&&
options
.
verbose
==
0
)
return
;
strcpy
(
msg_buf
,
""
);
ftime
(
&
ts
);
localtime_r
(
&
ts
.
time
,
&
timeinfo
);
strftime
(
msg_buf
,
80
,
"%Y%m%d %H%M%S"
,
&
timeinfo
);
sprintf
(
&
msg_buf
[
strlen
(
msg_buf
)],
".%.3hu "
,
ts
.
millitm
);
va_start
(
args
,
format
);
vsnprintf
(
&
msg_buf
[
strlen
(
msg_buf
)],
sizeof
(
msg_buf
)
-
strlen
(
msg_buf
),
format
,
args
);
va_end
(
args
);
printf
(
"%s
\n
"
,
msg_buf
);
fflush
(
stdout
);
}
#if defined(WIN32) || defined(_WINDOWS)
#define mqsleep(A) Sleep(1000*A)
#define START_TIME_TYPE DWORD
static
DWORD
start_time
=
0
;
START_TIME_TYPE
start_clock
(
void
)
{
return
GetTickCount
();
}
#elif defined(AIX)
#define mqsleep sleep
#define START_TIME_TYPE struct timespec
START_TIME_TYPE
start_clock
(
void
)
{
static
struct
timespec
start
;
clock_gettime
(
CLOCK_REALTIME
,
&
start
);
return
start
;
}
#else
#define mqsleep sleep
#define START_TIME_TYPE struct timeval
/* TODO - unused - remove? static struct timeval start_time; */
START_TIME_TYPE
start_clock
(
void
)
{
struct
timeval
start_time
;
gettimeofday
(
&
start_time
,
NULL
);
return
start_time
;
}
#endif
#if defined(WIN32)
long
elapsed
(
START_TIME_TYPE
start_time
)
{
return
GetTickCount
()
-
start_time
;
}
#elif defined(AIX)
#define assert(a)
long
elapsed
(
struct
timespec
start
)
{
struct
timespec
now
,
res
;
clock_gettime
(
CLOCK_REALTIME
,
&
now
);
ntimersub
(
now
,
start
,
res
);
return
(
res
.
tv_sec
)
*
1000L
+
(
res
.
tv_nsec
)
/
1000000L
;
}
#else
long
elapsed
(
START_TIME_TYPE
start_time
)
{
struct
timeval
now
,
res
;
gettimeofday
(
&
now
,
NULL
);
timersub
(
&
now
,
&
start_time
,
&
res
);
return
(
res
.
tv_sec
)
*
1000
+
(
res
.
tv_usec
)
/
1000
;
}
#endif
#define assert(a, b, c, d) myassert(__FILE__, __LINE__, a, b, c, d)
#define assert1(a, b, c, d, e) myassert(__FILE__, __LINE__, a, b, c, d, e)
int
tests
=
0
;
int
failures
=
0
;
FILE
*
xml
;
START_TIME_TYPE
global_start_time
;
char
output
[
3000
];
char
*
cur_output
=
output
;
void
write_test_result
(
void
)
{
long
duration
=
elapsed
(
global_start_time
);
fprintf
(
xml
,
" time=
\"
%ld.%.3ld
\"
>
\n
"
,
duration
/
1000
,
duration
%
1000
);
if
(
cur_output
!=
output
)
{
fprintf
(
xml
,
"%s"
,
output
);
cur_output
=
output
;
}
fprintf
(
xml
,
"</testcase>
\n
"
);
}
void
myassert
(
char
*
filename
,
int
lineno
,
char
*
description
,
int
value
,
char
*
format
,
...)
{
++
tests
;
if
(
!
value
)
{
va_list
args
;
++
failures
;
MyLog
(
LOGA_INFO
,
"Assertion failed, file %s, line %d, description: %s
\n
"
,
filename
,
lineno
,
description
);
va_start
(
args
,
format
);
vprintf
(
format
,
args
);
va_end
(
args
);
cur_output
+=
sprintf
(
cur_output
,
"<failure type=
\"
%s
\"
>file %s, line %d </failure>
\n
"
,
description
,
filename
,
lineno
);
}
else
MyLog
(
LOGA_DEBUG
,
"Assertion succeeded, file %s, line %d, description: %s"
,
filename
,
lineno
,
description
);
}
void
logProperties
(
MQTTProperties
*
props
)
{
int
i
=
0
;
for
(
i
=
0
;
i
<
props
->
count
;
++
i
)
{
int
id
=
props
->
array
[
i
].
identifier
;
const
char
*
name
=
MQTTPropertyName
(
id
);
char
*
intformat
=
"Property name %s value %d"
;
switch
(
MQTTProperty_getType
(
id
))
{
case
PROPERTY_TYPE_BYTE
:
MyLog
(
LOGA_INFO
,
intformat
,
name
,
props
->
array
[
i
].
value
.
byte
);
break
;
case
TWO_BYTE_INTEGER
:
MyLog
(
LOGA_INFO
,
intformat
,
name
,
props
->
array
[
i
].
value
.
integer2
);
break
;
case
FOUR_BYTE_INTEGER
:
MyLog
(
LOGA_INFO
,
intformat
,
name
,
props
->
array
[
i
].
value
.
integer4
);
break
;
case
VARIABLE_BYTE_INTEGER
:
MyLog
(
LOGA_INFO
,
intformat
,
name
,
props
->
array
[
i
].
value
.
integer4
);
break
;
case
BINARY_DATA
:
case
UTF_8_ENCODED_STRING
:
MyLog
(
LOGA_INFO
,
"Property name value %s %.*s"
,
name
,
props
->
array
[
i
].
value
.
data
.
len
,
props
->
array
[
i
].
value
.
data
.
data
);
break
;
case
UTF_8_STRING_PAIR
:
MyLog
(
LOGA_INFO
,
"Property name %s key %.*s value %.*s"
,
name
,
props
->
array
[
i
].
value
.
data
.
len
,
props
->
array
[
i
].
value
.
data
.
data
,
props
->
array
[
i
].
value
.
value
.
len
,
props
->
array
[
i
].
value
.
value
.
data
);
break
;
}
}
}
struct
aa
{
int
disconnected
;
}
test_topic_aliases_globals
=
{
0
,
};
void
disconnected
(
void
*
context
,
MQTTProperties
*
props
,
enum
MQTTReasonCodes
rc
)
{
MQTTClient
c
=
(
MQTTClient
)
context
;
printf
(
"Callback: disconnected, reason code
\"
%s
\"\n
"
,
MQTTReasonCodeString
(
rc
));
logProperties
(
props
);
test_topic_aliases_globals
.
disconnected
=
1
;
}
static
int
messages_arrived
=
0
;
int
messageArrived
(
void
*
context
,
char
*
topicName
,
int
topicLen
,
MQTTClient_message
*
message
)
{
MyLog
(
LOGA_DEBUG
,
"Callback: message received on topic %s is %.*s."
,
topicName
,
message
->
payloadlen
,
(
char
*
)(
message
->
payload
));
assert
(
"Message structure version should be 1"
,
message
->
struct_version
==
1
,
"message->struct_version was %d"
,
message
->
struct_version
);
if
(
message
->
struct_version
==
1
)
{
const
int
props_count
=
0
;
assert
(
"Properties count should be 0"
,
message
->
properties
.
count
==
props_count
,
"Properties count was %d
\n
"
,
message
->
properties
.
count
);
logProperties
(
&
message
->
properties
);
}
messages_arrived
++
;
MQTTClient_free
(
topicName
);
MQTTClient_freeMessage
(
&
message
);
return
1
;
}
int
test_client_topic_aliases
(
struct
Options
options
)
{
int
subsqos
=
2
;
MQTTClient
c
;
MQTTClient_connectOptions
opts
=
MQTTClient_connectOptions_initializer
;
MQTTClient_willOptions
wopts
=
MQTTClient_willOptions_initializer
;
MQTTProperties
props
=
MQTTProperties_initializer
;
MQTTProperties
connect_props
=
MQTTProperties_initializer
;
MQTTProperty
property
;
MQTTSubscribe_options
subopts
=
MQTTSubscribe_options_initializer
;
MQTTClient_message
pubmsg
=
MQTTClient_message_initializer
;
MQTTResponse
response
=
{
SUCCESS
,
NULL
};
MQTTClient_deliveryToken
dt
;
int
rc
=
0
;
int
count
=
0
;
char
*
test_topic
=
"test_client_topic_aliases"
;
int
topicAliasMaximum
=
0
;
fprintf
(
xml
,
"<testcase classname=
\"
test_client_topic_aliases
\"
name=
\"
client topic aliases
\"
"
);
global_start_time
=
start_clock
();
failures
=
0
;
MyLog
(
LOGA_INFO
,
"Starting test 1 - client topic aliases"
);
rc
=
MQTTClient_create
(
&
c
,
options
.
connection
,
"client_topic_alias_test"
,
MQTTCLIENT_PERSISTENCE_DEFAULT
,
NULL
);
assert
(
"good rc from create"
,
rc
==
MQTTCLIENT_SUCCESS
,
"rc was %d
\n
"
,
rc
);
if
(
rc
!=
MQTTCLIENT_SUCCESS
)
{
MQTTClient_destroy
(
&
c
);
goto
exit
;
}
rc
=
MQTTClient_setCallbacks
(
c
,
NULL
,
NULL
,
messageArrived
,
NULL
);
assert
(
"Good rc from setCallbacks"
,
rc
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
rc
);
rc
=
MQTTClient_setDisconnected
(
c
,
c
,
disconnected
);
assert
(
"Good rc from setDisconnected"
,
rc
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
rc
);
opts
.
keepAliveInterval
=
20
;
opts
.
cleansession
=
1
;
opts
.
MQTTVersion
=
options
.
MQTTVersion
;
if
(
options
.
haconnections
!=
NULL
)
{
opts
.
serverURIs
=
options
.
haconnections
;
opts
.
serverURIcount
=
options
.
hacount
;
}
MyLog
(
LOGA_DEBUG
,
"Connecting"
);
response
=
MQTTClient_connect5
(
c
,
&
opts
,
NULL
,
NULL
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
goto
exit
;
if
(
response
.
properties
)
{
logProperties
(
response
.
properties
);
MQTTResponse_free
(
response
);
}
pubmsg
.
payload
=
"a much longer message that we can shorten to the extent that we need to payload up to 11"
;
pubmsg
.
payloadlen
=
11
;
pubmsg
.
qos
=
1
;
pubmsg
.
retained
=
0
;
/* a Topic Alias of 0 is not allowed, so we should be disconnected */
property
.
identifier
=
TOPIC_ALIAS
;
property
.
value
.
integer2
=
0
;
MQTTProperties_add
(
&
pubmsg
.
properties
,
&
property
);
response
=
MQTTClient_publishMessage5
(
c
,
test_topic
,
&
pubmsg
,
&
dt
);
assert
(
"Good rc from publish"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
/* Now we expect to receive a disconnect packet telling us why */
count
=
0
;
while
(
test_topic_aliases_globals
.
disconnected
==
0
&&
++
count
<
10
)
{
#if defined(WIN32)
Sleep
(
1000
);
#else
usleep
(
1000000L
);
#endif
}
assert
(
"Disconnected should be called"
,
test_topic_aliases_globals
.
disconnected
==
1
,
"was %d"
,
test_topic_aliases_globals
.
disconnected
);
property
.
identifier
=
SESSION_EXPIRY_INTERVAL
;
property
.
value
.
integer4
=
30
;
MQTTProperties_add
(
&
connect_props
,
&
property
);
/* Now try a valid topic alias */
response
=
MQTTClient_connect5
(
c
,
&
opts
,
&
connect_props
,
NULL
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
goto
exit
;
if
(
response
.
properties
)
{
if
(
MQTTProperties_hasProperty
(
response
.
properties
,
TOPIC_ALIAS_MAXIMUM
))
topicAliasMaximum
=
MQTTProperties_getNumericValue
(
response
.
properties
,
TOPIC_ALIAS_MAXIMUM
);
logProperties
(
response
.
properties
);
MQTTResponse_free
(
response
);
}
assert
(
"topicAliasMaximum > 0"
,
topicAliasMaximum
>
0
,
"topicAliasMaximum was %d"
,
topicAliasMaximum
);
/* subscribe to a topic */
response
=
MQTTClient_subscribe5
(
c
,
test_topic
,
2
,
NULL
,
NULL
);
assert
(
"Good rc from subscribe"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
/* then publish to the topic */
MQTTProperties_free
(
&
pubmsg
.
properties
);
property
.
identifier
=
TOPIC_ALIAS
;
property
.
value
.
integer2
=
1
;
MQTTProperties_add
(
&
pubmsg
.
properties
,
&
property
);
messages_arrived
=
0
;
response
=
MQTTClient_publishMessage5
(
c
,
test_topic
,
&
pubmsg
,
&
dt
);
assert
(
"Good rc from publish"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
/* should get a response */
while
(
messages_arrived
==
0
&&
++
count
<
10
)
{
#if defined(WIN32)
Sleep
(
1000
);
#else
usleep
(
1000000L
);
#endif
}
assert
(
"1 message should have arrived"
,
messages_arrived
==
1
,
"was %d"
,
messages_arrived
);
/* now publish to the topic alias only */
messages_arrived
=
0
;
response
=
MQTTClient_publishMessage5
(
c
,
""
,
&
pubmsg
,
&
dt
);
assert
(
"Good rc from publish"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
/* should get a response */
while
(
messages_arrived
==
0
&&
++
count
<
10
)
{
#if defined(WIN32)
Sleep
(
1000
);
#else
usleep
(
1000000L
);
#endif
}
assert
(
"1 message should have arrived"
,
messages_arrived
==
1
,
"was %d"
,
messages_arrived
);
rc
=
MQTTClient_disconnect5
(
c
,
1000
,
SUCCESS
,
NULL
);
/* Reconnect. Topic aliases should be deleted, but not subscription */
opts
.
cleansession
=
0
;
response
=
MQTTClient_connect5
(
c
,
&
opts
,
NULL
,
NULL
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
MQTTResponse_free
(
response
);
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
goto
exit
;
/* then publish to the topic */
MQTTProperties_free
(
&
pubmsg
.
properties
);
messages_arrived
=
0
;
response
=
MQTTClient_publishMessage5
(
c
,
test_topic
,
&
pubmsg
,
&
dt
);
assert
(
"Good rc from publish"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
/* should get a response */
while
(
messages_arrived
==
0
&&
++
count
<
10
)
{
#if defined(WIN32)
Sleep
(
1000
);
#else
usleep
(
1000000L
);
#endif
}
assert
(
"1 message should have arrived"
,
messages_arrived
==
1
,
"was %d"
,
messages_arrived
);
/* now publish to the topic alias only */
messages_arrived
=
0
;
property
.
identifier
=
TOPIC_ALIAS
;
property
.
value
.
integer2
=
1
;
MQTTProperties_add
(
&
pubmsg
.
properties
,
&
property
);
response
=
MQTTClient_publishMessage5
(
c
,
""
,
&
pubmsg
,
&
dt
);
assert
(
"Good rc from publish"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
/* should not get a response */
while
(
messages_arrived
==
0
&&
++
count
<
10
)
{
#if defined(WIN32)
Sleep
(
1000
);
#else
usleep
(
1000000L
);
#endif
}
assert
(
"No message should have arrived"
,
messages_arrived
==
0
,
"was %d"
,
messages_arrived
);
MQTTProperties_free
(
&
pubmsg
.
properties
);
MQTTProperties_free
(
&
props
);
MQTTProperties_free
(
&
connect_props
);
MQTTClient_destroy
(
&
c
);
exit:
MyLog
(
LOGA_INFO
,
"TEST1: test %s. %d tests run, %d failures."
,
(
failures
==
0
)
?
"passed"
:
"failed"
,
tests
,
failures
);
write_test_result
();
return
failures
;
}
int
main
(
int
argc
,
char
**
argv
)
{
int
rc
=
0
;
int
(
*
tests
[])()
=
{
NULL
,
test_client_topic_aliases
};
int
i
;
xml
=
fopen
(
"TEST-test1.xml"
,
"w"
);
fprintf
(
xml
,
"<testsuite name=
\"
test1
\"
tests=
\"
%d
\"
>
\n
"
,
(
int
)(
ARRAY_SIZE
(
tests
)
-
1
));
setenv
(
"MQTT_C_CLIENT_TRACE"
,
"ON"
,
1
);
setenv
(
"MQTT_C_CLIENT_TRACE_LEVEL"
,
"ERROR"
,
1
);
getopts
(
argc
,
argv
);
for
(
i
=
0
;
i
<
options
.
iterations
;
++
i
)
{
if
(
options
.
test_no
==
0
)
{
/* run all the tests */
for
(
options
.
test_no
=
1
;
options
.
test_no
<
ARRAY_SIZE
(
tests
);
++
options
.
test_no
)
rc
+=
tests
[
options
.
test_no
](
options
);
/* return number of failures. 0 = test succeeded */
}
else
rc
=
tests
[
options
.
test_no
](
options
);
/* run just the selected test */
}
if
(
rc
==
0
)
MyLog
(
LOGA_INFO
,
"verdict pass"
);
else
MyLog
(
LOGA_INFO
,
"verdict fail"
);
fprintf
(
xml
,
"</testsuite>
\n
"
);
fclose
(
xml
);
return
rc
;
}
test/test15.c
View file @
7ea13339
...
@@ -58,9 +58,9 @@ struct Options
...
@@ -58,9 +58,9 @@ struct Options
int
iterations
;
int
iterations
;
}
options
=
}
options
=
{
{
"tcp://iot.eclipse.org:1883"
,
NULL
,
"tcp://localhost:1883"
,
"tcp://localhost:1883"
,
NULL
,
"tcp://localhost:1884"
,
0
,
0
,
0
,
0
,
0
,
0
,
...
@@ -291,7 +291,7 @@ void test1_sendAndReceive(MQTTClient* c, int qos, char* test_topic)
...
@@ -291,7 +291,7 @@ void test1_sendAndReceive(MQTTClient* c, int qos, char* test_topic)
char
*
topicName
=
NULL
;
char
*
topicName
=
NULL
;
int
topicLen
;
int
topicLen
;
int
i
=
0
;
int
i
=
0
;
int
iterations
=
1
;
//
50;
int
iterations
=
50
;
int
rc
;
int
rc
;
MQTTResponse
resp
;
MQTTResponse
resp
;
MQTTProperty
property
;
MQTTProperty
property
;
...
@@ -463,7 +463,7 @@ int test1(struct Options options)
...
@@ -463,7 +463,7 @@ int test1(struct Options options)
if
(
response
.
properties
)
if
(
response
.
properties
)
{
{
logProperties
(
response
.
properties
);
logProperties
(
response
.
properties
);
MQTT
Properties_free
(
response
.
properties
);
MQTT
Response_free
(
response
);
}
}
subopts
.
retainAsPublished
=
1
;
subopts
.
retainAsPublished
=
1
;
...
@@ -508,6 +508,7 @@ int test1(struct Options options)
...
@@ -508,6 +508,7 @@ int test1(struct Options options)
/* Just to make sure we can connect again */
/* Just to make sure we can connect again */
response
=
MQTTClient_connect5
(
c
,
&
opts
,
NULL
,
NULL
);
response
=
MQTTClient_connect5
(
c
,
&
opts
,
NULL
,
NULL
);
assert
(
"Connect successful"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
assert
(
"Connect successful"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
MQTTResponse_free
(
response
);
rc
=
MQTTClient_disconnect5
(
c
,
0
,
SUCCESS
,
&
props
);
rc
=
MQTTClient_disconnect5
(
c
,
0
,
SUCCESS
,
&
props
);
assert
(
"Disconnect successful"
,
rc
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
rc
);
assert
(
"Disconnect successful"
,
rc
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
rc
);
...
@@ -670,7 +671,9 @@ int test2(struct Options options)
...
@@ -670,7 +671,9 @@ int test2(struct Options options)
MyLog
(
LOGA_DEBUG
,
"Connecting"
);
MyLog
(
LOGA_DEBUG
,
"Connecting"
);
response
=
MQTTClient_connect5
(
c
,
&
opts
,
&
props
,
&
willProps
);
response
=
MQTTClient_connect5
(
c
,
&
opts
,
&
props
,
&
willProps
);
assert
(
"Good rc from connect"
,
rc
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
rc
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
MQTTResponse_free
(
response
);
if
(
rc
!=
MQTTCLIENT_SUCCESS
)
if
(
rc
!=
MQTTCLIENT_SUCCESS
)
goto
exit
;
goto
exit
;
...
@@ -719,6 +722,7 @@ int test3(struct Options options)
...
@@ -719,6 +722,7 @@ int test3(struct Options options)
MQTTClient
c
;
MQTTClient
c
;
MQTTClient_connectOptions
opts
=
MQTTClient_connectOptions_initializer
;
MQTTClient_connectOptions
opts
=
MQTTClient_connectOptions_initializer
;
MQTTClient_willOptions
wopts
=
MQTTClient_willOptions_initializer
;
MQTTClient_willOptions
wopts
=
MQTTClient_willOptions_initializer
;
MQTTResponse
response
;
fprintf
(
xml
,
"<testcase classname=
\"
test1
\"
name=
\"
connack return codes
\"
"
);
fprintf
(
xml
,
"<testcase classname=
\"
test1
\"
name=
\"
connack return codes
\"
"
);
global_start_time
=
start_clock
();
global_start_time
=
start_clock
();
...
@@ -756,8 +760,9 @@ int test3(struct Options options)
...
@@ -756,8 +760,9 @@ int test3(struct Options options)
opts.will->qos = 1;
opts.will->qos = 1;
opts.will->retained = 0;
opts.will->retained = 0;
opts.will->topicName = "will topic";*/
opts.will->topicName = "will topic";*/
r
c
=
MQTTClient_connect
(
c
,
&
opts
);
r
esponse
=
MQTTClient_connect5
(
c
,
&
opts
,
NULL
,
NULL
);
//assert("Not authorized", rc == 5, "rc was %d\n", rc);
//assert("Not authorized", rc == 5, "rc was %d\n", rc);
MQTTResponse_free
(
response
);
#if 0
#if 0
/* successful connection (RC = 0) */
/* successful connection (RC = 0) */
...
@@ -825,6 +830,7 @@ int test4_run(int qos)
...
@@ -825,6 +830,7 @@ int test4_run(int qos)
response
=
MQTTClient_connect5
(
c
,
&
opts
,
&
props
,
NULL
);
response
=
MQTTClient_connect5
(
c
,
&
opts
,
&
props
,
NULL
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
"rc was %d"
,
response
.
reasonCode
);
MQTTResponse_free
(
response
);
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
return
-
1
;
return
-
1
;
...
@@ -879,6 +885,7 @@ int test4_run(int qos)
...
@@ -879,6 +885,7 @@ int test4_run(int qos)
opts
.
cleansession
=
0
;
opts
.
cleansession
=
0
;
response
=
MQTTClient_connect5
(
c
,
&
opts
,
NULL
,
NULL
);
response
=
MQTTClient_connect5
(
c
,
&
opts
,
NULL
,
NULL
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
MQTTResponse_free
(
response
);
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
return
-
1
;
return
-
1
;
...
@@ -986,6 +993,7 @@ int test5(struct Options options)
...
@@ -986,6 +993,7 @@ int test5(struct Options options)
MyLog
(
LOGA_DEBUG
,
"Connecting"
);
MyLog
(
LOGA_DEBUG
,
"Connecting"
);
response
=
MQTTClient_connect5
(
c
,
&
opts
,
&
props
,
NULL
);
response
=
MQTTClient_connect5
(
c
,
&
opts
,
&
props
,
NULL
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d"
,
response
.
reasonCode
);
MQTTResponse_free
(
response
);
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
{
{
MQTTClient_destroy
(
&
c
);
MQTTClient_destroy
(
&
c
);
...
@@ -1101,6 +1109,7 @@ int test6(struct Options options)
...
@@ -1101,6 +1109,7 @@ int test6(struct Options options)
/* Connect to the broker */
/* Connect to the broker */
response
=
MQTTClient_connect5
(
test6_c1
,
&
opts
,
NULL
,
NULL
);
response
=
MQTTClient_connect5
(
test6_c1
,
&
opts
,
NULL
,
NULL
);
assert
(
"good rc from connect"
,
rc
==
MQTTCLIENT_SUCCESS
,
"rc was %d
\n
"
,
rc
);
assert
(
"good rc from connect"
,
rc
==
MQTTCLIENT_SUCCESS
,
"rc was %d
\n
"
,
rc
);
MQTTResponse_free
(
response
);
if
(
rc
!=
MQTTCLIENT_SUCCESS
)
if
(
rc
!=
MQTTCLIENT_SUCCESS
)
goto
exit
;
goto
exit
;
...
@@ -1117,6 +1126,7 @@ int test6(struct Options options)
...
@@ -1117,6 +1126,7 @@ int test6(struct Options options)
opts2
.
cleansession
=
1
;
opts2
.
cleansession
=
1
;
MyLog
(
LOGA_INFO
,
"Connecting Client_2 ..."
);
MyLog
(
LOGA_INFO
,
"Connecting Client_2 ..."
);
response
=
MQTTClient_connect5
(
test6_c2
,
&
opts2
,
NULL
,
NULL
);
response
=
MQTTClient_connect5
(
test6_c2
,
&
opts2
,
NULL
,
NULL
);
MQTTResponse_free
(
response
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d
\n
"
,
response
.
reasonCode
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d
\n
"
,
response
.
reasonCode
);
response
=
MQTTClient_subscribe5
(
test6_c2
,
test6_will_topic
,
2
,
NULL
,
NULL
);
response
=
MQTTClient_subscribe5
(
test6_c2
,
test6_will_topic
,
2
,
NULL
,
NULL
);
...
@@ -1211,6 +1221,7 @@ int test6a(struct Options options)
...
@@ -1211,6 +1221,7 @@ int test6a(struct Options options)
response
=
MQTTClient_connect5
(
test6_c1
,
&
opts
,
NULL
,
NULL
);
response
=
MQTTClient_connect5
(
test6_c1
,
&
opts
,
NULL
,
NULL
);
assert
(
"good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
assert
(
"good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d
\n
"
,
response
.
reasonCode
);
"rc was %d
\n
"
,
response
.
reasonCode
);
MQTTResponse_free
(
response
);
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
if
(
response
.
reasonCode
!=
MQTTCLIENT_SUCCESS
)
goto
exit
;
goto
exit
;
...
@@ -1227,6 +1238,7 @@ int test6a(struct Options options)
...
@@ -1227,6 +1238,7 @@ int test6a(struct Options options)
opts2
.
cleansession
=
1
;
opts2
.
cleansession
=
1
;
MyLog
(
LOGA_INFO
,
"Connecting Client_2 ..."
);
MyLog
(
LOGA_INFO
,
"Connecting Client_2 ..."
);
response
=
MQTTClient_connect5
(
test6_c2
,
&
opts2
,
NULL
,
NULL
);
response
=
MQTTClient_connect5
(
test6_c2
,
&
opts2
,
NULL
,
NULL
);
MQTTResponse_free
(
response
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d
\n
"
,
response
.
reasonCode
);
assert
(
"Good rc from connect"
,
response
.
reasonCode
==
MQTTCLIENT_SUCCESS
,
"rc was %d
\n
"
,
response
.
reasonCode
);
response
=
MQTTClient_subscribe5
(
test6_c2
,
test6_will_topic
,
2
,
NULL
,
NULL
);
response
=
MQTTClient_subscribe5
(
test6_c2
,
test6_will_topic
,
2
,
NULL
,
NULL
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment