阿里云IOT C-SDK 源码分析系列(1):应用框架概述

  在前面的文章:

阿里云IOT-C-SDK系列(1)概述:移植流程、程序框架、代码目录

阿里云IOT-C-SDK系列(2)快速体验:移植+示例C代码

阿里云IOT-C-SDK系列(2)快速体验:移植+示例C代码

阿里云IOT-C-SDK系列(4)SDK配置选项理解

阿里云IOT-C-SDK系列(5):进一步理解SDK的移植使用方式

    我们是从 移植、应用的角度分析了 阿里云iot c-sdk的移植和使用方式,但是想要深入的理解该SDK的工作原理,最直接有效的方式就是阅读源码。本文及后续的文章将会分析C-SDK的源码脉络,理解其工作原来。

    linkkit SDK是阿里云物联网平台的开发 SDK,简单的说,使用该SDK,可以方便的实现 单设备、网关设备连接到阿里云物联网平台上,在前面的文章也分析过,单设备联网相对比较简单,本文及后续的文章主要还是从网关设备的角度来分析。

    要理解工作原理,首先要了解一下使用该SDK进行开发应用程序的流程 步骤,下面就简单的用伪代码 罗列一下 网关设备应用程序 的 步骤:


/* 子设备四元组 信息*/
#define EXAMPLE_SUBDEV_ADD_NUM          3
#define EXAMPLE_SUBDEV_MAX_NUM          20
const iotx_linkkit_dev_meta_info_t subdevArr[EXAMPLE_SUBDEV_MAX_NUM] = {
    {
        "a13Npv1vjZ4",
        "PKbZL7baK8pBso94",
        "example_sub1",
        "eglNFNJiRuR0yncB9RP05sSTY4FrUIoe"
    },
    {
        "a1YRfb9bepk",
        "PKbZL7baK8pBso94",
        "test_02",
        "jFsErM3uA7UfbS6J0hm0QaEXsQbmO6Pa"
    },
    {
        "a1YRfb9bepk",
        "PKbZL7baK8pBso94",
        "test_03",
        "MjWMvCLBcuZyqUswryBbgypN8uOgJGVD"
    }
};

static user_example_ctx_t *user_example_get_ctx(void)
{
    return &g_user_example_ctx;
}


/* 用户 连接云服务器成功 回调函数 */
static int user_connected_event_handler(void)
{
    user_example_ctx_t *user_example_ctx = user_example_get_ctx();

    EXAMPLE_TRACE("Cloud Connected");

    user_example_ctx->cloud_connected = 1;

    return 0;
}

/* 用户 云服务器断开连接 回调函数 */
static int user_disconnected_event_handler(void)
{
    user_example_ctx_t *user_example_ctx = user_example_get_ctx();

    EXAMPLE_TRACE("Cloud Disconnected");

    user_example_ctx->cloud_connected = 0;

    return 0;
}


/* 用户自定义 属性设定 回调函数 */
static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
{
    int res = 0;
    user_example_ctx_t *user_example_ctx = user_example_get_ctx();
    EXAMPLE_TRACE("Property Set Received, Devid: %d, Request: %s", devid, request);

    res = IOT_Linkkit_Report(devid, ITM_MSG_POST_PROPERTY,
                             (unsigned char *)request, request_len);
    EXAMPLE_TRACE("Post Property Message ID: %d", res);

    return 0;
}


/* 用户自定义 上报回复 回调函数 */
static int user_report_reply_event_handler(const int devid, const int msgid, const int code, const char *reply,
        const int reply_len)
{
    const char *reply_value = (reply == NULL) ? ("NULL") : (reply);
    const int reply_value_len = (reply_len == 0) ? (strlen("NULL")) : (reply_len);

    EXAMPLE_TRACE("Message Post Reply Received, Devid: %d, Message ID: %d, Code: %d, Reply: %.*s", devid, msgid, code,
                  reply_value_len,
                  reply_value);
    return 0;
}


/* 网关主设备 联网状态检测函数 */
static int user_master_dev_available(void)
{
    user_example_ctx_t *user_example_ctx = user_example_get_ctx();

    if (user_example_ctx->cloud_connected && user_example_ctx->master_initialized) {
        return 1;
    }

    return 0;
}


/* 向网关 添加子设备 信息*/
static int example_add_subdev(iotx_linkkit_dev_meta_info_t *meta_info)
{
    int res = 0, devid = -1;
    devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_SLAVE, meta_info);
    if (devid == FAIL_RETURN) {
        EXAMPLE_TRACE("subdev open Failed\n");
        return FAIL_RETURN;
    }
    EXAMPLE_TRACE("subdev open susseed, devid = %d\n", devid);

    res = IOT_Linkkit_Connect(devid);
    if (res == FAIL_RETURN) {
        EXAMPLE_TRACE("subdev connect Failed\n");
        return res;
    }
    EXAMPLE_TRACE("subdev connect success: devid = %d\n", devid);

    res = IOT_Linkkit_Report(devid, ITM_MSG_LOGIN, NULL, 0);
    if (res == FAIL_RETURN) {
        EXAMPLE_TRACE("subdev login Failed\n");
        return res;
    }
    EXAMPLE_TRACE("subdev login success: devid = %d\n", devid);
    return res;
}

/* 用户自定义 Linkkit收到允许子设备入网的请求时, 会触发此事件并调用回调函数 */
int user_permit_join_event_handler(const char *product_key, const int time)
{
    user_example_ctx_t *user_example_ctx = user_example_get_ctx();

    EXAMPLE_TRACE("Product Key: %s, Time: %d", product_key, time);

    user_example_ctx->permit_join = 1;

    return 0;
}


/* 用户自定义 轮询接收、数据分发 线程 */
void *user_dispatch_yield(void *args)
{
    user_example_ctx_t *user_example_ctx = user_example_get_ctx();

    while (user_example_ctx->g_user_dispatch_thread_running) {
        IOT_Linkkit_Yield(USER_EXAMPLE_YIELD_TIMEOUT_MS);
    }

    return NULL;
}


int main(void)
{
    /* 设定SDK的debug 级别 */
    IOT_SetLogLevel(IOT_LOG_DEBUG);

    /* 注册用户自定义事件回调函数  */
    IOT_RegisterCallback(ITE_CONNECT_SUCC, user_connected_event_handler);
    IOT_RegisterCallback(ITE_DISCONNECTED, user_disconnected_event_handler);
    IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_event_handler);
    IOT_RegisterCallback(ITE_REPORT_REPLY, user_report_reply_event_handler);
    IOT_RegisterCallback(ITE_TIMESTAMP_REPLY, user_timestamp_reply_event_handler);
    IOT_RegisterCallback(ITE_INITIALIZE_COMPLETED, user_initialized);
    IOT_RegisterCallback(ITE_PERMIT_JOIN, user_permit_join_event_handler);

    /* Create Master Device Resources 创建网关设备资源 */
    master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info);
   
    /* Choose Login Server 选择登录服务器 */
    domain_type = IOTX_CLOUD_REGION_SHANGHAI;
    IOT_Ioctl(IOTX_IOCTL_SET_DOMAIN, (void *)&domain_type);

    /* Choose Login Method 设定登录方式 */
    dynamic_register = 0;
    IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register);

    /* Choose Whether You Need Post Property/Event Reply 设定是否 回显 信息*/
    post_event_reply = 0;
    IOT_Ioctl(IOTX_IOCTL_RECV_EVENT_REPLY, (void *)&post_event_reply);

    /* Start Connect Aliyun Server 网关设备开始连接 云服务器*/
    do {
        res = IOT_Linkkit_Connect(user_example_ctx->master_devid);
        if (res < 0) {
            EXAMPLE_TRACE("IOT_Linkkit_Connect failed, retry after 5s...\n");
            HAL_SleepMs(5000);
        }
    } while (res < 0);

	/* 创建用户自定义的 yield 、消息调度线程 */
    user_example_ctx->g_user_dispatch_thread_running = 1;
    res = HAL_ThreadCreate(&user_example_ctx->g_user_dispatch_thread, user_dispatch_yield, NULL, NULL, NULL);
    if (res < 0) {
        EXAMPLE_TRACE("HAL_ThreadCreate Failed\n");
        IOT_Linkkit_Close(user_example_ctx->master_devid);
        return -1;
    }

    /* Add subdev 注册、添加子设备(创建子设备资源并连接到服务器) */
     while((subdev_index < EXAMPLE_SUBDEV_ADD_NUM) && (user_example_ctx->permit_join != 0)) {
        /* Add next subdev */
        if (example_add_subdev((iotx_linkkit_dev_meta_info_t *)&subdevArr[user_example_ctx->subdev_index]) == SUCCESS_RETURN) {
    EXAMPLE_TRACE("subdev %s add succeed", device_name);
            } else {
				EXAMPLE_TRACE("subdev %s add failed", device_name);
            }
        user_example_ctx->subdev_index++;
    }
	
    while (1) {
        HAL_SleepMs(200);

        time_now_sec = user_update_sec();
        if (time_prev_sec == time_now_sec) {
            continue;
        }
        
        /* Post Proprety Example 循环上报 设备属性 */
        if (time_now_sec % 11 == 0 && user_master_dev_available()) {
            /* user_post_property(); */
        }

        /* Device Info Update Example 循环上报设备信息 */
        if (time_now_sec % 23 == 0 && user_master_dev_available()) {
            /* user_deviceinfo_update(); */
        }

 
        time_prev_sec = time_now_sec;
    }

	/* 关闭用户 消息调度线程 */
    user_example_ctx->g_user_dispatch_thread_running = 0;
    IOT_Linkkit_Close(user_example_ctx->master_devid);
    HAL_ThreadDelete(user_example_ctx->g_user_dispatch_thread);
	/* 设定SDK 的debug级别为 NONE*/
    IOT_SetLogLevel(IOT_LOG_NONE);
    return 0;
}

如果上面的代码还是难以理解,下面再用文字进行说明:

int main(void)
{
	/* 设定debug 级别 */
	
	/*-- 注册用户自定义的 事件回调函数 ---------------------*/
	/* 注册用户自定义<连接云服务器成功>事件回调函数 		*/
	/* 注册用户自定义<云服务器断开>事件回调函数 			*/
	/* 注册用户自定义<属性上报>事件回调函数 				*/
	/* 注册用户自定义<时间戳上报>事件回调函数 				*/
	/* 注册用户自定义<属性上报>事件回调函数 				*/
	/* 注册用户自定义<连接网络的设备初始化完成>事件回调函数 */
	/* 注册用户自定义<允许子设备入网>事件回调函数 			*/
	
	/* 调用 IOT_Linkkit_Open 创建网关主设备资源 */
	
	/* 调用 IOT_Ioctl 设定登录服务器、方式等配置参数 */
	
	/* 调用 IOT_Linkkit_Connect 发起 网关主设备 连接云服务器 */
	
	/* 创建用户自定义的 事件调度 线程(user_dispatch_yield)   */
	
	/* 收到 ITE_PERMIT_JOIN 和 ITE_INITIALIZE_COMPLETED 事件后 添加子设备 */
	/* 添加子设备的流程也是 先 xxx_Open 然后 xxx_Connect */

	while(1){
		
	/* 周期调用 IOT_Linkkit_Report(dev_id, 
				ITM_MSG_POST_PROPERTY, 
			    property_payload, strlen(property_payload));
		
        根据dev_id的不同,实现不同子设备的 属性上报
	*/
	}
	
	/* 调用 IOT_Linkkit_Close(master_devid); 关闭网关主设备及释放资源 */
	
	/* 调用 HAL_ThreadDelete(g_user_dispatch_thread); 关闭用户自定义 事件调度线程  */

    return 0;
	
}

 所以从上面的应用流程可知,我们还是要从 SDK 给用于提供的 有限的 API 接口入手来分析源码功能,官方提供的API和事件如下:官方链接《Alink协议API详解、Event列表详解

发布了256 篇原创文章 · 获赞 262 · 访问量 63万+

猜你喜欢

转载自blog.csdn.net/u012351051/article/details/104214695