5.Agent Tiny

      概述

      Agent Tiny是部署在具备广域网能力、对功耗/存储/计算资源有苛刻限制的终端设备上的轻量级互联互通中间件,开发者只需调用几个简单的API接口,便可实现设备快速接入到华为IoT云平台(OceanConnect)以及数据上报和命令接收等功能。

      以彩灯应用举例,Agent Tiny工作原理如下:
      5.Agent Tiny - 图1

      开发指导

      使用场景

      开发者只需实现平台抽象层接口,即可对接OceanConncet平台。

      功能

      Agent Tiny互联互通中间件为用户提供以下几类接口:

      接口分类 接口名 描述
      Agent Tiny依赖接口 atiny_cmd_ioctl Agent Tiny申明和调用,开发者实现。该接口是LwM2M标准对象向设备下发命令的统一入口,比如读写设备数据,下发复位,升级命令等。为了避免死锁,该接口中禁止调用Agent Tiny对外接口
      atiny_event_notify Agent Tiny申明和调用,开发者实现,Agent Tiny把注册过程的关键状态,以及运行过程的关键事件通知用户,便于用户根据自身的应用场景灵活地做可靠性处理。此外,为了避免死锁,该接口中禁止调用Agent Tiny对外接口
      Agent Tiny对外接口 atiny_init Agent Tiny的初始化接口,由Agent Tiny实现,开发者调用
      atiny_bind Agent Tiny的主函数体,由Agent Tiny实现,开发者调用,调用成功后,不会返回。该接口是Agent Tiny主循环体,实现了LwM2M协议处理,注册状态机,重传队列,订阅上报
      atiny_deinit Agent Tiny的去初始化接口,由Agent Tiny实现,开发者调用,该接口为阻塞式接口,调用该接口时,会直到agent tiny主任务退出,资源释放完毕,该接口才会退出
      atiny_data_report Agent Tiny数据上报接口,由agent Tiny实现,开发者调用,用户APP数据使用该接口上报,该接口为阻塞接口,不允许在中断中使用

      开发流程

      Agent Tiny典型场景的开发流程:

      1. 根据Agent Tiny提供的头文件说明,实现atiny_cmd_ioctl接口。该接口有三个参数,参数cmd为命令类型,参数arg的内存空间由Agent Tiny分配,其内容填充视cmd而异,如读数据相关命令,由device侧填充,Agent Tiny使用,如写数据命令,则由agent Tiny填充,device侧使用。参数len指arg所指向的内存空间长度,device侧填充或读取时,务必防止溢出。

      2. 根据Agent Tiny提供的头文件说明,实现atiny_event_notify接口。该接口有三个参数,参数stat为事件类型,参数arg是 Agent Tiny根据事件类型,传递给device侧的具体的事件信息,len为arg长度,device侧使用时务分防止溢出。

      3. 调用atiny_init初始化Agent Tiny,获取对应的Agent Tiny句柄,开发者应处理该接口返回值,返回错误时,句柄无效。

      4. 创建一个新任务,栈大小建议不小于4K,调用atiny_bind,启动Agent Tiny。atiny_bind调用成功后不再返回,atiny_bind内部实现了Agent Tiny的主体任务。

      5. 如需要停止Agent Tiny,调用atiny_deinit,该接口等待Agent Tiny退出且释放资源后返回。

      6. atiny_data_report可以在开发者业务的任何一个任务中调用。

      互斥锁错误码

      Agent Tiny对外接口和依赖接口,可能存在的错误,统一用以下错误码。

      序号 定义 实际数值 描述 参考解决方案
      1 ATINY_OK 0 正常返回码
      2 ATINY_ARG_INVALID -1 非法参数 确保入参合法
      3 ATINY_BUF_OVERFLOW -2 缓冲区溢出 确保缓冲区充足
      4 ATINY_MSG_CONGEST -3 消息拥塞 暂缓数据上报
      5 ATINY_MALLOC_FAILED -4 内存申请失败 检查内存是否有泄漏
      6 ATINY_RESOURCE_NOT_FOUND -5 数据上报类型非法 检查数据类型是否正确
      7 ATINY_RESOURCE_NOT_ENOUGH -6 系统资源不足 检查系统资源,比如信号量,套接字个数等,是否配置过少,或是否有泄漏
      8 ATINY_CLIENT_UNREGISTERED -7 AgentTiny注册失败 检查psk,服务器信息等是否正确
      9 ATINY_SOCKET_CREATE_FAILED -8 网络套接字创建失败 检查网络配置和参数是否正确

      平台差异性

      无。

      注意事项

      • atiny_cmd_ioctl和atiny_event_notify禁止调用atiny_deinit,atiny_data_report,atiny_init,atiny_bind四个Agent Tiny对外接口,否则可能产生死锁,或其他异常。

      • 调用atiny_deinit之前务必确认已调用atiny_bin,否则atiny_deinit将一直阻塞,调用完atiny_deinit后,对应的Agent Tiny句柄将失效,禁止再使用。

      • 承载atiny_bind的任务栈大小建议不小于4K,任务优先级视系统情况而定,太低可能会导致接收丢包,发送延迟等现象。

      编程实例

      实例描述

      本实例实现如下流程:

      1. 实现atiny_cmd_ioctl和atiny_event_notify。

      2. 创建数据上报任务。

      3. 调用atiny_init初始化AgentTiny。

      4. 调用atiny_bind启动AgentTiny。

      编程示例

      前提条件:

      在工程配置中,WITH_DTLS编译选项打开。

      代码实现如下:

      1. #define MAX_PSK_LEN 16
      2. #define DEFAULT_SERVER_IPV4 “139.159.209.89”
      3. #define DEFAULT_SERVER_PORT “5684”
      4. #define LWM2M_LIFE_TIME 50000
      5. char g_endpoint_name_s = “11110001”;
      6. unsigned char g_psk_value[MAX_PSK_LEN] = {0xef,0xe8,0x18,0x45,0xa3,0x53,0xc1,0x3c,0x0c,0x89,0x92,0xb3,0x1d,0x6b,0x6a,0x33};
      7. UINT32 TskHandle;
      8. static void g_phandle = NULL;
      9. static atiny_device_info_t g_device_info;
      10. static atiny_param_t g_atiny_params;
      11. int atiny_cmd_ioctl(atiny_cmd_e cmd, char arg, int len)
      12. {
      13. int result = ATINY_OK;
      14. switch(cmd)
      15. {
      16. case ATINY_DO_DEV_REBOOT:
      17. result = atiny_do_dev_reboot();
      18. break;
      19. case ATINY_GET_MIN_VOLTAGE:
      20. result = atiny_get_min_voltage((int)arg);
      21. break;
      22. default:
      23. result = ATINY_RESOURCE_NOT_FOUND;
      24. break;
      25. }
      26. return result;
      27. }
      28. void atiny_event_notify(atiny_event_e stat, char arg, int len)
      29. {
      30. (void)atiny_printf(“notify:stat:%d\r\n”, stat);
      31. }
      32. void ack_callback(atiny_report_type_e type, int cookie, data_send_status_e status)
      33. {
      34. printf(“ack type:%d cookie:%d status:%d\n”, type,cookie, status);
      35. }
      36. void app_data_report(void)
      37. {
      38. uint8_t buf[5] = {0,1,6,5,9};
      39. data_report_t report_data;
      40. int cnt = 0;
      41. report_data.buf = buf;
      42. report_data.callback = ack_callback;
      43. report_data.cookie = 0;
      44. report_data.len = sizeof(buf);
      45. report_data.type = APP_DATA;
      46. while(1)
      47. {
      48. report_data.cookie = cnt;
      49. cnt++;
      50. (void)atiny_data_report(g_phandle, &report_data);
      51. (void)LOS_TaskDelay(2000);
      52. }
      53. }
      54. UINT32 creat_report_task()
      55. {
      56. UINT32 uwRet = LOS_OK;
      57. TSK_INIT_PARAM_S task_init_param;
      58. task_init_param.usTaskPrio = 1;
      59. task_init_param.pcName = “app_data_report”;
      60. task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)app_data_report;
      61. task_init_param.uwStackSize = 0x1000;
      62. uwRet = LOS_TaskCreate(&TskHandle, &task_init_param);
      63. if(LOS_OK != uwRet)
      64. {
      65. return uwRet;
      66. }
      67. return uwRet;
      68. }
      69. void agent_tiny_entry(void)
      70. {
      71. UINT32 uwRet = LOS_OK;
      72. atiny_param_t atiny_params;
      73. atiny_security_param_t security_param = NULL;
      74. atiny_device_info_t device_info = &g_device_info;
      75. device_info->endpoint_name = g_endpoint_name_s;
      76. device_info->manufacturer = “test”;
      77. atiny_params = &g_atiny_params;
      78. atiny_params->server_params.binding = “UQ”;
      79. atiny_params->server_params.life_time = LWM2M_LIFE_TIME;
      80. atiny_params->server_params.storing_cnt = 0;
      81. security_param = &(atiny_params->security_params[0]);
      82. security_param->is_bootstrap = FALSE;
      83. security_param->server_ip = DEFAULT_SERVER_IPV4;
      84. security_param->server_port = DEFAULT_SERVER_PORT;
      85. security_param->psk_Id = g_endpoint_name_s;
      86. security_param->psk = (char*)g_psk_value;
      87. security_param->psk_len = sizeof(g_psk_value);
      88. if(ATINY_OK != atiny_init(atiny_params, &g_phandle))
      89. {
      90. return;
      91. }
      92. uwRet = creat_report_task();
      93. if(LOS_OK != uwRet)
      94. {
      95. return;
      96. }
      97. (void)atiny_bind(device_info, g_phandle);
      98. }

      结果验证

      1. 登录OceanConncet测试平台:

      https://139.159.209.89:8843/index.html#/device

      请在OceanConnect平台上提前注册账号。

      1. 选择查看“设备”。
        5.Agent Tiny - 图2

      2. 点击第一个设备,查看其设备标识码为11110001,说明设备已经注册。
        5.Agent Tiny - 图3