本文以C Link SDK中的Demo文件./demos/bootstrap_posix_demo.c为例,介绍如何调用Link SDK的API,实现设备的分发功能。

背景信息

  • 设备分发功能的更多信息,请参见概述

  • 通过设备分发功能获取设备接入信息后,可将设备接入物联网平台。MQTT接入的详细信息,请参见MQTT接入

步骤一:初始化

  1. 添加头文件。
    ……
    ……
    
    #include "aiot_bootstrap_api.h"
  2. 配置底层依赖和日志输出。
        aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb);
  3. 调用aiot_bootstrap_init,创建Bootstrap客户端实例,并初始化默认参数。
        bootstrap_handle =  aiot_bootstrap_init();
        if (bootstrap_handle == NULL) {
            printf("aiot_bootstrap_init failed\n");
            return -1;
        }

步骤二:配置功能

调用aiot_bootstrap_setopt,配置以下功能。

  1. 配置连接参数
    重要 TLS层的安全连接类型必须为证书方式AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA
    • 示例代码:
          int32_t res = STATE_SUCCESS;
          void *bootstrap_handle = NULL, *mqtt_handle = NULL;
          aiot_sysdep_network_cred_t cred;
          demo_info_t demo_info;
      
          /* TODO: 替换为自己设备的productKey和deviceName */
          char *product_key       = "a18wP******";
          char *device_name       = "LightSwitch";
          char *device_secret     = "uwMTmVAMnGGHaAkqmeDY6cHxxB******";
          ……
          ……
          memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
          cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA;  /* 使用RSA证书校验MQTT服务端 */
          cred.max_tls_fragment = 16384; /* 最大的分片长度为16 KB, 其它可选值还有4 KB、2 KB、1 KB、0.5 KB */
          cred.sni_enabled = 1;                               /* TLS建连时, 支持Server Name Indicator */
          cred.x509_server_cert = ali_ca_cert;                 /* 用来验证MQTT服务端的RSA根证书 */
          cred.x509_server_cert_len = strlen(ali_ca_cert);     /* 用来验证MQTT服务端的RSA根证书长度 */
          ……
          ……
          aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_HOST, (void *)host);
          aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_PORT, (void *)&port);
          aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_PRODUCT_KEY, (void *)product_key);
          aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_DEVICE_NAME, (void *)device_name);
          aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_NETWORK_CRED, (void *)&cred);
      
          ……
          ……
    • 相关参数:
      参数示例说明
      product_keya18wP******

      设备认证信息。更多信息,请参见获取设备认证信息

      本例程的身份认证方式为一机一密。

      其中,device_secret将在设备获取到接入域名和端口号以后,建立MQTT连接时,使用该参数。

      device_nameLightSwitch
      device_secretuwMTmVAMnGGHaAkqmeDY6cHxxB******
  2. 配置消息回调。
    • 示例代码:
          aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_RECV_HANDLER, (void *)demo_bootstrap_recv_handler); 
          aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_USERDATA, (void *)&demo_info);
    • 相关参数:
      配置项示例值说明
      AIOT_BOOTSTRAPOPT_RECV_HANDLERdemo_bootstrap_recv_handler接收到设备分发消息时,调用该函数。
      AIOT_BOOTSTRAPOPT_USERDATAdemo_info设置上下文。当触发函数demo_bootstrap_recv_handler时,回传userdata,您需自行对其做类型转换后,再使用。
  3. 配置状态监控
    1. 定义状态监控回调函数。
      void demo_bootstrap_event_handler(void *handle, const aiot_bootstrap_event_t *event, void *userdata)
      {
          switch (event->type) {
              case AIOT_BOOTSTRAPEVT_INVALID_RESPONSE: {
                  printf("AIOT_BOOTSTRAPEVT_INVALID_RESPONSE\n");
              }
              break;
              case AIOT_BOOTSTRAPEVT_INVALID_CMD: {
                  printf("AIOT_BOOTSTRAPEVT_INVALID_CMD\n");
              }
              break;
              default: {
      
              }
              break;
          }
      }
    2. 配置状态监控的回调函数。
      • 示例代码:
            aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_EVENT_HANDLER, (void *)demo_bootstrap_event_handler);
      • 相关参数:
        配置项示例值说明
        AIOT_BOOTSTRAPOPT_EVENT_HANDLERdemo_bootstrap_event_handler当设备连接状态发生变化时,根据该回调函数定义的处理逻辑,执行对应的处理。

步骤三:发送请求

重要 发送设备分发请求前,请确保已在物联网平台执行设备分发操作。否则,请求后返回的接入域名为设备当前的接入域名和端口号。

调用aiot_bootstrap_send_request,根据上一步配置的参数,向服务器发送HTTPS协议的请求,请求设备分发。

关于HTTPS请求的详细说明,请参见设备分发的请求数据格式

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

步骤四:接收应答

  1. 设备请求消息发送后,物联网平台返回应答报文。设备端调用aiot_bootstrap_recv,接收应答消息,根据消息回调函数的处理逻辑,执行对应处理。
        res = aiot_bootstrap_recv(bootstrap_handle);
        if (res < STATE_SUCCESS) {
            printf("aiot_bootstrap_recv failed, res: -0x%04X\n", -res);
            return -1;
        }
  2. 编写回调函数的处理逻辑。
    您可以参考以下内容,编写回调函数的处理逻辑:
    报文类型说明
    AIOT_BOOTSTRAPRECV_STATUS_CODE服务器返回的HTTP状态码,更多信息,请参见HTTP状态码

    示例代码未对接收的状态码编写处理逻辑,您可以根据业务需要,自行编写处理逻辑。

    AIOT_BOOTSTRAPRECV_CONNECTION_INFO发起设备分发后,物联网平台返回的应答报文。

    接收的消息的类型为aiot_bootstrap_recv_t,您需将其中的hostport(即设备接入的域名和端口号)保存至本地。

    示例代码仅将接收的设备分发消息,做打印处理。

    AIOT_BOOTSTRAPRECV_NOTIFY物联网平台下发的设备分发通知消息。

    在物联网平台执行设备分发操作后,向设备推送设备分发消息。具体操作,请参见物联网平台的设备分发

    示例代码仅做打印处理,您需编写处理逻辑,将设备断开后,在设备端重新发起设备分发请求,建立连接。

    void demo_bootstrap_recv_handler(void *handle, const aiot_bootstrap_recv_t *packet, void *userdata)
    {
        demo_info_t *demo_info = (demo_info_t *)userdata;
    
        switch (packet->type) {
            case AIOT_BOOTSTRAPRECV_STATUS_CODE: {
                demo_info->code = packet->data.status_code.code;
            }
            break;
            case AIOT_BOOTSTRAPRECV_CONNECTION_INFO: {
                demo_info->host = malloc(strlen(packet->data.connection_info.host) + 1);
                if (demo_info->host != NULL) {
                    memset(demo_info->host, 0, strlen(packet->data.connection_info.host) + 1);
                    /* TODO: 回调中,将设备分发消息内容存储指定位置, 这些空间就会被SDK释放 */
                    memcpy(demo_info->host, packet->data.connection_info.host, strlen(packet->data.connection_info.host));
                    demo_info->port = packet->data.connection_info.port;
                }
            }
            break;
            case AIOT_BOOTSTRAPRECV_NOTIFY: {
                printf("AIOT_BOOTSTRAPRECV_NOTIFY, cmd: %d\n", packet->data.notify.cmd);
    
            }
            default: {
    
            }
            break;
        }
    }

(可选)步骤五:建立MQTT连接

获取设备所需的接入域名和端口号后,设备与物联网平台建立MQTT连接。MQTT接入的详细说明,请参见MQTT接入

MQTT连接建立后,您可以参照以下步骤,再次实现设备分发。

  1. 调用aiot_bootstrap_setopt关联MQTT连接的句柄。
    • 示例代码:
          aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_MQTT_HANDLE, (void *)mqtt_handle);
    • 相关参数:
      配置项示例说明
      AIOT_BOOTSTRAPOPT_MQTT_HANDLEmqtt_handle当设备接收到物联网平台下推的设备分发消息,触发该回调函数。
  2. 登录物联网平台,执行设备分发操作。
    具体操作,请参见物联网平台的设备分发
  3. 设备端接收到下推的设备分发消息后,设备下线。然后,重新参照步骤一至步骤四,获取设备接入域名,将设备重新接入物联网平台。

步骤六:退出程序

调用aiot_bootstrap_deinit,销毁Bootstrap客户端实例,释放资源。

    res = aiot_bootstrap_deinit(&bootstrap_handle);
    if (res < 0) {
        printf("demo_start_stop failed\n");
        return -1;
    }

后续步骤

  • 例程文件配置完成后,需进行编译,生成可执行文件./demos/bootstrap-posix-demo

    更多信息,请参见编译与运行

  • 关于运行结果的详细说明,请参见运行日志