本文以C Link SDK中的Demo文件./demos/remote_access_basic_demo.c为例,介绍如何调用Link SDK的API,帮助设备实现安全隧道功能。

背景信息

  • 安全隧道功能的更多信息,请参见概述

  • 安全隧道功能基于MQTT接入,开发过程中涉及MQTT接入的代码说明,请参见MQTT接入

步骤一:初始化

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

步骤二:配置功能

调用aiot_ra_setopt,配置以下功能。

  1. 配置功能参数。
    重要 配置安全隧道功能参数前,请确保已配置设备认证信息等相关参数。具体操作,请参见MQTT配置连接参数
    • 示例代码:
          aiot_ra_setopt(ra_handle, AIOT_RAOPT_MQTT_HANDLE, mqtt_handle);
          aiot_ra_setopt(ra_handle, AIOT_RAOPT_NETWORK_CRED, (void *)&cred);
          aiot_ra_setopt(ra_handle, AIOT_RAOPT_EVENT_HANDLER, (void *)ra_event_cb);
          for(int i = 0; i < sizeof(services) / sizeof(aiot_ra_service_t); i++) {
              aiot_ra_setopt(ra_handle, AIOT_RAOPT_ADD_SERVICE, (void *)&services[i]);
          }
    • 相关参数:
      配置项示例说明
      AIOT_RAOPT_MQTT_HANDLEmqtt_handle安全隧道功能的请求基于MQTT连接,通过该配置项,关联MQTT连接句柄。
      AIOT_RAOPT_NETWORK_CREDcred安全隧道建立连接时,网络使用的安全凭据。
      AIOT_RAOPT_EVENT_HANDLERra_event_cbWebsocket状态发生变更时,触发该回调函数。
      AIOT_RAOPT_ADD_SERVICEservices[i]配置建立安全隧道连接时,设备端本地可支持的服务。
  2. 定义状态监控回调函数。
    重要 在编写状态监控回调函数的处理逻辑时,请勿调用耗时较长的阻塞函数。
    void ra_event_cb(void *handle, const aiot_ra_event_t *event, void *userdata)
    {
        switch(event->type)
        {
        case AIOT_RA_EVT_CONNECT:
            printf( "ra_event_cb AIOT_RA_EVT_CONNECT %s \r\n", event->tunnel_id);
            /* TODO: 告知Websocket建连成功, 不可在此处调用耗时较长的阻塞函数 */
            break;
        case AIOT_RA_EVT_DISCONNECT:
            printf( "ra_event_cb AIOT_RA_EVT_DISCONNECT %s \r\n", event->tunnel_id);
            /* TODO: 告知Websocket掉线, 不可在此处调用耗时较长的阻塞函数 */
            break;
        case AIOT_RA_EVT_OPEN_WEBSOCKET:
            printf( "ra_event_cb AIOT_RA_EVT_OPEN_WEBSOCKET %s \r\n", event->tunnel_id);
            /* TODO: 告知RA接收到打开Websocket链接命令, 不可在此处调用耗时较长的阻塞函数 */
            break;
        case AIOT_RA_EVT_CLOSE_WEBSOCKET:
            printf( "ra_event_cb AIOT_RA_EVT_CLOSE_WEBSOCKET %s \r\n", event->tunnel_id);
            /* TODO: 告知RA接收到关闭Websocket链接命令, 不可在此处调用耗时较长的阻塞函数 */
            break;
        }
    }
  3. 定义本地支持的远程服务类型。
    说明
    • 默认开启_SSH服务,否则无法实现远程登录功能。更多信息,请参见远程登录功能的使用示例
    • 如果设备提供用于被访问的指定服务,您需自行添加对应服务信息至设备的本地服务列表。
    aiot_ra_service_t services[] = {
        {
            .type = "_SSH",
            .ip = "127.0.0.1",
            .port = 22,
        },
        {
            .type = "Echo-service",
            .ip = "127.0.0.1",
            .port = 7,
        },
    };

步骤三:开启安全隧道功能

调用aiot_ra_start,向物联网平台发起请求,以通知物联网平台,设备已具备安全隧道功能。

    pthread_attr_t attr;
    pthread_attr_init(&attr);
    if (0 != pthread_create(&g_ra_process_thread, &attr, aiot_ra_start, (void*) ra_handle))
    {
        printf( "create remote_proxy_thread error!");
        return -1;
    }

步骤四:创建安全隧道

  1. 登录物联网平台控制台
  2. 创建安全隧道,获取建立访问端与物联网平台WebSocket连接所需的设备端URL访问端Token

安全隧道创建后,您还需自行开发访问端应用程序,以实现对设备的远程访问和管理。

步骤五:关闭安全隧道

调用aiot_ra_stop,关闭安全隧道。

    int i = 60000;
    while(1)
    {
        sleep(1);
        /* TODO: 业务逻辑 */
        i--;
        /*根据业务逻辑需求,设置条件,需要退出线程可以调用aiot_ra_stop*/
        if(i == 0)
        {
            /*退出线程,关闭RA服务*/
            aiot_ra_stop(ra_handle);
            break;
        }
    }

步骤六:退出程序

调用aiot_ra_deinit,销毁RA客户端实例,释放资源。

    aiot_ra_deinit(&ra_handle);

后续步骤

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

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

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