Skip to content

Commit

Permalink
Added client socket type support to the gateway Config.
Browse files Browse the repository at this point in the history
  • Loading branch information
arobenko committed May 14, 2024
1 parent 07e01ce commit a7c46a0
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 88 deletions.
2 changes: 1 addition & 1 deletion gateway/app/gateway/GatewayApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ bool GatewayApp::start(int argc, const char* argv[])

auto configFile = opts.configFile();
do {
if (!configFile.empty()) {
if (configFile.empty()) {
logInfo() << "No configuration file provided, using default configuration." << std::endl;
break;
}
Expand Down
59 changes: 0 additions & 59 deletions gateway/app/gateway/GatewayProgramOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,59 +16,12 @@ namespace po = boost::program_options;
namespace cc_mqttsn_gateway_app
{

namespace
{

using ConnectionTypeMap = std::map<std::string, GatewayProgramOptions::ConnectionType>;
const ConnectionTypeMap& connectionTypeMap()
{
static const ConnectionTypeMap Map = {
{"udp", GatewayProgramOptions::ConnectionType_Udp},
};

return Map;
}

std::string supportedConnectionTypes()
{
std::string result;
for (auto& info : connectionTypeMap()) {
if (!result.empty()) {
result.append(", ");
}

result.append(info.first);
}

return result;
}

const std::string& defaultConnectionType()
{
auto& map = connectionTypeMap();
auto iter =
std::find_if(
map.begin(), map.end(),
[](auto& info)
{
return info.second == GatewayProgramOptions::DefaultConnectionType;
});

assert(iter != map.end());
return iter->first;
}

} // namespace


GatewayProgramOptions::GatewayProgramOptions()
{
po::options_description opts("Options");
opts.add_options()
("help,h", "Display help message")
("config,c", po::value<std::string>()->default_value(std::string()), "Configuration file.")
("socket,s", po::value<std::string>()->default_value(defaultConnectionType()),
("Low level connection socket type. Available: " + supportedConnectionTypes()).c_str())
;

m_desc.add(opts);
Expand Down Expand Up @@ -97,16 +50,4 @@ std::string GatewayProgramOptions::configFile() const
return m_vm["config"].as<std::string>();
}

GatewayProgramOptions::ConnectionType GatewayProgramOptions::connectionType() const
{
auto socketStr = m_vm["socket"].as<std::string>();
auto& map = connectionTypeMap();
auto iter = map.find(socketStr);
if (iter == map.end()) {
return ConnectionType_ValuesLimit;
}

return iter->second;
}

} // namespace cc_mqttsn_gateway_app
11 changes: 0 additions & 11 deletions gateway/app/gateway/GatewayProgramOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,6 @@ class GatewayProgramOptions
public:
using OptDesc = boost::program_options::options_description;

static constexpr std::uint16_t DefaultPort = 1883U;

enum ConnectionType
{
ConnectionType_Udp,
ConnectionType_ValuesLimit
};

static const ConnectionType DefaultConnectionType = ConnectionType_Udp;

GatewayProgramOptions();

void printHelp();
Expand All @@ -39,7 +29,6 @@ class GatewayProgramOptions

bool helpRequested() const;
std::string configFile() const;
ConnectionType connectionType() const;


private:
Expand Down
16 changes: 12 additions & 4 deletions gateway/app/gateway/etc/cc_mqttsn_gateway.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
# both client / broker directions. Default value is 10 seconds.
#mqttsn_retry_period 10

# Number of attemts to try to re-send a message, acknowledgement of which needs
# Number of attempts to try to re-send a message, acknowledgement of which needs
# to be received. Default value is 3.
#mqttsn_retry_count 3

# In some use-cases, with interfaces such as RS-232 and/or bluetooth links,
# In some use-cases, with interfaces such as RS-232 and/or some bluetooth links,
# there is only one MQTT-SN client that can be connected to the gateway. In this
# case the client may omit its client ID information in the CONNECT message
# to save the amount of traffic. When forwarding the connection request to the
Expand Down Expand Up @@ -78,14 +78,22 @@
# 127.0.0.1 and 1883 respectively.
#mqttsn_broker 127.0.0.1 1883

# =================================================================
# Client socket configuration
# =================================================================

# Use "mqttsn_client_socket" option to specify the type of the I/O link socket
# to use. Supported values are: "udp" (default)
# mqttsn_client_socket udp

# =================================================================
# UDP configuration
# =================================================================

# Local UDP port the gateway listens to new incomming messages on. Default is
# 1883.
# 1883. Applicable only if "mqttsn_client_socket" is "udp".
#udp_listen_port 1883

# Remote UDP port the gateway broadcasts its ADVERTISE messages to. Default is
# 1883.
# 1883. Applicable only if "mqttsn_client_socket" is "udp".
#udp_broadcast_port 1883
125 changes: 125 additions & 0 deletions gateway/lib/doc/config.dox
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@
/// unsigned char id = cc_mqttsn_gw_config_id(handle);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # Gateway ID, reported in ADVERTISE and GWINFO messages. Default value is 0.
/// mqttsn_gw_id 0
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_advertise Advertise Period
/// The @ref cc_mqttsn_gw_gateway_page object sends @b ADVERTISE message periodically.
/// It needs to be configured with propere period value
Expand All @@ -91,6 +97,15 @@
/// unsigned short period = cc_mqttsn_gw_config_advertise_period(handle);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # Advertise period (in seconds), when gateway is expected to advertise its
/// # presence by broadcasting ADVERTISE message. Default value is 900 (=15 min).
/// # This value can be set to 0, which will indicate that gateway supports only
/// # direct connections and doesn't advertise its presence to others.
/// mqttsn_advertise 900
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_retry Retry Configuration
/// The @ref cc_mqttsn_gw_session_page object can be configured with period between
/// its retry attempts as well as number of such attempts (see
Expand All @@ -109,6 +124,18 @@
/// unsigned attempts = cc_mqttsn_gw_config_retry_count(handle);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # Time in seconds to wait before re-sending message, acknowledgement of which
/// # needs to be received. The same time interval is used to resend messages to
/// # both client / broker directions. Default value is 10 seconds.
/// mqttsn_retry_period 10
///
/// # Number of attempts to try to re-send a message, acknowledgement of which needs
/// # to be received. Default value is 3.
/// mqttsn_retry_count 3
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_default_client Default Client ID
/// Can be used in @ref cc_mqttsn_gw_session_page object configuration (see
/// @ref cc_mqttsn_gw_session_page_default_client_id).
Expand All @@ -123,6 +150,17 @@
/// const char* clientId = cc_mqttsn_gw_config_default_client_id(handle);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # In some use-cases, with interfaces such as RS-232 and/or some bluetooth links,
/// # there is only one MQTT-SN client that can be connected to the gateway. In this
/// # case the client may omit its client ID information in the CONNECT message
/// # to save the amount of traffic. When forwarding the connection request to the
/// # broker, gateway may replace empty client ID with some predefined value. Use
/// # "mqttsn_default_client_id" option to specify such default client ID.
/// mqttsn_default_client_id some_id
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_pub_only_keep_alive Keep Alive Period for Publish Only Clients
/// Can be used in @ref cc_mqttsn_gw_session_page object configuration (see
/// @ref cc_mqttsn_gw_session_page_publish_only).
Expand All @@ -137,6 +175,18 @@
/// unsigned short keepAlivePeriod = cc_mqttsn_gw_config_pub_only_keep_alive(handle);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # The gateway supports "publish only" clients, that do not attempt to connect
/// # to the gateway, and don't subscribe to any topics. Such clients are allowed to
/// # publish predefined topics with QoS=-1. The gateway connects to broker on
/// # behalf to such client. In addition to setting "mqttsn_default_client_id" value
/// # the gateway may be configured to set "keep alive" period in which client must
/// # send at least one message. Use "mqttsn_pub_only_keep_alive" option to set
/// # the value keep alive period in seconds. The default value is 60.
/// mqttsn_pub_only_keep_alive 60
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_sleeping_client_msg_limit Limit Messages for Sleeping Clients
/// Can be used in @ref cc_mqttsn_gw_session_page object configuration (see
/// @ref cc_mqttsn_gw_session_page_sleep).
Expand All @@ -151,6 +201,16 @@
/// unsigned limit = cc_mqttsn_gw_config_sleeping_client_msg_limit(handle);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # Gateway may support sleeping clients. When client is sleeping, the broker
/// # may publish the message to the client. The gateway is responsible to store
/// # these messages and report them to the client, when the latter wakes up. It
/// # is possible to set a limit on number of such stored messages using
/// # "mqttsn_sleeping_client_msg_limit" option.
/// mqttsn_sleeping_client_msg_limit 1024
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_predefined_topics Predefined Topics
/// The @ref cc_mqttsn_gw_session_page object can be configured with
/// number of predefined topics (see @ref cc_mqttsn_gw_session_page_predefined_topics).
Expand All @@ -174,6 +234,17 @@
/// }
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # List of predefined ids can be specified using multiple
/// # "mqttsn_predefined_topic" options. This option is expected to have 3
/// # parameters: client ID, topic string, and topic ID. The common predefined
/// # topic ID for all the possible clients may be specified using '*' as
/// # client ID parameter.
/// mqttsn_predefined_topic client1 predefined/topic/client1 1
/// mqttsn_predefined_topic * common/predefined/topic 2
/// @endcode
///
/// @b C interface also allows to retrieve number of predefined topics in case
/// there is no known limit for the buffer upfront and it needs to be dynamically
/// allocated:
Expand Down Expand Up @@ -207,6 +278,21 @@
/// unsigned count = cc_mqttsn_gw_config_available_auth_infos(handle);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # MQTT protocol supports client authentication using username and password,
/// # while MQTT-SN doesn't have such option. The gateway may be configured to
/// # use some authentication information when forwarding connection requests to
/// # the broker. Such authentication information may be specified using
/// # "mqttsn_auth" option. This option is expected to have 3 parameters:
/// # client ID, username string, password string. Note, that MQTT protocol
/// # specifies password as binary data. The password string parameter will be used
/// # as is unless it uses "\x" prefix for every binary byte. Just like with
/// # "mqttsn_predefined_topic" option, the client ID may also be a wildcard ('*').
/// mqttsn_auth client1 username1 ascii_password
/// mqttsn_auth client2 username2 \x00\x01\x02\x03\x04\x05
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_topic_id_range Topic ID Allocation Range
/// The @ref cc_mqttsn_gw_session_page object can be configured to limit its
/// range of topic IDs, which are allocated for newly registered topic strings
Expand All @@ -228,6 +314,15 @@
/// cc_mqttsn_gw_config_topic_id_alloc_range(handle, &minTopicId, &maxTopicId);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # The gateway is responsible to allocate topic IDs for published topics. It is
/// # possible to limit the range of such ID values using
/// # "mqttsn_topic_id_alloc_range" option. It receives two parameters of minimal
/// # and maximal numeric ID. Note, that valid IDs must be in range [1 - 65534].
/// mqttsn_topic_id_alloc_range 1000 5000
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_broker_addr Broker Address and Port
/// The MQTT-SN gateway application must connect and forward traffic to
/// MQTT broker. Below are API functions that can be used to retrieve the
Expand All @@ -245,6 +340,36 @@
/// unsigned short port = cc_mqttsn_gw_config_broker_port(handle);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # The connection to MQTT broker is usually performed over TCP/IP link.
/// # Use "mqttsn_broker" option to specify the address of the broker.
/// # The option receives two parameters: address and port. The default values are
/// # 127.0.0.1 and 1883 respectively.
/// mqttsn_broker 127.0.0.1 1883
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_client_socket Client I/O Socket Type
/// The MQTT-SN gateway application can support multiple client communication I/O
/// socket types. Below are API function that can retrieve such information.
///
/// @b C++ interface
/// @code
/// cc_mqttsn_gateway::Config::ClientConnectionType type = config.clientConnectionType();
/// @endcode
///
/// @b C interface
/// @code
/// CC_MqttsnClientConnectionType type = cc_mqttsn_gw_config_client_socket_type(handle);
/// @endcode
///
/// Applicable configuration file contents:
/// @code{.unparsed}
/// # Use "mqttsn_client_socket" option to specify the type of the I/O link socket
/// # to use. Supported values are: "udp" (default)
/// mqttsn_client_socket udp
/// @endcode
///
/// @section cc_mqttsn_gw_config_page_custom Custom Configuration Values
/// The @b Config object has a list of predefined options it recognises in the
/// configuration file. It also accumulates all the options it doesn't recognise.
Expand Down
20 changes: 15 additions & 5 deletions gateway/lib/include/cc_mqttsn_gateway/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ class Config
/// value is rest of the string until the end of the line.
/// @b NOTE, that the type is @b multimap, which allows multiple
/// entries with the same key.
typedef std::multimap<std::string, std::string> ConfigMap;
using ConfigMap = std::multimap<std::string, std::string>;

/// @brief Type of buffer that contains binary data.
typedef std::vector<std::uint8_t> BinaryData;
using BinaryData = std::vector<std::uint8_t>;

/// @brief Info about single predefined topic
struct PredefinedTopicInfo
Expand All @@ -53,7 +53,7 @@ class Config
};

/// @brief Type of list containing predefined topics.
typedef std::vector<PredefinedTopicInfo> PredefinedTopicsList;
using PredefinedTopicsList = std::vector<PredefinedTopicInfo>;

/// @brief Authentication info for single client
struct AuthInfo
Expand All @@ -64,12 +64,19 @@ class Config
};

/// @brief Type of list containing authentication information for multiple clients.
typedef std::vector<AuthInfo> AuthInfosList;
using AuthInfosList = std::vector<AuthInfo>;

/// @brief Range of topic IDs
/// @details First element of the pair is minimal ID, and second
/// element of the pair is maximal ID.
typedef std::pair<std::uint16_t, std::uint16_t> TopicIdsRange;
using TopicIdsRange = std::pair<std::uint16_t, std::uint16_t>;

/// @brief Client I/O socket connection type
enum ClientConnectionType
{
ClientConnectionType_Udp, ///< UDP/IP
ClientConnectionType_ValuesLimit ///< Limit to available values, must be last
};

/// @brief Constructor
Config();
Expand Down Expand Up @@ -139,6 +146,9 @@ class Config
/// @details Default value is @b 1883
std::uint16_t brokerTcpHostPort() const;

/// @brief Get client side I/O socket connection type
ClientConnectionType clientConnectionType() const;

private:
std::unique_ptr<ConfigImpl> m_pImpl;
};
Expand Down
Loading

0 comments on commit a7c46a0

Please sign in to comment.