Skip to content

Commit

Permalink
samples: nrf9160: mmss: Split connection.c into two files
Browse files Browse the repository at this point in the history
Split `connection.c` into two files better representing functional
separation: `message_queue.c` for the message queue, and
`cloud_connection.c` for the connection loop.

Signed-off-by: Georges Oates_Larsen <georges.larsen@nordicsemi.no>
  • Loading branch information
glarsennordic authored and rlubos committed Jul 24, 2023
1 parent 09f10fd commit 3bc9d0c
Show file tree
Hide file tree
Showing 9 changed files with 243 additions and 164 deletions.
3 changes: 2 additions & 1 deletion samples/cellular/nrf_cloud_mqtt_multi_service/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ zephyr_compile_definitions(PROJECT_NAME=${PROJECT_NAME})
# NORDIC SDK APP START
target_sources(app PRIVATE src/main.c)
target_sources(app PRIVATE src/application.c)
target_sources(app PRIVATE src/connection.c)
target_sources(app PRIVATE src/cloud_connection.c)
target_sources(app PRIVATE src/message_queue.c)
target_sources(app PRIVATE src/temperature.c)
target_sources(app PRIVATE src/fota_support.c)
target_sources(app PRIVATE src/led_control.c)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2022 Nordic Semiconductor ASA
/* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
Expand All @@ -15,7 +15,8 @@

#include "application.h"
#include "temperature.h"
#include "connection.h"
#include "cloud_connection.h"
#include "message_queue.h"

#include "location_tracking.h"
#include "led_control.h"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2022 Nordic Semiconductor ASA
/* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <stdio.h>

#include "nrf_cloud_codec_internal.h"
#include "connection.h"
#include "cloud_connection.h"
#include "at_commands.h"

LOG_MODULE_REGISTER(at_cmd_execution, CONFIG_MQTT_MULTI_SERVICE_LOG_LEVEL);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2022 Nordic Semiconductor ASA
/* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
Expand All @@ -7,18 +7,17 @@
#include <stdio.h>
#include <zephyr/net/socket.h>
#include <net/nrf_cloud.h>
#include <net/nrf_cloud_codec.h>
#include <date_time.h>
#include <zephyr/logging/log.h>
#include <modem/nrf_modem_lib.h>

#include "connection.h"
#include "cloud_connection.h"

#include "fota_support.h"
#include "location_tracking.h"
#include "led_control.h"

LOG_MODULE_REGISTER(connection, CONFIG_MQTT_MULTI_SERVICE_LOG_LEVEL);
LOG_MODULE_REGISTER(cloud_connection, CONFIG_MQTT_MULTI_SERVICE_LOG_LEVEL);

/* Flow control event identifiers */

Expand Down Expand Up @@ -47,18 +46,6 @@ static K_EVENT_DEFINE(network_connection_events);
static K_EVENT_DEFINE(cloud_connection_events);
static K_EVENT_DEFINE(datetime_connection_events);

/* Message Queue for enqueing outgoing messages during offline periods. */
K_MSGQ_DEFINE(device_message_queue,
sizeof(struct nrf_cloud_obj *),
CONFIG_MAX_OUTGOING_MESSAGES,
sizeof(struct nrf_cloud_obj *));

/* Tracks the number of consecutive message-send failures. A total count greater than
* CONFIG_MAX_CONSECUTIVE_SEND_FAILURES will trigger a connection reset and cooldown.
* Resets on every successful device message send.
*/
static int send_failure_count;

static dev_msg_handler_cb_t general_dev_msg_handler;
/**
* @brief Notify that network connection has been established.
Expand Down Expand Up @@ -524,110 +511,6 @@ static void free_queued_dev_msg_message(struct nrf_cloud_obj *msg_obj)
k_free(msg_obj);
}

int consume_device_message(void)
{
struct nrf_cloud_obj *queued_msg;
int ret;

LOG_DBG("Consuming an enqueued device message");

/* Wait until a message is available to send. */
ret = k_msgq_get(&device_message_queue, &queued_msg, K_FOREVER);
if (ret) {
LOG_ERR("Failed to retrieve item from outgoing message queue, error: %d", ret);
return -ret;
}

/* Wait until we are able to send it. */
LOG_DBG("Waiting for valid connection before transmitting device message");
(void)await_connection(K_FOREVER);

/* Attempt to send it.
*
* Note, it is possible (and better) to batch-send device messages when more than one is
* queued up. We limit this sample to sending individual messages mainly to keep the sample
* simple and accessible. See the Asset Tracker V2 application for an example of batch
* message sending.
*/
LOG_DBG("Attempting to transmit enqueued device message");

struct nrf_cloud_tx_data mqtt_msg = {
.qos = MQTT_QOS_1_AT_LEAST_ONCE,
.topic_type = NRF_CLOUD_TOPIC_MESSAGE,
.obj = queued_msg
};

/* Send message */
ret = nrf_cloud_send(&mqtt_msg);

if (ret) {
LOG_ERR("Transmission of enqueued device message failed, nrf_cloud_send "
"gave error: %d. The message will be re-enqueued and tried again "
"later.", ret);

/* Re-enqueue the message for later retry.
* No need to create a copy since we already copied the
* message object struct when it was first enqueued.
*/
ret = enqueue_device_message(queued_msg, false);
if (ret) {
LOG_ERR("Could not re-enqueue message, discarding.");
free_queued_dev_msg_message(queued_msg);
}

/* Increment the failure counter. */
send_failure_count += 1;

/* If we have failed too many times in a row, there is likely a bigger problem,
* and we should reset our connection to nRF Cloud, and wait for a few seconds.
*/
if (send_failure_count > CONFIG_MAX_CONSECUTIVE_SEND_FAILURES) {
/* Disconnect. */
disconnect_cloud();

/* Wait for a few seconds before trying again. */
k_sleep(K_SECONDS(CONFIG_CONSECUTIVE_SEND_FAILURE_COOLDOWN_SECONDS));
}
} else {
/* Clean up the message receive from the queue */
free_queued_dev_msg_message(queued_msg);

LOG_DBG("Enqueued device message consumed successfully");

/* Either overwrite the existing pattern with a short success pattern, or just
* disable the previously requested pattern, depending on if we are in verbose mode.
*/
if (IS_ENABLED(CONFIG_LED_VERBOSE_INDICATION)) {
short_led_pattern(LED_SUCCESS);
} else {
stop_led_pattern();
}

/* Reset the failure counter, since we succeeded. */
send_failure_count = 0;
}

return ret;
}

int send_device_message(struct nrf_cloud_obj *const msg_obj)
{
/* Enqueue the message, creating a copy to be managed by the queue. */
int ret = enqueue_device_message(msg_obj, true);

if (ret) {
LOG_ERR("Cannot add message to queue");
nrf_cloud_obj_free(msg_obj);
} else {
/* The message data now belongs to the queue.
* Reset the provided object so it cannot be modified.
*/
nrf_cloud_obj_reset(msg_obj);
}

return ret;
}

/**
* @brief Close any connection to nRF Cloud, and reset connection status event state.
* For internal use only. Externally, disconnect_cloud() may be used to trigger a disconnect.
Expand Down Expand Up @@ -809,14 +692,6 @@ static int setup_network(void)
return 0;
}

void message_queue_thread_fn(void)
{
/* Continually attempt to consume device messages */
while (true) {
(void) consume_device_message();
}
}

void connection_management_thread_fn(void)
{
long_led_pattern(LED_WAITING);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* Copyright (c) 2022 Nordic Semiconductor ASA
/* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef _CONNECTION_H_
#define _CONNECTION_H_
#ifndef _CLOUD_CONNECTION_H_
#define _CLOUD_CONNECTION_H_
#include <net/nrf_cloud.h>

/**
Expand Down Expand Up @@ -80,33 +80,10 @@ bool await_connection(k_timeout_t timeout);
*/
bool await_date_time_known(k_timeout_t timeout);

/**
* @brief Consume (attempt to send) a single device message from the device message queue. Will wait
* until connection to nRF Cloud is established before actually sending. If message fails
* to send, it will be dropped.
*
* @return int - 0 on success, otherwise negative error code.
*/
int consume_device_message(void);

/**
* @brief Schedule a cloud object to be sent as a device message payload. Message will
* be held asynchronously until a valid nRF Cloud connection is established.
* Caller is no longer responsible for device message memory after function returns.
* @return int - 0 on success, otherwise negative error.
*/
int send_device_message(struct nrf_cloud_obj *const msg_obj);

/**
* @brief The message queue thread function.
* Continually consumes device messages from the device message queue.
*/
void message_queue_thread_fn(void);

/**
* @brief The connection management thread function.
* Manages our connection to nRF Cloud, resetting and restablishing as necessary.
*/
void connection_management_thread_fn(void);

#endif /* _CONNECTION_H_ */
#endif /* _CLOUD_CONNECTION_H_ */
9 changes: 5 additions & 4 deletions samples/cellular/nrf_cloud_mqtt_multi_service/src/main.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2022 Nordic Semiconductor ASA
/* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
Expand All @@ -7,7 +7,8 @@
#include <stdio.h>
#include <zephyr/logging/log.h>
#include "application.h"
#include "connection.h"
#include "cloud_connection.h"
#include "message_queue.h"
#include "led_control.h"

LOG_MODULE_REGISTER(main, CONFIG_MQTT_MULTI_SERVICE_LOG_LEVEL);
Expand All @@ -24,11 +25,11 @@ K_THREAD_DEFINE(led_thread, CONFIG_LED_THREAD_STACK_SIZE, led_animation_thread_f
K_THREAD_DEFINE(app_thread, CONFIG_APPLICATION_THREAD_STACK_SIZE, main_application_thread_fn,
NULL, NULL, NULL, 0, 0, 0);

/* Define, and automatically start the message queue thread. See connection.c */
/* Define, and automatically start the message queue thread. See message_queue.c */
K_THREAD_DEFINE(msg_thread, CONFIG_MESSAGE_THREAD_STACK_SIZE, message_queue_thread_fn,
NULL, NULL, NULL, 0, 0, 0);

/* Define, and automatically start the connection management thread. See connection.c
/* Define, and automatically start the connection management thread. See cloud_connection.c
*
* The connection thread is given higher priority (-1) so that it can preempt the other threads,
* for instance in the event of a call to disconnect_cloud().
Expand Down
Loading

0 comments on commit 3bc9d0c

Please sign in to comment.