本文以C Link SDK中的Demo文件./demos/http_basic_demo为例,介绍如何调用Link SDK的API,将HTTPS协议的设备接入物联网平台并进行消息收发。

背景信息

HTTPS接入的更多信息,请参见概述

步骤一:初始化

配置底层依赖和日志输出。aiot_http_init,创建客户端实例,并初始化默认参数。

 /* 配置SDK的底层依赖 */
    aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
    /* 配置SDK的日志输出 */
    aiot_state_set_logcb(demo_state_logcb);
    ...
    ...

    /* 创建1个HTTPS客户端实例并内部初始化默认参数 */
    http_handle = aiot_http_init();

步骤二:配置功能

调用aiot_http_setopt,配置以下功能。

  1. 配置连接参数
  2. 配置事件回调

更多功能的配置项,请参见aiot_http_option_t

  1. 配置连接参数
    • 示例代码:
          char       *http_host = "iot-as-http.cn-shanghai.aliyuncs.com";
          …
          aiot_sysdep_network_cred_t cred;
          char *product_key       = "a18wP******";
          char *device_name       = "LightSwitch";
          char *device_secret     = "uwMTmVAMnGGHaAkqmeDY6cHxxB******";
          …
          …
      
          /* 配置HTTPS服务器域名。 */
          aiot_http_setopt(http_handle, AIOT_HTTPOPT_HOST, (void *)host);
          /* 配置服务器端口。 */
          aiot_http_setopt(http_handle, AIOT_HTTPOPT_PORT, (void *)&port);
          /* 配置设备安全凭证。 */
          aiot_http_setopt(http_handle, AIOT_HTTPOPT_NETWORK_CRED, &cred);
          /* 配置设备ProductKey。 */
          aiot_http_setopt(http_handle, AIOT_HTTPOPT_PRODUCT_KEY, product_key);
          /* 配置设备DeviceName。 */
          aiot_http_setopt(http_handle, AIOT_HTTPOPT_DEVICE_NAME, device_name);
          /* 配置设备DeviceSecret。 */
          aiot_http_setopt(http_handle, AIOT_HTTPOPT_DEVICE_SECRET, device_secret);
                                      
    • 相关参数:
      参数 示例 说明
      http_host iot-06z00ax1o******.http.iothub.aliyuncs.com 设备的接入域名。
      • 企业版实例,或2021年07月30日之后(含当日)开通的公共实例:在实例详情页面的开发配置面板,查看接入域名。
      • 2021年07月30日之前(不含当日)开通的公共实例:接入域名格式为https://iot-as-http.${YourRegionId}.aliyuncs.com

      接入域名的格式及其更多信息,请参见查看实例终端节点

      product_key a18wP******

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

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

      device_name LightSwitch
      device_secret uwMTmVAMnGGHaAkqmeDY6cHxxB******
  2. 配置状态监控
    1. 配置状态监控的回调函数。
      • 示例代码:
            int main(int argc, char *argv[])
        {
            ...
            ...
        
            /* 配置数据到达时, SDK应调用的用户回调函数 */
            aiot_http_setopt(http_handle, AIOT_HTTPOPT_RECV_HANDLER, demo_http_recv_handler);
            /* 配置内部状态变化时, SDK应调用的用户回调函数 */
            aiot_http_setopt(http_handle, AIOT_HTTPOPT_EVENT_HANDLER, demo_http_event_handler);
        
        }
      • 相关参数:
        配置项 示例值 说明
        AIOT_HTTPOPT_RECV_HANDLER demo_http_recv_handler 当设备接收到应答报文后,触发该函数,执行对应处理。
        AIOT_HTTPOPT_EVENT_HANDLER demo_http_event_handler 当Token变化时,触发该回调函数,以确保Token的有效性。
    2. 定义状态监控回调函数。
      • 在Token变化时,触发回调函数,设置执行操作。
        void demo_http_event_handler(void *handle, const aiot_http_event_t *event, void *user_data)
        {
            int32_t res;
        
            /* Token失效事件处理 */
            if (event->type == AIOT_HTTPEVT_TOKEN_INVALID) {
                printf("token invalid, invoke iot_http_auth to get new token\n");
                res = aiot_http_auth(handle);
                printf("aiot_http_auth in callback, res = -0x%04x\r\n", -res);
            }
        }
      • 在读取到网络报文时,触发回调函数,执行设置的处理。示例仅做打印处理,您在编写处理逻辑时,需考虑以下几点。
        • 应答报文的参数说明,请参见HTTPS连接通信
        • 正常接收报文含AIOT_HTTPRECV_STATUS_CODEAIOT_HTTPRECV_HEADERAIOT_HTTPRECV_BODY三个事件,分别表示:通信是否成功、报文的类型和报文的包体。
        • 根据业务需要,处理状态码。状态码的更多信息,请参见HTTP状态码
        void demo_http_recv_handler(void *handle, const aiot_http_recv_t *packet, void *userdata)
        {
            switch (packet->type) {
                case AIOT_HTTPRECV_STATUS_CODE: {
                    /* TODO: 以下代码如果不被注释, SDK收到HTTPS报文时, 会通过这个用户回调打印HTTPS状态码, 如404, 200, 302等。 */
                    /* printf("status code: %d\n", packet->data.status_code.code); */
                }
                break;
        
                case AIOT_HTTPRECV_HEADER: {
                    /* TODO: 以下代码如果不被注释, SDK收到HTTPS报文时, 会通过该回调打印HTTPS首部, 如Content-Length等。 */
                    /* printf("key: %s, value: %s\n", packet->data.header.key, packet->data.header.value); */
                }
                break;
        
                /* TODO: 如果需要处理物联网平台的HTTPS回应报文, 在此处修改。当前示例仅打印回应。 */
                case AIOT_HTTPRECV_BODY: {
                    printf("%.*s\r\n", packet->data.body.len, packet->data.body.buffer);
                }
                break;
        
                default: {
                }
                break;
        
            }
        }

步骤三:请求连接

调用aiot_http_auth,根据配置连接的参数,向指定的物联网平台HTTPS服务器,发送身份认证请求,获取Token。

/* 设备认证, 获取Token */
    res = aiot_http_auth(http_handle);
    if (res == 0) {
        printf("aiot_http_auth succeed\r\n");
    } else {
        /* 如果认证失败, 就销毁实例, 回收资源, 退出程序 */
        printf("aiot_http_auth failed, res = -0x%04x\r\n", -res);
        aiot_http_deinit(&http_handle);
        return -1;
    }

步骤四:发送消息

调用aiot_http_send,在demo_http_post_lightswitch中,向指定Topic发送消息。

说明
  • 例程仅打印发送的消息。实际业务中,您需自定义函数demo_http_post_lightswitch
  • 您需删除例程中代码两边的注释符号,以演示设备向物联网平台上报消息。
  • 示例代码:
    int32_t demo_http_post_lightswitch(void *handle)
    {
        char data[] = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}";
        int32_t res;
    
        res = aiot_http_send(handle,
                             "/a1wAf******/LightSwitch/user/update",
                             (uint8_t *)data,
                             strlen(data));
        if (res < 0) {
            printf("aiot_http_send res = -0x%04X\r\n", -res);
            return res;
        }
        …
        …
    }
  • 相关参数:
    参数 示例 说明
    data[] {\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}} 上报至物联网平台的消息内容。

    由于示例消息的Topic类型为自定义,因此数据格式可自定义。

    关于数据格式的更多信息,请参见数据格式

    topic /a1wAf******/LightSwitch/user/update 拥有发布权限的Topic。其中,
    • a18wP******为设备的ProductKey。
    • LightSwitch为设备的DeviceName。
    设备通过该Topic向物联网平台发送消息。

    关于Topic的更多信息,请参见什么是Topic

步骤五:接收应答

消息发送后,物联网平台返回应答报文。设备端调用aiot_http_recv接收HTTPS应答数据,根据事件回调函数,执行对应处理。

    res = aiot_http_recv(handle);
    if (res >= 0) {
        /* 成功接收到服务器应答, 且业务应答码为0, 说明数据上报成功 */
        return 0;
    } else {
        printf("aiot_http_recv res = -0x%04X\r\n", -res);
        return -1;
    }
}

步骤六:退出程序

调用aiot_http_deinit,销毁HTTPS客户端实例,释放资源。

    aiot_http_deinit(&http_handle);
    printf("program exit as normal return\r\n");
    printf("\r\n");

    return 0;

后续步骤

  • 例程文件配置完成后,需进行编译,生成可执行文件./output/http-basic-demo

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

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