

# Tutorial: Demonstrate MQTT message communication with the AWS IoT Device Client
<a name="iot-dc-testconn"></a>

This tutorial demonstrates how the AWS IoT Device Client can subscribe to and publish MQTT messages, which are commonly used in IoT solutions.

**To start this tutorial:**
+ Have your local host computer and Raspberry Pi configured as used in [the previous section](iot-dc-install-dc.md).

  If you saved the microSD card image after installing the AWS IoT Device Client, you can use a microSD card with that image with your Raspberry Pi.
+ If you have run this demo before, review [Step 2: Cleaning up your AWS account after building demos with the AWS IoT Device Client](iot-dc-cleanup.md#iot-dc-cleanup-cloud) to delete all AWS IoT resources that you created in earlier runs to avoid duplicate resource errors.

This tutorial takes about 45 minutes to complete.

**When you're finished with this topic:**
+ You'll have demonstrated different ways that your IoT device can subscribe to MQTT messages from AWS IoT and publish MQTT messages to AWS IoT.

**Required equipment:**
+ Your local development and testing environment from [the previous section](iot-dc-install-dc.md)
+ The Raspberry Pi that you used in [the previous section](iot-dc-install-dc.md)
+ The microSD memory card from the Raspberry Pi that you used in [the previous section](iot-dc-install-dc.md)

**Topics**
+ [Prepare the Raspberry Pi to demonstrate MQTT message communication](iot-dc-testconn-provision.md)
+ [Demonstrate publishing messages with the AWS IoT Device Client](iot-dc-testconn-publish.md)
+ [Demonstrate subscribing to messages with the AWS IoT Device Client](iot-dc-testconn-subscribe.md)

# Prepare the Raspberry Pi to demonstrate MQTT message communication
<a name="iot-dc-testconn-provision"></a>

This procedure creates the resources in AWS IoT and in the Raspberry Pi to demonstrate MQTT message communication using the AWS IoT Device Client.

**Topics**
+ [Create the certificate files to demonstrate MQTT communication](#iot-dc-testconn-provision-certs)
+ [Provision your device to demonstrate MQTT communication](#iot-dc-testconn-provision-aws)
+ [Configure the AWS IoT Device Client config file and MQTT test client to demonstrate MQTT communication](#iot-dc-testconn-provision-dc-config)

## Create the certificate files to demonstrate MQTT communication
<a name="iot-dc-testconn-provision-certs"></a>

This procedure creates the device certificate files for this demo.

**To create and download the device certificate files for your Raspberry Pi**



1. In the terminal window on your local host computer, enter the following command to create the device certificate files for your device.

   ```
   mkdir ~/certs/pubsub
   aws iot create-keys-and-certificate \
   --set-as-active \
   --certificate-pem-outfile "~/certs/pubsub/device.pem.crt" \
   --public-key-outfile "~/certs/pubsub/public.pem.key" \
   --private-key-outfile "~/certs/pubsub/private.pem.key"
   ```

   The command returns a response like the following. Save the `certificateArn` value for later use.

   ```
   {
   "certificateArn": "arn:aws:iot:us-west-2:57EXAMPLE833:cert/76e7e4edb3e52f52334be2f387a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificateId": "76e7e4edb3e52f5233EXAMPLE7a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDWTCCAkGgAwIBAgI_SHORTENED_FOR_EXAMPLE_Lgn4jfgtS\n-----END CERTIFICATE-----\n",
   "keyPair": {
       "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BA_SHORTENED_FOR_EXAMPLE_ImwIDAQAB\n-----END PUBLIC KEY-----\n",
       "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQE_SHORTENED_FOR_EXAMPLE_T9RoDiukY\n-----END RSA PRIVATE KEY-----\n"
   }
   }
   ```

1. Enter the following commands to set the permissions on the certificate directory and its files.

   ```
   chmod 700 ~/certs/pubsub
   chmod 644 ~/certs/pubsub/*
   chmod 600 ~/certs/pubsub/private.pem.key
   ```

1. Run this command to review the permissions on your certificate directories and files.

   ```
   ls -l ~/certs/pubsub
   ```

   The output of the command should be the same as what you see here, except the file dates and times will be different.

   ```
   -rw-r--r-- 1 pi pi 1220 Oct 28 13:02 device.pem.crt
   -rw------- 1 pi pi 1675 Oct 28 13:02 private.pem.key
   -rw-r--r-- 1 pi pi  451 Oct 28 13:02 public.pem.key
   ```

1. Enter these commands to create the directories for the log files.

   ```
   mkdir ~/.aws-iot-device-client
   mkdir ~/.aws-iot-device-client/log
   chmod 745 ~/.aws-iot-device-client/log
   echo " " > ~/.aws-iot-device-client/log/aws-iot-device-client.log
   echo " " > ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   chmod 600 ~/.aws-iot-device-client/log/*
   ```

## Provision your device to demonstrate MQTT communication
<a name="iot-dc-testconn-provision-aws"></a>

This section creates the AWS IoT resources that provision your Raspberry Pi in AWS IoT. 

**To provision your device in AWS IoT:**

1. In the terminal window on your local host computer, enter the following command to get the address of the device data endpoint for your AWS account.

   ```
   aws iot describe-endpoint --endpoint-type IoT:Data-ATS
   ```

   The endpoint value hasn’t changed since the time you ran this command for the previous tutorial. Running the command again here is done to make it easy to find and paste the data endpoint value into the config file used in this tutorial.

   The command from the previous steps returns a response like the following. Record the `endpointAddress` value for later use.

   ```
   {
   "endpointAddress": "a3qjEXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

1. Enter this command to create a new AWS IoT thing resource for your Raspberry Pi.

   ```
   aws iot create-thing --thing-name "PubSubTestThing"
   ```

   Because an AWS IoT thing resource is a *virtual* representation of your device in the cloud, we can create multiple thing resources in AWS IoT to use for different purposes. They can all be used by the same physical IoT device to represent different aspects of the device.

   These tutorials will only use one thing resource at a time to represent the Raspberry Pi. This way, in these tutorials, they represent the different demos so that after you create the AWS IoT resources for a demo, you can go back and repeat the demo using the resources you created specifically for each.

   If your AWS IoT thing resource was created, the command returns a response like this.

   ```
   {
   "thingName": "PubSubTestThing",
   "thingArn": "arn:aws:iot:us-west-2:57EXAMPLE833:thing/PubSubTestThing",
   "thingId": "8ea78707-32c3-4f8a-9232-14bEXAMPLEfd"
   }
   ```

1. In the terminal window:

   1. Open a text editor, such as `nano`.

   1. Copy this JSON document and paste it into your open text editor.  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Connect"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:client/PubSubTestThing"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/pubtopic"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Subscribe"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topicfilter/test/dc/subtopic"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Receive"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/subtopic"
                  ]
              }
          ]
      }
      ```

   1. In the editor, in each `Resource` section of the policy document, replace *us-west-2:57EXAMPLE833* with your AWS Region, a colon character (:), and your 12-digit AWS account number.

   1. Save the file in your text editor as **\$1/policies/pubsub\$1test\$1thing\$1policy.json**. 

1. Run this command to use the policy document from the previous steps to create an AWS IoT policy.

   ```
   aws iot create-policy \
   --policy-name "PubSubTestThingPolicy" \
   --policy-document "file://~/policies/pubsub_test_thing_policy.json"
   ```

   If the policy is created, the command returns a response like this.

   ```
   {
                                       "policyName": "PubSubTestThingPolicy",
                                       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/PubSubTestThingPolicy",
                                       "policyDocument": "{\n\"Version\": \"2012-10-17\",		 	 	 \n\"Statement\": [\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Connect\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Publish\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Subscribe\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/subtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Receive\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*\"\n]\n}\n]\n}\n",
                                       "policyVersionId": "1"
                                       }
   ```

1. Run this command to attach the policy to the device certificate. Replace `certificateArn` with the `certificateArn` value you saved earlier in this section.

   ```
   aws iot attach-policy \
   --policy-name "PubSubTestThingPolicy" \
   --target "certificateArn"
   ```

   If successful, this command returns nothing.

1. Run this command to attach the device certificate to the AWS IoT thing resource. Replace `certificateArn` with the `certificateArn` value you saved earlier in this section.

   ```
   aws iot attach-thing-principal \
   --thing-name "PubSubTestThing" \
   --principal "certificateArn"
   ```

   If successful, this command returns nothing.

After you successfully provision your device in AWS IoT, you're ready to continue to [Configure the AWS IoT Device Client config file and MQTT test client to demonstrate MQTT communication](#iot-dc-testconn-provision-dc-config).

## Configure the AWS IoT Device Client config file and MQTT test client to demonstrate MQTT communication
<a name="iot-dc-testconn-provision-dc-config"></a>

This procedure creates a config file to test the AWS IoT Device Client.

**To create the config file to test the AWS IoT Device Client**

1. In the terminal window on your local host computer that's connected to your Raspberry Pi:

   1. Open a text editor, such as `nano`.

   1. Copy this JSON document and paste it into your open text editor.

      ```
      {
        "endpoint": "a3qEXAMPLEaffp-ats.iot.us-west-2.amazonaws.com",
        "cert": "~/certs/pubsub/device.pem.crt",
        "key": "~/certs/pubsub/private.pem.key",
        "root-ca": "~/certs/AmazonRootCA1.pem",
        "thing-name": "PubSubTestThing",
        "logging": {
          "enable-sdk-logging": true,
          "level": "DEBUG",
          "type": "STDOUT",
          "file": ""
        },
        "jobs": {
          "enabled": false,
          "handler-directory": ""
        },
        "tunneling": {
          "enabled": false
        },
        "device-defender": {
          "enabled": false,
          "interval": 300
        },
        "fleet-provisioning": {
          "enabled": false,
          "template-name": "",
          "template-parameters": "",
          "csr-file": "",
          "device-key": ""
        },
        "samples": {
          "pub-sub": {
            "enabled": true,
            "publish-topic": "test/dc/pubtopic",
            "publish-file": "",
            "subscribe-topic": "test/dc/subtopic",
            "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
          }
        },
        "config-shadow": {
          "enabled": false
        },
        "sample-shadow": {
          "enabled": false,
          "shadow-name": "",
          "shadow-input-file": "",
          "shadow-output-file": ""
        }
      }
      ```

   1. Replace the *endpoint* value with device data endpoint for your AWS account that you found in [Provision your device in AWS IoT Core](iot-dc-install-provision.md#iot-dc-install-dc-provision).

   1. Save the file in your text editor as **\$1/dc-configs/dc-pubsub-config.json**.

   1. Run this command to set the permissions on the new config file.

      ```
      chmod 644 ~/dc-configs/dc-pubsub-config.json
      ```

1. To prepare the **MQTT test client** to subscribe to all MQTT messages:

   1. On your local host computer, in the [AWS IoT console](https://console.aws.amazon.com//iot/home#/test), choose **MQTT test client**.

   1. In the **Subscribe to a topic** tab, in **Topic filter**, enter **\$1** (a single pound sign), and choose **Subscribe**.

   1. Below the **Subscriptions** label, confirm that you see **\$1** (a single pound sign).

   Leave the window with the **MQTT test client** open while you continue this tutorial.

After you save the file and configure the **MQTT test client**, you're ready to continue to [Demonstrate publishing messages with the AWS IoT Device Client](iot-dc-testconn-publish.md).

# Demonstrate publishing messages with the AWS IoT Device Client
<a name="iot-dc-testconn-publish"></a>

The procedures in this section demonstrate how the AWS IoT Device Client can send default and custom MQTT messages.

These policy statements in the policy that you created in the previous step for these exercises give the Raspberry Pi permission to perform these actions:
+ 

**`iot:Connect`**  
Gives the client named `PubSubTestThing`, your Raspberry Pi running the AWS IoT Device Client, to connect.

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Connect"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing"
        ]
      }
  ```
+ 

**`iot:Publish`**  
Gives the Raspberry Pi permission to publish messages with an MQTT topic of `test/dc/pubtopic`.

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Publish"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic"
        ]
      }
  ```

  The `iot:Publish` action gives permission to publish to the MQTT topics listed in the Resource array. The *content* of those messages is not controlled by the policy statement.

## Publish the default message using the AWS IoT Device Client
<a name="iot-dc-testconn-publish-default"></a>

This procedure runs the AWS IoT Device Client so that it publishes a single default MQTT message that the **MQTT test client** receives and displays.

**To send the default MQTT message from the AWS IoT Device Client**

1. Make sure that both the terminal window on your local host computer that's connected to your Raspberry Pi and the window with the **MQTT test client** are visible while you perform this procedure.

1. In the terminal window, enter these commands to run the AWS IoT Device Client using the config file created in [Create the config file](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1).

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-config.json
   ```

   In the terminal window, the AWS IoT Device Client displays information messages and any errors that occur when it runs.

   If no errors are displayed in the terminal window, review the **MQTT test client**.

1. In the **MQTT test client**, in the **Subscriptions** window, see the *Hello World\$1* message sent to the `test/dc/pubtopic` message topic.

1. If the AWS IoT Device Client displays no errors and you see *Hello World\$1* sent to the `test/dc/pubtopic` message in the **MQTT test client**, you've demonstrated a successful connection.

1. In the terminal window, enter **^C** (Ctrl-C) to stop the AWS IoT Device Client.

After you've demonstrated that the AWS IoT Device Client published the default MQTT message, you can continue to the [Publish a custom message using the AWS IoT Device Client](#iot-dc-testconn-publish-custom).

## Publish a custom message using the AWS IoT Device Client
<a name="iot-dc-testconn-publish-custom"></a>

The procedures in this section create a custom MQTT message and then runs the AWS IoT Device Client so that it publishes the custom MQTT message one time for the **MQTT test client** to receive and display.

### Create a custom MQTT message for the AWS IoT Device Client
<a name="iot-dc-testconn-publish-custom-create"></a>

Perform these steps in the terminal window on the local host computer that's connected to your Raspberry Pi.

**To create a custom message for the AWS IoT Device Client to publish**

1. In the terminal window, open a text editor, such as `nano`.

1. Into the text editor, copy and paste the following JSON document. This will be the MQTT message payload that the AWS IoT Device Client publishes.

   ```
   {
     "temperature": 28,
     "humidity": 80,
     "barometer": 1013,
     "wind": {
       "velocity": 22,
       "bearing": 255
     }
   }
   ```

1. Save the contents of the text editor as **\$1/messages/sample-ws-message.json**. 

1. Enter the following command to set the permissions of the message file that you just created.

   ```
   chmod 600 ~/messages/*
   ```

**To create a config file for the AWS IoT Device Client to use to send the custom message**

1. In the terminal window, in a text editor such as `nano`, open the existing AWS IoT Device Client config file: **\$1/dc-configs/dc-pubsub-config.json**. 

1. Edit the `samples` object to look like this. No other part of this file needs to be changed.

   ```
     "samples": {
       "pub-sub": {
         "enabled": true,
         "publish-topic": "test/dc/pubtopic",
         "publish-file": "~/messages/sample-ws-message.json",
         "subscribe-topic": "test/dc/subtopic",
         "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
   ```

1. Save the contents of the text editor as **\$1/dc-configs/dc-pubsub-custom-config.json**. 

1. Run this command to set the permissions on the new config file.

   ```
   chmod 644 ~/dc-configs/dc-pubsub-custom-config.json
   ```

### Publish the custom MQTT message by using the AWS IoT Device Client
<a name="iot-dc-testconn-publish-custom-publish"></a>

This change affects only the *contents* of the MQTT message payload, so the current policy will continue to work. However, if the *MQTT topic* (as defined by the `publish-topic` value in `~/dc-configs/dc-pubsub-custom-config.json`) was changed, the `iot::Publish` policy statement would also need to be modified to allow the Raspberry Pi to publish to the new MQTT topic.

**To send the MQTT message from the AWS IoT Device Client**

1. Make sure that both the terminal window and the window with the **MQTT test client** are visible while you perform this procedure. Also, make sure that your **MQTT test client** is still subscribed to the **\$1** topic filter. If it isn't, subscribe to the **\$1** topic filter again.

1. In the terminal window, enter these commands to run the AWS IoT Device Client using the config file created in [Create the config file](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1).

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-custom-config.json
   ```

   In the terminal window, the AWS IoT Device Client displays information messages and any errors that occur when it runs.

   If no errors are displayed in the terminal window, review the MQTT test client.

1. In the **MQTT test client**, in the **Subscriptions** window, see the custom message payload sent to the `test/dc/pubtopic` message topic.

1. If the AWS IoT Device Client displays no errors and you see the custom message payload that you published to the `test/dc/pubtopic` message in the **MQTT test client**, you've published a custom message successfully.

1. In the terminal window, enter **^C** (Ctrl-C) to stop the AWS IoT Device Client.

After you've demonstrated that the AWS IoT Device Client published a custom message payload, you can continue to [Demonstrate subscribing to messages with the AWS IoT Device Client](iot-dc-testconn-subscribe.md).

# Demonstrate subscribing to messages with the AWS IoT Device Client
<a name="iot-dc-testconn-subscribe"></a>

In this section, you'll demonstrate two types of message subscriptions:
+ Single topic subscription
+ Wild-card topic subscription

These policy statements in the policy created for these exercises give the Raspberry Pi permission to perform these actions:
+ 

**`iot:Receive`**  
Gives the AWS IoT Device Client permission to receive MQTT topics that match those named in the `Resource` object.

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Receive"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/subtopic"
        ]
      }
  ```
+ 

**`iot:Subscribe`**  
Gives the AWS IoT Device Client permission to subscribe to MQTT topic filters that match those named in the `Resource` object.

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Subscribe"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/subtopic"
        ]
      }
  ```

## Subscribe to a single MQTT message topic
<a name="iot-dc-testconn-subscribe-simple-topic"></a>

This procedure demonstrates how the AWS IoT Device Client can subscribe to and log MQTT messages.

In the terminal window on your local host computer that's connected to your Raspberry Pi, list the contents of **\$1/dc-configs/dc-pubsub-custom-config.json** or open the file in a text editor to review its contents. Locate the `samples` object, which should look like this.

```
  "samples": {
    "pub-sub": {
      "enabled": true,
      "publish-topic": "test/dc/pubtopic",
      "publish-file": "~/messages/sample-ws-message.json",
      "subscribe-topic": "test/dc/subtopic",
      "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
```

Notice the `subscribe-topic` value is the MQTT topic to which the AWS IoT Device Client will subscribe when it runs. The AWS IoT Device Client writes the message payloads that it receives from this subscription to the file named in the `subscribe-file` value.

**To subscribe to a MQTT message topic from the AWS IoT Device Client**

1. Make sure that both the terminal window and the window with the MQTT test client are visible while you perform this procedure. Also, make sure that your **MQTT test client** is still subscribed to the **\$1** topic filter. If it isn't, subscribe to the **\$1** topic filter again.

1. In the terminal window, enter these commands to run the AWS IoT Device Client using the config file created in [Create the config file](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1).

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-custom-config.json
   ```

   In the terminal window, the AWS IoT Device Client displays information messages and any errors that occur when it runs.

   If no errors are displayed in the terminal window, continue in the AWS IoT console.

1. In the AWS IoT console, in the **MQTT test client**, choose the **Publish to a topic** tab.

1. In **Topic name**, enter **test/dc/subtopic**

1. In **Message payload**, review the message contents.

1. Choose **Publish** to publish the MQTT message.

1. In the terminal window, watch for the *message received * entry from the AWS IoT Device Client that looks like this.

   ```
   2021-11-10T16:02:20.890Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 45 bytes
   ```

1. After you see the *message received * entry that shows the message was received, enter **^C** (Ctrl-C) to stop the AWS IoT Device Client.

1. Enter this command to view the end of the message log file and see the message you published from the **MQTT test client**.

   ```
   tail ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   ```

By viewing the message in the log file, you've demonstrated that the AWS IoT Device Client received the message that you published from the MQTT test client.

## Subscribe to multiple MQTT message topic using wildcard characters
<a name="iot-dc-testconn-subscribe-wild-topic"></a>

These procedures demonstrate how the AWS IoT Device Client can subscribe to and log MQTT messages using wildcard characters. To do this, you'll:

1. Update the topic filter that the AWS IoT Device Client uses to subscribe to MQTT topics.

1. Update the policy used by the device to allow the new subscriptions.

1. Run the AWS IoT Device Client and publish messages from the MQTT test console.

**To create a config file to subscribe to multiple MQTT message topics by using a wildcard MQTT topic filter**

1. In the terminal window on your local host computer that's connected to your Raspberry Pi, open **\$1/dc-configs/dc-pubsub-custom-config.json** for editing and locate the `samples` object.

1. In the text editor, locate the `samples` object and update the `subscribe-topic` value to look like this. 

   ```
     "samples": {
       "pub-sub": {
         "enabled": true,
         "publish-topic": "test/dc/pubtopic",
         "publish-file": "~/messages/sample-ws-message.json",
         "subscribe-topic": "test/dc/#",
         "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
   ```

   The new `subscribe-topic` value is an [MQTT topic filter](topics.md#topicfilters) with an MQTT wild card character at the end. This describes a subscription to all MQTT topics that start with `test/dc/`. The AWS IoT Device Client writes the message payloads that it receives from this subscription to the file named in `subscribe-file`.

1. Save the modified config file as **\$1/dc-configs/dc-pubsub-wild-config.json**, and exit the editor.

**To modify the policy used by your Raspberry Pi to allow subscribing to and receiving multiple MQTT message topics**

1. In the terminal window on your local host computer that's connected to your Raspberry Pi, in your favorite text editor, open **\$1/policies/pubsub\$1test\$1thing\$1policy.json** for editing, and then locate the `iot::Subscribe` and `iot::Receive` policy statements in the file.

1. In the `iot::Subscribe` policy statement, update the string in the Resource object to replace `subtopic` with `*`, so that it looks like this.

   ```
       {
         "Effect": "Allow",
         "Action": [
           "iot:Subscribe"
         ],
         "Resource": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/*"
         ]
       }
   ```
**Note**  
The [MQTT topic filter wild card characters](topics.md#topicfilters) are the `+` (plus sign) and the `#` (pound sign). A subscription request with a `#` at the end subscribes to all topics that start with the string that precedes the `#` character (for example, `test/dc/` in this case).   
The resource value in the policy statement that authorizes this subscription, however, must use a `*` (an asterisk) in place of the `#` (a pound sign) in the topic filter ARN. This is because the policy processor uses a different wild card character than MQTT uses.  
For more information about using wild card characters for topics and topic filters in policies, see [Using wildcard characters in MQTT and AWS IoT Core policies](pub-sub-policy.md#pub-sub-policy-cert).

1. In the `iot::Receive` policy statement, update the string in the Resource object to replace `subtopic` with `*`, so that it looks like this.

   ```
       {
         "Effect": "Allow",
         "Action": [
           "iot:Receive"
         ],
         "Resource": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*"
         ]
       }
   ```

1. Save the updated policy document as **\$1/policies/pubsub\$1wild\$1test\$1thing\$1policy.json**, and exit the editor.

1. Enter this command to update the policy for this tutorial to use the new resource definitions.

   ```
   aws iot create-policy-version \
   --set-as-default \
   --policy-name "PubSubTestThingPolicy" \
   --policy-document "file://~/policies/pubsub_wild_test_thing_policy.json"
   ```

   If the command succeeds, it returns a response like this. Notice that `policyVersionId` is now `2`, indicating this is the second version of this policy. 

   If you successfully updated the policy, you can continue to the next procedure.

   ```
   {
       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/PubSubTestThingPolicy",
       "policyDocument": "{\n  \"Version\": \"2012-10-17\",		 	 	 \n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Connect\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Publish\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Subscribe\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Receive\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*\"\n      ]\n    }\n  ]\n}\n",
       "policyVersionId": "2",
       "isDefaultVersion": true
   }
   ```

   If you get an error that there are too many policy versions to save a new one, enter this command to list the current versions of the policy. Review the list that this command returns to find a policy version that you can delete.

   ```
   aws iot list-policy-versions --policy-name "PubSubTestThingPolicy"
   ```

   Enter this command to delete a version that you no longer need. Note that you can't delete the default policy version. The default policy version is the one with a `isDefaultVersion` value of `true`.

   ```
   aws iot delete-policy-version \
   --policy-name "PubSubTestThingPolicy" \
   --policy-version-id policyId
   ```

   After deleting a policy version, retry this step.

With the updated config file and policy, you're ready to demonstrate wild card subscriptions with the AWS IoT Device Client.

**To demonstrate how the AWS IoT Device Client subscribes to and receives multiple MQTT message topics**

1. In the **MQTT test client**, check the subscriptions. If the **MQTT test client** is subscribed to the to the in the **\$1** topic filter, continue to the next step. If not, in the **MQTT test client**, in **Subscribe to a topic** tab, in **Topic filter**, enter **\$1** (a pound sign character), and then choose **Subscribe** to subscribe to it.

1. In the terminal window on your local host computer that's connected to your Raspberry Pi, enter these commands to start the AWS IoT Device Client.

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-wild-config.json
   ```

1. While watching the AWS IoT Device Client output in the terminal window on the local host computer, return to the **MQTT test client**. In the **Publish to a topic** tab, in **Topic name**, enter **test/dc/subtopic** , and then choose **Publish**. 

1. In the terminal window, confirm that the message was received by looking for a message such as:

   ```
   2021-11-10T16:34:20.101Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 76 bytes
   ```

1. While watching the AWS IoT Device Client output in the terminal window of the local host computer, return to the **MQTT test client**. In the **Publish to a topic** tab, in **Topic name**, enter **test/dc/subtopic2** , and then choose **Publish**. 

1. In the terminal window, confirm that the message was received by looking for a message such as:

   ```
   2021-11-10T16:34:32.078Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 77 bytes
   ```

1. After you see the messages that confirm both messages were received, enter **^C** (Ctrl-C) to stop the AWS IoT Device Client.

1. Enter this command to view the end of the message log file and see the message you published from the **MQTT test client**.

   ```
   tail -n 20 ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   ```
**Note**  
The log file contains only message payloads. The message topics are not recorded in the received message log file.  
You might also see the message published by the AWS IoT Device Client in the received log. This is because the wild card topic filter includes that message topic and, sometimes, the subscription request can be processed by message broker before the published message is sent to subscribers.

The entries in the log file demonstrate that the messages were received. You can repeat this procedure using other topic names. All messages that have a topic name that begins with `test/dc/` should be received and logged. Messages with topic names that begin with any other text are ignored.

After demonstrating how the AWS IoT Device Client can publish and subscribe to MQTT messages, continue to [Tutorial: Demonstrate remote actions (jobs) with the AWS IoT Device Client](iot-dc-runjobs.md).