Quality of Service
The Quality of Service (QoS) library provides APIs to store and handle acknowledgment of multiple in-flight messages. The library is transport agnostic, which means that it does not enforce any transport-related functionality to the caller.
Implementation
The following sequence diagram shows a typical usage of the library:
Configuration
To use this library, set the CONFIG_QOS
Kconfig option and include the include/lib/qos.h
file to your project.
Additionally, Configure the following options when using this library:
Usage
The qos_message_add()
and qos_message_remove()
functions add and remove the messages respectively from the library.
Before adding a message, it must be associated with a message flag.
This flag determines whether or not the message needs to be stored in the pending list that is internal to the library and how the message must be notified.
Following are the available flags:
QOS_FLAG_RELIABILITY_ACK_DISABLED
- The library notifies the message only once and is not added to the internal pending list.QOS_FLAG_RELIABILITY_ACK_REQUIRED
- The library adds the message to the internal pending list and notifies after every time interval set in theCONFIG_QOS_MESSAGE_NOTIFY_TIMEOUT_SECONDS
Kconfig option with theQOS_EVT_MESSAGE_TIMER_EXPIRED
event. The library notifies the message until the message is removed or the limit set through theCONFIG_QOS_MESSAGE_NOTIFIED_COUNT_MAX
Kconfig option is reached.
Note
All messages that are added to the library using the qos_message_add()
function is notified with the QOS_EVT_MESSAGE_TIMER_EXPIRED
event.
The following code block displays how the library can be initialized and a single message is added:
/* Define message types that can be used to route data. */
enum {
SENSOR_DATA,
DIAGNOSTIC_DATA
};
/* Event handler used to receive notifications from the library. */
static void qos_event_handler(const struct qos_evt *evt)
{
switch (evt->type) {
case QOS_EVT_MESSAGE_NEW:
case QOS_EVT_MESSAGE_TIMER_EXPIRED:
/* Check evt->message.type and route message based on type. */
break;
case QOS_EVT_MESSAGE_REMOVED_FROM_LIST:
/* Free payload if (evt->message.heap_allocated == true) */
break;
default:
break;
}
}
/* QoS library message data structure. */
struct qos_data message = {
.heap_allocated = true,
.data.buf = pointer_to_payload,
.data.len = size_of_payload,
.id = qos_message_id_get_next(),
.type = SENSOR_DATA,
.flags = QOS_FLAG_RELIABILITY_ACK_REQUIRED
};
/* Initialize the QoS library and set the library event handler. */
err = qos_init(qos_event_handler);
if (err) {
LOG_ERR("qos_init, err", err);
return err;
}
/* Add a single message. */
err = qos_message_add(&message);
if (err) {
LOG_ERR("qos_message_add, error: %d", err);
return err;
}
To remove a message from the pending list, call qos_message_remove()
with the message ID of the corresponding message:
err = qos_message_remove(message_id);
if (err) {
LOG_ERR("qos_message_remove, error: %d", err);
return err;
}
Messages added to the library can be associated with specific message types.
These message types can be used to route messages after they have been notified in the library callback handler.
For messages that require acknowledgment, message transport libraries often need a message ID.
The application can use the qos_message_id_get_next()
function to generate the Message IDs.
Note
Some transport libraries reserve specific message IDs for internal use, typically lower integer ranges.
Hence, the qos_message_id_get_next()
function generates IDs based on an ID base, QOS_MESSAGE_ID_BASE
of 15000.
Samples using the library
The Asset Tracker v2 application uses this library.
API documentation
include/qos.h
lib/qos.c