Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support MQTT version 5.0 #11

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c4ab4a7
Slightly working MQTT 5
dustin Sep 17, 2019
8801f60
Publish more than one property in the example.
dustin Sep 18, 2019
27646b7
[]byte properties use the same encoding as strings
dustin Sep 18, 2019
abc7ab7
Fix string property encoding.
dustin Sep 18, 2019
96f0894
Generated tests (and a test generator)
dustin Sep 18, 2019
b4702b9
Reuse publish test builder.
dustin Sep 18, 2019
59ce180
Reusable properties encoding
dustin Sep 18, 2019
9986847
Generate connection tests.
dustin Sep 18, 2019
be377fc
Generate subscribe requests.
dustin Sep 18, 2019
067650b
Test decoding publish messages.
dustin Sep 18, 2019
64bcf06
Fixed a couple warnings.
dustin Sep 18, 2019
e2c9f9c
Some hlint fixes and other cleanups.
dustin Sep 18, 2019
66e9de1
Generated test update with current generator.
dustin Sep 18, 2019
1a69a14
Reuse more generator.
dustin Sep 18, 2019
12adc11
MQTT 5 allows passwords without usernames.
dustin Sep 19, 2019
56e2fc1
Support all subscription options.
dustin Sep 19, 2019
96ce2f8
Fix suback parsing for v5.
dustin Sep 20, 2019
1b21fab
Introduce lwmqtt_serialized_properties_t for props output.
dustin Sep 20, 2019
3368cfa
Properties visitor to read all the properties.
dustin Sep 20, 2019
012bc4a
Disconnect (now with reasons!)
dustin Sep 21, 2019
46c7ecf
v5 unsubscribe requests
dustin Sep 21, 2019
75592a7
Properly parsing unsub acks.
dustin Sep 21, 2019
64b8b08
Easier API for property visiting.
dustin Sep 21, 2019
ee81468
Implemented all the various puback messages.
dustin Sep 21, 2019
4b7da36
Consider returned status in pub ACKs.
dustin Sep 21, 2019
3d1b30b
Plumb properties through subscription functions.
dustin Sep 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic -Werror -Wno-unused-parameter")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Werror -Wno-unused-parameter")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-unused-parameter")

include_directories(include)

Expand Down Expand Up @@ -40,7 +40,9 @@ set(TEST_FILES
tests/helpers.cpp
tests/packet.cpp
tests/string.cpp
tests/tests.cpp)
tests/tests.cpp
tests/generated.cpp
)

add_executable(tests ${TEST_FILES})

Expand Down
10 changes: 7 additions & 3 deletions examples/async.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ lwmqtt_client_t client;

pthread_mutex_t mutex;

static void message_arrived(lwmqtt_client_t *_client, void *ref, lwmqtt_string_t topic, lwmqtt_message_t msg) {
static void message_arrived(lwmqtt_client_t *_client, void *ref, lwmqtt_string_t topic, lwmqtt_message_t msg,
lwmqtt_serialized_properties_t props) {
printf("message_arrived: %.*s => %.*s (%d)\n", (int)topic.len, topic.data, (int)msg.payload_len, (char *)msg.payload,
(int)msg.payload_len);
}
Expand Down Expand Up @@ -102,7 +103,9 @@ int main() {
printf("connected!\n");

// subscribe to topic
err = lwmqtt_subscribe_one(&client, lwmqtt_string("hello"), LWMQTT_QOS0, COMMAND_TIMEOUT);
lwmqtt_sub_options_t subopts = lwmqtt_default_sub_options;
lwmqtt_properties_t subprops = lwmqtt_empty_props;
err = lwmqtt_subscribe_one(&client, lwmqtt_string("hello"), subopts, subprops, COMMAND_TIMEOUT);
if (err != LWMQTT_SUCCESS) {
printf("failed lwmqtt_subscribe: %d\n", err);
exit(1);
Expand Down Expand Up @@ -135,7 +138,8 @@ int main() {
pthread_mutex_lock(&mutex);

// publish message
err = lwmqtt_publish(&client, lwmqtt_string("hello"), msg, COMMAND_TIMEOUT);
lwmqtt_properties_t props = lwmqtt_empty_props;
err = lwmqtt_publish(&client, lwmqtt_string("hello"), msg, props, COMMAND_TIMEOUT);
if (err != LWMQTT_SUCCESS) {
printf("failed lwmqtt_publish: %d\n", err);
exit(1);
Expand Down
52 changes: 47 additions & 5 deletions examples/sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,41 @@ lwmqtt_unix_timer_t timer1, timer2, timer3;

lwmqtt_client_t client;

static void message_arrived(lwmqtt_client_t *_client, void *ref, lwmqtt_string_t topic, lwmqtt_message_t msg) {
static void prop_byte_printer(void *ref, lwmqtt_prop_t prop, uint8_t value) {
printf(" Property %x (byte): 0x%x\n", prop, value);
}

static void prop_int16_printer(void *ref, lwmqtt_prop_t prop, int16_t value) {
printf(" Property %x (int): %d\n", prop, value);
}

static void prop_int32_printer(void *ref, lwmqtt_prop_t prop, int32_t value) {
printf(" Property %x (int32): %d\n", prop, value);
}

static void prop_str_printer(void *ref, lwmqtt_prop_t prop, lwmqtt_string_t value) {
printf(" Property %x (string): %.*s\n", prop, (int)value.len, value.data);
}

static void prop_user_printer(void *ref, lwmqtt_string_t k, lwmqtt_string_t v) {
printf(" User property: k=%.*s, v=%.*s\n", (int)k.len, k.data, (int)v.len, v.data);
}

static void message_arrived(lwmqtt_client_t *_client, void *ref, lwmqtt_string_t topic, lwmqtt_message_t msg,
lwmqtt_serialized_properties_t props) {
printf("message_arrived: %.*s => %.*s (%d)\n", (int)topic.len, topic.data, (int)msg.payload_len, (char *)msg.payload,
(int)msg.payload_len);

lwmqtt_property_callbacks_t cb = {
.byte_prop = prop_byte_printer,
.int16_prop = prop_int16_printer,
.int32_prop = prop_int32_printer,
.str_prop = prop_str_printer,
.user_prop = prop_user_printer,
};
if (lwmqtt_property_visitor(NULL, props, cb) != LWMQTT_SUCCESS) {
exit(1);
}
}

int main() {
Expand All @@ -26,12 +58,13 @@ int main() {
lwmqtt_set_network(&client, &network, lwmqtt_unix_network_read, lwmqtt_unix_network_write);
lwmqtt_set_timers(&client, &timer1, &timer2, lwmqtt_unix_timer_set, lwmqtt_unix_timer_get);
lwmqtt_set_callback(&client, NULL, message_arrived);
lwmqtt_set_protocol(&client, LWMQTT_MQTT5);

// configure message time
lwmqtt_unix_timer_set(&timer3, MESSAGE_TIMEOUT);

// connect to broker
lwmqtt_err_t err = lwmqtt_unix_network_connect(&network, "public.cloud.shiftr.io", 1883);
lwmqtt_err_t err = lwmqtt_unix_network_connect(&network, "localhost", 1883);
if (err != LWMQTT_SUCCESS) {
printf("failed lwmqtt_unix_network_connect: %d\n", err);
exit(1);
Expand All @@ -56,7 +89,9 @@ int main() {
printf("connected!\n");

// subscribe to topic
err = lwmqtt_subscribe_one(&client, lwmqtt_string("hello"), LWMQTT_QOS0, COMMAND_TIMEOUT);
lwmqtt_sub_options_t subopts = lwmqtt_default_sub_options;
lwmqtt_properties_t subprops = lwmqtt_empty_props;
err = lwmqtt_subscribe_one(&client, lwmqtt_string("hello"), subopts, subprops, COMMAND_TIMEOUT);
if (err != LWMQTT_SUCCESS) {
printf("failed lwmqtt_subscribe: %d\n", err);
exit(1);
Expand Down Expand Up @@ -91,10 +126,17 @@ int main() {
// check if message is due
if (lwmqtt_unix_timer_get(&timer3) <= 0) {
// prepare message
lwmqtt_message_t msg = {.qos = LWMQTT_QOS0, .retained = false, .payload = (uint8_t *)("world"), .payload_len = 5};
lwmqtt_message_t msg = {.qos = LWMQTT_QOS0, .retained = true, .payload = (uint8_t *)("world"), .payload_len = 5};

// publish message
err = lwmqtt_publish(&client, lwmqtt_string("hello"), msg, COMMAND_TIMEOUT);
lwmqtt_property_t proplist[] = {
{.prop = LWMQTT_PROP_MESSAGE_EXPIRY_INTERVAL, .value = {.int32 = 30}},
{.prop = LWMQTT_PROP_USER_PROPERTY,
.value = {.pair = {.k = lwmqtt_string("hello from"), .v = lwmqtt_string("lwmqtt")}}},
};

lwmqtt_properties_t props = {2, (lwmqtt_property_t *)&proplist};
err = lwmqtt_publish(&client, lwmqtt_string("hello"), msg, props, COMMAND_TIMEOUT);
if (err != LWMQTT_SUCCESS) {
printf("failed lwmqtt_keep_alive: %d\n", err);
exit(1);
Expand Down
3 changes: 3 additions & 0 deletions gentests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.stack-work/
gentests.cabal
*~
2 changes: 2 additions & 0 deletions gentests/Setup.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain
Loading