Tous les produits
Search
Centre de documentation

:Exemple

Dernière mise à jour :Aug 10, 2026

Cet article explique comment utiliser des certificats X.509 pour connecter des appareils basés sur MQTT à . Le fichier de code d'exemple ./demos/mqtt_x509_auth_demo.c est utilisé.

Informations générales

Étape 1 : Initialisation

  1. Ajoutez les fichiers d'en-tête.

    #include "aiot_state_api.h"
    #include "aiot_sysdep_api.h"
    #include "aiot_mqtt_api.h"
  2. Configurez les dépendances sous-jacentes et la sortie des journaux.

        aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb);
  3. Appelez la fonction aiot_mqtt_init pour créer une instance de client MQTT et initialiser les paramètres par défaut.

        mqtt_handle = aiot_mqtt_init();
        if (mqtt_handle == NULL) {
            printf("aiot_mqtt_init failed\n");
            return -1;
        }

no heading

Étape 2 : Configuration des fonctionnalités

Appelez l'opération aiot_mqtt_setopt pour configurer les éléments suivants :

  1. Définir les paramètres de connexion.

  2. Configurer un rappel pour obtenir les informations d'identité de l'appareil.

  3. Configurer des rappels pour surveiller l'état et recevoir des messages.

Pour plus d'informations sur les autres options de configuration, consultez la documentation relative à aiot_mqtt_option_t.

  1. Définissez les paramètres de connexion.

    • const char client_cert[] = {
          "-----BEGIN CERTIFICATE-----\r\n"
          "MIIDiDCCAnCgAwIBAgIIAJ3GD7c2860wDQYJKoZIhvcNAQELBQAwUzEoMCYGA1UE\r\n"
          ... 
          ...
          "v4aDacYavCH03JXKQ6zWpAwnwLcYrbW7XdhtDrqFCj+v6VJ6NDZaTGEW3/I=\r\n"
          "-----END CERTIFICATE-----\r\n"
      };
      
      const char client_private_key[] = {
      
          "-----BEGIN RSA PRIVATE KEY-----\r\n"
          "MIIEowIBAAKCAQEApyRaelm4b4sKOlqBywOIR4RIJrYEfNtYIAofMIkkwnClrqgh\r\n"
          ...    
          ...
          "mPw5JEAkNBy6wOWepJ9Tv1wY8yFEzV2dVsx3P93p5P3UdZb4M7i0\r\n"
          "-----END RSA PRIVATE KEY-----\r\n"
      };
          ...
      int main(int argc, char *argv[])
      {
          int32_t     res = STATE_SUCCESS;
          void       *mqtt_handle = NULL;
          char       *host = "x509.itls.cn-shanghai.aliyuncs.com";
      
          uint16_t    port = 1883; 
          aiot_sysdep_network_cred_t cred; 
      
          char *product_key       = "";
          char *device_name       = "";
          char *device_secret     = "";
      
          ...
          /* The security credential structure. To establish a TLS connection, specify the CA certificate in this structure. */
          aiot_sysdep_network_cred_t cred;
      
          /* Create a security credential for the SDK to establish a TLS connection. */
          memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
          cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA;  /* Verify the MQTT broker by using the RSA certificate. */
          cred.max_tls_fragment = 16384; /* The fragment can be up to 16 KB in length. Other optional values include 4 KB, 2 KB, 1 KB, and 0.5 KB. */
          cred.sni_enabled = 1;                               /* The Server Name Indicator (SNI) extension is supported when you establish a TLS connection. */
          cred.x509_server_cert = ali_ca_crt;                 /* The RSA root certificate that is used to verify the MQTT broker. */
          cred.x509_server_cert_len = strlen(ali_ca_crt);     /* The length of the RSA root certificate. */
      
          /* TODO: When you use an X.509 certificate for two-way authentication, you must add the following code to set a security credential. */
          cred.x509_client_cert = client_cert;
          cred.x509_client_cert_len = strlen(client_cert);
          cred.x509_client_privkey = client_private_key;
          cred.x509_client_privkey_len = strlen(client_private_key);
      
          /* Set the security credential of the connection. */
          aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred);
      
          ...
      }
    • ParamètreExempleDescription
      client_cert[]
          "-----BEGIN CERTIFICATE-----\r\n"
          "MIIDiDCCAnCgAwIBAgIIAJ3GD7c2860wDQYJKoZIhvcNAQELBQAwUzEoMCYGA1UE\r\n"
          ... 
          ...
          "v4aDacYavCH03JXKQ6zWpAwnwLcYrbW7XdhtDrqFCj+v6VJ6NDZaTGEW3/I=\r\n"
          "-----END CERTIFICATE-----\r\n"
      Les informations du certificat X.509 de l'appareil.

      Sur la page Détails de l'appareil de la console IoT Platform, cliquez sur Download à côté de X.509 Certificate pour télécharger les informations du certificat. Après avoir décompressé le fichier de certificat, remplacez la valeur de ce paramètre par les informations contenues dans le fichier .cer en respectant le format de la valeur d'exemple.

      Les informations du certificat se composent de plusieurs chaînes de caractères. Les points de suspension (…) dans l'exemple de code indiquent les chaînes omises. Ajoutez " au début et \r\n" à la fin de chaque chaîne.

      client_private_key[]
          "-----BEGIN RSA PRIVATE KEY-----\r\n"
          "MIIEowIBAAKCAQEApyRaelm4b4sKOlqBywOIR4RIJrYEfNtYIAofMIkkwnClrqgh\r\n"
          ... 
          ...
          "mPw5JEAkNBy6wOWepJ9Tv1wY8yFEzV2dVsx3P93p5P3UdZb4M7i0\r\n"
          "-----END RSA PRIVATE KEY-----\r\n"
      La clé privée du certificat X.509.

      Sur la page Détails de l'appareil de la console IoT Platform, cliquez sur Download à côté de X.509 Certificate pour télécharger les informations du certificat. Après avoir décompressé le fichier de certificat, remplacez la valeur de ce paramètre par les informations contenues dans le fichier .key en respectant le format de la valeur d'exemple.

      La clé privée se compose de plusieurs chaînes de caractères. Les points de suspension (…) dans l'exemple de code indiquent les chaînes omises. Ajoutez " au début et \r\n" à la fin de chaque chaîne.

      hostx509.itls.cn-shanghai.aliyuncs.com Format : x509.itls.${YourRegionId}.aliyuncs.com.

      Remplacez ${YourRegionId} par l'ID de la région où l'appareil se connecte à IoT Platform. Pour plus d'informations, consultez la rubrique Régions et zones.

      port1883Le numéro de port.
      product_key""Si vous utilisez des certificats X.509 pour l'authentification, spécifiez une chaîne vide pour chacun de ces paramètres.
      device_name""
      device_secret""
  2. Configurez un rappel pour obtenir les informations d'identité de l'appareil.

    Une fois qu'un appareil s'est authentifié à l'aide d'un certificat X.509 et a établi une connexion avec IoT Platform, IoT Platform envoie à l'appareil un message contenant un

    ProductKey

    et un

    DeviceName

    . Vous devez configurer un rappel pour recevoir ce message. Ce rappel est appelé afin d'enregistrer ces paramètres à un emplacement spécifique pour une utilisation ultérieure.

    Vous pouvez personnaliser la fonction demo_get_device_info. Dans cet exemple, le message est analysé et affiché.

    • 
      static void demo_get_device_info(const char *topic, uint16_t topic_len, const char *payload, uint32_t payload_len)
      {
          const char *target_topic = "/ext/auth/identity/response";
          char *p_product_key = NULL;
          uint32_t product_key_len = 0;
          char *p_device_name = NULL;
          uint32_t device_name_len = 0;
          int32_t res = STATE_SUCCESS;
      
          if (topic_len != strlen(target_topic) || memcmp(topic, target_topic, topic_len) != 0) {
              return;
          }
      
          /* TODO: The core_json_value operation in the SDK is specified as an example. 
      
                   You must replace the operation with an operation from a JSON parsing library such as cJSON to process payloads.
          */
          res = core_json_value(payload, payload_len, "productKey", strlen("productKey"), &p_product_key, &product_key_len);
          if (res < 0) {
              return;
          }
          res = core_json_value(payload, payload_len, "deviceName", strlen("deviceName"), &p_device_name, &device_name_len);
          if (res < 0) {
              return;
          }
      
          if (g_product_key == NULL) {
              g_product_key = malloc(product_key_len + 1);
              if (NULL == g_product_key) {
                  return;
              }
      
              memset(g_product_key, 0, product_key_len + 1);
              memcpy(g_product_key, p_product_key, product_key_len);
          }
          if (g_device_name == NULL) {
              g_device_name = malloc(device_name_len + 1);
              if (NULL == g_product_key) {
                  return;
              }
      
              memset(g_device_name, 0, device_name_len + 1);
              memcpy(g_device_name, p_device_name, device_name_len);
          }
      
          printf("device productKey: %s\r\n", g_product_key);
          printf("device deviceName: %s\r\n", g_device_name);
      }
    • Remarque :

      IoT Platform utilise la rubrique /ext/auth/identity/response pour envoyer un ProductKey et un DeviceName à l'appareil. Format du Payload :

      {
          "productKey":"***",
          "deviceName":"***"
      }
  3. Configurez la surveillance de l'état et les rappels de messages.

    1. Configurez la fonction de rappel de surveillance de l'état.

      • Exemple de code :

         int main(int argc, char *argv[])
        {
            ...
            ...
        
            /* Configure the default MQTT message callback function. */
            aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_HANDLER, (void *)demo_mqtt_default_recv_handler);
            /* Configure the MQTT event callback function. */
            aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_EVENT_HANDLER, (void *)demo_mqtt_event_handler);
            ...
            ...
        }
                                      
      • Paramètres associés :

        |
        **Élément de configuration**
        |
        **Valeur d'exemple**
        |
        **Description**
        | | --- | --- | --- | |
        AIOT_MQTTOPT_RECV_HANDLER
        |
        demo_mqtt_default_recv_handler
        |
        Lorsqu'un message est reçu, la logique de traitement correspondante définie dans cette fonction de rappel est exécutée.
        | |
        AIOT_MQTTOPT_EVENT_HANDLER
        |
        demo_mqtt_event_handler
        |
        Lorsque l'état de la connexion de l'appareil change, la logique de traitement correspondante définie dans cette fonction de rappel est exécutée.
        |

















    2. Définissez la fonction de rappel de surveillance de l'état.

      Important
      • Évitez de définir une logique de gestion d'événements chronophage, car elle pourrait bloquer le thread de réception des messages.

      • L'état de la connexion peut changer en raison d'événements tels que des anomalies réseau, des reconnexions automatiques réussies ou des déconnexions.

      • Vous pouvez modifier le code au niveau du marqueur TODO pour gérer les changements d'état de la connexion.

      /* This is an MQTT event callback function. This function is triggered when the device connects to, reconnects to, or disconnects from the network. For event definitions, see core/aiot_mqtt_api.h. */
      void demo_mqtt_event_handler(void *handle, const aiot_mqtt_event_t *event, void *userdata)
      {
          switch (event->type) {
              /* The aiot_mqtt_connect() function is called to establish a connection with the MQTT server. */
              case AIOT_MQTTEVT_CONNECT: {
                  printf("AIOT_MQTTEVT_CONNECT\n");
                  /* TODO: Handle the successful connection establishment of the SDK. Do not call long-running blocking functions here. */
              }
              break;
      
              /* The SDK is passively disconnected due to network issues and then automatically and successfully reconnects. */
              case AIOT_MQTTEVT_RECONNECT: {
                  printf("AIOT_MQTTEVT_RECONNECT\n");
                  /* TODO: Handle the successful reconnection of the SDK. Do not call long-running blocking functions here. */
              }
              break;
      
              /* The SDK is passively disconnected due to network issues. This can be caused by a read/write failure at the network layer or a failure to receive a heartbeat response from the server as expected. */
              case AIOT_MQTTEVT_DISCONNECT: {
                  char *cause = (event->data.disconnect == AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) ? ("network disconnect") :
                                ("heartbeat disconnect");
                  printf("AIOT_MQTTEVT_DISCONNECT: %s\n", cause);
                  /* TODO: Handle the passive disconnection of the SDK. Do not call long-running blocking functions here. */
              }
              break;
      
              default: {
      
              }
          }
      }
                                      
    3. Définissez la fonction de rappel de réception des messages.

      Important
      • Évitez de définir une logique de gestion d'événements chronophage pour ne pas bloquer le thread de réception des messages.

      • Pour traiter les messages reçus, modifiez le code au niveau du marqueur TODO.

      
      /* This is the default MQTT message callback function. This function is called when the SDK receives an MQTT message from the server and you have not configured a specific callback for it. */
      void demo_mqtt_default_recv_handler(void *handle, const aiot_mqtt_recv_t *packet, void *userdata)
      {
          switch (packet->type) {
              case AIOT_MQTTRECV_HEARTBEAT_RESPONSE: {
                  printf("heartbeat response\n");
                  /* TODO: Handle the server's response to the heartbeat. This is generally not required. */
              }
              break;
      
              case AIOT_MQTTRECV_SUB_ACK: {
                  printf("suback, res: -0x%04X, packet id: %d, max qos: %d\n",
                         -packet->data.sub_ack.res, packet->data.sub_ack.packet_id, packet->data.sub_ack.max_qos);
                  /* TODO: Handle the server's response to the subscription request. This is generally not required. */
              }
              break;
      
              case AIOT_MQTTRECV_PUB: {
                  printf("pub, qos: %d, topic: %.*s\n", packet->data.pub.qos, packet->data.pub.topic_len, packet->data.pub.topic);
                  printf("pub, payload: %.*s\n", packet->data.pub.payload_len, packet->data.pub.payload);
                  /* TODO: Handle the service message sent from the server. */
              }
              break;
      
              case AIOT_MQTTRECV_PUB_ACK: {
                  printf("puback, packet id: %d\n", packet->data.pub_ack.packet_id);
                  /* TODO: Handle the server's response to a reported message with QoS=1. This is generally not required. */
              }
              break;
      
              default: {
      
              }
          }
      }

no heading

Étape 3 : Demande de connexion

Appelez l'opération aiot_mqtt_connect pour envoyer une demande d'authentification et de connexion à IoT Platform.

/* Establish an MQTT connection with IoT Platform. */  */
    res = aiot_mqtt_connect(mqtt_handle);
    if (res < STATE_SUCCESS) {
        /* Release resources of the MQTT instance if the MQTT connection fails to be established.  */
        aiot_mqtt_deinit(&mqtt_handle);
        printf("aiot_mqtt_connect failed: -0x%04X\n", -res);
        return -1;
    }

Étape 4 : Démarrage du thread de maintien actif

Appelez la fonction aiot_mqtt_process pour envoyer des messages heartbeat au serveur. Cette fonction maintient une connexion persistante pour l'appareil et renvoie les messages non accusés de réception ayant un niveau de qualité de service (QoS) de 1.

  1. Démarrez le thread de maintien actif.

        res = pthread_create(&g_mqtt_process_thread, NULL, demo_mqtt_process_thread, mqtt_handle);
        if (res < 0) {
            printf("pthread_create demo_mqtt_process_thread failed: %d\n", res);
            return -1;
        }
  2. Définissez la fonction de gestionnaire du thread de maintien actif.

    void *demo_mqtt_process_thread(void *args)
    {
        int32_t res = STATE_SUCCESS;
    
        while (g_mqtt_process_thread_running) {
            res = aiot_mqtt_process(args);
            if (res == STATE_USER_INPUT_EXEC_DISABLED) {
                break;
            }
            sleep(1);
        }
        return NULL;
    }

Étape 5 : Démarrage du thread de réception

Appelez la fonction aiot_mqtt_recv pour recevoir les messages MQTT du serveur. La fonction de rappel de messages traite ces messages. Si l'appareil est déconnecté, il se reconnecte automatiquement et déclenche la fonction de rappel d'événement.

  1. Démarrez le thread de réception.

    
        res = pthread_create(&g_mqtt_recv_thread, NULL, demo_mqtt_recv_thread, mqtt_handle);
        if (res < 0) {
            printf("pthread_create demo_mqtt_recv_thread failed: %d\n", res);
            return -1;
        }
                                        
  2. Définissez la fonction de gestionnaire du thread de réception.

    void *demo_mqtt_recv_thread(void *args)
    {
        int32_t res = STATE_SUCCESS;
    
        while (g_mqtt_recv_thread_running) {
            res = aiot_mqtt_recv(args);
            if (res < STATE_SUCCESS) {
                if (res == STATE_USER_INPUT_EXEC_DISABLED) {
                    break;
                }
                sleep(1);
            }
        }
        return NULL;
    }

Étape 6 : Abonnement à une rubrique

Appelez l'opération aiot_mqtt_sub pour vous abonner à une rubrique spécifique.

  • Exemple de code :

        {
            char *sub_topic = "/a18wP******/LightSwitch/user/get";
    
            res = aiot_mqtt_sub(mqtt_handle, sub_topic, NULL, 1, NULL);
            if (res < 0) {
                printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res);
                return -1;
            }
        }
    Remarque

    Une fois la configuration terminée, supprimez les symboles de commentaire du code concerné.

  • Paramètres associés :

    Paramètre

    Exemple

    Description

    sub_topic

    /a18wP/LightSwitch/user/get

    Une rubrique à laquelle l'appareil est autorisé à s'abonner.

    • a18wP correspond au ProductKey de l'appareil.

    • LightSwitch correspond au DeviceName de l'appareil.

    Cet exemple utilise une rubrique personnalisée par défaut.

    L'appareil reçoit les messages d'IoT Platform via cette rubrique.

    Pour plus d'informations sur les rubriques, consultez la rubrique Qu'est-ce qu'une rubrique ?.

Étape 7 : Envoi d'un message

Appelez la fonction aiot_mqtt_pub pour envoyer un message à une rubrique spécifique.

  • Exemple de code :

         {
            char *pub_topic = "/a18wP******/LightSwitch/user/update";
            char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}";
    
            res = aiot_mqtt_pub(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0);
            if (res < 0) {
                printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res);
                return -1;
            }
        }
    Remarque

    Une fois la configuration terminée, supprimez les symboles de commentaire autour du code concerné.

  • Paramètres associés :

    Paramètre

    Exemple

    Description

    pub_topic

    /a18wP/LightSwitch/user/update

    Une rubrique à laquelle l'appareil est autorisé à publier.

    • a18wP correspond au ProductKey de l'appareil.

    • LightSwitch correspond au DeviceName de l'appareil.

    L'appareil envoie des messages à IoT Platform via cette rubrique.

    Pour plus d'informations sur les rubriques, consultez la rubrique Qu'est-ce qu'une rubrique ?.

    pub_payload

    {\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}

    Le contenu du message envoyé à IoT Platform.

    Étant donné que la catégorie de rubrique pour le message d'exemple est personnalisée, le format des données peut également être personnalisé.

    Pour plus d'informations sur les formats de données, consultez la rubrique Formats de données.

Une fois que l'appareil a établi la communication MQTT avec IoT Platform, assurez-vous que le volume de communication ne dépasse pas le seuil autorisé.

  • Pour plus d'informations sur les limites de communication, consultez la rubrique Limites.

  • Si le volume de communication dépasse le seuil, connectez-vous à la console IoT Platform pour afficher les messages en attente. Pour plus d'informations, consultez la rubrique Afficher et surveiller les groupes de consommateurs.

Étape 8 : Déconnexion

Remarque

MQTT est généralement utilisé pour les appareils nécessitant une connexion persistante. Par conséquent, le programme n'atteint généralement pas ce point.

Dans le programme d'exemple, le thread principal est chargé de configurer les paramètres et d'établir la connexion. Une fois la connexion établie, le thread principal peut entrer en veille.

Vous pouvez appeler la fonction aiot_mqtt_disconnect pour envoyer un message de déconnexion à IoT Platform et se déconnecter du réseau.

    res = aiot_mqtt_disconnect(mqtt_handle);
    if (res < STATE_SUCCESS) {
        aiot_mqtt_deinit(&mqtt_handle);
        printf("aiot_mqtt_disconnect failed: -0x%04X\n", -res);
        return -1;
    }

Étape 9 : Sortie du programme

Vous pouvez appeler la fonction aiot_mqtt_deinit pour détruire l'instance de client MQTT et libérer les ressources.

    res = aiot_mqtt_deinit(&mqtt_handle);
    if (res < STATE_SUCCESS) {
        printf("aiot_mqtt_deinit failed: -0x%04X\n", -res);
        return -1;
    }

Étapes suivantes