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