aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.c821
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.h506
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_decoder.c262
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_encoder.c457
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h446
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.c313
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.h74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.c88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.h233
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_lwip.c349
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_socket.c319
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_tls.c185
12 files changed, 4053 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.c
new file mode 100644
index 0000000..ecb6fcd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.c
@@ -0,0 +1,821 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file mqtt.c
+ *
+ * @brief MQTT Client API Implementation.
+ */
+
+
+#include "mqtt.h"
+#include "mem_manager.h"
+#include "mqtt_transport.h"
+#include "mqtt_internal.h"
+#include "iot_timer.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+/**< Never changing ping request, needed for Keep Alive. */
+static const uint8_t m_ping_packet[MQTT_PKT_HEADER_SIZE] = \
+ {MQTT_PKT_TYPE_PINGREQ, \
+ 0x00};
+
+/**< Never changing disconnect request. */
+static const uint8_t m_disc_packet[MQTT_PKT_HEADER_SIZE] = \
+ {MQTT_PKT_TYPE_DISCONNECT, \
+ 0x00};
+
+static mqtt_client_t * m_mqtt_client[MQTT_MAX_CLIENTS]; /**< MQTT Client table. */
+SDK_MUTEX_DEFINE(m_mqtt_mutex) /**< Mutex variable for the module, currently unused. */
+
+
+static uint32_t get_client_index(mqtt_client_t * const p_client)
+{
+ for (uint32_t index = 0; index < MQTT_MAX_CLIENTS; index++)
+ {
+ if (m_mqtt_client[index] == p_client)
+ {
+ return index;
+ }
+ }
+
+ return MQTT_MAX_CLIENTS;
+}
+
+
+void client_free(mqtt_client_t * const p_client)
+{
+ MQTT_STATE_INIT(p_client);
+
+ // Free memory used for TX packets and reset the pointer.
+ nrf_free(p_client->p_packet);
+ p_client->p_packet = NULL;
+
+ // Free TLS instance and reset the instance.
+ UNUSED_VARIABLE(nrf_tls_free(&p_client->tls_instance));
+ NRF_TLS_INTSANCE_INIT(&p_client->tls_instance);
+}
+
+
+void client_init(mqtt_client_t * const p_client)
+{
+ memset(p_client, 0, sizeof(*p_client));
+
+ MQTT_STATE_INIT(p_client);
+
+ p_client->protocol_version = MQTT_VERSION_3_1_0;
+ p_client->clean_session = 1;
+
+ NRF_TLS_INTSANCE_INIT(&p_client->tls_instance);
+}
+
+
+/**@brief Notifies event to the application.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * @param[in] p_evt Reason for disconnection.
+ */
+void event_notify(mqtt_client_t * const p_client, const mqtt_evt_t * p_evt, uint32_t flags)
+{
+ const mqtt_evt_cb_t evt_cb = p_client->evt_cb;
+
+ if (evt_cb != NULL)
+ {
+ MQTT_MUTEX_UNLOCK();
+
+ evt_cb(p_client, p_evt);
+
+ MQTT_MUTEX_LOCK();
+
+ if (IS_SET(flags,MQTT_EVT_FLAG_INSTANCE_RESET))
+ {
+ client_init(p_client);
+ }
+ }
+}
+
+
+/**@brief Notifies disconnection event to the application.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * @param[in] result Reason for disconnection.
+ */
+void disconnect_event_notify(mqtt_client_t * p_client, uint32_t result)
+{
+ mqtt_evt_t evt;
+ const uint32_t client_index = get_client_index(p_client);
+
+ // Remove the client from internal table.
+ if (client_index != MQTT_MAX_CLIENTS)
+ {
+ m_mqtt_client[client_index] = NULL;
+ }
+
+ // Determine appropriate event to generate.
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED) ||
+ MQTT_VERIFY_STATE(p_client, MQTT_STATE_DISCONNECTING))
+ {
+ evt.id = MQTT_EVT_DISCONNECT;
+ evt.result = result;
+ }
+ else
+ {
+ evt.id = MQTT_EVT_CONNACK;
+ evt.result = MQTT_CONNECTION_FAILED;
+ }
+
+ // Free the instance.
+ client_free(p_client);
+
+ // Notify application.
+ event_notify(p_client, &evt, MQTT_EVT_FLAG_INSTANCE_RESET);
+}
+
+
+uint32_t mqtt_init(void)
+{
+ SDK_MUTEX_INIT(m_mqtt_mutex);
+
+ MQTT_MUTEX_LOCK();
+
+ memset(m_mqtt_client, 0, sizeof(m_mqtt_client));
+
+ MQTT_MUTEX_UNLOCK();
+
+ return nrf_tls_init();
+}
+
+
+void mqtt_client_init(mqtt_client_t * const p_client)
+{
+ NULL_PARAM_CHECK_VOID(p_client);
+
+ MQTT_MUTEX_LOCK();
+
+ client_init(p_client);
+
+ MQTT_MUTEX_UNLOCK();
+}
+
+
+uint32_t mqtt_connect(mqtt_client_t * const p_client)
+{
+ // Look for a free instance if available.
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t client_index = 0;
+
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_client->client_id.p_utf_str);
+
+ MQTT_MUTEX_LOCK();
+
+ for (client_index = 0; client_index < MQTT_MAX_CLIENTS; client_index++)
+ {
+ if (m_mqtt_client[client_index] == NULL)
+ {
+ // Found a free instance.
+ m_mqtt_client[client_index] = p_client;
+
+ // Allocate buffer packets in TX path.
+ p_client->p_packet = nrf_malloc(MQTT_MAX_PACKET_LENGTH);
+ break;
+ }
+ }
+
+ if ((client_index == MQTT_MAX_CLIENTS) || (p_client->p_packet == NULL))
+ {
+ err_code = (NRF_ERROR_NO_MEM | IOT_MQTT_ERR_BASE);
+ }
+ else
+ {
+ err_code = tcp_request_connection(p_client);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Free the instance.
+ m_mqtt_client[client_index] = NULL;
+ nrf_free(p_client->p_packet);
+ err_code = MQTT_ERR_TCP_PROC_FAILED;
+ }
+ }
+
+ UNUSED_VARIABLE(p_client);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish(mqtt_client_t * const p_client,
+ mqtt_publish_param_t const * const p_param)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+ uint32_t offset = 0;
+ uint32_t mqtt_packetlen = 0;
+ uint8_t * p_payload;
+
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Topic size 0x%08x, Data size 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message.topic.topic.utf_strlen,
+ p_param->message.payload.bin_strlen);
+
+ MQTT_MUTEX_LOCK();
+
+ p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ // Pack topic.
+ err_code = pack_utf8_str(&p_param->message.topic.topic,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (p_param->message.topic.qos)
+ {
+ err_code = pack_uint16(p_param->message_id,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack message on the topic.
+ err_code = pack_bin_str(&p_param->message.payload,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(MQTT_PKT_TYPE_PUBLISH,
+ 0, // Duplicate flag not set.
+ p_param->message.topic.qos,
+ 0); // Retain flag not set.
+
+ mqtt_packetlen = mqtt_encode_fixed_header(message_type, // Message type
+ offset, // Payload size without the fixed header
+ &p_payload); // Address where the p_payload is contained.
+
+
+ // Publish message.
+ err_code = mqtt_transport_write(p_client, p_payload, mqtt_packetlen);
+ }
+ }
+
+ MQTT_TRC("<< %s", (uint32_t)__func__);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+/**@brief Encodes and sends messages that contain only message id in the variable header.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * @param[in] op_code Opcode for the message.
+ * @param[in] message_id Message id to be encoded in the variable header.
+ *
+ * @retval NRF_SUCCESS or an error code indicating a reason for failure.
+ */
+uint32_t mqtt_message_id_only_enc_n_send(mqtt_client_t * const p_client,
+ uint8_t opcode,
+ uint16_t message_id)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+ uint32_t offset = 0;
+ uint32_t mqtt_packetlen = 0;
+ uint8_t * p_payload;
+
+ p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ err_code = pack_uint16(message_id,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(opcode,
+ 0, // Duplicate flag not set.
+ 0, // QoS unused.
+ 0); // Retain flag not set.
+
+ mqtt_packetlen = mqtt_encode_fixed_header(message_type, // Message type
+ offset, // Payload size without the fixed header
+ &p_payload); // Address where the p_payload is contained.
+
+ // Publish message.
+ err_code = mqtt_transport_write(p_client, p_payload, mqtt_packetlen);
+ }
+ }
+
+ return err_code;
+}
+
+
+/**@brief Sends raw message to the peer.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * @param[in] p_message Raw message to be sent to the peer.
+ * @param[in] message_id Message id to be encoded in the variable header.
+ *
+ * @retval NRF_SUCCESS or an error code indicating a reason for failure.
+ */
+uint32_t mqtt_raw_message_send(mqtt_client_t * const p_client,
+ const uint8_t * p_message,
+ uint16_t message_len)
+{
+ uint32_t err_code;
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ err_code = mqtt_transport_write(p_client, p_message, message_len);
+ }
+ else
+ {
+ err_code = MQTT_ERR_NOT_CONNECTED;
+ }
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish_ack(mqtt_client_t * const p_client,
+ mqtt_puback_param_t const * p_param)
+{
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Message id 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code = mqtt_message_id_only_enc_n_send(p_client,
+ MQTT_PKT_TYPE_PUBACK,
+ p_param->message_id);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish_receive(mqtt_client_t * const p_client,
+ mqtt_pubrec_param_t const * const p_param)
+{
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Message id 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code = mqtt_message_id_only_enc_n_send(p_client,
+ MQTT_PKT_TYPE_PUBREC,
+ p_param->message_id);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish_release(mqtt_client_t * const p_client,
+ mqtt_pubrel_param_t const * const p_param)
+{
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Message id 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code = mqtt_message_id_only_enc_n_send(p_client,
+ MQTT_PKT_TYPE_PUBREL,
+ p_param->message_id);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish_complete(mqtt_client_t * const p_client,
+ mqtt_pubcomp_param_t const * const p_param)
+{
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Message id 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code = mqtt_message_id_only_enc_n_send(p_client,
+ MQTT_PKT_TYPE_PUBCOMP,
+ p_param->message_id);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_disconnect(mqtt_client_t * const p_client)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+
+ NULL_PARAM_CHECK(p_client);
+
+ MQTT_MUTEX_LOCK();
+
+ err_code = mqtt_raw_message_send(p_client, m_disc_packet, MQTT_FIXED_HEADER_SIZE);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ MQTT_SET_STATE_EXCLUSIVE(p_client, MQTT_STATE_DISCONNECTING);
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_subscribe(mqtt_client_t * const p_client,
+ mqtt_subscription_list_t const * const p_param)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+ uint32_t offset = 0;
+ uint32_t count = 0;
+ uint32_t mqtt_packetlen = 0;
+ uint8_t * p_payload;
+
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s message id 0x%04x topic count 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id,
+ p_param->list_count);
+
+ MQTT_MUTEX_LOCK();
+
+ p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ err_code = pack_uint16(p_param->message_id,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ do
+ {
+ err_code = pack_utf8_str(&p_param->p_list[count].topic,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = pack_uint8(p_param->p_list[count].qos,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ count++;
+ } while ((err_code != NRF_SUCCESS) || (count < p_param->list_count));
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(MQTT_PKT_TYPE_SUBSCRIBE, 0, 1, 0);
+
+ // Rewind the packet to encode the packet correctly.
+ mqtt_packetlen = mqtt_encode_fixed_header(message_type, // Message type, Duplicate Flag, QoS and retain flag setting.
+ offset, // p_payload size without the fixed header
+ &p_payload); // Address where the p_payload is contained. Header will encoded by rewinding the location.
+ // Send message.
+ err_code = mqtt_transport_write(p_client, p_payload, mqtt_packetlen);
+ }
+ }
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_unsubscribe(mqtt_client_t * const p_client,
+ mqtt_subscription_list_t const * const p_param)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+ uint32_t count = 0;
+ uint32_t offset = 0;
+ uint32_t mqtt_packetlen = 0;
+ uint8_t * p_payload;
+
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_MUTEX_LOCK();
+
+ p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ err_code = pack_uint16(p_param->message_id,
+ MQTT_MAX_PACKET_LENGTH,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ do
+ {
+ err_code = pack_utf8_str(&p_param->p_list[count].topic,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ count++;
+ } while ((err_code != NRF_SUCCESS) || (count < p_param->list_count));
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(MQTT_PKT_TYPE_UNSUBSCRIBE,
+ 0, // Duplicate flag.
+ MQTT_QoS_1_ATLEAST_ONCE,
+ 0); // Retain flag.
+
+ // Rewind the packet to encode the packet correctly.
+ mqtt_packetlen = mqtt_encode_fixed_header(message_type, // Message type, Duplicate Flag, QoS and retain flag setting.
+ offset, // Payload size without the fixed header
+ &p_payload); // Address where the p_payload is contained. Header will encoded by rewinding the location.
+
+ // Send message.
+ err_code = mqtt_transport_write(p_client, p_payload, mqtt_packetlen);
+ }
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_ping(mqtt_client_t * const p_client)
+{
+ uint32_t err_code;
+
+ NULL_PARAM_CHECK(p_client);
+
+ MQTT_MUTEX_LOCK();
+
+ err_code = mqtt_raw_message_send(p_client, m_ping_packet, MQTT_PKT_HEADER_SIZE);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_abort(mqtt_client_t * const p_client)
+{
+ MQTT_MUTEX_LOCK();
+
+ NULL_PARAM_CHECK(p_client);
+
+ if (p_client->state != MQTT_STATE_IDLE)
+ {
+ mqtt_client_tcp_abort(p_client);
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t mqtt_live(void)
+{
+ iot_timer_time_in_ms_t elapsed_time;
+ uint32_t index;
+
+ // Note: The module should not be locked when calling this TLS API.
+ nrf_tls_process();
+
+ MQTT_MUTEX_LOCK();
+
+ for (index = 0; index < MQTT_MAX_CLIENTS; index++)
+ {
+ mqtt_client_t * p_client = m_mqtt_client[index];
+ if (p_client != NULL)
+ {
+ UNUSED_VARIABLE(iot_timer_wall_clock_delta_get(&p_client->last_activity,
+ &elapsed_time));
+
+ if ((MQTT_KEEPALIVE > 0) && (elapsed_time > ((MQTT_KEEPALIVE - 2) * 1000)))
+ {
+ UNUSED_VARIABLE(mqtt_ping(p_client));
+ }
+ if (p_client->p_pending_packet != NULL)
+ {
+ uint32_t err;
+ err = mqtt_transport_write(p_client, p_client->p_pending_packet,
+ p_client->pending_packetlen);
+
+ if (err == NRF_SUCCESS)
+ {
+ p_client->p_pending_packet = NULL;
+ p_client->pending_packetlen = 0;
+ }
+ }
+ }
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t mqtt_input(mqtt_client_t * p_client, uint32_t timeout)
+{
+ uint32_t err_code;
+
+ NULL_PARAM_CHECK(p_client);
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_TRC("%s: 0x%08x", __func__, p_client->state);
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED) ||
+ MQTT_VERIFY_STATE(p_client, MQTT_STATE_DISCONNECTING))
+ {
+ err_code = tcp_receive_packet(p_client, timeout);
+ }
+ else
+ {
+ err_code = (NRF_ERROR_INVALID_STATE | IOT_MQTT_ERR_BASE);
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.h
new file mode 100644
index 0000000..980426a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.h
@@ -0,0 +1,506 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file mqtt.h
+ *
+ * @defgroup iot_sdk_mqtt_api MQTT Client on nRF5x
+ * @ingroup iot_sdk_mqtt
+ * @{
+ * @brief MQTT Client Implementation on the Nordic nRF platforms.
+ *
+ * @details
+ * MQTT Client's Application interface is defined in this header.
+ *
+ * @note The implementation assumes LwIP Stack is available with TCP module enabled.
+ *
+ * @note By default the implementation uses MQTT version 3.1.0.
+ * However few cloud services like the Xively use the version 3.1.1.
+ * For this please set p_client.protocol_version = MQTT_VERSION_3_1_1.
+ */
+
+#ifndef MQTT_H_
+#define MQTT_H_
+
+#include <stdint.h>
+#include "iot_defines.h"
+#include "iot_timer.h"
+#include "nrf_tls.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief MQTT Asynchronous Events notified to the application from the module
+ * through the callback registered by the application. */
+typedef enum
+{
+ MQTT_EVT_CONNACK, /**< Acknowledgment of connection request. Event result accompanying the event indicates whether the connection failed or succeeded. */
+ MQTT_EVT_DISCONNECT, /**< Disconnection Event. MQTT Client Reference is no longer valid once this event is received for the client. */
+ MQTT_EVT_PUBLISH, /**< Publish event received when message is published on a topic client is subscribed to. */
+ MQTT_EVT_PUBACK, /**< Acknowledgment for published message with QoS 1. */
+ MQTT_EVT_PUBREC, /**< Reception confirmation for published message with QoS 2. */
+ MQTT_EVT_PUBREL, /**< Release of published published messages with QoS 2. */
+ MQTT_EVT_PUBCOMP, /**< Confirmation to a publish release message. Applicable only to QoS 2 messages. */
+ MQTT_EVT_SUBACK, /**< Acknowledgment to a subscription request. */
+ MQTT_EVT_UNSUBACK /**< Acknowledgment to a unsubscription request. */
+} mqtt_evt_id_t;
+
+/**@brief MQTT version protocol level. */
+typedef enum
+{
+ MQTT_VERSION_3_1_0 = 3, /**< Protocol level for 3.1.0. */
+ MQTT_VERSION_3_1_1 = 4 /**< Protocol level for 3.1.1. */
+} mqtt_version_t;
+
+/**@brief MQTT transport type. */
+typedef enum
+{
+ MQTT_TRANSPORT_NON_SECURE = 0x00, /**< Use non secure TCP transport for MQTT connection. */
+ MQTT_TRANSPORT_SECURE = 0x01, /**< Use secure TCP transport (TLS) for MQTT connection. */
+ MQTT_TRANSPORT_MAX = 0x02 /**< Shall not be used as a transport type. Indicator of maximum transport types possible. */
+} mqtt_transport_type_t;
+
+/**@brief MQTT Quality of Service types. */
+typedef enum
+{
+ MQTT_QoS_0_AT_MOST_ONCE = 0x00, /**< Lowest Quality of Service, no acknowledgment needed for published message. */
+ MQTT_QoS_1_ATLEAST_ONCE = 0x01, /**< Medium Quality of Service, if acknowledgment expected for published message, duplicate messages permitted. */
+ MQTT_QoS_2_EACTLY_ONCE = 0x02 /**< Highest Quality of Service, acknowledgment expected and message shall be published only once. Message not published to interested parties unless client issues a PUBREL. */
+} mqtt_qos_t;
+
+/**@brief MQTT Asynchronous Events notified to the application from the module
+ * through the callback registered by the application. */
+typedef enum
+{
+ MQTT_CONNECTION_ACCEPTED = 0x00, /**< Connection accepted. */
+ MQTT_UNACCEPTABLE_PROTOCOL_VERSION = 0x01, /**< The Server does not support the level of the MQTT protocol requested by the Client. */
+ MQTT_IDENTIFIER_REJECTED = 0x02, /**< The Client identifier is correct UTF-8 but not allowed by the Server. */
+ MQTT_SERVER_UNAVAILABLE = 0x03, /**< The Network Connection has been made but the MQTT service is unavailable. */
+ MQTT_BAD_USER_NAME_OR_PASSWORD = 0x04, /**< The data in the user name or password is malformed. */
+ MQTT_NOT_AUTHORIZED = 0x05 /**< The Client is not authorized to connect. */
+} mqtt_conn_return_code_t;
+
+/**@brief MQTT client forward declaration @ref mqtt_client_t for details. */
+typedef struct mqtt_client_t mqtt_client_t;
+
+/**@brief Abstracts UTF-8 encoded strings. */
+typedef struct
+{
+ uint8_t * p_utf_str; /**< Pointer to UTF-8 string. */
+ uint32_t utf_strlen; /**< Length of UTF string. */
+} mqtt_utf8_t;
+
+/**@brief Abstracts binary strings. */
+typedef struct
+{
+ uint8_t * p_bin_str; /**< Pointer to binary stream. */
+ uint32_t bin_strlen; /**< Length of binary stream. */
+} mqtt_binstr_t;
+
+/**@brief Abstracts MQTT UTF-8 encoded topic that can be subscribed to or published. */
+typedef struct
+{
+ mqtt_utf8_t topic; /**< Topic on to be published or subscribed to. */
+ uint8_t qos; /**< Quality of service requested for the subscription. @ref mqtt_qos_t for details. */
+} mqtt_topic_t;
+
+/**@brief Abstracts MQTT UTF-8 encoded unique client identifier. */
+typedef mqtt_utf8_t mqtt_client_id_t;
+
+/**@brief Abstracts MQTT UTF-8 encoded password to be used for the client connection. */
+typedef mqtt_utf8_t mqtt_password_t;
+
+/**@brief Abstracts MQTT UTF-8 encoded user name to be used for the client connection. */
+typedef mqtt_utf8_t mqtt_username_t;
+
+/**@brief Abstracts will message used in @ref mqtt_connect request.
+ *
+ * @note utf8 is used here instead of binary string as a zero length encoding is expected in
+ * will message is empty.
+ */
+typedef mqtt_utf8_t mqtt_will_message_t;
+
+/**@brief Abstracts message in binary encoded string received or published on a topic. */
+typedef mqtt_binstr_t mqtt_message_t;
+
+/**@brief Parameters for a publish message. */
+typedef struct
+{
+ mqtt_topic_t topic; /**< Topic on which data was published. */
+ mqtt_message_t payload; /**< Payload on the topic published. */
+} mqtt_publish_message_t;
+
+/**@brief Parameters for a connection acknowledgment (connack). */
+typedef struct
+{
+ uint8_t session_present_flag; /**< The Session Present flag enables a Client to establish whether the Client and Server have a consistent view about whether there is already stored Session state. */
+ mqtt_conn_return_code_t return_code; /**< The appropriate non-zero Connect return code indicates if the Server is unable to process a connection request for some reason. */
+} mqtt_connack_param_t;
+
+/**@brief Parameters for MQTT publish acknowledgment(puback). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_puback_param_t;
+
+/**@brief Parameters for MQTT publish receive(pubrec). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_pubrec_param_t;
+
+/**@brief Parameters for MQTT publish release(pubrec). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_pubrel_param_t;
+
+/**@brief Parameters for MQTT publish complete(pubcomp). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_pubcomp_param_t;
+
+/**@brief Parameters for MQTT subscription acknowledgment (suback). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_suback_param_t;
+
+/**@brief Parameters for MQTT unsubscription acknowledgment (unsuback). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_unsuback_param_t;
+
+/**@brief Parameters for a publish message. */
+typedef struct
+{
+ mqtt_publish_message_t message; /**< Messages including topic, QoS and its payload (if any) to be published. */
+ uint16_t message_id; /**< Message id used for the publish message. Redundant for QoS 0. */
+ uint8_t dup_flag:1; /**< Duplicate flag. If 1, it indicates the message is being retransmitted. Has no meaning with QoS 0. */
+ uint8_t retain_flag:1; /**< retain flag. If 1, the message shall be stored persistently by the broker. */
+} mqtt_publish_param_t;
+
+/**@brief List of topics in a subscription request. */
+typedef struct
+{
+ mqtt_topic_t * p_list; /**< Array containing topics along with QoS for each. */
+ uint32_t list_count; /**< Number of topics in the subscription list */
+ uint16_t message_id; /**< Message id used to identify subscription request. */
+} mqtt_subscription_list_t;
+
+/**
+ * @brief Defines event parameters notified along with asynchronous events to the application.
+ * Currently, only MQTT_EVT_PUBLISH is accompanied with parameters.
+ */
+typedef union
+{
+ mqtt_connack_param_t connack; /**< Parameters accompanying MQTT_EVT_CONNACK event. */
+ mqtt_publish_param_t publish; /**< Parameters accompanying MQTT_EVT_PUBLISH event. */
+ mqtt_puback_param_t puback; /**< Parameters accompanying MQTT_EVT_PUBACK event. */
+ mqtt_pubrec_param_t pubrec; /**< Parameters accompanying MQTT_EVT_PUBREC event. */
+ mqtt_pubrel_param_t pubrel; /**< Parameters accompanying MQTT_EVT_PUBREL event. */
+ mqtt_pubcomp_param_t pubcomp; /**< Parameters accompanying MQTT_EVT_PUBCOMP event. */
+ mqtt_suback_param_t suback; /**< Parameters accompanying MQTT_EVT_SUBACK event. */
+ mqtt_suback_param_t unsuback; /**< Parameters accompanying MQTT_EVT_UNSUBACK event. */
+} mqtt_evt_param_t;
+
+/**@brief Defined MQTT asynchronous event notified to the application. */
+typedef struct
+{
+ mqtt_evt_id_t id; /**< Identifies the event. */
+ mqtt_evt_param_t param; /**< Contains parameters (if any) accompanying the event. */
+ uint32_t result; /**< Event result. For example, MQTT_EVT_CONNACK has a result code indicating success or failure code of connection procedure. */
+} mqtt_evt_t;
+
+/**@brief Asynchronous event notification callback registered by the application with
+ * the module to receive module events.
+ *
+ * @param[in] p_client Identifies the client for which the event is notified.
+ * @param[in] p_evet Event description along with result and associated parameters (if any).
+ */
+typedef void (*mqtt_evt_cb_t)(mqtt_client_t * const p_client, const mqtt_evt_t * p_evt);
+
+/**@brief MQTT Client definition to maintain information relevant to the client. */
+struct mqtt_client_t
+{
+ mqtt_client_id_t client_id; /**< Unique client identification to be used for the connection. Shall be zero length or NULL valued. */
+ mqtt_username_t * p_user_name; /**< User name (if any) to be used for the connection. NULL indicates no user name. */
+ mqtt_password_t * p_password; /**< Password (if any) to be used for the connection. Note that if password is provided, user name shall also be provided. NULL indicates no password. */
+ mqtt_topic_t * p_will_topic; /**< Will topic and QoS. Can be NULL. */
+ mqtt_will_message_t * p_will_message; /**< Will message. Can be NULL. Non NULL value valid only if will topic is not NULL. */
+ nrf_tls_key_settings_t * p_security_settings; /**< Provide security settings like PSK, own certificate etc here. The memory provided for the settings shall be resident. */
+ mqtt_evt_cb_t evt_cb; /**< Application callback registered with the module to get MQTT events. */
+ ipv6_addr_t broker_addr; /**< IPv6 Address of MQTT broker to which client connection is requested. */
+ uint16_t broker_port; /**< Broker's Port number. */
+ uint8_t poll_abort_counter; /**< Poll abort counter maintained for the TCP connection. */
+ uint8_t protocol_version; /**< MQTT protocol version. */
+ uint8_t transport_type; /**< Transport type selection for client instance. @ref mqtt_transport_type_t for possible values. MQTT_TRANSPORT_MAX is not a valid type.*/
+ uint8_t will_retain:1; /**< Will retain flag, 1 if will message shall be retained persistently. */
+ uint8_t clean_session:1; /**< Clean session flag indicating a fresh (1) or a retained session (0). Default is 1. */
+ iot_timer_time_in_ms_t last_activity; /**< Internal. Ticks maintaining wallcock in last activity that occurred. Needed for periodic PING. */
+ uint32_t state; /**< Internal. Shall not be touched by the application. Client's state in the connection. */
+ int socket_fd; /**< Internal. Shall not be touched by the application. TCP socket file descriptor. */
+ uint32_t tcp_id; /**< Internal. Shall not be touched by the application. TCP Connection Reference provided by the IP stack. */
+ uint8_t * p_packet; /**< Internal. Shall not be touched by the application. Used for creating MQTT packet in TX path. */
+ uint8_t * p_pending_packet; /**< Internal. Shall not be touched by the application. */
+ nrf_tls_instance_t tls_instance; /**< Internal. Shall not be touched by the application. TLS instance identifier. Valid only if transport is a secure one. */
+ uint32_t pending_packetlen; /**< Internal. Shall not be touched by the application. */
+};
+
+
+/**
+ * @brief Initializes the module.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Shall be called before initiating any procedures on the module.
+ * @note If module initialization fails, no module APIs shall be called.
+ */
+uint32_t mqtt_init(void);
+
+
+/**
+ * @brief Initializes the client instance.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ *
+ * @note Shall be called before connecting the client in order to avoid unexpected behavior
+ * caused by uninitialized parameters.
+ */
+void mqtt_client_init(mqtt_client_t * const p_client);
+
+
+/**
+ * @brief API to request new MQTT client connection.
+ *
+ * @param[out] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ *
+ * @note This memory is assumed to be resident until mqtt_disconnect is called.
+ * @note Any subsequent changes to parameters like broker address, user name, device id, etc. have
+ * no effect once MQTT connection is established.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ * @note If more than one simultaneous client connections are needed, please define
+ * MQTT_MAX_CLIENTS to override default of 1.
+ * @note Please define MQTT_KEEPALIVE time to override default of 1 minute.
+ * @note Please define MQTT_MAX_PACKET_LENGTH time to override default of 128 bytes.
+ * Ensure the system has enough memory for the new length per client.
+ */
+uint32_t mqtt_connect(mqtt_client_t * const p_client);
+
+
+/**
+ * @brief API to publish messages on topics.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Parameters to be used for the publish message.
+ * Shall not be NULL.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish(mqtt_client_t * const p_client,
+ mqtt_publish_param_t const * const p_param);
+
+
+/**
+ * @brief API used by subscribing client to send acknowledgment to the broker.
+ * Applicable only to QoS 1 publish messages.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Identifies message being acknowledged.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish_ack(mqtt_client_t * const p_client,
+ mqtt_puback_param_t const * const p_param);
+
+
+/**
+ * @brief API to send assured acknowledgment from a subscribing client to the broker.
+ * Should be called on reception of @ref MQTT_EVT_PUBLISH with QoS set to
+ * @ref MQTT_QoS_2_EACTLY_ONCE.
+ *
+ * @param[in] p_client Identifies client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Identifies message being acknowledged.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish_receive(mqtt_client_t * const p_client,
+ mqtt_pubrec_param_t const * const p_param);
+
+
+/**
+ * @brief API to used by publishing client to request releasing published data.
+ * Shall be used only after @ref MQTT_EVT_PUBREC is received and is valid
+ * only for QoS level @ref MQTT_QoS_2_EACTLY_ONCE.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Identifies message being released.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish_release(mqtt_client_t * const p_client,
+ mqtt_pubrel_param_t const * const p_param);
+
+
+/**
+ * @brief API used by subscribing clients to acknowledge reception of a released message.
+ * Should be used on reception @ref MQTT_EVT_PUBREL event.
+ *
+ * @param[in] p_client Identifies client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Identifies message being completed.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish_complete(mqtt_client_t * const p_client,
+ mqtt_pubcomp_param_t const * const p_param);
+
+
+/**
+ * @brief API to request subscribing to a topic on the connection.
+ *
+ * @param[in] p_client Identifies client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Subscription parameters. Shall not be NULL.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_subscribe(mqtt_client_t * const p_client,
+ mqtt_subscription_list_t const * const p_param);
+
+
+/**
+ * @brief API to request un-subscribe from a topic on the connection.
+ *
+ * @param[in] p_client Identifies client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Parameters describing topics being unsubscribed from.
+ * Shall not be NULL.
+ *
+ * @note QoS included in topic description is unused in this API.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_unsubscribe(mqtt_client_t * const p_client,
+ mqtt_subscription_list_t const * const p_param);
+
+
+/**
+ * @brief API to abort MQTT connection.
+ *
+ * @param[in] p_client Identifies client instance for which procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_abort(mqtt_client_t * const p_client);
+
+
+/**
+ * @brief API to disconnect MQTT connection.
+ *
+ * @param[in] p_client Identifies client instance for which procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_disconnect(mqtt_client_t * const p_client);
+
+
+/**
+ * @brief This API should be called periodically for the module to be able to keep the connection
+ * alive by sending Ping Requests if need be.
+ *
+ * @note Application shall ensure that the periodicity of calling this function makes it possible to
+ * respect the Keep Alive time agreed with the broker on connection.
+ * @ref mqtt_connect for details on Keep Alive time.
+ *
+ * @retval NRF_SUCCESS or an result code indicating reason for failure.
+ */
+uint32_t mqtt_live(void);
+
+
+/**
+ * @brief Wait for an incoming MQTT packet.
+ * The registered callback will be called with the packet payload.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] timeout Maximum interval (in milliseconds) to wait for a packet.
+ * If timeout is 0, the interval is indefinitely.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note This API is only supported when using the socket transport layer.
+ */
+uint32_t mqtt_input(mqtt_client_t * const p_client, uint32_t timeout);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MQTT_H_
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_decoder.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_decoder.c
new file mode 100644
index 0000000..4a95865
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_decoder.c
@@ -0,0 +1,262 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file mqtt_decoder.c
+ *
+ * @brief Decoder functions needs for decoding packets received from the broker.
+ */
+
+#include "mqtt_internal.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_dec
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_LENGTH_VALUE_MASK 0x7F
+#define MQTT_LENGTH_CONTINUATION_BIT 0x80
+#define MQTT_LENGTH_MULTIPLIER 0x80
+
+
+uint32_t unpack_uint8(uint8_t * p_val,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= SIZE_OF_UINT8)
+ {
+ // Create unit8 value.
+ (*p_val) = buffer[*p_offset];
+
+ // Increment offset.
+ (*p_offset) += SIZE_OF_UINT8;
+
+ // Indicate success.
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ MQTT_TRC("<< %s result:0x%08x val:0x%02x", __func__, err_code, (*p_val));
+ return err_code;
+}
+
+
+uint32_t unpack_uint16(uint16_t * p_val,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= SIZE_OF_UINT16)
+ {
+ // Create unit16 value.
+ (*p_val) = ((buffer[*p_offset] & 0x00FF) << 8); // MSB
+ (*p_val) |= (buffer[(*p_offset+1)] & 0x00FF); // LSB
+
+ // Increment offset.
+ (*p_offset) += SIZE_OF_UINT16;
+
+ // Indicate success.
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ MQTT_TRC("<< %s result:0x%08x val:0x%04x", __func__, err_code, (*p_val));
+
+ return err_code;
+}
+
+
+uint32_t unpack_utf8_str(mqtt_utf8_t * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint16_t utf8_strlen;
+ uint32_t err_code = unpack_uint16(&utf8_strlen, buffer_len, buffer, p_offset);
+
+ p_str->p_utf_str = NULL;
+ p_str->utf_strlen = 0;
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ buffer_len, buffer, (*p_offset), available_len);
+
+ if (utf8_strlen <= available_len)
+ {
+ // Zero length UTF8 strings permitted.
+ if (utf8_strlen)
+ {
+ // Point to right location in buffer.
+ p_str->p_utf_str = &buffer[(*p_offset)];
+ }
+
+ // Populate length field.
+ p_str->utf_strlen = utf8_strlen;
+
+ // Increment offset.
+ (*p_offset) += utf8_strlen;
+
+ // Indicate success
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ // Reset to original value.
+ (*p_offset) -= SIZE_OF_UINT16;
+
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+
+ MQTT_TRC("<< %s result:0x%08x utf8 len:0x%08x", __func__, err_code, p_str->utf_strlen);
+
+ return err_code;
+}
+
+
+uint32_t unpack_bin_str(mqtt_binstr_t * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t error_code = NRF_ERROR_DATA_SIZE;
+
+ MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x", __func__,
+ buffer_len, buffer, (*p_offset));
+
+ if (buffer_len >= (*p_offset))
+ {
+ p_str->p_bin_str = NULL;
+ p_str->bin_strlen = 0;
+
+ // Indicate success zero length binary strings are permitted.
+ error_code = NRF_SUCCESS;
+
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ if (available_len)
+ {
+ // Point to start of binary string.
+ p_str->p_bin_str = &buffer[(*p_offset)];
+ p_str->bin_strlen = available_len;
+
+ // Increment offset.
+ (*p_offset) += available_len;
+ }
+ }
+
+ MQTT_TRC("<< %s bin len:0x%08x", __func__, p_str->bin_strlen);
+
+ return error_code;
+}
+
+
+uint32_t packet_length_decode(uint8_t * p_buffer,
+ uint32_t buffer_len,
+ uint32_t * p_remaining_length,
+ uint32_t * p_offset)
+{
+ uint32_t index = (*p_offset);
+ uint32_t remaining_length = 0;
+ uint32_t multiplier = 1;
+
+ do
+ {
+ if (index >= buffer_len)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ remaining_length += (p_buffer[index] & MQTT_LENGTH_VALUE_MASK) * multiplier;
+ multiplier *= MQTT_LENGTH_MULTIPLIER;
+
+ } while ((p_buffer[index++] & MQTT_LENGTH_CONTINUATION_BIT) != 0);
+
+ *p_offset = index;
+ *p_remaining_length = remaining_length;
+
+ MQTT_TRC("%s: RL:0x%08x RLS:0x%08x", __func__, remaining_length, index);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_encoder.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_encoder.c
new file mode 100644
index 0000000..74476f2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_encoder.c
@@ -0,0 +1,457 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file mqtt_encoder.c
+ *
+ * @brief Encoding functions needed to create packet to be sent to the broker.
+ */
+
+
+#include "mqtt_internal.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_enc
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_3_1_0_PROTO_DESC_LEN 6
+#define MQTT_3_1_1_PROTO_DESC_LEN 4
+
+const uint8_t mqtt_3_1_0_proto_desc_str[MQTT_3_1_0_PROTO_DESC_LEN] = {'M', 'Q', 'I', 's', 'd', 'p'};
+const uint8_t mqtt_3_1_1_proto_desc_str[MQTT_3_1_1_PROTO_DESC_LEN] = {'M', 'Q', 'T', 'T'};
+
+const mqtt_utf8_t mqtt_3_1_0_proto_desc =
+{
+ .p_utf_str = (uint8_t *)&mqtt_3_1_0_proto_desc_str[0],
+ .utf_strlen = MQTT_3_1_0_PROTO_DESC_LEN
+};
+
+const mqtt_utf8_t mqtt_3_1_1_proto_desc =
+{
+ .p_utf_str = (uint8_t *)&mqtt_3_1_1_proto_desc_str[0],
+ .utf_strlen = MQTT_3_1_1_PROTO_DESC_LEN
+};
+
+uint32_t pack_uint8(uint8_t val,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ MQTT_TRC(">> %s V:%02x BL:%08x, B:%p, O:%08x", __func__,
+ val, buffer_len, buffer, (*p_offset));
+
+ // Pack value.
+ buffer[(*p_offset)] = val;
+
+ // Increment offset.
+ (*p_offset) += SIZE_OF_UINT8;
+
+ // Indicate success.
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+
+uint32_t pack_uint16(uint16_t val,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ MQTT_TRC(">> %s V:%04x BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ val, buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= SIZE_OF_UINT16)
+ {
+ // Pack value.
+ buffer[(*p_offset)] = MSB_16(val);
+ buffer[(*p_offset)+1] = LSB_16(val);
+
+ // Increment offset.
+ (*p_offset) += SIZE_OF_UINT16;
+
+ // Indicate success.
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ return err_code;
+}
+
+
+uint32_t pack_utf8_str(mqtt_utf8_t const * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+ err_code = NRF_ERROR_NO_MEM;
+
+ MQTT_TRC(">> %s USL:%08x BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ GET_UT8STR_BUFFER_SIZE(p_str), buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= GET_UT8STR_BUFFER_SIZE(p_str))
+ {
+ // Length followed by string.
+ err_code = pack_uint16(p_str->utf_strlen, buffer_len, buffer, p_offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ memcpy(&buffer[(*p_offset)], p_str->p_utf_str, p_str->utf_strlen);
+
+ (*p_offset) += p_str->utf_strlen;
+
+ err_code = NRF_SUCCESS;
+ }
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t pack_bin_str(mqtt_binstr_t const * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+ err_code = NRF_ERROR_NO_MEM;
+
+ MQTT_TRC(">> %s BSL:%08x BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ GET_BINSTR_BUFFER_SIZE(p_str), buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= GET_BINSTR_BUFFER_SIZE(p_str))
+ {
+ memcpy(&buffer[(*p_offset)], p_str->p_bin_str, p_str->bin_strlen);
+
+ (*p_offset) += p_str->bin_strlen;
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ return err_code;
+}
+
+
+void packet_length_encode(uint32_t remaining_length, uint8_t * p_buff, uint32_t * p_size)
+{
+ uint16_t index = 0;
+ const uint32_t offset = (*p_size);
+
+ MQTT_TRC(">> RL:0x%08x O:%08x P:%p", remaining_length, offset, p_buff);
+
+ do
+ {
+ if (p_buff != NULL)
+ {
+ p_buff[offset+index] = remaining_length % 0x80;
+ }
+
+ remaining_length /= 0x80;
+
+ if (remaining_length > 0)
+ {
+ if (p_buff != NULL)
+ {
+ p_buff[offset+index] |= 0x80;
+ }
+ }
+
+ index++;
+
+ } while (remaining_length > 0);
+
+ MQTT_TRC("<< RLS:0x%08x", index);
+
+ *p_size += index;
+}
+
+
+uint32_t mqtt_encode_fixed_header(uint8_t message_type, uint32_t length, uint8_t ** pp_packet)
+{
+ uint32_t packet_length = 0xFFFFFFFF;
+
+ if (MQTT_MAX_PAYLOAD_SIZE >= length)
+ {
+ uint32_t offset = 1;
+
+ MQTT_TRC("<< %s MT:0x%02x L:0x%08x", __func__, message_type, length);
+ packet_length_encode(length, NULL, &offset);
+
+ MQTT_TRC("Remaining length size = %02x", offset);
+
+ uint8_t * p_mqtt_header = ((*pp_packet) - offset);
+
+ // Reset offset.
+ offset = 0;
+ UNUSED_VARIABLE(pack_uint8(message_type, MQTT_MAX_PACKET_LENGTH, p_mqtt_header, &offset));
+ packet_length_encode(length, p_mqtt_header, &offset);
+
+ (* pp_packet) = p_mqtt_header;
+
+ packet_length = (length + offset);
+ }
+
+ return packet_length;
+}
+
+
+uint32_t zero_len_str_encode(uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const offset)
+{
+ return pack_uint16(0x0000, buffer_len, buffer, offset);
+}
+
+
+void connect_request_encode(const mqtt_client_t * p_client,
+ uint8_t ** pp_packet,
+ uint32_t * p_packet_length)
+{
+ uint32_t err_code;
+ uint32_t offset = 0;
+ uint8_t * p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+ uint8_t connect_flags = p_client->clean_session << 1; // Clean session always.
+
+ const mqtt_utf8_t * p_mqtt_proto_desc;
+ if (p_client->protocol_version == MQTT_VERSION_3_1_1)
+ {
+ p_mqtt_proto_desc = &mqtt_3_1_1_proto_desc;
+ }
+ else
+ {
+ p_mqtt_proto_desc = &mqtt_3_1_0_proto_desc;
+ }
+
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ // Pack protocol description.
+ MQTT_TRC("Encoding Protocol Description. Str:%s Size:%08x.",
+ p_mqtt_proto_desc->p_utf_str,
+ p_mqtt_proto_desc->utf_strlen);
+
+ err_code = pack_utf8_str(p_mqtt_proto_desc,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ MQTT_TRC("Encoding Protocol Version %02x.", p_client->protocol_version);
+ // Pack protocol version.
+ err_code = pack_uint8(p_client->protocol_version,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+
+ // Remember position of connect flag and
+ // leave one byte for it to be packed once we determine its value.
+ const uint32_t connect_flag_offset = MQTT_FIXED_HEADER_EXTENDED_SIZE + offset;
+ offset++;
+
+ if (err_code == NRF_SUCCESS)
+ {
+ MQTT_TRC("Encoding Keep Alive Time %04x.", MQTT_KEEPALIVE);
+ // Pack keep alive time.
+ err_code = pack_uint16(MQTT_KEEPALIVE,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ MQTT_TRC("Encoding Client Id. Str:%s Size:%08x.",
+ p_client->client_id.p_utf_str,
+ p_client->client_id.utf_strlen);
+
+ // Pack client id
+ err_code = pack_utf8_str(&p_client->client_id,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack will topic and QoS
+ if (p_client->p_will_topic != NULL)
+ {
+ MQTT_TRC("Encoding Will Topic. Str:%s Size:%08x.",
+ p_client->p_will_topic->topic.p_utf_str,
+ p_client->p_will_topic->topic.utf_strlen);
+
+ // Set Will topic in connect flags.
+ connect_flags |= MQTT_CONNECT_FLAG_WILL_TOPIC;
+
+ err_code = pack_utf8_str(&p_client->p_will_topic->topic,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // QoS is always 1 as of now.
+ connect_flags |= ((p_client->p_will_topic->qos & 0x03) << 3);
+ connect_flags |= p_client->will_retain << 5;
+
+ if (p_client->p_will_message != NULL)
+ {
+ MQTT_TRC("Encoding Will Message. Str:%s Size:%08x.",
+ p_client->p_will_message->p_utf_str,
+ p_client->p_will_message->utf_strlen);
+
+ err_code = pack_utf8_str(p_client->p_will_message,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ else
+ {
+ MQTT_TRC("Encoding Zero Length Will Message.");
+ err_code = zero_len_str_encode(MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack Username if any.
+ if (p_client->p_user_name != NULL)
+ {
+ connect_flags |= MQTT_CONNECT_FLAG_USERNAME;
+
+ MQTT_TRC("Encoding Username. Str:%s, Size:%08x.",
+ p_client->p_user_name->p_utf_str,
+ p_client->p_user_name->utf_strlen);
+
+ err_code = pack_utf8_str(p_client->p_user_name,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack Password if any.
+ if (p_client->p_password != NULL)
+ {
+ MQTT_TRC("Encoding Password. Str:%s Size:%08x.",
+ p_client->p_password->p_utf_str,
+ p_client->p_password->utf_strlen);
+
+ connect_flags |= MQTT_CONNECT_FLAG_PASSWORD;
+ err_code = pack_utf8_str(p_client->p_password,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack the connect flags.
+ p_client->p_packet[connect_flag_offset] = connect_flags;
+
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(MQTT_PKT_TYPE_CONNECT,
+ 0, // Duplicate flag not set.
+ 0, // QoS not set.
+ 0); // Retain not set.
+
+ offset = mqtt_encode_fixed_header(message_type,
+ offset,
+ &p_payload);
+
+ (*p_packet_length) = offset;
+ (*pp_packet) = p_payload;
+ }
+ else
+ {
+ (*p_packet_length) = 0;
+ (*pp_packet) = NULL;
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h
new file mode 100644
index 0000000..807b2f9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h
@@ -0,0 +1,446 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file mqtt_internal.h
+ *
+ * @brief Function and data structures internal to MQTT module.
+ */
+
+#ifndef MQTT_INTERNAL_H_
+#define MQTT_INTERNAL_H_
+
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "mqtt.h"
+#include "iot_errors.h"
+#include "nrf_tls.h"
+#include <stdint.h>
+#include <string.h>
+#include "nrf_error.h"
+#include "nrf_tls.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MQTT_MAX_CLIENTS
+#define MQTT_MAX_CLIENTS 1 /**< Maximum number of clients that can be managed by the module. */
+#endif //MQTT_MAX_CLIENTS
+
+#ifndef MQTT_KEEPALIVE
+#define MQTT_KEEPALIVE 60 /**< Keep alive time for MQTT (in seconds). Sending of Ping Requests to be keep the connection alive are governed by this value. */
+#endif //MQTT_KEEPALIVE
+
+#ifndef MQTT_MAX_PACKET_LENGTH
+#define MQTT_MAX_PACKET_LENGTH 128 /**< Maximum MQTT packet size that can be sent (including the fixed and variable header). */
+#endif // MQTT_MAX_PACKET_LENGTH
+
+#define MQTT_FIXED_HEADER_SIZE 2 /**< Fixed header minimum size. Remaining length size is 1 in this case. */
+#define MQTT_FIXED_HEADER_EXTENDED_SIZE 5 /**< Maximum size of the fixed header. Remaining length size is 4 in this case. */
+
+/**@brief MQTT Control Packet Types. */
+#define MQTT_PKT_TYPE_CONNECT 0x10
+#define MQTT_PKT_TYPE_CONNACK 0x20
+#define MQTT_PKT_TYPE_PUBLISH 0x30
+#define MQTT_PKT_TYPE_PUBACK 0x40
+#define MQTT_PKT_TYPE_PUBREC 0x50
+#define MQTT_PKT_TYPE_PUBREL 0x60
+#define MQTT_PKT_TYPE_PUBCOMP 0x70
+#define MQTT_PKT_TYPE_SUBSCRIBE 0x82 // QoS 1 for subscribe
+#define MQTT_PKT_TYPE_SUBACK 0x90
+#define MQTT_PKT_TYPE_UNSUBSCRIBE 0xA2
+#define MQTT_PKT_TYPE_UNSUBACK 0xB0
+#define MQTT_PKT_TYPE_PINGREQ 0xC0
+#define MQTT_PKT_TYPE_PINGRSP 0xD0
+#define MQTT_PKT_TYPE_DISCONNECT 0xE0
+
+
+/**@brief Masks for MQTT header flags. */
+#define MQTT_HEADER_DUP_MASK 0x08
+#define MQTT_HEADER_QOS_MASK 0x06
+#define MQTT_HEADER_RETAIN_MASK 0x01
+#define MQTT_HEADER_CONNACK_MASK 0x0F
+
+/**@brief Masks for MQTT header flags. */
+#define MQTT_CONNECT_FLAG_CLEAN_SESSION 0x02
+#define MQTT_CONNECT_FLAG_WILL_TOPIC 0x04
+#define MQTT_CONNECT_FLAG_WILL_RETAIN 0x20
+#define MQTT_CONNECT_FLAG_PASSWORD 0x40
+#define MQTT_CONNECT_FLAG_USERNAME 0x80
+
+/**@brief Size of mandatory header of MQTT Packet. */
+#define MQTT_PKT_HEADER_SIZE 2
+
+/**@brief */
+#define MQTT_MAX_PAYLOAD_SIZE 0x0FFFFFFF
+
+/**@brief Maximum size of variable and payload in the packet. */
+#define MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD (MQTT_MAX_PACKET_LENGTH - MQTT_FIXED_HEADER_EXTENDED_SIZE)
+
+/**@brief Defines size of uint8 in bytes. */
+#define SIZE_OF_UINT8 1
+
+/**@brief Defines size of uint8 in bytes. */
+#define SIZE_OF_UINT16 2
+
+/**@brief Computes total size needed to pack a UTF8 string. */
+#define GET_UT8STR_BUFFER_SIZE(STR) (SIZE_OF_UINT16 + (STR)->utf_strlen)
+
+/**@brief Computes total size needed to pack a binary stream. */
+#define GET_BINSTR_BUFFER_SIZE(STR) ((STR)->bin_strlen)
+
+/**@brief Unsubscribe packet size. */
+#define MQTT_UNSUBSCRIBE_PKT_SIZE 4
+
+/**@brief Sets MQTT Client's state with one indicated in 'STATE'. */
+#define MQTT_SET_STATE(CLIENT, STATE) ((CLIENT)->state |= (STATE))
+
+/**@brief Sets MQTT Client's state exclusive to 'STATE'. */
+#define MQTT_SET_STATE_EXCLUSIVE(CLIENT, STATE) ((CLIENT)->state = (STATE))
+
+/**@brief Verifies if MQTT Client's state is set with one indicated in 'STATE'. */
+#define MQTT_VERIFY_STATE(CLIENT, STATE) ((CLIENT)->state & (STATE))
+
+/**@brief Reset 'STATE' in MQTT Client's state. */
+#define MQTT_RESET_STATE(CLIENT, STATE) ((CLIENT)->state &= ~(STATE))
+
+/**@brief Initialize MQTT Client's state. */
+#define MQTT_STATE_INIT(CLIENT) (CLIENT)->state = MQTT_STATE_IDLE
+
+/**@brief Computes the first byte of MQTT message header based on message type, duplication flag,
+ * QoS and the retain flag.
+ */
+#define MQTT_MESSAGES_OPTIONS(TYPE, DUP, QOS, RETAIN) \
+ (((TYPE) & 0xF0) | \
+ (((DUP) << 3) & 0x08) | \
+ (((QOS) << 1) & 0x06) | \
+ ((RETAIN) & 0x01))
+
+
+#define MQTT_EVT_FLAG_NONE 0x00000000
+#define MQTT_EVT_FLAG_INSTANCE_RESET 0x00000001
+
+
+/**
+ * @defgroup iot_mqtt_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case the need to use an alternative architecture arises.
+ * @{
+ */
+#define MQTT_MUTEX_LOCK() SDK_MUTEX_LOCK(m_mqtt_mutex) /**< Lock module using mutex */
+#define MQTT_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_mqtt_mutex) /**< Unlock module using mutex */
+
+/** @} */
+
+/**@brief Check if the input pointer is NULL, if so it returns NRF_ERROR_NULL.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_MQTT_ERR_BASE); \
+ }
+
+#define NULL_PARAM_CHECK_VOID(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return; \
+ }
+
+/**@brief MQTT States. */
+typedef enum
+{
+ MQTT_STATE_IDLE = 0x00000000, /**< Idle state, implying the client entry in the table is unused/free. */
+ MQTT_STATE_TCP_CONNECTING = 0x00000001, /**< TCP Connection has been requested, awaiting result of the request. */
+ MQTT_STATE_TCP_CONNECTED = 0x00000002, /**< TCP Connection successfully established. */
+ MQTT_STATE_CONNECTED = 0x00000004, /**< MQTT Connection successful. */
+ MQTT_STATE_PENDING_WRITE = 0x00000008, /**< State that indicates write callback is awaited for an issued request. */
+ MQTT_STATE_DISCONNECTING = 0x00000010 /**< TCP Disconnect has been requested, awaiting result of the request. */
+} mqtt_state_t;
+
+
+/**@brief Packs unsigned 8 bit value to the buffer at the offset requested.
+ *
+ * @param[in] val Value to be packed.
+ * @param[in] buffer_len Total size of the buffer on which value is to be packed.
+ * This shall not be zero.
+ * @param[out] p_buffer Buffer where the value is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the value is to be packed. If the procedure
+ * is successful, the offset is incremented to point to the next write/pack
+ * location on the buffer.
+ *
+ * @retval NRF_SUCCESS if procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t pack_uint8(uint8_t val,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Packs unsigned 16 bit value to the buffer at the offset requested.
+ *
+ * @param[in] val Value to be packed.
+ * @param[in] buffer_len Total size of the buffer on which value is to be packed.
+ * This shall not be zero.
+ * @param[out] p_buffer Buffer where the value is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the value is to be packed. If the procedure
+ * is successful, the offset is incremented to point to the next write/pack
+ * location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length minus
+ * the size of unsigned 16 bit integer.
+ */
+uint32_t pack_uint16(uint16_t val,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Packs utf8 string to the buffer at the offset requested.
+ *
+ * @param[in] p_str UTF-8 string and its length to be packed.
+ * @param[in] buffer_len Total size of the buffer on which string is to be packed.
+ * This shall not be zero.
+ * @param[out] p_buffer Buffer where the string is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the string is to be packed. If the procedure
+ * is successful, the offset is incremented to point to the next write/pack
+ * location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length minus
+ * the size of unsigned 16 bit integer.
+ * @retval NRF_ERROR_NO_MEM if there is no room on the buffer to pack the string.
+ */
+uint32_t pack_utf8_str(mqtt_utf8_t const * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Packs binary string to the buffer at the offset requested.
+ *
+ * @param[in] p_str Binary string and its length to be packed.
+ * @param[in] buffer_len Total size of the buffer on which string is to be packed.
+ * @param[in] p_buffer Buffer where the string is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the string is to be packed. If the procedure
+ * is successful, the offset is incremented to point to the next write/pack
+ * location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ * @retval NRF_ERROR_NO_MEM if there is no room on the buffer to pack the string.
+ */
+uint32_t pack_bin_str(mqtt_binstr_t const * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Unpacks unsigned 8 bit value from the buffer from the offset requested.
+ *
+ * @param[out] p_val Memory where the value is to be unpacked.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer from which the value is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t unpack_uint8(uint8_t * p_val,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+/**@brief Unpacks unsigned 16 bit value from the buffer from the offset requested.
+ *
+ * @param[out] p_val Memory where the value is to be unpacked.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer from which the value is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t unpack_uint16(uint16_t * p_val,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Unpacks unsigned 16 bit value from the buffer from the offset requested.
+ *
+ * @param[out] p_str Memory where the utf8 string and its value are to be unpacked.
+ * No copy of data is performed for the string.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer from which the string is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t unpack_utf8_str(mqtt_utf8_t * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Unpacks binary string from the buffer from the offset requested.
+ *
+ * @param[out] p_str Memory where the binary string and its length are to be unpacked.
+ * No copy of data is performed for the string.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer where the value is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t unpack_bin_str(mqtt_binstr_t * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Unpacks utf8 string from the buffer from the offset requested.
+ *
+ * @param[out] p_str Memory where the utf8 string and its length are to be unpacked.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer where the value is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t zero_len_str_encode(uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Computes and encodes length for the MQTT fixed header.
+ *
+ * @note The remaining length is not packed as a fixed unsigned 32 bit integer. Instead it is packed
+ * on algorithm below:
+ *
+ * @code
+ * do
+ * encodedByte = X MOD 128
+ * X = X DIV 128
+ * // if there are more data to encode, set the top bit of this byte
+ * if ( X > 0 )
+ * encodedByte = encodedByte OR 128
+ * endif
+ * 'output' encodedByte
+ * while ( X > 0 )
+ * @endcode
+ *
+ * @param[in] remaining_length Length of variable header and payload in the MQTT message.
+ * @param[out] p_buffer Buffer where the length is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the length is to be packed.
+ */
+void packet_length_encode(uint32_t remaining_length, uint8_t * p_buffer, uint32_t * p_offset);
+
+
+/**@brief Decode MQTT Packet Length in the MQTT fixed header.
+ *
+ * @param[in] p_buffer Buffer where the length is to be decoded.
+ * @param[in] buffer_len Length of p_buffer
+ * @param[out] p_remaining_length Length of variable header and payload in the MQTT message.
+ * @param[inout] p_offset Offset on the buffer from where the length is to be unpacked.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t packet_length_decode(uint8_t * p_buffer,
+ uint32_t buffer_len,
+ uint32_t * p_remaining_length,
+ uint32_t * p_offset);
+
+
+/**@brief Encodes fixed header for the MQTT message and provides pointer to start of the header.
+ *
+ * @param[in] message_type Message type containing packet type and the flags.
+ * Use @ref MQTT_MESSAGES_OPTIONS to construct the message_type.
+ * @param[in] length Buffer where the message payload along with variable header.
+ * @param[inout] pp_packet Pointer to the MQTT message variable header and payload.
+ * The 5 bytes before the start of the message are assumed by the
+ * routine to be available to pack the fixed header. However, since
+ * the fixed header length is variable length, the pointer to the
+ * start of the MQTT message along with encoded fixed header is
+ * supplied as output parameter if the procedure was successful.
+ *
+ * @retval 0xFFFFFFFF if the procedure failed, else length of total MQTT message along with the
+ * fixed header.
+ */
+uint32_t mqtt_encode_fixed_header(uint8_t message_type, uint32_t length, uint8_t ** pp_packet);
+
+
+/**@brief Constructs/encodes connect packet.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * All information required for creating the packet like client id,
+ * clean session flag, retain session flag etc are assumed to be
+ * populated for the client instance when this procedure is requested.
+ * @param[out] pp_packet Pointer to the MQTT connect message.
+ * @param[out] p_packet_length Length of the connect request.
+ *
+ * @retval 0xFFFFFFFF if the procedure failed, else length of total MQTT message along with the
+ * fixed header.
+ */
+void connect_request_encode(const mqtt_client_t * p_client,
+ uint8_t ** pp_packet,
+ uint32_t * p_packet_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MQTT_INTERNAL_H_
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.c
new file mode 100644
index 0000000..10b0ae4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.c
@@ -0,0 +1,313 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file mqtt_rx.c
+ *
+ * @brief Handles packet receive on transport TCP or TLS.
+ */
+#include "mqtt_internal.h"
+
+void event_notify(mqtt_client_t * const p_client, const mqtt_evt_t * p_evt, uint32_t flags);
+void disconnect_event_notify(mqtt_client_t * p_client, uint32_t result);
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_rx
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+static uint32_t mqtt_handle_packet(mqtt_client_t * p_client,
+ uint8_t * p_data,
+ uint32_t datalen,
+ uint32_t offset)
+{
+ mqtt_evt_t evt;
+ uint32_t err_code = NRF_SUCCESS;
+ bool notify_event = true;
+
+ // Success by default, overwritten in special cases.
+ evt.result = NRF_SUCCESS;
+
+ switch (p_data[0] & 0xF0)
+ {
+ case MQTT_PKT_TYPE_CONNACK:
+ {
+ MQTT_TRC("[%p]: Received MQTT_PKT_TYPE_CONNACK!", p_client);
+
+ if (p_client->protocol_version == MQTT_VERSION_3_1_1)
+ {
+ evt.param.connack.session_present_flag = p_data[2] & MQTT_HEADER_CONNACK_MASK;
+
+ MQTT_TRC("[%p]: session_present_flag: %d",
+ p_client,
+ evt.param.connack.session_present_flag);
+ }
+
+ evt.param.connack.return_code =
+ (mqtt_conn_return_code_t)(p_data[3] & MQTT_HEADER_CONNACK_MASK);
+
+ MQTT_TRC("[%p]: return_code: %d",
+ p_client,
+ evt.param.connack.return_code);
+
+ if (evt.param.connack.return_code == MQTT_CONNECTION_ACCEPTED)
+ {
+ // Set state.
+ MQTT_SET_STATE(p_client, MQTT_STATE_CONNECTED);
+ }
+
+ evt.result = evt.param.connack.return_code;
+ evt.id = MQTT_EVT_CONNACK;
+
+ break;
+ }
+ case MQTT_PKT_TYPE_PUBLISH:
+ {
+ evt.param.publish.dup_flag = p_data[0] & MQTT_HEADER_DUP_MASK;
+ evt.param.publish.retain_flag = p_data[0] & MQTT_HEADER_RETAIN_MASK;
+ evt.param.publish.message.topic.qos = ((p_data[0] & MQTT_HEADER_QOS_MASK) >> 1);
+
+ MQTT_TRC("[CID %p]: Received MQTT_PKT_TYPE_PUBLISH, QoS:%02x",
+ p_client, evt.param.publish.message.topic.qos);
+
+ err_code = unpack_utf8_str(&evt.param.publish.message.topic.topic,
+ datalen,
+ p_data,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (evt.param.publish.message.topic.qos)
+ {
+ err_code = unpack_uint16(&evt.param.publish.message_id,
+ datalen,
+ p_data,
+ &offset);
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = unpack_bin_str(&evt.param.publish.message.payload,
+ datalen,
+ p_data,
+ &offset);
+
+ // Zero length publish messages are permitted.
+ if (err_code != NRF_SUCCESS)
+ {
+ evt.param.publish.message.payload.p_bin_str = NULL;
+ evt.param.publish.message.payload.bin_strlen = 0;
+ }
+ }
+
+ MQTT_TRC("PUB message len %08x, topic len %08x",
+ evt.param.publish.message.payload.bin_strlen,
+ evt.param.publish.message.topic.topic.utf_strlen);
+
+ evt.id = MQTT_EVT_PUBLISH;
+ evt.result = err_code;
+
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&p_client->last_activity));
+
+ break;
+ }
+
+ case MQTT_PKT_TYPE_PUBACK:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PUBACK!");
+
+ evt.id = MQTT_EVT_PUBACK;
+ err_code = unpack_uint16(&evt.param.puback.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+
+ case MQTT_PKT_TYPE_PUBREC:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PUBREC!");
+
+ evt.id = MQTT_EVT_PUBREC;
+ err_code = unpack_uint16(&evt.param.pubrec.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_PUBREL:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PUBREL!");
+
+ evt.id = MQTT_EVT_PUBREL;
+ err_code = unpack_uint16(&evt.param.pubrel.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_PUBCOMP:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PUBCOMP!");
+
+ evt.id = MQTT_EVT_PUBCOMP;
+ err_code = unpack_uint16(&evt.param.pubcomp.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_SUBACK:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_SUBACK!");
+
+ evt.id = MQTT_EVT_SUBACK;
+ err_code = unpack_uint16(&evt.param.pubrec.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_UNSUBACK:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_UNSUBACK!");
+
+ evt.id = MQTT_EVT_UNSUBACK;
+ err_code = unpack_uint16(&evt.param.pubrec.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_PINGRSP:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PINGRSP!");
+
+ // No notification of Ping response to application.
+ notify_event = false;
+ break;
+ }
+ default:
+ {
+ // Nothing to notify.
+ notify_event = false;
+ break;
+ }
+ }
+
+ if (notify_event == true)
+ {
+ event_notify(p_client, &evt, MQTT_EVT_FLAG_NONE);
+ }
+
+ return err_code;
+}
+
+
+uint32_t mqtt_handle_rx_data(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t offset = 0;
+
+ while (offset < datalen)
+ {
+ uint32_t start = offset;
+ uint32_t remaining_length = 0;
+
+ offset = 1; // Skip first byte to offset MQTT packet length.
+ err_code = packet_length_decode(p_data + start,
+ datalen - start,
+ &remaining_length,
+ &offset);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ uint32_t packet_length = offset + remaining_length;
+
+ if (start + packet_length > datalen)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ err_code = mqtt_handle_packet(p_client,
+ p_data + start,
+ packet_length,
+ offset);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ offset = start + packet_length;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.h
new file mode 100644
index 0000000..7372f0c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.h
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file mqtt_rx.h
+ *
+ * @brief Internal methods to submit received packet.
+ */
+
+#ifndef MQTT_RX_H_
+#define MQTT_RX_H_
+
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "mqtt.h"
+#include "iot_errors.h"
+#include "nrf_tls.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Handles MQTT messages received from the peer. For TLS, this routine is evoked to handle
+ * decrypted application data. For TCP, this routine is evoked to handle TCP data.
+ *
+ * @param[in] p_client Identifies the client for which the data was received.
+ * @param[in] p_data MQTT data received.
+ * @param[inout] datalen Length of data received.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful, else an error code indicating the reason
+ * for failure.
+ */
+uint32_t mqtt_handle_rx_data(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MQTT_RX_H_
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.c
new file mode 100644
index 0000000..5d0fbd8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.c
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file mqtt_transport.c
+ *
+ * @brief Internal functions to handle transport in MQTT module.
+ */
+
+
+#include "mqtt_transport.h"
+
+
+/**< Function pointer array for TCP/TLS transport handlers. */
+const transport_procedure_t transport_fn[MQTT_TRANSPORT_MAX] =
+{
+ {
+ mqtt_client_tcp_connect,
+ mqtt_client_tcp_write,
+ mqtt_client_tcp_read,
+ mqtt_client_tcp_disconnect
+ },
+ {
+ mqtt_client_tls_connect,
+ mqtt_client_tls_write,
+ mqtt_client_tls_read,
+ mqtt_client_tls_disconnect
+ }
+};
+
+
+uint32_t mqtt_transport_connect(mqtt_client_t * p_client)
+{
+ return transport_fn[p_client->transport_type].connect(p_client);
+}
+
+
+uint32_t mqtt_transport_write(mqtt_client_t * p_client, uint8_t const * p_data, uint32_t datalen)
+{
+ return transport_fn[p_client->transport_type].write(p_client, p_data, datalen);
+}
+
+
+uint32_t mqtt_transport_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen)
+{
+ return transport_fn[p_client->transport_type].read(p_client, p_data, datalen);
+}
+
+
+uint32_t mqtt_transport_disconnect(mqtt_client_t * p_client)
+{
+ return transport_fn[p_client->transport_type].disconnect(p_client);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.h
new file mode 100644
index 0000000..da588a7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.h
@@ -0,0 +1,233 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file mqtt_transport.h
+ *
+ * @brief Internal functions to handle transport in MQTT module.
+ */
+
+#ifndef MQTT_TRANSPORT_H_
+#define MQTT_TRANSPORT_H_
+
+#include "mqtt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Transport for handling transport connect procedure. */
+typedef uint32_t (*transport_connect_handler_t)(mqtt_client_t * p_client);
+
+/**@brief Transport write handler. */
+typedef uint32_t (*transport_write_handler_t)(mqtt_client_t * p_client, uint8_t const * data, uint32_t datalen);
+
+/**@brief Transport read handler. */
+typedef uint32_t (*transport_read_handler_t)(mqtt_client_t * p_client, uint8_t * data, uint32_t datalen);
+
+/**@brief Transport disconnect handler. */
+typedef uint32_t (*transport_disconnect_handler_t)(mqtt_client_t * p_client);
+
+/**@brief Transport procedure handlers. */
+typedef struct
+{
+ transport_connect_handler_t connect; /**< Transport connect handler. Handles TCP connection callback based on type of transport.*/
+ transport_write_handler_t write; /**< Transport write handler. Handles transport write based on type of transport. */
+ transport_read_handler_t read; /**< Transport read handler. Handles transport read based on type of transport. */
+ transport_disconnect_handler_t disconnect; /**< Transport disconnect handler. Handles transport disconnection based on type of transport. */
+} transport_procedure_t;
+
+
+/**@brief Handles TCP Connection Complete for configured transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_transport_connect(mqtt_client_t * p_client);
+
+
+/**@brief Handles write requests on configured transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Data to be written on the transport.
+ * @param[in] datalen Length of data to be written on the transport.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_transport_write(mqtt_client_t * p_client, uint8_t const * p_data, uint32_t datalen);
+
+
+/**@brief Handles read requests on configured transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Pointer where read data is to be fetched.
+ * @param[in] datalen Size of memory provided for the operation.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_transport_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen);
+
+
+/**@brief Handles transport disconnection requests on configured transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_transport_disconnect(mqtt_client_t * p_client);
+
+
+/**@brief Initiates TCP Connection.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t tcp_request_connection(mqtt_client_t * p_client);
+
+
+/**
+ * @brief Wait for an incoming MQTT packet.
+ * The registered callback will be called with the packet payload.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] timeout Maximum interval (in milliseconds) to wait for a packet.
+ * If timeout is 0, the interval is indefinitely.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t tcp_receive_packet(mqtt_client_t * p_client, uint32_t timeout);
+
+
+/**@brief Handles TCP Connection Complete for TCP(non-secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tcp_connect(mqtt_client_t * p_client);
+
+
+/**@brief Handles write requests on TCP(non-secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Data to be written on the transport.
+ * @param[in] datalen Length of data to be written on the transport.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tcp_write(mqtt_client_t * p_client, uint8_t const * p_data, uint32_t datalen);
+
+
+/**@brief Handles read requests on TCP(non-secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Pointer where read data is to be fetched.
+ * @param[in] datalen Size of memory provided for the operation.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tcp_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen);
+
+
+/**@brief Handles transport disconnection requests on TCP(non-secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tcp_disconnect(mqtt_client_t * p_client);
+
+
+/**@brief Handles read requests on TLS(secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Pointer where read data is to be fetched.
+ * @param[in] datalen Size of memory provided for the operation.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tls_connect(mqtt_client_t * p_client);
+
+
+/**@brief Handles write requests on TLS(secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Data to be written on the transport.
+ * @param[in] datalen Length of data to be written on the transport.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tls_write(mqtt_client_t * p_client, uint8_t const * p_data, uint32_t datalen);
+
+
+/**@brief Handles read requests on TLS(secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Pointer where read data is to be fetched.
+ * @param[in] datalen Size of memory provided for the operation.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tls_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen);
+
+
+/**@brief Handles transport disconnection requests on TLS(secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tls_disconnect(mqtt_client_t * p_client);
+
+
+/**@brief Aborts TCP connection.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+void mqtt_client_tcp_abort(mqtt_client_t * p_client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MQTT_TRANSPORT_H_
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_lwip.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_lwip.c
new file mode 100644
index 0000000..b609cd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_lwip.c
@@ -0,0 +1,349 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file
+ *
+ * @brief MQTT Client Implementation over LwIP Stack port on nRF.
+ *
+ * This file contains the source code for MQTT Protocol over LwIP Stack for a nRF device.
+ * The implementation is limited to MQTT Client role only.
+ */
+
+
+#include "mqtt_transport.h"
+#include "mqtt_internal.h"
+#include "mqtt_rx.h"
+
+#include "lwip/opt.h"
+#include "lwip/stats.h"
+#include "lwip/sys.h"
+#include "lwip/pbuf.h"
+/*lint -save -e607 */
+#include "lwip/tcp.h"
+/*lint -restore -e607 */
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_lwip
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+void disconnect_event_notify(mqtt_client_t * p_client, uint32_t result);
+
+
+/**@brief Close TCP connection and clean up client instance.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ */
+static void tcp_close_connection(const mqtt_client_t * p_client)
+{
+ tcp_arg((struct tcp_pcb *)p_client->tcp_id, NULL);
+ UNUSED_VARIABLE(tcp_output((struct tcp_pcb *)p_client->tcp_id));
+ tcp_recv((struct tcp_pcb *)p_client->tcp_id, NULL);
+
+ UNUSED_VARIABLE(tcp_close((struct tcp_pcb *)p_client->tcp_id));
+}
+
+
+err_t tcp_write_complete_cb(void *p_arg, struct tcp_pcb *ttcp_id, u16_t len)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t *p_client = (mqtt_client_t *)(p_arg);
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_DISCONNECTING))
+ {
+ MQTT_TRC("[%p]: Closing TCP connection.", p_client);
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, NRF_SUCCESS);
+ }
+ else
+ {
+ MQTT_RESET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+ MQTT_TRC("[%p]: TCP Write Complete.", p_client);
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t mqtt_client_tcp_write(mqtt_client_t * p_client, uint8_t const * data, uint32_t datalen)
+{
+ uint32_t retval = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ retval = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED))
+ {
+ tcp_sent((struct tcp_pcb *)p_client->tcp_id, tcp_write_complete_cb);
+
+ MQTT_MUTEX_UNLOCK ();
+
+ uint32_t err = tcp_write((struct tcp_pcb *)p_client->tcp_id,
+ data,
+ datalen,
+ TCP_WRITE_FLAG_COPY);
+
+ MQTT_MUTEX_LOCK ();
+
+ if (err == ERR_OK)
+ {
+ MQTT_SET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&p_client->last_activity));
+ MQTT_TRC("[%p]: TCP Write in Progress, length 0x%08x.", p_client, datalen);
+ retval = NRF_SUCCESS;
+ }
+ else
+ {
+ MQTT_TRC("[%p]: TCP write failed, err = %d", err);
+ retval = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ }
+
+ return retval;
+}
+
+
+uint32_t mqtt_client_tcp_read(mqtt_client_t * p_id, uint8_t * p_data, uint32_t datalen)
+{
+ return mqtt_handle_rx_data( p_id, p_data, datalen);
+}
+
+
+/**@brief Callback registered with TCP to handle incoming data on the connection. */
+err_t recv_callback(void * p_arg, struct tcp_pcb * p_tcp_id, struct pbuf * p_buffer, err_t err)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t * p_client = (mqtt_client_t *)(p_arg);
+
+ MQTT_TRC(">> %s, result 0x%08x, buffer %p", __func__, err, p_buffer);
+
+ if (err == ERR_OK && p_buffer != NULL)
+ {
+ MQTT_TRC(">> Packet buffer length 0x%08x ", p_buffer->tot_len);
+ tcp_recved(p_tcp_id, p_buffer->tot_len);
+ UNUSED_VARIABLE(mqtt_transport_read(p_client, p_buffer->payload, p_buffer->tot_len));
+ }
+ else
+ {
+ MQTT_TRC("Error receiving data, closing connection");
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, MQTT_ERR_TRANSPORT_CLOSED);
+ }
+
+ UNUSED_VARIABLE(pbuf_free(p_buffer));
+
+ MQTT_MUTEX_UNLOCK();
+
+ return ERR_OK;
+}
+
+
+uint32_t mqtt_client_tcp_connect(mqtt_client_t * p_client)
+{
+ connect_request_encode(p_client, &p_client->p_pending_packet, &p_client->pending_packetlen);
+
+ // Send MQTT identification message to broker.
+ uint32_t err = mqtt_client_tcp_write(p_client, p_client->p_pending_packet,
+ p_client->pending_packetlen);
+ if (err != ERR_OK)
+ {
+ mqtt_client_tcp_abort(p_client);
+ }
+ else
+ {
+ p_client->p_pending_packet = NULL;
+ p_client->pending_packetlen = 0;
+ }
+
+ return err;
+}
+
+
+/**@brief TCP Connection Callback. MQTT Connection */
+err_t tcp_connection_callback(void * p_arg, struct tcp_pcb * p_tcp_id, err_t err)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t * p_client = (mqtt_client_t *)p_arg;
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTING) &&
+ (err == ERR_OK))
+ {
+ MQTT_SET_STATE(p_client, MQTT_STATE_TCP_CONNECTED);
+
+ // Register callback.
+ tcp_recv(p_tcp_id, recv_callback);
+ uint32_t err_code = mqtt_transport_connect(p_client);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ MQTT_TRC("Transport connect handler returned %08x", err_code);
+ disconnect_event_notify(p_client, MQTT_CONNECTION_FAILED);
+ }
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err;
+}
+
+
+void mqtt_client_tcp_abort(mqtt_client_t * p_client)
+{
+ tcp_abort((struct tcp_pcb *)p_client->tcp_id);
+ disconnect_event_notify(p_client, MQTT_ERR_TCP_PROC_FAILED);
+ MQTT_STATE_INIT(p_client);
+}
+
+
+void tcp_error_handler(void * p_arg, err_t err)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t * p_client = (mqtt_client_t *)(p_arg);
+
+ disconnect_event_notify(p_client, err);
+
+ MQTT_STATE_INIT(p_client);
+
+ MQTT_MUTEX_UNLOCK();
+}
+
+
+err_t tcp_connection_poll(void * p_arg, struct tcp_pcb * p_tcp_id)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t * p_client = (mqtt_client_t *)(p_arg);
+
+ p_client->poll_abort_counter++;
+
+ MQTT_MUTEX_UNLOCK();
+
+ return ERR_OK;
+}
+
+
+uint32_t tcp_request_connection(mqtt_client_t * p_client)
+{
+ p_client->poll_abort_counter = 0;
+ p_client->tcp_id = (uint32_t)tcp_new_ip6();
+
+ err_t err = tcp_connect((struct tcp_pcb *)p_client->tcp_id,
+ (ip_addr_t *)&p_client->broker_addr,
+ p_client->broker_port,
+ tcp_connection_callback);
+
+ if (err != ERR_OK)
+ {
+ UNUSED_VARIABLE(mqtt_abort(p_client));
+ }
+ else
+ {
+ tcp_arg((struct tcp_pcb *)p_client->tcp_id, p_client);
+ tcp_err((struct tcp_pcb *)p_client->tcp_id, tcp_error_handler);
+ tcp_poll((struct tcp_pcb *)p_client->tcp_id, tcp_connection_poll, 10);
+ tcp_accept((struct tcp_pcb *)p_client->tcp_id, tcp_connection_callback);
+
+ MQTT_SET_STATE(p_client, MQTT_STATE_TCP_CONNECTING);
+ }
+
+ return err;
+}
+
+
+uint32_t mqtt_client_tcp_disconnect(mqtt_client_t * p_client)
+{
+ uint32_t err_code = NRF_ERROR_INVALID_STATE;
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ const uint8_t packet[] = {MQTT_PKT_TYPE_DISCONNECT, 0x00};
+ UNUSED_VARIABLE(tcp_write((struct tcp_pcb *)p_client->tcp_id,
+ (void *)packet,
+ sizeof(packet),
+ 1));
+
+ tcp_close_connection(p_client);
+ err_code = NRF_SUCCESS;
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED))
+ {
+ tcp_close_connection(p_client);
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+
+uint32_t tcp_receive_packet(mqtt_client_t * p_client, uint32_t timeout)
+{
+ // This is not used in the lwip transport implementation.
+ return NRF_ERROR_NOT_SUPPORTED | IOT_MQTT_ERR_BASE;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_socket.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_socket.c
new file mode 100644
index 0000000..27bf6b6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_socket.c
@@ -0,0 +1,319 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file
+ *
+ * @brief MQTT Client Implementation over BSD Socket API on nRF.
+ *
+ * This file contains the source code for MQTT Protocol over BSD Socket API for a nRF device.
+ * The implementation is limited to MQTT Client role only.
+ */
+
+
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "mem_manager.h"
+#include "mqtt_transport.h"
+#include "mqtt_internal.h"
+#include "mqtt_rx.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_soc
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+void disconnect_event_notify(mqtt_client_t * p_client, uint32_t result);
+
+
+/**@brief Close TCP connection and clean up client instance.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ */
+static void tcp_close_connection(const mqtt_client_t * p_client)
+{
+ MQTT_TRC("Closing socket %d", p_client->socket_fd);
+ UNUSED_VARIABLE(close(p_client->socket_fd));
+}
+
+
+uint32_t mqtt_client_tcp_write(mqtt_client_t * p_client, uint8_t const * data, uint32_t datalen)
+{
+ uint32_t err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED))
+ {
+ MQTT_TRC("[%p]: TCP writing %d bytes.", p_client, datalen);
+ MQTT_SET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ MQTT_MUTEX_UNLOCK();
+
+ ssize_t nbytes = send(p_client->socket_fd, data, datalen, 0);
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_RESET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ if (nbytes == datalen)
+ {
+ MQTT_TRC("[%p]: TCP write complete.", p_client);
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&p_client->last_activity));
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ MQTT_TRC("TCP write failed, errno = %d, closing connection", errno);
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, MQTT_ERR_TRANSPORT_CLOSED);
+ err_code = (NRF_ERROR_INTERNAL | IOT_MQTT_ERR_BASE);
+ }
+ }
+ else
+ {
+ err_code = MQTT_ERR_NOT_CONNECTED;
+ }
+
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tcp_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen)
+{
+ return mqtt_handle_rx_data(p_client, p_data, datalen);
+}
+
+
+uint32_t mqtt_client_tcp_connect(mqtt_client_t * p_client)
+{
+ uint32_t err_code;
+
+ connect_request_encode(p_client, &p_client->p_pending_packet, &p_client->pending_packetlen);
+
+ // Send MQTT identification message to broker.
+ MQTT_SET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ MQTT_MUTEX_UNLOCK();
+
+ ssize_t nbytes = send(p_client->socket_fd,
+ p_client->p_pending_packet,
+ p_client->pending_packetlen,
+ 0);
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_RESET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ if (nbytes == p_client->pending_packetlen)
+ {
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&p_client->last_activity));
+ p_client->p_pending_packet = NULL;
+ p_client->pending_packetlen = 0;
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ mqtt_client_tcp_abort(p_client);
+ err_code = (NRF_ERROR_INTERNAL | IOT_MQTT_ERR_BASE);
+ }
+
+ return err_code;
+}
+
+
+void mqtt_client_tcp_abort(mqtt_client_t * p_client)
+{
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, MQTT_ERR_TCP_PROC_FAILED);
+}
+
+
+uint32_t tcp_receive_packet(mqtt_client_t * p_client, uint32_t timeout)
+{
+ if (timeout != 0)
+ {
+ // TODO: Implement support for timeout.
+ return NRF_ERROR_NOT_SUPPORTED | IOT_MQTT_ERR_BASE;
+ }
+
+ uint8_t * p_packet = nrf_malloc(MQTT_MAX_PACKET_LENGTH);
+ if (p_packet == NULL)
+ {
+ return NRF_ERROR_NO_MEM | IOT_MQTT_ERR_BASE;
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ ssize_t p_len = recv(p_client->socket_fd, p_packet, MQTT_MAX_PACKET_LENGTH, 0);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code;
+
+ if (p_len > 0)
+ {
+ err_code = mqtt_transport_read(p_client, p_packet, p_len);
+ MQTT_TRC("Received %d bytes from %d: 0x%08x",
+ p_len, p_client->socket_fd, err_code);
+ }
+ else if (p_len == 0)
+ {
+ // Receiving 0 bytes indicates an orderly shutdown.
+ MQTT_TRC("Received end of stream, closing connection");
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, MQTT_ERR_TRANSPORT_CLOSED);
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ MQTT_TRC("Error receiving data, errno = %d, closing connection", errno);
+ mqtt_client_tcp_abort(p_client);
+ err_code = (NRF_ERROR_INVALID_DATA | IOT_MQTT_ERR_BASE);
+ }
+
+ nrf_free(p_packet);
+
+ return err_code;
+}
+
+
+uint32_t tcp_request_connection(mqtt_client_t * p_client)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ p_client->socket_fd = socket(AF_INET6, SOCK_STREAM, 0);
+ MQTT_TRC("Created socket %d", p_client->socket_fd);
+ if (p_client->socket_fd < 0)
+ {
+ err_code = (NRF_ERROR_INTERNAL | IOT_MQTT_ERR_BASE);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ struct sockaddr_in6 dest;
+ memset(&dest, 0, sizeof(dest));
+ dest.sin6_family = AF_INET6;
+ dest.sin6_port = htons(p_client->broker_port);
+ memcpy(&dest.sin6_addr, p_client->broker_addr.u8, sizeof(dest.sin6_addr));
+
+ int ret = connect(p_client->socket_fd, (struct sockaddr *)&dest, sizeof(dest));
+ if (ret == 0)
+ {
+ MQTT_SET_STATE(p_client, MQTT_STATE_TCP_CONNECTED);
+ err_code = mqtt_transport_connect(p_client);
+ MQTT_TRC("Sent connect %d: 0x%08x", p_client->socket_fd, err_code);
+ }
+ else
+ {
+ mqtt_client_tcp_abort(p_client);
+ err_code = (NRF_ERROR_INTERNAL | IOT_MQTT_ERR_BASE);
+ }
+ }
+
+ while (!MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED) && err_code == NRF_SUCCESS)
+ {
+ // Receive until connected.
+ MQTT_TRC("Receive until connected");
+ err_code = tcp_receive_packet(p_client, 0);
+ }
+
+ MQTT_TRC("Connect completed");
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tcp_disconnect(mqtt_client_t * p_client)
+{
+ uint32_t err_code;
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ const uint8_t packet[] = {MQTT_PKT_TYPE_DISCONNECT, 0x00};
+ MQTT_SET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ MQTT_MUTEX_UNLOCK();
+
+ UNUSED_VARIABLE(send(p_client->socket_fd, (void *)packet, sizeof(packet), 0));
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_RESET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+ tcp_close_connection(p_client);
+ err_code = NRF_SUCCESS;
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED))
+ {
+ tcp_close_connection(p_client);
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ err_code = (NRF_ERROR_INVALID_STATE | IOT_MQTT_ERR_BASE);
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_tls.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_tls.c
new file mode 100644
index 0000000..8f74600
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_tls.c
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @file
+ *
+ * @brief MQTT Client Implementation TLS layer.
+ *
+ * This file contains the source code for MQTT Protocol TLS layer for a nRF device.
+ * The implementation is limited to MQTT Client role only.
+ */
+
+
+#include "mqtt_transport.h"
+#include "mqtt_internal.h"
+#include "mqtt_rx.h"
+#include "mem_manager.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_tls
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+uint32_t mqtt_client_tls_output_handler(nrf_tls_instance_t const * p_instance,
+ uint8_t const * p_data,
+ uint32_t datalen)
+{
+ NULL_PARAM_CHECK(p_instance);
+
+ uint32_t err_code = NRF_ERROR_INTERNAL;
+ mqtt_client_t * p_client = (mqtt_client_t *)p_instance->transport_id;
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_TRC(">> %s, client %p", __func__, p_client);
+
+ if (p_client != NULL)
+ {
+ err_code = mqtt_client_tcp_write(p_client, p_data, datalen);
+ }
+
+ MQTT_TRC("<< %s, client %p, result 0x%08x", __func__,
+ p_client, err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tls_connect(mqtt_client_t * p_client)
+{
+ const nrf_tls_options_t tls_option =
+ {
+ .output_fn = mqtt_client_tls_output_handler,
+ .transport_type = NRF_TLS_TYPE_STREAM,
+ .role = NRF_TLS_ROLE_CLIENT,
+ .p_key_settings = p_client->p_security_settings
+ };
+
+ connect_request_encode(p_client,
+ &p_client->p_pending_packet,
+ &p_client->pending_packetlen);
+
+ p_client->tls_instance.transport_id = (uint32_t)p_client;
+
+ MQTT_MUTEX_UNLOCK ();
+
+ uint32_t err_code = nrf_tls_alloc(&p_client->tls_instance, &tls_option);
+
+ MQTT_MUTEX_LOCK ();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tls_write(mqtt_client_t * p_client,
+ uint8_t const * p_data,
+ uint32_t datalen)
+{
+ MQTT_MUTEX_UNLOCK ();
+
+ uint32_t err_code = nrf_tls_write(&p_client->tls_instance, p_data, &datalen);
+
+ MQTT_MUTEX_LOCK ();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tls_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen)
+{
+ uint32_t err = nrf_tls_input(&p_client->tls_instance, p_data, datalen);
+
+ if ((err == NRF_SUCCESS) && (p_client->p_pending_packet == NULL))
+ {
+ uint32_t rx_datalen = 1024;
+ uint8_t * p_mqtt_data = nrf_malloc(1024);
+
+ if (p_data != NULL)
+ {
+ MQTT_MUTEX_UNLOCK ();
+
+ err = nrf_tls_read(&p_client->tls_instance,
+ p_mqtt_data,
+ &rx_datalen);
+
+ MQTT_MUTEX_LOCK ();
+
+ if ((err == NRF_SUCCESS) && (rx_datalen > 0))
+ {
+ err = mqtt_handle_rx_data(p_client, p_mqtt_data, rx_datalen);
+ }
+
+ nrf_free(p_mqtt_data);
+ }
+ }
+
+ return err;
+}
+
+
+uint32_t mqtt_client_tls_disconnect(mqtt_client_t * p_client)
+{
+ return mqtt_client_tcp_disconnect(p_client);
+}