# MQTTSN Class

A lightweight, fully-featured MQTT-SN client implementation.

## Syntax

```text
ipworksiot.MQTTSN
```

## Remarks

The MQTTSN class provides a lightweight, fully-featured MQTT-SN (MQTT for Sensor Networks) client implementation over UDP.

### Connecting

 Connecting to a gateway is easy; in the simplest case, set the [ClientId](#clientid-property-mqttsn-class) property and call the [ConnectTo](#connectto-method-mqttsn-class) method, passing it the gateway's hostname and port number.

When connecting to an MQTT gateway, the class sends the following information:

- The values of the [ClientId](#clientid-property-mqttsn-class), [CleanSession](#cleansession-property-mqttsn-class), and [KeepAliveInterval](#keepaliveinterval-property-mqttsn-class) properties.
- The values of the [WillTopic](#willtopic-property-mqttsn-class) and [WillMessage](#willmessage-property-mqttsn-class) properties and the [WillRetain](#WillRetain) and [WillQOS](#WillQOS) configuration settings.

Refer to [CleanSession](#cleansession-property-mqttsn-class) for more information about MQTT sessions; refer to [WillTopic](#willtopic-property-mqttsn-class), [WillMessage](#willmessage-property-mqttsn-class), [WillQOS](#WillQOS) and [WillRetain](#WillRetain) for more information about MQTT Wills.

**Basic Connection Example**

```csharp
mqttsn1.ClientId = "testClient";
mqttsn1.CleanSession = true;
mqttsn1.KeepAliveInterval = 30;
mqttsn1.WillTopic = "wills/" + mqttsn1.ClientId;
mqttsn1.WillMessage = mqttsn1.ClientId + " was disconnected ungracefully!";
mqttsn1.ConnectTo(host, port);
```

### Topic Subscriptions

 The [Subscribe](#subscribe-method-mqttsn-class) and [Unsubscribe](#unsubscribe-method-mqttsn-class) methods are used to subscribe to and unsubscribe from topics.

When subscribing, pass the topic name or id, topic id type and QoS level. Topic filters may contain wildcards in order to match multiple topics on the server. If a topic name is specified, the [SubscribedTopicId](#SubscribedTopicId) configuration setting will contain the assigned id for the topic.

**Subscribe Examples**

```csharp
String fullTopicName = "full/topic/name";
mqttsn1.Subscribe(fullTopicName, 0, 2); // subscribe with topic name
int assignedTopicId = mqttsn1.Config("SubscribedTopicId"); // map id to topic name used

mqttsn1.Subscribe(fullTopicName+"/#", 0, 2) // topic name with wildcard; SubscribedTopicId will be 0
mqttsn1.OnTopicId += (s,e) => { // will fire before messages matching the wildcard are sent to the client
  int topicId = e.TopicId;
  String topicName = e.TopicName;
  // establish mapping between these
};

mqttsn1.Subscribe("aa", 2, 2); // subscribe with short topic name; no need for registration
```

After subscribing to topics, any messages received on that topic will cause the [MessageIn](#messagein-event-mqttsn-class) event to fire. Refer to [MessageIn](#messagein-event-mqttsn-class) for more information about processing steps for inbound messages.

When unsubscribing, pass the topic id or exact topic name used to subscribe.

**Unsubscribe Examples**

```csharp
String fullTopicName = "full/topic/name";
mqtt1.Unsubscribe(fullTopicName, 0); // unsubscribe from topic name

mqtt1.Unsubscribe(fullTopicName+"/#", 0); // must use full topic filter if includes wildcard; can't unsubscribe from individual topics included in the filter

mqtt1.Unsubscribe("aa", 2); // unsubscribe from short topic
```

Refer to [Subscribe](#subscribe-method-mqttsn-class) and [Unsubscribe](#unsubscribe-method-mqttsn-class) for more information about subscriptions and topic names.

### Publishing Messages

 To publish messages to topics, use the [PublishMessage](#publishmessage-method-mqttsn-class) and [PublishData](#publishdata-method-mqttsn-class) methods.

[PublishMessage](#publishmessage-method-mqttsn-class) is used to publish a message with a string payload, while [PublishData](#publishdata-method-mqttsn-class) is used to publish a message with a raw data payload. Both also accept the topic id to publish to, the topic id type and a QoS level at which to publish.

**Publish Examples**

```csharp
// Publish string messages
int id = mqttsn1.RegisterTopic("topic/name"); // must register topic names that are not short or pre-defined
mqttsn1.PublishMessage(id, 0, 2, "hello"); // publish message with registered topic name

mqttsn1.PublishMessage("aa", 2, 2, "hello"); // publish message with short topic name

// Publish a raw data message.
byte[] picture = ...;
mqtt1.PublishData(id, 0, 2, picture);
```

Refer to [PublishData](#publishdata-method-mqttsn-class) and [PublishMessage](#publishmessage-method-mqttsn-class) for more information about message publishing as well as topic names.

### Sleeping

 To save battery, clients may enter a sleep state in which their messages will be buffered for them. To manage sleeping, use [StartSleep](#startsleep-method-mqttsn-class) and [StopSleep](#stopsleep-method-mqttsn-class). To receive all buffered messages then return to sleep, use [RetrieveMessages](#retrievemessages-method-mqttsn-class).

If the client exceeds the sleep duration passed to [StartSleep](#startsleep-method-mqttsn-class) without waking or sending any packets, it will be considered lost and will disconnect.

**Sleep Examples**

```csharp
mqttsn1.StartSleep(8); // sleep for 8 seconds
// ... wait for 5 seconds
mqttsn1.RetrieveMessages(); // MessageIn will fire for each message buffered during that time
// ... wait for 5 more seconds (ok because <8 seconds since last packet sent)
mqttsn1.StopSleep();
```

## Property List

*The following is the full list of the properties of the class with short descriptions. Click on the links for further details.*

|  |  |
| --- | --- |
| [CleanSession](#cleansession-property-mqttsn-class) | Determines whether a clean session is used once connected. |
| [ClientId](#clientid-property-mqttsn-class) | A string that uniquely identifies this instance of the class to the server. |
| [Connected](#connected-property-mqttsn-class) | Whether the class is connected. |
| [KeepAliveInterval](#keepaliveinterval-property-mqttsn-class) | The maximum period of inactivity the gateway should allow between receiving messages from the client. |
| [LocalHost](#localhost-property-mqttsn-class) | The name of the local host or user-assigned IP interface through which connections are initiated or accepted. |
| [LocalPort](#localport-property-mqttsn-class) | This property includes the User Datagram Protocol (UDP) port in the local host where UDP binds. |
| [RemoteHost](#remotehost-property-mqttsn-class) | This property includes the address of the remote host. Domain names are resolved to IP addresses. |
| [RemotePort](#remoteport-property-mqttsn-class) | This property specifies the User Datagram Protocol (UDP) port in the remote host. |
| [Timeout](#timeout-property-mqttsn-class) | A timeout for the class. |
| [WillMessage](#willmessage-property-mqttsn-class) | The message that the server should publish in the event of an ungraceful disconnection. |
| [WillTopic](#willtopic-property-mqttsn-class) | The topic that the server should publish the WillMessage to in the event of an ungraceful disconnection. |

## Method List

*The following is the full list of the methods of the class with short descriptions. Click on the links for further details.*

|  |  |
| --- | --- |
| [Config](#config-method-mqttsn-class) | Sets or retrieves a configuration setting. |
| [Connect](#connect-method-mqttsn-class) | Connects to the MQTTSN Gateway. |
| [ConnectTo](#connectto-method-mqttsn-class) | Connects to the remote host. |
| [Disconnect](#disconnect-method-mqttsn-class) | Disconnect from the MQTTSN Gateway. |
| [DiscoverGateway](#discovergateway-method-mqttsn-class) | Broadcast a SEARCHGW message to network clients and gateways. |
| [DoEvents](#doevents-method-mqttsn-class) | This method processes events from the internal message queue. |
| [Ping](#ping-method-mqttsn-class) | Send a PINGREQ message to the gateway to reset the Keep Alive interval and ensure the gateway's liveliness. |
| [PublishData](#publishdata-method-mqttsn-class) | Publishes a message with a raw data payload. |
| [PublishMessage](#publishmessage-method-mqttsn-class) | Publishes a message with a string payload. |
| [RegisterTopic](#registertopic-method-mqttsn-class) | Register a topic name. Returns the topic id mapped to the newly registered topic name. |
| [Reset](#reset-method-mqttsn-class) | This method will reset the class. |
| [RetrieveMessages](#retrievemessages-method-mqttsn-class) | Receive currently buffered messages and return to sleep. |
| [SendDiscoverResponse](#senddiscoverresponse-method-mqttsn-class) | Asynchronously respond to a SEARCHGW message received from a peer. |
| [StartSleep](#startsleep-method-mqttsn-class) | Enter sleep state for the specified duration. |
| [StopSleep](#stopsleep-method-mqttsn-class) | Enter active state, ending the sleep period. |
| [Subscribe](#subscribe-method-mqttsn-class) | Subscribes the class to the specified topic. |
| [Unsubscribe](#unsubscribe-method-mqttsn-class) | Unsubscribes the class from the specified topic. |
| [UpdateWillMessage](#updatewillmessage-method-mqttsn-class) | Update the will message stored in session state data by the server. |
| [UpdateWillTopic](#updatewilltopic-method-mqttsn-class) | Update the will topic, will QoS and will retain flag stored in session state data by the server. |

## Event List

*The following is the full list of the events fired by the class with short descriptions. Click on the links for further details.*

|  |  |
| --- | --- |
| [Connected](#connected-event-mqttsn-class) | Fired after a MQTTSN connection completes (or fails). |
| [Disconnected](#disconnected-event-mqttsn-class) | Fired when a MQTTSN connection is closed. |
| [DiscoverRequest](#discoverrequest-event-mqttsn-class) | Fired when the class receives a SEARCHGW packet from another client. |
| [Error](#error-event-mqttsn-class) | Fired when information is available about errors during data delivery. |
| [GatewayInfo](#gatewayinfo-event-mqttsn-class) | Fired when the class receives a GWINFO or ADVERTISE packet. |
| [Log](#log-event-mqttsn-class) | Fires once for each log message. |
| [MessageIn](#messagein-event-mqttsn-class) | Fired when an incoming message has been received and/or fully acknowledged. |
| [TopicInfo](#topicinfo-event-mqttsn-class) | Fired when the client receives a REGISTER packet from the gateway assigning a topic id to a topic name. |

## Config Settings

*The following is a list of config settings for the class with short descriptions. Click on the links for further details.*

|  |  |
| --- | --- |
| [ConnectionTimeout](#ConnectionTimeout) | How long to wait for a connection attempt to succeed. |
| [Duplicate](#Duplicate) | Whether to set the Duplicate flag when publishing a message. |
| [LogLevel](#LogLevel) | The level of detail that is logged. |
| [PingTimeout](#PingTimeout) | Length of time to wait for a PINGRESP packet. |
| [Retain](#Retain) | Whether to set the Retain flag when publishing a message. |
| [SubscribedTopicId](#SubscribedTopicId) | Topic id assigned by the gateway when a topic name is used in a SUBSCRIBE message. |
| [SubscribeDUP](#SubscribeDUP) | Whether to set the Duplicate flag when subscribe to a topic. |
| [WillQOS](#WillQOS) | The QoS value to use for the Will message. |
| [WillRetain](#WillRetain) | Whether the server should retain the Will message after publishing it. |
| [BuildInfo](#BuildInfo) | Information about the product's build. |
| [GUIAvailable](#GUIAvailable) | Whether or not a message loop is available for processing events. |
| [LicenseInfo](#LicenseInfo) | Information about the current license. |
| [MaskSensitiveData](#MaskSensitiveData) | Whether sensitive data is masked in log messages. |
| [UseDaemonThreads](#UseDaemonThreads) | Whether threads created by the class are daemon threads. |
| [UseFIPSCompliantAPI](#UseFIPSCompliantAPI) | Tells the class whether or not to use FIPS certified APIs. |
| [UseInternalSecurityAPI](#UseInternalSecurityAPI) | Whether or not to use the system security libraries or an internal implementation. |
| [UseVirtualThreads](#UseVirtualThreads) | Whether threads created by the class use virtual threads instead of platform threads. |

# CleanSession Property ([MQTTSN](#mqttsn-class) Class)

Determines whether a clean session is used once connected.

## Syntax

```text
public boolean isCleanSession();
public void setCleanSession(boolean cleanSession);
```

## Default Value

True

## Remarks

This property determines whether or not the class should instruct the server to use a clean session when it connects. (Note that this property must be set to the desired value *before* calling [Connect](#connect-method-mqttsn-class).)

By default, CleanSession is true, so the server will discard any state data previously associated with the current [ClientId](#clientid-property-mqttsn-class) once the class has connected successfully. In addition, the server will not save any state data when the class disconnects.

Setting CleanSession to *False* before connecting will cause the server to re-associate any previously stored state data for the current [ClientId](#clientid-property-mqttsn-class). The server will also save any state data that exists when the class is disconnected.

The server-side session state consists of:

- client subscriptions,
- QoS 1 and 2 messages which are buffering or unacknowledged,
- QoS 2 messages received from the client but not completely acknowledged, and
- the [WillMessage](#willmessage-property-mqttsn-class) and [WillTopic](#willtopic-property-mqttsn-class) if set.

Note that retained messages are not deleted as a result of a session ending, but are not part of the session state.

This property is not available at design time.

# ClientId Property ([MQTTSN](#mqttsn-class) Class)

A string that uniquely identifies this instance of the class to the server.

## Syntax

```text
public String getClientId();
public void setClientId(String clientId);
```

## Default Value

""

## Remarks

The ClientId string is used by the server to uniquely identify each client that is connected to it.

If ClientId is empty when [Connect](#connect-method-mqttsn-class) is called, the class's behavior depends on value of [CleanSession](#cleansession-property-mqttsn-class). If [CleanSession](#cleansession-property-mqttsn-class) is *True*, the class will automatically generate a unique value for ClientId before connecting. If [CleanSession](#cleansession-property-mqttsn-class) is *False*, the class throws an exception.

This property is not available at design time.

# Connected Property ([MQTTSN](#mqttsn-class) Class)

Whether the class is connected.

## Syntax

```text
public boolean isConnected();
```

## Default Value

False

## Remarks

This property is used to determine whether or not the class is connected to the remote host. When connecting to an MQTT gateway, the class sends the following information:

- The values of the [ClientId](#clientid-property-mqttsn-class), [CleanSession](#cleansession-property-mqttsn-class), and [KeepAliveInterval](#keepaliveinterval-property-mqttsn-class) properties.
- The values of the [WillTopic](#willtopic-property-mqttsn-class) and [WillMessage](#willmessage-property-mqttsn-class) properties and the [WillRetain](#WillRetain) and [WillQOS](#WillQOS) configuration settings.

Refer to [CleanSession](#cleansession-property-mqttsn-class) for more information about MQTT sessions; refer to [WillTopic](#willtopic-property-mqttsn-class), [WillMessage](#willmessage-property-mqttsn-class), [WillQOS](#WillQOS) and [WillRetain](#WillRetain) for more information about MQTT Wills.

**Basic Connection Example**

```csharp
mqttsn1.ClientId = "testClient";
mqttsn1.CleanSession = true;
mqttsn1.KeepAliveInterval = 30;
mqttsn1.WillTopic = "wills/" + mqttsn1.ClientId;
mqttsn1.WillMessage = mqttsn1.ClientId + " was disconnected ungracefully!";
mqttsn1.RemoteHost = host;
mqttsn1.RemotePort = port;
mqttsn1.Connect();
```

This property is read-only and not available at design time.

# KeepAliveInterval Property ([MQTTSN](#mqttsn-class) Class)

The maximum period of inactivity the gateway should allow between receiving messages from the client.

## Syntax

```text
public int getKeepAliveInterval();
public void setKeepAliveInterval(int keepAliveInterval);
```

## Default Value

0

## Remarks

The KeepAliveInterval, if set to a non-zero value, is the maximum number of seconds that the gateway will allow the connection to be idle without receiving a message from the client. The value of KeepAliveInterval is sent to the server when [Connect](#connect-method-mqttsn-class) is called; it cannot be changed when the class is already connected.

MQTT servers are required to measure periods of inactivity for all clients who specify a non-zero KeepAliveInterval, and must consider them lost if they have not communicated within the KeepAliveInterval. The gateway will activate the Will feature for lost clients.

To maintain the connection, the server must send a PINGREQ (ping request) packet within the KeepAliveInterval seconds after the most recent message sent. For more see the [Ping](#ping-method-mqttsn-class) method.

Similarly, if the class doesn't receive a PINGRESP (ping response) packet after multiple retransmissions of the PINGREQ packet, it should first try to connect to another gateway before trying to re-connect to the original one.

If KeepAliveInterval is set to 0 (default), the server is not required to consider inactivity. Note that, regardless of keep-alive settings, the server is always free to disconnect clients it deems "unresponsive".

This property is not available at design time.

# LocalHost Property ([MQTTSN](#mqttsn-class) Class)

The name of the local host or user-assigned IP interface through which connections are initiated or accepted.

## Syntax

```text
public String getLocalHost();
public void setLocalHost(String localHost);
```

## Default Value

""

## Remarks

This property contains the name of the local host as obtained by the *gethostname()* system call, or if the user has assigned an IP address, the value of that address.

In multihomed hosts (machines with more than one IP interface) setting LocalHost to the IP address of an interface will make the class initiate connections (or accept in the case of server classes) only through that interface. It is recommended to provide an IP address rather than a hostname when setting this property to ensure the desired interface is used.

If the class is connected, the LocalHost property shows the IP address of the interface through which the connection is made in internet dotted format (aaa.bbb.ccc.ddd). In most cases, this is the address of the local host, except for multihomed hosts (machines with more than one IP interface).

NOTE: LocalHost is not persistent. You must always set it in code, and never in the property window.

# LocalPort Property ([MQTTSN](#mqttsn-class) Class)

This property includes the User Datagram Protocol (UDP) port in the local host where UDP binds.

## Syntax

```text
public int getLocalPort();
public void setLocalPort(int localPort);
```

## Default Value

0

## Remarks

The LocalPort property must be set before UDP is activated (Active is set to True). This instructs the class to bind to a specific port (or communication endpoint) in the local machine.

Setting it to *0* (default) enables the Transmission Control Protocol (TCP)/IP stack to choose a port at random. The chosen port will be shown by the LocalPort property after the connection is established.

LocalPort cannot be changed once the class is Active. Any attempt to set the LocalPort property when the class is Active will generate an error.

The LocalPort property is useful when trying to connect to services that require a trusted port on the client side.

# RemoteHost Property ([MQTTSN](#mqttsn-class) Class)

This property includes the address of the remote host. Domain names are resolved to IP addresses.

## Syntax

```text
public String getRemoteHost();
public void setRemoteHost(String remoteHost);
```

## Default Value

""

## Remarks

The RemoteHost property specifies the IP address (IP number in dotted internet format) or domain name of the remote host.

If RemoteHost is set to 255.255.255.255, the class broadcasts data on the local subnet.

If the RemoteHost property is set to a domain name, a DNS request is initiated, and upon successful termination of the request, the RemoteHost property is set to the corresponding address. If the search is not successful, an error is returned.

If [UseConnection](#UseConnection) is set to True, the RemoteHost must be set before the class is activated (Active is set to True).

# RemotePort Property ([MQTTSN](#mqttsn-class) Class)

This property specifies the User Datagram Protocol (UDP) port in the remote host.

## Syntax

```text
public int getRemotePort();
public void setRemotePort(int remotePort);
```

## Default Value

0

## Remarks

The RemotePort is the UDP port on the [RemoteHost](#remotehost-property-mqttsn-class) to send UDP datagrams to.

A valid port number (a value between 1 and 65535) is required.

If [UseConnection](#UseConnection) is set to True, the RemotePort must be set before the class is activated (Active is set to True).

# Timeout Property ([MQTTSN](#mqttsn-class) Class)

A timeout for the class.

## Syntax

```text
public int getTimeout();
public void setTimeout(int timeout);
```

## Default Value

60

## Remarks

This property defines the timeout when sending data. A value of 0 means data will be sent asynchronously and a positive value means data is sent synchronously.

The class will use [DoEvents](#doevents-method-mqttsn-class) to enter an efficient wait loop during any potential waiting period, making sure that all system events are processed immediately as they arrive. This ensures that the host application does not "freeze" and remains responsive.

If Timeout expires, and the operation is not yet complete, the component throws an exception. Please note that by default, all timeouts are *inactivity timeouts*, i.e. the timeout period is extended by Timeout seconds when any amount of data is successfully sent or received. The default value for the Timeout property is 60 seconds.

# WillMessage Property ([MQTTSN](#mqttsn-class) Class)

The message that the server should publish in the event of an ungraceful disconnection.

## Syntax

```text
public String getWillMessage();
public void setWillMessage(String willMessage);
```

## Default Value

""

## Remarks

This property may be set before calling [Connect](#connect-method-mqttsn-class) to specify to the server a message that should be published on [WillTopic](#willtopic-property-mqttsn-class) if the connection is closed ungracefully or lost.

The WillMessage will only be sent to the server when [Connect](#connect-method-mqttsn-class) is called if [WillTopic](#willtopic-property-mqttsn-class) is set. Note that in MQTTSN the clean session concept is extended to will topic and will message. The WillMessage can be updated with the [UpdateWillMessage](#updatewillmessage-method-mqttsn-class) method.

Refer to [WillTopic](#willtopic-property-mqttsn-class) for more information about MQTT Will functionality.

This property is not available at design time.

# WillTopic Property ([MQTTSN](#mqttsn-class) Class)

The topic that the server should publish the WillMessage to in the event of an ungraceful disconnection.

## Syntax

```text
public String getWillTopic();
public void setWillTopic(String willTopic);
```

## Default Value

""

## Remarks

This property may be set before calling [Connect](#connect-method-mqttsn-class) to specify the topic name that the server should publish the [WillMessage](#willmessage-property-mqttsn-class) on if the connection is closed ungracefully or lost.

### MQTT Wills

The Will feature of MQTT allows a client to specify to the server a [WillMessage](#willmessage-property-mqttsn-class) to publish (as well as a WillTopic to publish it on) in the event that the server considers the client lost or ungracefully disconnected.

An "ungraceful disconnection" is any disconnection *other than* one triggered by calling [Disconnect](#disconnect-method-mqttsn-class). If the client enters sleep mode, the server will not publish the Will. However, if the client is lost as a result of exceeding the sleep duration without sending a message, the server will publish the Will.

In addition to the WillTopic and [WillMessage](#willmessage-property-mqttsn-class) properties, the [WillQOS](#WillQOS) setting may be used to specify the Will message's QoS level, and the [WillRetain](#WillRetain) setting to set the Will message's Retain flag. Refer to those settings for more information.

If WillTopic is set to empty string (default) when [Connect](#connect-method-mqttsn-class) is called, the class *will not* send a Will to the server.

In MQTTSN, the WillTopic, [WillMessage](#willmessage-property-mqttsn-class), [WillQOS](#WillQOS) and [WillRetain](#WillRetain) may all be updated using the [UpdateWillMessage](#updatewillmessage-method-mqttsn-class) and [UpdateWillTopic](#updatewilltopic-method-mqttsn-class) methods.

This property is not available at design time.

# Config Method ([MQTTSN](#mqttsn-class) Class)

Sets or retrieves a configuration setting.

## Syntax

```text
public String config(String configurationString);
```

## Remarks

Config is a generic method available in every class. It is used to set and retrieve [configuration settings](#config-settings-mqttsn-class) for the class.

These settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the class, access to these *internal properties* is provided through the Config method.

To set a configuration setting named *PROPERTY*, you must call *Config("PROPERTY=VALUE")*, where *VALUE* is the value of the setting expressed as a string. For boolean values, use the strings "True", "False", "0", "1", "Yes", or "No" (case does not matter).

To read (query) the value of a [configuration setting](#config-settings-mqttsn-class), you must call *Config("PROPERTY")*. The value will be returned as a string.

# Connect Method ([MQTTSN](#mqttsn-class) Class)

Connects to the MQTTSN Gateway.

## Syntax

```text
public void connect();
```

## Remarks

This method connects to the MQTTSN Gateway, specified by [RemoteHost](#remotehost-property-mqttsn-class) and [RemotePort](#remoteport-property-mqttsn-class), by sending a CONNECT packet.

When connecting to an MQTT gateway, the class sends the following information:

- The values of the [ClientId](#clientid-property-mqttsn-class), [CleanSession](#cleansession-property-mqttsn-class), and [KeepAliveInterval](#keepaliveinterval-property-mqttsn-class) properties.
- The values of the [WillTopic](#willtopic-property-mqttsn-class) and [WillMessage](#willmessage-property-mqttsn-class) properties and the [WillRetain](#WillRetain) and [WillQOS](#WillQOS) configuration settings.

Refer to [CleanSession](#cleansession-property-mqttsn-class) for more information about MQTT sessions; refer to [WillTopic](#willtopic-property-mqttsn-class), [WillMessage](#willmessage-property-mqttsn-class), [WillQOS](#WillQOS) and [WillRetain](#WillRetain) for more information about MQTT Wills.

**Basic Connection Example**

```csharp
mqttsn1.ClientId = "testClient";
mqttsn1.CleanSession = true;
mqttsn1.KeepAliveInterval = 30;
mqttsn1.WillTopic = "wills/" + mqttsn1.ClientId;
mqttsn1.WillMessage = mqttsn1.ClientId + " was disconnected ungracefully!";
mqttsn1.RemoteHost = host;
mqttsn1.RemotePort = port;
mqttsn1.Connect();
```

# ConnectTo Method ([MQTTSN](#mqttsn-class) Class)

Connects to the remote host.

## Syntax

```text
public void connectTo(String host, int port);
```

## Remarks

This method connects to the MQTTSN Gateway, specified by *Host* and *Port*, by sending a CONNECT packet. Calling this method is equivalent to setting the [RemoteHost](#remotehost-property-mqttsn-class) property to *Host* and setting [RemotePort](#remoteport-property-mqttsn-class) to *Port*.

When connecting to an MQTT gateway, the class sends the following information:

- The values of the [ClientId](#clientid-property-mqttsn-class), [CleanSession](#cleansession-property-mqttsn-class), and [KeepAliveInterval](#keepaliveinterval-property-mqttsn-class) properties.
- The values of the [WillTopic](#willtopic-property-mqttsn-class) and [WillMessage](#willmessage-property-mqttsn-class) properties and the [WillRetain](#WillRetain) and [WillQOS](#WillQOS) configuration settings.

Refer to [CleanSession](#cleansession-property-mqttsn-class) for more information about MQTT sessions; refer to [WillTopic](#willtopic-property-mqttsn-class), [WillMessage](#willmessage-property-mqttsn-class), [WillQOS](#WillQOS) and [WillRetain](#WillRetain) for more information about MQTT Wills.

**Basic Connection Example**

```csharp
mqttsn1.ClientId = "testClient";
mqttsn1.CleanSession = true;
mqttsn1.KeepAliveInterval = 30;
mqttsn1.WillTopic = "wills/" + mqttsn1.ClientId;
mqttsn1.WillMessage = mqttsn1.ClientId + " was disconnected ungracefully!";
mqttsn1.ConnectTo(host, port);
```

# Disconnect Method ([MQTTSN](#mqttsn-class) Class)

Disconnect from the MQTTSN Gateway.

## Syntax

```text
public void disconnect();
```

## Remarks

This method disconnects from the MQTTSN Gateway by sending a DISCONNECT packet.

Refer to the [Connected](#connected-property-mqttsn-class) property for more information about MQTT-specific behavior.

# DiscoverGateway Method ([MQTTSN](#mqttsn-class) Class)

Broadcast a SEARCHGW message to network clients and gateways.

## Syntax

```text
public void discoverGateway(int broadcastRadius);
```

## Remarks

Broadcast a SEARCHGW message in order to discover nearby gateways. Network clients and gateways may respond with a GWINFO message containing a gateway id. Such a response will trigger the [GatewayInfo](#gatewayinfo-event-mqttsn-class) event.

This functionality is not yet implemented.

# DoEvents Method ([MQTTSN](#mqttsn-class) Class)

This method processes events from the internal message queue.

## Syntax

```text
public void doEvents();
```

## Remarks

When DoEvents is called, the class processes any available events. If no events are available, it waits for a preset period of time, and then returns.

# Ping Method ([MQTTSN](#mqttsn-class) Class)

Send a PINGREQ message to the gateway to reset the Keep Alive interval and ensure the gateway's liveliness.

## Syntax

```text
public void ping();
```

## Remarks

The client must send a PINGREQ message using this method during each [KeepAliveInterval](#keepaliveinterval-property-mqttsn-class) period. If the client does not send any message to the gateway during this period, it will be considered lost and will disconnect.

The client also uses this message to supervise the liveliness of the gateway to which they are connected. If a client does not receive a PINGRESP from the gateway even after multiple retransmissions of the PINGREQ message, it should first try to connect to another gateway before trying to re-connect to this gateway.

See [KeepAliveInterval](#keepaliveinterval-property-mqttsn-class) for more information.

For more detailed requirements regarding Keep Alive intervals and reconnection, refer to the MQTTSN specification.

# PublishData Method ([MQTTSN](#mqttsn-class) Class)

Publishes a message with a raw data payload.

## Syntax

```text
public void publishData(String topicId, int topicIdType, int QOS, byte[] data);
```

## Remarks

This method publishes an MQTTSN message with a raw data payload to the specified *TopicId* at a given *QOS* level.

The [Retain](#Retain) configuration setting may be set before calling this method in order to publish a retained message (see [Retain](#Retain) for more information).

Note that the class will only allow one publish flow at a time.

**Publish Examples**

```csharp
// Publish string messages
int id = mqttsn1.RegisterTopic("topic/name"); // must register topic names that are not short or pre-defined
mqttsn1.PublishMessage(id, 0, 2, "hello"); // publish message with registered topic name

mqttsn1.PublishMessage("aa", 2, 2, "hello"); // publish message with short topic name

// Publish a raw data message.
byte[] picture = ...;
mqtt1.PublishData(id, 0, 2, picture);
```

### Topic Ids

A topic id is a short identifier corresponding to a longer topic name which is used in MQTTSN due to the limited bandwidth and small message payload in wireless sensor networks.

The type of topic id sent with the message must be specified. *TopicIdType* may have the following values:

- *0*: Registered topic id
- *1*: Pre-defined topic id
- *2*: Short topic name

A registered topic id identifies a topic name registered with the server before the time of the message. To register a topic id for a given topic name with the gateway so that messages may be published to that topic using that topic id, use the [RegisterTopic](#registertopic-method-mqttsn-class) method.

A pre-defined topic id is one whose mapping to a topic name is known in advance by both the client and the gateway - no registration is necessary.

A short topic name has a fixed length of two bytes and is short enough that no registration is necessary. To use one, simply set the correct *TopicIdType* and set the *TopicId* to a two-character string.

### Topic Names

Topic names are case-sensitive, must be 1-65535 characters long, and may include any characters *except* wildcard characters (*#* and *+*) and the null character. The */* character separates levels within a topic name, which is important in the context of subscribing (see [Subscribe](#subscribe-method-mqttsn-class) for more information).

Keep in mind that using topic names with leading or trailing */* characters will cause topic levels with zero-length names to be created. That is, a topic name like */a/b/* consists of the levels *''*, *'a'*, *'b'*, and *''*. Depending on the server, multiple successive */*s may also cause zero-length levels to be created, or may be treated as a single */*.

Topic names that begin with a *$* are "system topics", and servers will typically prevent clients from publishing to them.

### QoS Values

QoS values set the service level for delivery of a message. Values range from -1 to 2 and have the following meanings:

| QoS Level | Description |
| --- | --- |
| -1 | Simple publish - No connection, registration or subscription needed. |
| 0 | At most once - The published message is sent once, and if it does not arrive it is lost. |
| 1 | At least once - Guarantees that the published message arrives, but there may be duplicates. |
| 2 | Exactly once - Guarantees that the publish message arrives and that there are no duplicates. |

To send a message with QoS -1, simply set [RemoteHost](#remotehost-property-mqttsn-class) and [RemoteHost](#remotehost-property-mqttsn-class) and call [PublishMessage](#publishmessage-method-mqttsn-class) with a pre-defined topic id or short topic name. No connection or registration is necessary. The client will not be informed whether the gateway address is correct, whether the gateway is alive, or whether the messages arrive at the gateway.

**Publish QoS -1 Example**

```csharp
mqttsn1 = new Mqttsn();
mqttsn1.RemoteHost = gatewayAddress;
mqttsn1.RemotePort = gatewayPort;
mqttsn1.PublishMessage("aa", 2, -1, "hello"); // publish QoS -1 message; no connection or registration
```

### Republishing Messages

For QoS 1 and 2 messages, the client is responsible for retransmitting the message if it is not fully acknowledged within a reasonable wait time. To do so, set the [Duplicate](#Duplicate) flag configuration setting and call the publish method again.

After a reasonable amount of retransmission attempts, the client should abort the procedure and assume the gateway has disconnected. It should then try to connect to another gateway, only returning to the original if it fails.

# PublishMessage Method ([MQTTSN](#mqttsn-class) Class)

Publishes a message with a string payload.

## Syntax

```text
public void publishMessage(String topicId, int topicIdType, int QOS, String message);
```

## Remarks

This method publishes an MQTTSN message with a string payload to the specified *TopicId* at a given *QOS* level.

The [Retain](#Retain) configuration setting may be set before calling this method in order to publish a retained message (see [Retain](#Retain) for more information).

Note that the class will only allow one publish flow at a time.

**Publish Examples**

```csharp
// Publish string messages
int id = mqttsn1.RegisterTopic("topic/name"); // must register topic names that are not short or pre-defined
mqttsn1.PublishMessage(id, 0, 2, "hello"); // publish message with registered topic name

mqttsn1.PublishMessage("aa", 2, 2, "hello"); // publish message with short topic name

// Publish a raw data message.
byte[] picture = ...;
mqtt1.PublishData(id, 0, 2, picture);
```

### Topic Ids

A topic id is a short identifier corresponding to a longer topic name which is used in MQTTSN due to the limited bandwidth and small message payload in wireless sensor networks.

The type of topic id sent with the message must be specified. *TopicIdType* may have the following values:

- *0*: Registered topic id
- *1*: Pre-defined topic id
- *2*: Short topic name

A registered topic id identifies a topic name registered with the server before the time of the message. To register a topic id for a given topic name with the gateway so that messages may be published to that topic using that topic id, use the [RegisterTopic](#registertopic-method-mqttsn-class) method.

A pre-defined topic id is one whose mapping to a topic name is known in advance by both the client and the gateway - no registration is necessary.

A short topic name has a fixed length of two bytes and is short enough that no registration is necessary. To use one, simply set the correct *TopicIdType* and set the *TopicId* to a two-character string.

### Topic Names

Topic names are case-sensitive, must be 1-65535 characters long, and may include any characters *except* wildcard characters (*#* and *+*) and the null character. The */* character separates levels within a topic name, which is important in the context of subscribing (see [Subscribe](#subscribe-method-mqttsn-class) for more information).

Keep in mind that using topic names with leading or trailing */* characters will cause topic levels with zero-length names to be created. That is, a topic name like */a/b/* consists of the levels *''*, *'a'*, *'b'*, and *''*. Depending on the server, multiple successive */*s may also cause zero-length levels to be created, or may be treated as a single */*.

Topic names that begin with a *$* are "system topics", and servers will typically prevent clients from publishing to them.

### QoS Values

QoS values set the service level for delivery of a message. Values range from -1 to 2 and have the following meanings:

| QoS Level | Description |
| --- | --- |
| -1 | Simple publish - No connection, registration or subscription needed. |
| 0 | At most once - The published message is sent once, and if it does not arrive it is lost. |
| 1 | At least once - Guarantees that the published message arrives, but there may be duplicates. |
| 2 | Exactly once - Guarantees that the publish message arrives and that there are no duplicates. |

To send a message with QoS -1, simply set [RemoteHost](#remotehost-property-mqttsn-class) and [RemoteHost](#remotehost-property-mqttsn-class) and call PublishMessage with a pre-defined topic id or short topic name. No connection or registration is necessary. The client will not be informed whether the gateway address is correct, whether the gateway is alive, or whether the messages arrive at the gateway.

**Publish QoS -1 Example**

```csharp
mqttsn1 = new Mqttsn();
mqttsn1.RemoteHost = gatewayAddress;
mqttsn1.RemotePort = gatewayPort;
mqttsn1.PublishMessage("aa", 2, -1, "hello"); // publish QoS -1 message; no connection or registration
```

### Republishing Messages

For QoS 1 and 2 messages, the client is responsible for retransmitting the message if it is not fully acknowledged within a reasonable wait time. To do so, set the [Duplicate](#Duplicate) flag configuration setting and call the publish method again.

After a reasonable amount of retransmission attempts, the client should abort the procedure and assume the gateway has disconnected. It should then try to connect to another gateway, only returning to the original if it fails.

# RegisterTopic Method ([MQTTSN](#mqttsn-class) Class)

Register a topic name. Returns the topic id mapped to the newly registered topic name.

## Syntax

```text
public int registerTopic(String topicName);
```

## Remarks

Requests that the gateway establish a new topic id mapping for the *TopicName* provided. If accepted, the gateway assigns a topic id to the received topic name and returns it. At this point, the client may begin sending messages with this topic id.

### Topic Names

Topic names are case-sensitive, must be 1-65535 characters long, and may include any characters *except* wildcard characters (*#* and *+*) and the null character. The */* character separates levels within a topic name, which is important in the context of subscribing (see [Subscribe](#subscribe-method-mqttsn-class) for more information).

Keep in mind that using topic names with leading or trailing */* characters will cause topic levels with zero-length names to be created. That is, a topic name like */a/b/* consists of the levels *''*, *'a'*, *'b'*, and *''*. Depending on the server, multiple successive */*s may also cause zero-length levels to be created, or may be treated as a single */*.

Topic names that begin with a *$* are "system topics", and servers will typically prevent clients from publishing to them.

# Reset Method ([MQTTSN](#mqttsn-class) Class)

This method will reset the class.

## Syntax

```text
public void reset();
```

## Remarks

This method will reset the class's properties to their default values.

# RetrieveMessages Method ([MQTTSN](#mqttsn-class) Class)

Receive currently buffered messages and return to sleep.

## Syntax

```text
public void retrieveMessages();
```

## Remarks

Request any messages currently being buffered by the server for the current sleep period and return to sleep after they have been received.

Any available buffered messages will be sent to the client by the MQTTSN Gateway and the sleep interval will be reset.

This method sends a PINGREQ method with the [ClientId](#clientid-property-mqttsn-class), requesting buffered messages which will be sent if available (see [MessageIn](#messagein-event-mqttsn-class)). When the server has sent all messages, it will sent a PINGRESP message, causing the client to re-enter sleep mode. Once the PINGRESP is received, the duration the client may sleep restarts.

# SendDiscoverResponse Method ([MQTTSN](#mqttsn-class) Class)

Asynchronously respond to a SEARCHGW message received from a peer.

## Syntax

```text
public void sendDiscoverResponse(int gatewayId, String gatewayAddress);
```

## Remarks

Asynchronously respond to a SEARCHGW message received from a peer. See also [DiscoverRequest](#discoverrequest-event-mqttsn-class).

This functionality is not yet implemented.

# StartSleep Method ([MQTTSN](#mqttsn-class) Class)

Enter sleep state for the specified duration.

## Syntax

```text
public void startSleep(int duration);
```

## Remarks

When this method is called, the gateway will buffer all incoming messages for the client until the next time it awakes. To receive all currently buffered messages, call [StopSleep](#stopsleep-method-mqttsn-class) or [RetrieveMessages](#retrievemessages-method-mqttsn-class).

While in the sleep state, the client no longer must abide by the [KeepAliveInterval](#keepaliveinterval-property-mqttsn-class), but must awake before the end of the sleep duration. If it does not send the gateway any messages in this interval, it will be considered lost and will disconnect.

If [RetrieveMessages](#retrievemessages-method-mqttsn-class) is called, the client will return to sleep after receiving the messages and the sleep timer will restart. If [StopSleep](#stopsleep-method-mqttsn-class) is called, the client will enter the active state.

**Sleep Examples**

```csharp
mqttsn1.StartSleep(8); // sleep for 8 seconds
// ... wait for 5 seconds
mqttsn1.RetrieveMessages(); // MessageIn will fire for each message buffered during that time
// ... wait for 5 more seconds (ok because <8 seconds since last packet sent)
mqttsn1.StopSleep();
```

# StopSleep Method ([MQTTSN](#mqttsn-class) Class)

Enter active state, ending the sleep period.

## Syntax

```text
public void stopSleep();
```

## Remarks

Wake up from the sleep state and receive any messages which were buffered by the gateway during the sleep period. This method must be called before the end of the duration specified in the [StartSleep](#startsleep-method-mqttsn-class) method.

Once active, the client is once again subject to [KeepAliveInterval](#keepaliveinterval-property-mqttsn-class) supervision just like after connection.

# Subscribe Method ([MQTTSN](#mqttsn-class) Class)

Subscribes the class to the specified topic.

## Syntax

```text
public void subscribe(String topicId, int topicIdType, int QOS);
```

## Remarks

This method subscribes the class to the *TopicId* using the given *QoS* level.

*TopicIdType* indicates the category of value specified in *TopicId* and may have the following values:

- *0*: Topic name - a full topic name as described in [RegisterTopic](#registertopic-method-mqttsn-class) to be registered by the gateway.
- *1*: Pre-defined topic id - id whose mapping to a topic name is known in advance by both the client and the gateway - no registration is necessary.
- *2*: Short topic name - has a fixed length of two bytes and is short enough that no registration is necessary. To use one, simply set the correct *TopicIdType* and set the *TopicId* to a two-character string.

If the topic name option is used, the topic id returned with the SUBACK packet will be accessible in the [SubscribedTopicId](#SubscribedTopicId) configuration setting. If a topic name with a wildcard character is used, [SubscribedTopicId](#SubscribedTopicId) will be *0*. When the gateway has a PUBLISH message with a topic name matching the wildcard to be sent to the client, it will follow the registration process described in [TopicInfo](#topicinfo-event-mqttsn-class).

**Subscribe Examples**

```csharp
String fullTopicName = "full/topic/name";
mqttsn1.Subscribe(fullTopicName, 0, 2); // subscribe with topic name
int assignedTopicId = mqttsn1.Config("SubscribedTopicId"); // map id to topic name used

mqttsn1.Subscribe(fullTopicName+"/#", 0, 2) // topic name with wildcard; SubscribedTopicId will be 0
mqttsn1.OnTopicId += (s,e) => { // will fire before messages matching the wildcard are sent to the client
  int topicId = e.TopicId;
  String topicName = e.TopicName;
  // establish mapping between these
};

mqttsn1.Subscribe("aa", 2, 2); // subscribe with short topic name; no need for registration
```

### Topic Filters

A topic filter is a string which can be passed to *TopicId* when *TopicIdType* is *0* and can match one or more topic names.

A topic filter is a case-sensitive string between 1 and 65535 characters long (per topic filter), and can include any character other than the null character. Certain characters have special meanings:

- */* - The topic level separator
- *#* - The multi-level wildcard (zero or more levels)
- *+* - The single-level wildcard (exactly one level)
- Leading *$* - Denotes a "system topic"

Note that both types of wildcards may be used in the same topic filter.

**Topic Level Separators**

The topic level separator, as its name implies, is used to separate a topic name (or in this case, filter) into "levels". This concept of topic names having levels is what allows topic filters to match multiple topics through the use of wildcards. For the examples in the next sections, assume the following topics exist:

- *home/floor1*
- *home/floor1/livingRoom*
- *home/floor1/livingRoom/temperature*
- *home/floor1/kitchen/temperature*
- *home/floor1/kitchen/fridge/temperature*
- *home/floor2/bedroom1*
- *home/floor2/bedroom1/temperature*

**Multi-level Wildcards**

The multi-level wildcard character is used at the end of a topic filter to make it match an arbitrary number of successive levels. For example, the topic filter *home/floor1/#* would match the following topics:

- *home/floor1 (because it can match zero levels)*
- *home/floor1/livingRoom*
- *home/floor1/livingRoom/temperature*
- *home/floor1/kitchen/temperature*
- *home/floor1/kitchen/fridge/temperature*

Here are some things to keep in mind when using a multi-level wildcard:

- *#* must always be the last character in the topic filter (e.g., *home/floor1/#/livingRoom* is not valid)
- *#* must always be preceded by a */* (e.g., *home/floor1#* is not valid)
- *#* by itself is a valid topic filter, and will match all topics except system topics

**Single-level Wildcards**

The single-level wildcard character is used between two */*s in a topic filter to make it any single level. For example, the topic filter *home/floor1/+/temperature* would match the following topics:

- *home/floor1/livingRoom/temperature*
- *home/floor1/kitchen/temperature*

Any number of single-level wildcards are supported in a topic filter. For example, the topic filter *home/+/+/temperature* would match the following topics:

- *home/floor1/livingRoom/temperature*
- *home/floor1/kitchen/temperature*
- *home/floor2/bedroom1/temperature*

Here are some things to keep in mind when using single-level wildcards:

- *+* must always be separated from other levels using */*s (e.g., *home/floor1+* is invalid, but *+/floor1/+* is valid)
- *+* by itself is a valid topic filter, and will match all topics with exactly one level in their name except system topics
- Remember, topic names with a leading */* have a zero-length string as their first level. So a topic named */people* would be matched by the topic filter *+/+*, but *not* by *+*
- *+* *must* match *exactly* one level. So for example, the topic filter *home/floor1/kitchen/+/temperature* would match */home/floor1/kitchen/fridge/temperature*, but *not* *home/floor1/kitchen/temperature*

### QoS Values

QoS values set the service level for delivery of a message. For subscriptions, values range from 0 to 2 and have the following meanings:

| QoS Level | Description |
| --- | --- |
| -1 | Simple publish - No connection, registration or subscription needed. |
| 0 | At most once - The published message is sent once, and if it does not arrive it is lost. |
| 1 | At least once - Guarantees that the published message arrives, but there may be duplicates. |
| 2 | Exactly once - Guarantees that the publish message arrives and that there are no duplicates. |

A QoS value of -1 is not applicable to subscriptions.

Note that if this message is being resent, the [SubscribeDUP](#SubscribeDUP) configuration setting must be enabled. For more details on retransmission intervals and counts, see the MQTTSN specification.

# Unsubscribe Method ([MQTTSN](#mqttsn-class) Class)

Unsubscribes the class from the specified topic.

## Syntax

```text
public void unsubscribe(String topicId, int topicIdType);
```

## Remarks

This method unsubscribes the class to the *TopicId*.

*TopicIdType* indicates the category of value specified in *TopicId* and may have the following values:

- *0*: Topic name - a full topic name as described in [RegisterTopic](#registertopic-method-mqttsn-class) to be registered by the gateway.
- *1*: Pre-defined topic id - id whose mapping to a topic name is known in advance by both the client and the gateway - no registration is necessary.
- *2*: Short topic name - has a fixed length of two bytes and is short enough that no registration is necessary. To use one, simply set the correct *TopicIdType* and set the *TopicId* to a two-character string.

**Unsubscribe Examples**

```csharp
String fullTopicName = "full/topic/name";
mqtt1.Unsubscribe(fullTopicName, 0); // unsubscribe from topic name

mqtt1.Unsubscribe(fullTopicName+"/#", 0); // must use full topic filter if includes wildcard; can't unsubscribe from individual topics included in the filter

mqtt1.Unsubscribe("aa", 2); // unsubscribe from short topic
```

# UpdateWillMessage Method ([MQTTSN](#mqttsn-class) Class)

Update the will message stored in session state data by the server.

## Syntax

```text
public void updateWillMessage();
```

## Remarks

When this message is called, the value of [WillMessage](#willmessage-property-mqttsn-class) will be used to update the will message stored by the server.

This method may be called when this value is empty, in this case the server value will be cleared.

See [UpdateWillTopic](#updatewilltopic-method-mqttsn-class) for more on updating will settings.

# UpdateWillTopic Method ([MQTTSN](#mqttsn-class) Class)

Update the will topic, will QoS and will retain flag stored in session state data by the server.

## Syntax

```text
public void updateWillTopic();
```

## Remarks

When this message is called, the value of [WillTopic](#willtopic-property-mqttsn-class), [WillQOS](#WillQOS) and [WillRetain](#WillRetain) will be used to update the will message stored by the server.

This method may be called when these values are empty, in this case the server values will be cleared.

See [UpdateWillMessage](#updatewillmessage-method-mqttsn-class) for more on updating will settings.

# Connected Event ([MQTTSN](#mqttsn-class) Class)

Fired after a MQTTSN connection completes (or fails).

## Syntax

```text
public class DefaultMQTTSNEventListener implements MQTTSNEventListener {
  ...
  public void connected(MQTTSNConnectedEvent e) {}
  ...
}

public class MQTTSNConnectedEvent {
  public int statusCode;
  public String description;
}
```

## Remarks

If no will topic or message is set, this event will fire immediately. If a will topic and the will message are set, this event will be fired after the will packet exchange.

If the connection is made normally, *StatusCode* is 0 and *Description* is "OK".

Please refer to the [Error Codes](#trappable-errors-mqttsn-class) section for more information.

Refer to the [Connected](#connected-property-mqttsn-class) property for more information about MQTT-specific behavior.

# Disconnected Event ([MQTTSN](#mqttsn-class) Class)

Fired when a MQTTSN connection is closed.

## Syntax

```text
public class DefaultMQTTSNEventListener implements MQTTSNEventListener {
  ...
  public void disconnected(MQTTSNDisconnectedEvent e) {}
  ...
}

public class MQTTSNDisconnectedEvent {
  public int statusCode;
  public String description;
}
```

## Remarks

If the connection is broken normally, *StatusCode* is 0 and *Description* is "OK".

Refer to the [Connected](#connected-property-mqttsn-class) property for more information about MQTT-specific behavior.

# DiscoverRequest Event ([MQTTSN](#mqttsn-class) Class)

Fired when the class receives a SEARCHGW packet from another client.

## Syntax

```text
public class DefaultMQTTSNEventListener implements MQTTSNEventListener {
  ...
  public void discoverRequest(MQTTSNDiscoverRequestEvent e) {}
  ...
}

public class MQTTSNDiscoverRequestEvent {
  public int radius;
  public int gatewayId; //read-write
  public String gatewayAddress; //read-write
  public boolean respond; //read-write
}
```

## Remarks

This event allows the client to process the received gateway info and decide whether or not to respond to the search request.

If *Respond* is set to *True*, the class will respond with a GWINFO packet.

This functionality is not yet implemented.

# Error Event ([MQTTSN](#mqttsn-class) Class)

Fired when information is available about errors during data delivery.

## Syntax

```text
public class DefaultMQTTSNEventListener implements MQTTSNEventListener {
  ...
  public void error(MQTTSNErrorEvent e) {}
  ...
}

public class MQTTSNErrorEvent {
  public int errorCode;
  public String description;
}
```

## Remarks

The Error event is fired in case of exceptional conditions during message processing. Normally the class throws an exception.

The *ErrorCode* parameter contains an error code, and the *Description* parameter contains a textual description of the error. For a list of valid error codes and their descriptions, please refer to the [Error Codes](#trappable-errors-mqttsn-class) section.

# GatewayInfo Event ([MQTTSN](#mqttsn-class) Class)

Fired when the class receives a GWINFO or ADVERTISE packet.

## Syntax

```text
public class DefaultMQTTSNEventListener implements MQTTSNEventListener {
  ...
  public void gatewayInfo(MQTTSNGatewayInfoEvent e) {}
  ...
}

public class MQTTSNGatewayInfoEvent {
  public String messageType;
  public int gatewayId;
  public String gatewayAddress;
  public int interval;
}
```

## Remarks

This event allows packets containing gateway information to be processed. These packets could be received from regular gateway advertisements or gateway info requests from this or other clients. This gateway information is used to manage the client's list of active gateways.

The value of *MessageType* could be *GWINFO* or *ADVERTISE*.

*GatewayAddress* will be in format *host:port*.

If the gateway address field is not present in the received GWINFO packet, *GatewayAddress* will use the packet source IP address.

This functionality is not yet implemented.

# Log Event ([MQTTSN](#mqttsn-class) Class)

Fires once for each log message.

## Syntax

```text
public class DefaultMQTTSNEventListener implements MQTTSNEventListener {
  ...
  public void log(MQTTSNLogEvent e) {}
  ...
}

public class MQTTSNLogEvent {
  public int logLevel;
  public String message;
  public String logType;
}
```

## Remarks

This event fires once for each log message generated by the class. The verbosity is controlled by the [LogLevel](#LogLevel) setting.

*LogLevel* indicates the level of the *Message*. Possible values are:

|  |  |
| --- | --- |
| 0 (None) | No events are logged. |
| 1 (Info - default) | Informational events are logged. |
| 2 (Verbose) | Detailed data is logged. |
| 3 (Debug) | Debug data is logged. |

*LogType* identifies the type of log entry. Possible values are:

- Info: General information about the class.
- Packet: Packet content logging.
- Reconnect: Reconnection status messages.
- Session: Session status messages.

# MessageIn Event ([MQTTSN](#mqttsn-class) Class)

Fired when an incoming message has been received and/or fully acknowledged.

## Syntax

```text
public class DefaultMQTTSNEventListener implements MQTTSNEventListener {
  ...
  public void messageIn(MQTTSNMessageInEvent e) {}
  ...
}

public class MQTTSNMessageInEvent {
  public int msgId;
  public String topicId;
  public int topicIdType;
  public int QOS;
  public byte[] message;
  public boolean retained;
  public boolean duplicate;
  public int returnCode; //read-write
}
```

## Remarks

Fired on reception of a PUBLISH packet for QoS 0 and 1 messages, and reception of a PUBREL packet for QoS 2 messages.

- *MsgId*: a unique (among currently unacknowledged incoming messages) identifier attached to messages of QoS 1 and 2. Otherwise value will be *0*.
- *TopicId*: topic id of type *TopicIdType*.
- *TopicIdType*: *0* = registered topic id, *1* = pre-defined topic id, *2* = short topic name.
- *QOS*: The message's QoS level.
- *Message*: The message data.
- *Retained*: Whether or not this message was received as a result of subscribing to a topic.
- *Duplicate*: Whether or not the server has indicated that this message is a duplicate of another message sent previously.
- *ReturnCode*: QoS 1 messages can be accepted or rejected by setting the *ReturnCode* to a value listed below.

  - *0*: accepted
  - *1*: rejected - congestion
  - *2*: rejected - invalid topic id
  - *3*: rejected - not supported

### Inbound Message Processing

Incoming messages with a QoS of 1 follow these steps:

1. The [TopicInfo](#topicinfo-event-mqttsn-class) event is fired (if the gateway sends a REGISTER packet because it needs to inform the client name and assigned topic id it will use in a PUBLISH message).
2. The class sends a REGACK (register acknowledgment) packet in response (if a REGISTER packet was received).
3. The MessageIn event is fired.
4. The class sends a PUBACK (publish acknowledgment) packet in response (with the return code from the MessageIn event if one is set).

Incoming messages with a QoS of 2 follow these steps:

1. The [TopicInfo](#topicinfo-event-mqttsn-class) event is fired (if the gateway sends a REGISTER packet because it needs to inform the client name and assigned topic id it will use in a PUBLISH message).
2. The class sends a REGACK (register acknowledgment) packet in response (if a REGISTER packet was received).
3. The class sends a PUBREC (publish received) packet in response.
4. The class waits to receive a PUBREL (publish release) packet.
5. The class sends a PUBCOMP (publish complete) packet in response.
6. The MessageIn event is fired.

# TopicInfo Event ([MQTTSN](#mqttsn-class) Class)

Fired when the client receives a REGISTER packet from the gateway assigning a topic id to a topic name.

## Syntax

```text
public class DefaultMQTTSNEventListener implements MQTTSNEventListener {
  ...
  public void topicInfo(MQTTSNTopicInfoEvent e) {}
  ...
}

public class MQTTSNTopicInfoEvent {
  public int topicId;
  public String topicName;
  public int returnCode; //read-write
}
```

## Remarks

A gateway sends a REGISTER packet to a client if it wants to inform that client about the topic name and the assigned topic id that it will use later on when sending PUBLISH messages of the corresponding topic name. The client must establish a new topic id mapping to the topic name indicated.

This happens for example when the client connects without starting a clean session or the client has subscribed to topic names that contain wildcard characters.

When a REGISTER packet is received, the class will respond with a REGACK packet. To set the value of the return code contained in the packet, set it to one of the below values.

- *0*: accepted
- *1*: rejected - congestion
- *2*: rejected - invalid topic id
- *3*: rejected - not supported

When a client subscribes to a topic with wildcard characters, the specific topic names it will receive messages on have not yet been registered to topic ids, so the first step in receiving such messages is the REGISTER packet. It can then receive incoming messages with that id. See [MessageIn](#messagein-event-mqttsn-class) for more.

# Config Settings ([MQTTSN](#mqttsn-class) Class)

 The class accepts one or more of the following *configuration settings*. Configuration settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the class, access to these *internal properties* is provided through the [Config](#config-method-mqttsn-class) method.

### MQTTSN Config Settings

**ConnectionTimeout**: How long to wait for a connection attempt to succeed.This setting controls how long the class will wait, in seconds, for connection attempt to succeed before timing out. The default is 60 seconds.

**Duplicate**: Whether to set the Duplicate flag when publishing a message.When enabled, the component will set the Duplicate flag when a message is published using [PublishData](#publishdata-method-mqttsn-class) or [PublishMessage](#publishmessage-method-mqttsn-class). See those methods for details on retransmission.

**LogLevel**: The level of detail that is logged.This setting controls the level of detail that is logged through the [Log](#log-event-mqttsn-class) event. Possible values are:

|  |  |
| --- | --- |
| 0 (None) | No events are logged. |
| 1 (Info - default) | Informational events are logged. |
| 2 (Verbose) | Detailed data is logged. |
| 3 (Debug) | Debug data is logged. |

**PingTimeout**: Length of time to wait for a PINGRESP packet.This setting controls how long the class will wait, in seconds, for a response to a ping message before timing out. The default is 5 seconds.

**Retain**: Whether to set the Retain flag when publishing a message.When enabled, the class will set the Retain flag when a message is published using [PublishData](#publishdata-method-mqttsn-class) or [PublishMessage](#publishmessage-method-mqttsn-class). By default, this is disabled.

Publishing a *non-empty* message with the Retain flag set and a non-zero QoS will cause the server to store it (replacing any previously retained message in the process) so that it can be delivered to any clients which subscribe to the topic in the future. (If the QoS is 0, the server *can* store the message, but it is not *required* to do so indefinitely, if at all.)

If the class publishes an *empty* message with the Retain flag set, then (regardless of its QoS) the server will remove any previously retained message for the topic.

Note that messages with the Retain flag set are still processed by the server and delivered as usual to clients currently subscribed to the topic, regardless of whether they are empty or not. Also note that retained messages are not part of a session's state, they are retained until they are either removed or replaced by another retained message, regardless of whether or not the client connected with [CleanSession](#cleansession-property-mqttsn-class) set to *True*.

**SubscribedTopicId**: Topic id assigned by the gateway when a topic name is used in a SUBSCRIBE message.When the client uses a *TopicIdType* of *0* (topic name), this name must be registered to a topic id. In this scenario, the topic id assigned will be included in the SUBACK message and will be set here when it is received.

See [Subscribe](#subscribe-method-mqttsn-class) for more details.

**SubscribeDUP**: Whether to set the Duplicate flag when subscribe to a topic.When enabled, the component will set the Duplicate flag when [Subscribe](#subscribe-method-mqttsn-class) is called. See that method for details on retransmission.

**WillQOS**: The QoS value to use for the Will message.If [WillTopic](#willtopic-property-mqttsn-class) is set to a non-empty string when [Connect](#connect-method-mqttsn-class) is called, this is the QoS value that will be used for the Will message; possible values are 0 (default), 1, and 2. (Note that this setting is ignored if [WillTopic](#willtopic-property-mqttsn-class) is empty.)

Refer to [WillTopic](#willtopic-property-mqttsn-class) for more information.

**WillRetain**: Whether the server should retain the Will message after publishing it.If [WillTopic](#willtopic-property-mqttsn-class) is set to a non-empty string when [Connect](#connect-method-mqttsn-class) is called, this determines whether or not the server will treat the Will message as retained. By default, this is disabled. (Note that this setting is ignored if [WillTopic](#willtopic-property-mqttsn-class) is empty.)

See [Retain](#Retain) for general information about how retained messages are handled by the server.

Refer to [WillTopic](#willtopic-property-mqttsn-class) for more information.

### Base Config Settings

**BuildInfo**: Information about the product's build.When queried, this setting will return a string containing information about the product's build.

**GUIAvailable**: Whether or not a message loop is available for processing events.In a GUI-based application, long-running blocking operations may cause the application to stop responding to input until the operation returns. The class will attempt to discover whether or not the application has a message loop and, if one is discovered, it will process events in that message loop during any such blocking operation.

In some non-GUI applications, an invalid message loop may be discovered that will result in errant behavior. In these cases, setting [GUIAvailable](#GUIAvailable) to *false* will ensure that the class does not attempt to process external events.

**LicenseInfo**: Information about the current license.When queried, this setting will return a string containing information about the license this instance of a class is using. It will return the following information:

- Product: The product the license is for.
- Product Key: The key the license was generated from.
- License Source: Where the license was found (e.g., RuntimeLicense, License File).
- License Type: The type of license installed (e.g., Royalty Free, Single Server).
- Last Valid Build: The last valid build number for which the license will work.

**MaskSensitiveData**: Whether sensitive data is masked in log messages.In certain circumstances it may be beneficial to mask sensitive data, like passwords, in log messages. Set this to *true* to mask sensitive data. The default is *true*.

**UseDaemonThreads**: Whether threads created by the class are daemon threads.If set to True (default), when the class creates a thread, the thread's Daemon property will be explicitly set to True. When set to False, the class will not set the Daemon property on the created thread. The default value is True.

**UseFIPSCompliantAPI**: Tells the class whether or not to use FIPS certified APIs.When set to *true*, the class will utilize the underlying operating system's certified APIs. Java editions, regardless of OS, utilize Bouncy Castle Federal Information Processing Standards (FIPS), while all other Windows editions make use of Microsoft security libraries.

The Java edition requires installation of the FIPS-certified Bouncy Castle library regardless of the target operating system. This can be downloaded from [https://www.bouncycastle.org/fips-java/](https://www.bouncycastle.org/fips-java/). Only the "Provider" library is needed. The jar file should then be installed in a JRE search path.

The following classes must be imported in the application in which the component will be used:

```text
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
```

The Bouncy Castle provider must be added as a valid provider and must also be configured to operate in FIPS mode:

```text
System.setProperty("org.bouncycastle.fips.approved_only","true");
Security.addProvider(new BouncyCastleFipsProvider());
```

When [UseFIPSCompliantAPI](#UseFIPSCompliantAPI) is *true*, Secure Sockets Layer (SSL)-enabled classes can optionally be configured to use the Transport Layer Security (TLS) Bouncy Castle library. When SSLProvider is set to *sslpAutomatic* (default) or *sslpInternal*, an internal TLS implementation is used, but all cryptographic operations are offloaded to the Bouncy Castle FIPS provider to achieve FIPS-compliant operation. If SSLProvider is set to *sslpPlatform*, the Bouncy Castle JSSE will be used in place of the internal TLS implementation.

To enable the use of the Bouncy Castle JSSE take the following steps in addition to the steps above. Both the Bouncy Castle FIPS provider and the Bouncy Castle JSSE must be configured to use the Bouncy Castle TLS library in FIPS mode. Obtain the Bouncy Castle TLS library from [https://www.bouncycastle.org/fips-java/](https://www.bouncycastle.org/fips-java/). The jar file should then be installed in a JRE search path.

The following classes must be imported in the application in which the component will be used:

```text
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

//required to use BCJSSE when SSLProvider is set to sslpPlatform
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
```

The Bouncy Castle provider must be added as a valid provider and also must be configured to operate in FIPS mode:

```text
System.setProperty("org.bouncycastle.fips.approved_only","true");
Security.addProvider(new BouncyCastleFipsProvider());

//required to use BCJSSE when SSLProvider is set to sslpPlatform
Security.addProvider(new BouncyCastleJsseProvider("fips:BCFIPS"));

//optional - configure logging level of BCJSSE
Logger.getLogger("org.bouncycastle.jsse").setLevel(java.util.logging.Level.OFF);

//configure the class to use BCJSSE
component.setSSLProvider(1); //platform
component.config("UseFIPSCompliantAPI=true");
```

 NOTE: TLS 1.3 support requires the Bouncy Castle TLS library version 1.0.14 or later.

FIPS mode can be enabled by setting the *UseFIPSCompliantAPI* configuration setting to *true*. This is a static setting that applies to all instances of all classes of the toolkit within the process. It is recommended to enable or disable this setting once before the component has been used to establish a connection. Enabling FIPS while an instance of the component is active and connected may result in unexpected behavior.

For more details, please see the [FIPS 140-2 Compliance](https://www.nsoftware.com/kb/articles/fips.rst) article.

NOTE: Enabling FIPS compliance requires a special license; please contact [sales@nsoftware.com](mailto:sales@nsoftware.com) for details.

**UseInternalSecurityAPI**: Whether or not to use the system security libraries or an internal implementation. When set to *false*, the class will use the system security libraries by default to perform cryptographic functions where applicable.

Setting this configuration setting to *true* tells the class to use the internal implementation instead of using the system security libraries.

 This setting is set to *false* by default on all platforms.

**UseVirtualThreads**: Whether threads created by the class use virtual threads instead of platform threads.If set to *true*, when the class creates a thread, it will be created as a virtual thread instead of a platform thread. Virtual threads are lightweight threads managed by the JVM that are multiplexed onto a small pool of carrier threads, significantly reducing memory usage and platform thread count under high-concurrency workloads. Requires Java 24 or later. The default value is *false*.

# Trappable Errors ([MQTTSN](#mqttsn-class) Class)

### UDP Errors

|  |  |
| --- | --- |
| 104 | UDP is already Active. |
| 106 | You cannot change the [LocalPort](#localport-property-mqttsn-class) while the class is Active. |
| 107 | You cannot change the [LocalHost](#localhost-property-mqttsn-class) at this time. A connection is in progress. |
| 109 | The class must be Active for this operation. |
| 112 | You cannot change [MaxPacketSize](#MaxPacketSize) while the class is Active. |
| 113 | You cannot change [ShareLocalPort](#ShareLocalPort) option while the class is Active. |
| 114 | You cannot change [RemoteHost](#remotehost-property-mqttsn-class) when [UseConnection](#UseConnection) is set and the class Active. |
| 115 | You cannot change [RemotePort](#remoteport-property-mqttsn-class) when [UseConnection](#UseConnection) is set and the class is Active. |
| 116 | [RemotePort](#remoteport-property-mqttsn-class) cannot be zero when [UseConnection](#UseConnection) is set. Please specify a valid service port number. |
| 117 | You cannot change [UseConnection](#UseConnection) while the class is Active. |
| 118 | Message cannot be longer than [MaxPacketSize](#MaxPacketSize). |
| 119 | Message too short. |
| 434 | Unable to convert string to selected CodePage. |

### SSL Errors

|  |  |
| --- | --- |
| 270 | Cannot load specified security library. |
| 271 | Cannot open certificate store. |
| 272 | Cannot find specified certificate. |
| 273 | Cannot acquire security credentials. |
| 274 | Cannot find certificate chain. |
| 275 | Cannot verify certificate chain. |
| 276 | Error during handshake. |
| 280 | Error verifying certificate. |
| 281 | Could not find client certificate. |
| 282 | Could not find server certificate. |
| 283 | Error encrypting data. |
| 284 | Error decrypting data. |

### TCP/IP Errors

|  |  |
| --- | --- |
| 10004 | [10004] Interrupted system call. |
| 10009 | [10009] Bad file number. |
| 10013 | [10013] Access denied. |
| 10014 | [10014] Bad address. |
| 10022 | [10022] Invalid argument. |
| 10024 | [10024] Too many open files. |
| 10035 | [10035] Operation would block. |
| 10036 | [10036] Operation now in progress. |
| 10037 | [10037] Operation already in progress. |
| 10038 | [10038] Socket operation on nonsocket. |
| 10039 | [10039] Destination address required. |
| 10040 | [10040] Message is too long. |
| 10041 | [10041] Protocol wrong type for socket. |
| 10042 | [10042] Bad protocol option. |
| 10043 | [10043] Protocol is not supported. |
| 10044 | [10044] Socket type is not supported. |
| 10045 | [10045] Operation is not supported on socket. |
| 10046 | [10046] Protocol family is not supported. |
| 10047 | [10047] Address family is not supported by protocol family. |
| 10048 | [10048] Address already in use. |
| 10049 | [10049] Cannot assign requested address. |
| 10050 | [10050] Network is down. |
| 10051 | [10051] Network is unreachable. |
| 10052 | [10052] Net dropped connection or reset. |
| 10053 | [10053] Software caused connection abort. |
| 10054 | [10054] Connection reset by peer. |
| 10055 | [10055] No buffer space available. |
| 10056 | [10056] Socket is already connected. |
| 10057 | [10057] Socket is not connected. |
| 10058 | [10058] Cannot send after socket shutdown. |
| 10059 | [10059] Too many references, cannot splice. |
| 10060 | [10060] Connection timed out. |
| 10061 | [10061] Connection refused. |
| 10062 | [10062] Too many levels of symbolic links. |
| 10063 | [10063] File name is too long. |
| 10064 | [10064] Host is down. |
| 10065 | [10065] No route to host. |
| 10066 | [10066] Directory is not empty |
| 10067 | [10067] Too many processes. |
| 10068 | [10068] Too many users. |
| 10069 | [10069] Disc Quota Exceeded. |
| 10070 | [10070] Stale NFS file handle. |
| 10071 | [10071] Too many levels of remote in path. |
| 10091 | [10091] Network subsystem is unavailable. |
| 10092 | [10092] WINSOCK DLL Version out of range. |
| 10093 | [10093] Winsock is not loaded yet. |
| 11001 | [11001] Host not found. |
| 11002 | [11002] Nonauthoritative 'Host not found' (try again or check DNS setup). |
| 11003 | [11003] Nonrecoverable errors: FORMERR, REFUSED, NOTIMP. |
| 11004 | [11004] Valid name, no data record (check DNS setup). |
