

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# coreMQTT 交互身分驗證示範
<a name="mqtt-demo-ma"></a>

**重要**  <a name="deprecation-message-demo"></a>
此示範託管在已棄用的 Amazon-FreeRTOS 儲存庫上。我們建議您在建立新專案時從[這裡開始](freertos-getting-started-modular.md)。如果您已經有以現在已棄用之 Amazon-FreeRTOS 儲存庫為基礎的現有 FreeRTOS 專案，請參閱 [Amazon-FreeRTOS Github 儲存庫遷移指南](github-repo-migration.md)。 FreeRTOS 

## 簡介
<a name="mqtt-demo-ma-introduction"></a>

coreMQTT 交互身分驗證示範專案說明如何使用 TLS 與用戶端和伺服器之間的交互身分驗證建立與 MQTT 代理程式的連線。此示範使用 mbedTLS 型傳輸介面實作來建立伺服器和用戶端驗證的 TLS 連線，並示範 MQTT 在 [QoS 1 ](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Toc442180914)層級的訂閱發佈工作流程。它會訂閱主題篩選條件，然後發佈至符合篩選條件的主題，並等待從 QoS 1 層級的伺服器收到這些訊息。此發佈至代理程式並從代理程式接收相同訊息的週期會無限期重複。此示範中的訊息會在 QoS 1 傳送，根據 MQTT 規格保證至少交付一次。

**注意**  
若要設定和執行 FreeRTOS 示範，請遵循中的步驟[FreeRTOS 入門](freertos-getting-started.md)。

## 來源碼
<a name="mqtt-demo-ma-source-code"></a>

示範來源檔案已命名`mqtt_demo_mutual_auth.c`，可在 `freertos/demos/coreMQTT/`目錄和 [ GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c) 網站中找到。

## 功能
<a name="mqtt-demo-ma-functionality"></a>

示範會建立單一應用程式任務，透過一組範例循環，示範如何連線到代理程式、訂閱代理程式上的主題、發佈至代理程式上的主題，最後中斷與代理程式的連線。示範應用程式會同時訂閱和發佈至相同的主題。每次示範發佈訊息到 MQTT 代理程式時，代理程式都會傳送相同的訊息回示範應用程式。

成功完成示範後，會產生類似下圖的輸出。

![\[成功完成時的 MQTT 示範終端機輸出\]](http://docs.aws.amazon.com/zh_tw/freertos/latest/userguide/images/coremqtt-mad-output.png)


 AWS IoT 主控台會產生類似下圖的輸出。

![\[成功完成時的 MQTT 示範主控台輸出\]](http://docs.aws.amazon.com/zh_tw/freertos/latest/userguide/images/coremqtt-mad-console.png)


## 使用指數退避和抖動重試邏輯
<a name="mqtt-demo-ma-retry-logic"></a>

[ prvBackoffForRetry](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L671-L717) 函數顯示如何使用伺服器進行失敗的網路操作，例如 TLS 連線或 MQTT 訂閱請求，以指數退避和抖動重試。函數會計算下一次重試嘗試的退避期間，並在重試嘗試尚未用盡時執行退避延遲。由於計算退避期間需要產生隨機數字，函數會使用 PKCS11 模組來產生隨機數字。如果廠商平台支援，則使用 PKCS11 模組允許存取 True Random Number Generator (TRNG)。我們建議您使用裝置特定的熵來源植入隨機數字產生器，以降低連線重試期間裝置發生碰撞的機率。

## 連線至 MQTT 代理程式
<a name="mqtt-demo-ma-connecting"></a>

[ prvConnectToServerWithBackoffRetries](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L721-L782) 函數會嘗試與 MQTT 代理程式建立相互驗證的 TLS 連線。如果連線失敗，則會在退避期間之後重試。退避期間會呈指數增加，直到達到最大嘗試次數或達到最大退避期間為止。`BackoffAlgorithm_GetNextBackoff` 函數提供指數增加的退避值，並在達到最大嘗試次數`RetryUtilsRetriesExhausted`時傳回 。如果在設定的嘗試次數之後，無法建立與代理程式的 TLS 連線，`prvConnectToServerWithBackoffRetries`則函數會傳回失敗狀態。

[ prvCreateMQTTConnectionWithBroker](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L785-L848) 函數示範如何使用乾淨的工作階段與 MQTT 代理程式建立 MQTT 連線。它使用在 `FreeRTOS-Plus/Source/Application-Protocols/platform/freertos/transport/src/tls_freertos.c` 檔案中實作的 TLS 傳輸界面。請記住，我們正在 中設定代理程式的持續作用秒數`xConnectInfo`。

下一個函數顯示如何使用 函數在 MQTT 內容中設定 TLS 傳輸界面和時間`MQTT_Init`函數。它也會顯示如何設定事件回呼函數指標 (`prvEventCallback`)。此回呼用於報告傳入訊息。

## 訂閱 MQTT 主題
<a name="mqtt-demo-ma-subscribing"></a>

[ prvMQTTSubscribeWithBackoffRetries](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L871-L969) 函數示範如何在 MQTT 代理程式上訂閱主題篩選條件。此範例示範如何訂閱一個主題篩選條件，但可以在相同的訂閱 API 呼叫中傳遞主題篩選條件清單，以訂閱多個主題篩選條件。此外，如果 MQTT 代理程式拒絕訂閱請求，訂閱將針對 以指數退避重試`RETRY_MAX_ATTEMPTS`。

## 發佈到主題
<a name="mqtt-demo-ma-publishing"></a>

[ prvMQTTPublishToTopic](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L972-L1004) 函數示範如何發佈至 MQTT 代理程式上的主題。

## 接收傳入訊息
<a name="mqtt-demo-ma-receiving"></a>

應用程式會在連線到代理程式之前註冊事件回呼函數，如先前所述。`prvMQTTDemoTask` 函數會呼叫 `MQTT_ProcessLoop`函數來接收傳入的訊息。收到傳入 MQTT 訊息時，它會呼叫應用程式註冊的事件回呼函數。[ prvEventCallback ](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L1139-L1154)函數是這類事件回呼函數的範例。 會`prvEventCallback`檢查傳入封包類型，並呼叫適當的處理常式。在下列範例中，函數會呼叫 `prvMQTTProcessIncomingPublish()`來處理傳入發佈訊息`prvMQTTProcessResponse()`或處理確認 (ACK)。

## 處理傳入的 MQTT 發佈封包
<a name="mqtt-demo-ma-processing"></a>

[ prvMQTTProcessIncomingPublish](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L1108-L1135) 函數示範如何處理來自 MQTT 代理程式的發佈封包。

## 取消訂閱主題
<a name="mqtt-demo-ma-unsubscribing"></a>

工作流程中的最後一個步驟是取消訂閱主題，讓代理程式不會從 傳送任何已發佈的訊息`mqttexampleTOPIC`。以下是函數 [ prvMQTTUnsubscribeFromTopic](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L1007-L1043) 的定義。

## 變更示範中使用的根 CA
<a name="mqtt-demo-ma-root-ca"></a>

根據預設，FreeRTOS 示範會使用 Amazon Root CA 1 憑證 (RSA 2048 位元金鑰） 來驗證 AWS IoT Core 伺服器。您可以使用其他 [ CA 憑證進行伺服器身分驗證](https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs)，包括 Amazon Root CA 3 憑證 (ECC 256 位元金鑰）。若要變更 coreMQTT 交互身分驗證示範的根 CA：

1. 在文字編輯器中，開啟 `freertos/vendors/vendor/boards/board/aws_demos/config_files/mqtt_demo_mutual_auth_config.h` 檔案。

1. 在 檔案中，找到以下行。

   ```
    * #define democonfigROOT_CA_PEM    "...insert here..." 
   ```

   取消註解此行，並視需要將其移至註解區塊結尾 ` */`。

1. 複製您要使用的 CA 憑證，然後將其貼到`"...insert here..."`文字中。結果應如下列範例所示。

   ```
   #define democonfigROOT_CA_PEM   "-----BEGIN CERTIFICATE-----\n"\
   "MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5\n"\
   "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n"\
   "Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG\n"\
   "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg\n"\
   "Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl\n"\
   "ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j\n"\
   "QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr\n"\
   "ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr\n"\
   "BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM\n"\
   "YyRIHN8wfdVoOw==\n"\
   "-----END CERTIFICATE-----\n"
   ```

1. （選用） 您可以變更其他示範的根 CA。為每個`freertos/vendors/vendor/boards/board/aws_demos/config_files/demo-name_config.h`檔案重複步驟 1 到 3。