飞道的博客

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

679人阅读  评论(0)

  在前面的文章:

阿里云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进行开发应用程序的流程 步骤,下面就简单的用伪代码 罗列一下 网关设备应用程序 的 步骤:


  
  1. /* 子设备四元组 信息*/
  2. #define EXAMPLE_SUBDEV_ADD_NUM 3
  3. #define EXAMPLE_SUBDEV_MAX_NUM 20
  4. const iotx_linkkit_dev_meta_info_t subdevArr[EXAMPLE_SUBDEV_MAX_NUM] = {
  5. {
  6. "a13Npv1vjZ4",
  7. "PKbZL7baK8pBso94",
  8. "example_sub1",
  9. "eglNFNJiRuR0yncB9RP05sSTY4FrUIoe"
  10. },
  11. {
  12. "a1YRfb9bepk",
  13. "PKbZL7baK8pBso94",
  14. "test_02",
  15. "jFsErM3uA7UfbS6J0hm0QaEXsQbmO6Pa"
  16. },
  17. {
  18. "a1YRfb9bepk",
  19. "PKbZL7baK8pBso94",
  20. "test_03",
  21. "MjWMvCLBcuZyqUswryBbgypN8uOgJGVD"
  22. }
  23. };
  24. static user_example_ctx_t *user_example_get_ctx( void)
  25. {
  26. return &g_user_example_ctx;
  27. }
  28. /* 用户 连接云服务器成功 回调函数 */
  29. static int user_connected_event_handler( void)
  30. {
  31. user_example_ctx_t *user_example_ctx = user_example_get_ctx();
  32. EXAMPLE_TRACE( "Cloud Connected");
  33. user_example_ctx->cloud_connected = 1;
  34. return 0;
  35. }
  36. /* 用户 云服务器断开连接 回调函数 */
  37. static int user_disconnected_event_handler( void)
  38. {
  39. user_example_ctx_t *user_example_ctx = user_example_get_ctx();
  40. EXAMPLE_TRACE( "Cloud Disconnected");
  41. user_example_ctx->cloud_connected = 0;
  42. return 0;
  43. }
  44. /* 用户自定义 属性设定 回调函数 */
  45. static int user_property_set_event_handler( const int devid, const char *request, const int request_len)
  46. {
  47. int res = 0;
  48. user_example_ctx_t *user_example_ctx = user_example_get_ctx();
  49. EXAMPLE_TRACE( "Property Set Received, Devid: %d, Request: %s", devid, request);
  50. res = IOT_Linkkit_Report(devid, ITM_MSG_POST_PROPERTY,
  51. ( unsigned char *)request, request_len);
  52. EXAMPLE_TRACE( "Post Property Message ID: %d", res);
  53. return 0;
  54. }
  55. /* 用户自定义 上报回复 回调函数 */
  56. static int user_report_reply_event_handler( const int devid, const int msgid, const int code, const char *reply,
  57. const int reply_len)
  58. {
  59. const char *reply_value = (reply == NULL) ? ( "NULL") : (reply);
  60. const int reply_value_len = (reply_len == 0) ? (strlen( "NULL")) : (reply_len);
  61. EXAMPLE_TRACE( "Message Post Reply Received, Devid: %d, Message ID: %d, Code: %d, Reply: %.*s", devid, msgid, code,
  62. reply_value_len,
  63. reply_value);
  64. return 0;
  65. }
  66. /* 网关主设备 联网状态检测函数 */
  67. static int user_master_dev_available( void)
  68. {
  69. user_example_ctx_t *user_example_ctx = user_example_get_ctx();
  70. if (user_example_ctx->cloud_connected && user_example_ctx->master_initialized) {
  71. return 1;
  72. }
  73. return 0;
  74. }
  75. /* 向网关 添加子设备 信息*/
  76. static int example_add_subdev(iotx_linkkit_dev_meta_info_t *meta_info)
  77. {
  78. int res = 0, devid = -1;
  79. devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_SLAVE, meta_info);
  80. if (devid == FAIL_RETURN) {
  81. EXAMPLE_TRACE( "subdev open Failed\n");
  82. return FAIL_RETURN;
  83. }
  84. EXAMPLE_TRACE( "subdev open susseed, devid = %d\n", devid);
  85. res = IOT_Linkkit_Connect(devid);
  86. if (res == FAIL_RETURN) {
  87. EXAMPLE_TRACE( "subdev connect Failed\n");
  88. return res;
  89. }
  90. EXAMPLE_TRACE( "subdev connect success: devid = %d\n", devid);
  91. res = IOT_Linkkit_Report(devid, ITM_MSG_LOGIN, NULL, 0);
  92. if (res == FAIL_RETURN) {
  93. EXAMPLE_TRACE( "subdev login Failed\n");
  94. return res;
  95. }
  96. EXAMPLE_TRACE( "subdev login success: devid = %d\n", devid);
  97. return res;
  98. }
  99. /* 用户自定义 Linkkit收到允许子设备入网的请求时, 会触发此事件并调用回调函数 */
  100. int user_permit_join_event_handler( const char *product_key, const int time)
  101. {
  102. user_example_ctx_t *user_example_ctx = user_example_get_ctx();
  103. EXAMPLE_TRACE( "Product Key: %s, Time: %d", product_key, time);
  104. user_example_ctx->permit_join = 1;
  105. return 0;
  106. }
  107. /* 用户自定义 轮询接收、数据分发 线程 */
  108. void *user_dispatch_yield( void *args)
  109. {
  110. user_example_ctx_t *user_example_ctx = user_example_get_ctx();
  111. while (user_example_ctx->g_user_dispatch_thread_running) {
  112. IOT_Linkkit_Yield(USER_EXAMPLE_YIELD_TIMEOUT_MS);
  113. }
  114. return NULL;
  115. }
  116. int main( void)
  117. {
  118. /* 设定SDK的debug 级别 */
  119. IOT_SetLogLevel(IOT_LOG_DEBUG);
  120. /* 注册用户自定义事件回调函数 */
  121. IOT_RegisterCallback(ITE_CONNECT_SUCC, user_connected_event_handler);
  122. IOT_RegisterCallback(ITE_DISCONNECTED, user_disconnected_event_handler);
  123. IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_event_handler);
  124. IOT_RegisterCallback(ITE_REPORT_REPLY, user_report_reply_event_handler);
  125. IOT_RegisterCallback(ITE_TIMESTAMP_REPLY, user_timestamp_reply_event_handler);
  126. IOT_RegisterCallback(ITE_INITIALIZE_COMPLETED, user_initialized);
  127. IOT_RegisterCallback(ITE_PERMIT_JOIN, user_permit_join_event_handler);
  128. /* Create Master Device Resources 创建网关设备资源 */
  129. master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info);
  130. /* Choose Login Server 选择登录服务器 */
  131. domain_type = IOTX_CLOUD_REGION_SHANGHAI;
  132. IOT_Ioctl(IOTX_IOCTL_SET_DOMAIN, ( void *)&domain_type);
  133. /* Choose Login Method 设定登录方式 */
  134. dynamic_register = 0;
  135. IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, ( void *)&dynamic_register);
  136. /* Choose Whether You Need Post Property/Event Reply 设定是否 回显 信息*/
  137. post_event_reply = 0;
  138. IOT_Ioctl(IOTX_IOCTL_RECV_EVENT_REPLY, ( void *)&post_event_reply);
  139. /* Start Connect Aliyun Server 网关设备开始连接 云服务器*/
  140. do {
  141. res = IOT_Linkkit_Connect(user_example_ctx->master_devid);
  142. if (res < 0) {
  143. EXAMPLE_TRACE( "IOT_Linkkit_Connect failed, retry after 5s...\n");
  144. HAL_SleepMs( 5000);
  145. }
  146. } while (res < 0);
  147. /* 创建用户自定义的 yield 、消息调度线程 */
  148. user_example_ctx->g_user_dispatch_thread_running = 1;
  149. res = HAL_ThreadCreate(&user_example_ctx->g_user_dispatch_thread, user_dispatch_yield, NULL, NULL, NULL);
  150. if (res < 0) {
  151. EXAMPLE_TRACE( "HAL_ThreadCreate Failed\n");
  152. IOT_Linkkit_Close(user_example_ctx->master_devid);
  153. return -1;
  154. }
  155. /* Add subdev 注册、添加子设备(创建子设备资源并连接到服务器) */
  156. while((subdev_index < EXAMPLE_SUBDEV_ADD_NUM) && (user_example_ctx->permit_join != 0)) {
  157. /* Add next subdev */
  158. if (example_add_subdev((iotx_linkkit_dev_meta_info_t *)&subdevArr[user_example_ctx->subdev_index]) == SUCCESS_RETURN) {
  159. EXAMPLE_TRACE( "subdev %s add succeed", device_name);
  160. } else {
  161. EXAMPLE_TRACE( "subdev %s add failed", device_name);
  162. }
  163. user_example_ctx->subdev_index++;
  164. }
  165. while ( 1) {
  166. HAL_SleepMs( 200);
  167. time_now_sec = user_update_sec();
  168. if (time_prev_sec == time_now_sec) {
  169. continue;
  170. }
  171. /* Post Proprety Example 循环上报 设备属性 */
  172. if (time_now_sec % 11 == 0 && user_master_dev_available()) {
  173. /* user_post_property(); */
  174. }
  175. /* Device Info Update Example 循环上报设备信息 */
  176. if (time_now_sec % 23 == 0 && user_master_dev_available()) {
  177. /* user_deviceinfo_update(); */
  178. }
  179. time_prev_sec = time_now_sec;
  180. }
  181. /* 关闭用户 消息调度线程 */
  182. user_example_ctx->g_user_dispatch_thread_running = 0;
  183. IOT_Linkkit_Close(user_example_ctx->master_devid);
  184. HAL_ThreadDelete(user_example_ctx->g_user_dispatch_thread);
  185. /* 设定SDK 的debug级别为 NONE*/
  186. IOT_SetLogLevel(IOT_LOG_NONE);
  187. return 0;
  188. }

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


  
  1. int main( void)
  2. {
  3. /* 设定debug 级别 */
  4. /*-- 注册用户自定义的 事件回调函数 ---------------------*/
  5. /* 注册用户自定义<连接云服务器成功>事件回调函数 */
  6. /* 注册用户自定义<云服务器断开>事件回调函数 */
  7. /* 注册用户自定义<属性上报>事件回调函数 */
  8. /* 注册用户自定义<时间戳上报>事件回调函数 */
  9. /* 注册用户自定义<属性上报>事件回调函数 */
  10. /* 注册用户自定义<连接网络的设备初始化完成>事件回调函数 */
  11. /* 注册用户自定义<允许子设备入网>事件回调函数 */
  12. /* 调用 IOT_Linkkit_Open 创建网关主设备资源 */
  13. /* 调用 IOT_Ioctl 设定登录服务器、方式等配置参数 */
  14. /* 调用 IOT_Linkkit_Connect 发起 网关主设备 连接云服务器 */
  15. /* 创建用户自定义的 事件调度 线程(user_dispatch_yield) */
  16. /* 收到 ITE_PERMIT_JOIN 和 ITE_INITIALIZE_COMPLETED 事件后 添加子设备 */
  17. /* 添加子设备的流程也是 先 xxx_Open 然后 xxx_Connect */
  18. while( 1){
  19. /* 周期调用 IOT_Linkkit_Report(dev_id,
  20. ITM_MSG_POST_PROPERTY,
  21. property_payload, strlen(property_payload));
  22. 根据dev_id的不同,实现不同子设备的 属性上报
  23. */
  24. }
  25. /* 调用 IOT_Linkkit_Close(master_devid); 关闭网关主设备及释放资源 */
  26. /* 调用 HAL_ThreadDelete(g_user_dispatch_thread); 关闭用户自定义 事件调度线程 */
  27. return 0;
  28. }

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


转载:https://blog.csdn.net/u012351051/article/details/104214695
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场